diff options
875 files changed, 61965 insertions, 1965 deletions
diff --git a/demos/declarative/minehunt/main.cpp b/demos/declarative/minehunt/main.cpp index c756e66..8ca37ff 100644 --- a/demos/declarative/minehunt/main.cpp +++ b/demos/declarative/minehunt/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/demos/demos.pro b/demos/demos.pro index 08dd8af..4c2318c 100644 --- a/demos/demos.pro +++ b/demos/demos.pro @@ -55,6 +55,7 @@ wince*:SUBDIRS += demos_sqlbrowser } contains(QT_CONFIG, phonon):!static:SUBDIRS += demos_mediaplayer contains(QT_CONFIG, webkit):contains(QT_CONFIG, svg):!symbian:SUBDIRS += demos_browser +contains(QT_CONFIG, multimedia):SUBDIRS += demos_multimedia # install sources.files = README *.pro @@ -82,6 +83,7 @@ demos_sqlbrowser.subdir = sqlbrowser demos_undo.subdir = undo demos_qtdemo.subdir = qtdemo demos_mediaplayer.subdir = qmediaplayer +demos_multimedia.subdir = multimedia demos_browser.subdir = browser diff --git a/demos/multimedia/multimedia.pro b/demos/multimedia/multimedia.pro new file mode 100644 index 0000000..042650f --- /dev/null +++ b/demos/multimedia/multimedia.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = player + + diff --git a/demos/multimedia/player/main.cpp b/demos/multimedia/player/main.cpp new file mode 100644 index 0000000..87c5b87 --- /dev/null +++ b/demos/multimedia/player/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "player.h" + +#include <QtGui> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + Player player; + player.show(); + + return app.exec(); +}; diff --git a/demos/multimedia/player/player.cpp b/demos/multimedia/player/player.cpp new file mode 100644 index 0000000..64b1f25 --- /dev/null +++ b/demos/multimedia/player/player.cpp @@ -0,0 +1,325 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "player.h" + +#include "playercontrols.h" +#include "playlistmodel.h" +#include "videowidget.h" + +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediaplaylist.h> + +#include <QtGui> + +Player::Player(QWidget *parent) + : QWidget(parent) + , videoWidget(0) + , coverLabel(0) + , slider(0) + , colorDialog(0) +{ + player = new QMediaPlayer(this); + playlist = new QMediaPlaylist(this); + playlist->setMediaObject(player); + + 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))); + + videoWidget = new VideoWidget; + videoWidget->setMediaObject(player); + + playlistModel = new PlaylistModel(this); + playlistModel->setPlaylist(playlist); + + playlistView = new QListView; + playlistView->setModel(playlistModel); + playlistView->setCurrentIndex(playlistModel->index(playlist->currentIndex(), 0)); + + connect(playlistView, SIGNAL(activated(QModelIndex)), this, SLOT(jump(QModelIndex))); + + slider = new QSlider(Qt::Horizontal); + slider->setRange(0, player->duration() / 1000); + + connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(seek(int))); + + QPushButton *openButton = new QPushButton(tr("Open")); + + connect(openButton, SIGNAL(clicked()), this, SLOT(open())); + + PlayerControls *controls = new PlayerControls; + 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()), playlist, SLOT(previous())); + 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(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))); + + QPushButton *fullScreenButton = new QPushButton(tr("FullScreen")); + fullScreenButton->setCheckable(true); + + if (videoWidget != 0) { + connect(fullScreenButton, SIGNAL(clicked(bool)), videoWidget, SLOT(setFullScreen(bool))); + connect(videoWidget, SIGNAL(fullScreenChanged(bool)), + fullScreenButton, SLOT(setChecked(bool))); + } else { + fullScreenButton->setEnabled(false); + } + + QPushButton *colorButton = new QPushButton(tr("Color Options...")); + if (videoWidget) + connect(colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog())); + else + colorButton->setEnabled(false); + + QBoxLayout *displayLayout = new QHBoxLayout; + if (videoWidget) + displayLayout->addWidget(videoWidget, 2); + else + displayLayout->addWidget(coverLabel, 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); + controlLayout->addWidget(colorButton); + + QBoxLayout *layout = new QVBoxLayout; + layout->addLayout(displayLayout); + layout->addWidget(slider); + layout->addLayout(controlLayout); + + setLayout(layout); + + metaDataChanged(); + + QStringList fileNames = qApp->arguments(); + fileNames.removeAt(0); + foreach (QString const &fileName, fileNames) { + if (QFileInfo(fileName).exists()) + playlist->addMedia(QUrl::fromLocalFile(fileName)); + } +} + +Player::~Player() +{ + delete playlist; + delete player; +} + +void Player::open() +{ + QStringList fileNames = QFileDialog::getOpenFileNames(); + foreach (QString const &fileName, fileNames) + playlist->addMedia(QUrl::fromLocalFile(fileName)); +} + +void Player::durationChanged(qint64 duration) +{ + slider->setMaximum(duration / 1000); +} + +void Player::positionChanged(qint64 progress) +{ + slider->setValue(progress / 1000); +} + +void Player::metaDataChanged() +{ + //qDebug() << "update metadata" << player->metaData(QtMultimedia::Title).toString(); + if (player->isMetaDataAvailable()) { + setTrackInfo(QString("%1 - %2") + .arg(player->metaData(QtMultimedia::AlbumArtist).toString()) + .arg(player->metaData(QtMultimedia::Title).toString())); + + if (coverLabel) { + QUrl url = player->metaData(QtMultimedia::CoverArtUrlLarge).value<QUrl>(); + + coverLabel->setPixmap(!url.isEmpty() + ? QPixmap(url.toString()) + : QPixmap()); + } + } +} + +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) +{ + switch (status) { + case QMediaPlayer::UnknownMediaStatus: + case QMediaPlayer::NoMedia: + case QMediaPlayer::LoadedMedia: + case QMediaPlayer::BufferingMedia: + case QMediaPlayer::BufferedMedia: +#ifndef QT_NO_CURSOR + unsetCursor(); +#endif + setStatusInfo(QString()); + break; + case QMediaPlayer::LoadingMedia: +#ifndef QT_NO_CURSOR + setCursor(QCursor(Qt::BusyCursor)); +#endif + setStatusInfo(tr("Loading...")); + break; + case QMediaPlayer::StalledMedia: +#ifndef QT_NO_CURSOR + setCursor(QCursor(Qt::BusyCursor)); +#endif + break; + case QMediaPlayer::EndOfMedia: +#ifndef QT_NO_CURSOR + unsetCursor(); +#endif + setStatusInfo(QString()); + QApplication::alert(this); + break; + case QMediaPlayer::InvalidMedia: +#ifndef QT_NO_CURSOR + unsetCursor(); +#endif + setStatusInfo(player->errorString()); + break; + } +} + +void Player::bufferingProgress(int progress) +{ + setStatusInfo(tr("Buffering %4%%").arg(progress)); +} + +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::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); + + colorDialog = new QDialog(this); + colorDialog->setWindowTitle(tr("Color Options")); + colorDialog->setLayout(layout); + } + colorDialog->show(); +} diff --git a/demos/multimedia/player/player.h b/demos/multimedia/player/player.h new file mode 100644 index 0000000..0ad609b --- /dev/null +++ b/demos/multimedia/player/player.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLAYER_H +#define PLAYER_H + +#include <QtGui/QWidget> + +#include <qmediaplayer.h> +#include <qmediaplaylist.h> +#include <qvideowidget.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractItemView; +class QLabel; +class QModelIndex; +class QSlider; +class QMediaPlayer; +class QVideoWidget; +class PlaylistModel; + +class Player : public QWidget +{ + Q_OBJECT +public: + Player(QWidget *parent = 0); + ~Player(); + +Q_SIGNALS: + void fullScreenChanged(bool fullScreen); + +private slots: + void open(); + void durationChanged(qint64 duration); + void positionChanged(qint64 progress); + void metaDataChanged(); + + void seek(int seconds); + void jump(const QModelIndex &index); + void playlistPositionChanged(int); + + void statusChanged(QMediaPlayer::MediaStatus status); + void bufferingProgress(int progress); + + void showColorDialog(); + +private: + void setTrackInfo(const QString &info); + void setStatusInfo(const QString &info); + + QMediaPlayer *player; + QMediaPlaylist *playlist; + QVideoWidget *videoWidget; + QLabel *coverLabel; + QSlider *slider; + PlaylistModel *playlistModel; + QAbstractItemView *playlistView; + QDialog *colorDialog; + QString trackInfo; + QString statusInfo; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/demos/multimedia/player/player.pro b/demos/multimedia/player/player.pro new file mode 100644 index 0000000..dc731e4 --- /dev/null +++ b/demos/multimedia/player/player.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +TARGET = player + +QT += gui multimedia + + +HEADERS = \ + player.h \ + playercontrols.h \ + playlistmodel.h \ + videowidget.h + +SOURCES = \ + main.cpp \ + player.cpp \ + playercontrols.cpp \ + playlistmodel.cpp \ + videowidget.cpp + +target.path = $$[QT_INSTALL_DEMOS]/multimedia/player +INSTALLS += target + diff --git a/demos/multimedia/player/playercontrols.cpp b/demos/multimedia/player/playercontrols.cpp new file mode 100644 index 0000000..3798a71 --- /dev/null +++ b/demos/multimedia/player/playercontrols.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "playercontrols.h" + +#include <QtGui/qboxlayout.h> +#include <QtGui/qslider.h> +#include <QtGui/qstyle.h> +#include <QtGui/qtoolbutton.h> +#include <QtGui/qcombobox.h> + +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; + playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + + connect(playButton, SIGNAL(clicked()), this, SLOT(playClicked())); + + stopButton = new QToolButton; + stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop)); + stopButton->setEnabled(false); + + connect(stopButton, SIGNAL(clicked()), this, SIGNAL(stop())); + + nextButton = new QToolButton; + nextButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward)); + + connect(nextButton, SIGNAL(clicked()), this, SIGNAL(next())); + + previousButton = new QToolButton; + previousButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward)); + + connect(previousButton, SIGNAL(clicked()), this, SIGNAL(previous())); + + muteButton = new QToolButton; + muteButton->setIcon(style()->standardIcon(QStyle::SP_MediaVolume)); + + connect(muteButton, SIGNAL(clicked()), this, SLOT(muteClicked())); + + volumeSlider = new QSlider(Qt::Horizontal); + volumeSlider->setRange(0, 100); + + connect(volumeSlider, SIGNAL(sliderMoved(int)), this, SIGNAL(changeVolume(int))); + + rateBox = new QComboBox; + 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->value(); +} + +void PlayerControls::setVolume(int volume) +{ + 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()); +} diff --git a/demos/multimedia/player/playercontrols.h b/demos/multimedia/player/playercontrols.h new file mode 100644 index 0000000..99894ff --- /dev/null +++ b/demos/multimedia/player/playercontrols.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLAYERCONTROLS_H +#define PLAYERCONTROLS_H + +#include <QtMultimedia/qmediaplayer.h> + +#include <QtGui/qwidget.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractButton; +class QAbstractSlider; +class QComboBox; + +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; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/demos/multimedia/player/playlistmodel.cpp b/demos/multimedia/player/playlistmodel.cpp new file mode 100644 index 0000000..b60f914 --- /dev/null +++ b/demos/multimedia/player/playlistmodel.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "playlistmodel.h" + +#include <QtCore/qfileinfo.h> +#include <QtCore/qurl.h> + +#include <qmediaplaylist.h> + +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))); + } + + 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))); + } + + + reset(); +} + +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)); +} + + diff --git a/demos/multimedia/player/playlistmodel.h b/demos/multimedia/player/playlistmodel.h new file mode 100644 index 0000000..0180282 --- /dev/null +++ b/demos/multimedia/player/playlistmodel.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PLAYLISTMODEL_H +#define PLAYLISTMODEL_H + +#include <QtCore/qabstractitemmodel.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaPlaylist; + +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; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/demos/multimedia/player/videowidget.cpp b/demos/multimedia/player/videowidget.cpp new file mode 100644 index 0000000..3bf36c3 --- /dev/null +++ b/demos/multimedia/player/videowidget.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videowidget.h" + +#include <QtGui> + +VideoWidget::VideoWidget(QWidget *parent) + : QVideoWidget(parent) +{ + setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); +} + +void VideoWidget::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && isFullScreen()) { + showNormal(); + + 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(); +} diff --git a/demos/multimedia/player/videowidget.h b/demos/multimedia/player/videowidget.h new file mode 100644 index 0000000..543e1e0 --- /dev/null +++ b/demos/multimedia/player/videowidget.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef VIDEOWIDGET_H +#define VIDEOWIDGET_H + +#include <QtMultimedia/qvideowidget.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class VideoWidget : public QVideoWidget +{ + Q_OBJECT +public: + VideoWidget(QWidget *parent = 0); + +protected: + void keyPressEvent(QKeyEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/doc/doc.pri b/doc/doc.pri index 9d7d5da..0fc4d72 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -31,8 +31,14 @@ QT_DOCUMENTATION = ($$QDOC qt-api-only.qdocconf assistant.qdocconf designer.qdoc $$GENERATOR doc-build/html-qml/qml.qhp -o doc/qch/qml.qch \ ) +QT_ZH_CN_DOCUMENTATION = ($$QDOC qt-api-only_zh_CN.qdocconf) && \ + (cd $$QT_BUILD_TREE && \ + $$GENERATOR doc-build/html-qt_zh_CN/qt.qhp -o doc/qch/qt_zh_CN.qch \ + ) + win32-g++:isEmpty(QMAKE_SH) { QT_DOCUMENTATION = $$replace(QT_DOCUMENTATION, "/", "\\\\") + QT_ZH_CN_DOCUMENTATION = $$replace(QT_ZH_CN_DOCUMENTATION, "/", "\\\\") } # Build rules: @@ -43,6 +49,9 @@ qch_docs.depends += sub-tools docs.depends = adp_docs qch_docs +docs_zh_CN.depends = docs +docs_zh_CN.commands = $$QT_ZH_CN_DOCUMENTATION + # Install rules htmldocs.files = $$QT_BUILD_TREE/doc/html htmldocs.path = $$[QT_INSTALL_DOCS] @@ -55,5 +64,5 @@ qchdocs.CONFIG += no_check_exist docimages.files = $$QT_BUILD_TREE/doc/src/images docimages.path = $$[QT_INSTALL_DOCS]/src -QMAKE_EXTRA_TARGETS += qdoc adp_docs qch_docs docs +QMAKE_EXTRA_TARGETS += qdoc adp_docs qch_docs docs docs_zh_CN INSTALLS += htmldocs qchdocs docimages diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc index 1456eae9..10c53d5 100644 --- a/doc/src/declarative/advtutorial.qdoc +++ b/doc/src/declarative/advtutorial.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/advtutorial1.qdoc b/doc/src/declarative/advtutorial1.qdoc index 86d14ad..598537a 100644 --- a/doc/src/declarative/advtutorial1.qdoc +++ b/doc/src/declarative/advtutorial1.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/advtutorial2.qdoc b/doc/src/declarative/advtutorial2.qdoc index 2aa68f3..1addf45 100644 --- a/doc/src/declarative/advtutorial2.qdoc +++ b/doc/src/declarative/advtutorial2.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/advtutorial3.qdoc b/doc/src/declarative/advtutorial3.qdoc index e6e4e97..d101a98 100644 --- a/doc/src/declarative/advtutorial3.qdoc +++ b/doc/src/declarative/advtutorial3.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/advtutorial4.qdoc b/doc/src/declarative/advtutorial4.qdoc index 855963c..059f8bf 100644 --- a/doc/src/declarative/advtutorial4.qdoc +++ b/doc/src/declarative/advtutorial4.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/anchor-layout.qdoc b/doc/src/declarative/anchor-layout.qdoc index 2bd0ec5..f4db5bf 100644 --- a/doc/src/declarative/anchor-layout.qdoc +++ b/doc/src/declarative/anchor-layout.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index bf5907d..acf72e3 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc index de5a959..86485d0 100644 --- a/doc/src/declarative/basictypes.qdoc +++ b/doc/src/declarative/basictypes.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -65,6 +65,8 @@ \qml Item { width: 100; height: 200 } \endqml + + \sa {QML Basic Types} */ /*! @@ -80,6 +82,7 @@ Item { focus: true; clip: false } \endqml + \sa {QML Basic Types} */ /*! @@ -99,6 +102,7 @@ {http://en.wikipedia.org/wiki/IEEE_754} {IEEE floating point} format. + \sa {QML Basic Types} */ /*! @@ -114,6 +118,7 @@ Text { text: "Hello world!" } \endqml + \sa {QML Basic Types} */ /*! @@ -136,6 +141,7 @@ \raw HTML \endraw + \sa {QML Basic Types} */ /*! @@ -162,6 +168,7 @@ Rectangle { color: "#800000FF" } \endqml + \sa {QML Basic Types} */ /*! @@ -177,6 +184,7 @@ Widget { pos: "0,20" } \endqml + \sa {QML Basic Types} */ /*! @@ -192,6 +200,7 @@ Widget { size: "150x50" } \endqml + \sa {QML Basic Types} */ /*! @@ -207,6 +216,7 @@ Widget { geometry: "50,50,100x100" } \endqml + \sa {QML Basic Types} */ /*! @@ -222,6 +232,7 @@ DatePicker { minDate: "2000-01-01"; maxDate: "2020-12-31" } \endqml + \sa {QML Basic Types} */ /*! @@ -237,6 +248,7 @@ TimePicker { time: "14:22:15" } \endqml + \sa {QML Basic Types} */ /*! @@ -261,6 +273,7 @@ Text { font.family: "Helvetica"; font.pointSize: 13; font.bold: true } \endqml + \sa {QML Basic Types} */ /*! @@ -286,6 +299,7 @@ Text { text: MyItem.someaction.text } \endqml + \sa {QML Basic Types} */ /*! @@ -313,6 +327,7 @@ \c Child1, \c Child2 and \c Child3 will all be added to the children list in the order in which they appear. + \sa {QML Basic Types} */ /*! @@ -338,4 +353,6 @@ \qml Rotation { angle: 60; axis.x: 0; axis.y: 1; axis.z: 0 } \endqml + + \sa {QML Basic Types} */ diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 8228c11..6a1b2b1 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc index fede2cd..1d0a5a4 100644 --- a/doc/src/declarative/dynamicobjects.qdoc +++ b/doc/src/declarative/dynamicobjects.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,28 +21,27 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \page qmldynamicobjects.html -\title Dynamic Object Creation +\title Dynamic Object Management QML has some support for dynamically loading and managing QML objects from within Javascript blocks. It is preferable to use the existing QML elements for diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index cfbabf2..9bc44db 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc index 41a8574..c731d4a 100644 --- a/doc/src/declarative/example-slideswitch.qdoc +++ b/doc/src/declarative/example-slideswitch.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -121,7 +121,7 @@ states (\e on and \e off). This second function is called when the knob is released and we want to make sure that the knob does not end up between states (neither \e on nor \e off). If it is the case call the \c toggle() function otherwise we do nothing. -For more information on scripts see \l{qmlecmascript.html}{JavaScript Blocks}. +For more information on scripts see \l{qmljavascript.html}{JavaScript Blocks}. \section2 Transition \snippet examples/declarative/slideswitch/content/Switch.qml 7 diff --git a/doc/src/declarative/examples.qdoc b/doc/src/declarative/examples.qdoc index 3288e17..46cac07 100644 --- a/doc/src/declarative/examples.qdoc +++ b/doc/src/declarative/examples.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/extending-examples.qdoc b/doc/src/declarative/extending-examples.qdoc index 17bef4e..e92fa04 100644 --- a/doc/src/declarative/extending-examples.qdoc +++ b/doc/src/declarative/extending-examples.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc index 3b9c7f3..c75c22e 100644 --- a/doc/src/declarative/extending.qdoc +++ b/doc/src/declarative/extending.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc index 46bfc38..63df61c 100644 --- a/doc/src/declarative/focus.qdoc +++ b/doc/src/declarative/focus.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index 764552a..00b9cb7 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -71,7 +71,7 @@ when the property has one of the following types: \o Vector3D \endlist -There are also string based constructors for these types, see \l{basicqmltypes.html}{Qml Types}. +There are also string based constructors for these types, see \l{qmlbasictypes.html}{Qml Types}. \section3 Qt.rgba(qreal red, qreal green, qreal blue, qreal alpha) This function returns a Color with the specified \c red, \c green, \c blue and \c alpha components. All components should be in the range 0-1 inclusive. diff --git a/doc/src/declarative/integrating.qdoc b/doc/src/declarative/integrating.qdoc index d93a6ff..b7f8b17 100644 --- a/doc/src/declarative/integrating.qdoc +++ b/doc/src/declarative/integrating.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -68,10 +68,12 @@ elements, and QML is a better choice if your UI is comprised of a large number of simple and dynamic elements. \section1 Adding QML to a QGraphicsView based UI -If you have an existing Graphics View based UI you can create new items in QML, -and use \l{QmlComponent} to create \l{QGraphicsObject}s from the QML files. These -\l{QGraphicsObject}s can then be placed into your \l{QGraphicsScene} using \l{QGraphicsScene::addItem} -or by reparenting them to an item already in the \l{QGraphicsScene}. + +If you have an existing Graphics View based UI you can create new +items in QML, and use \l{QmlComponent} to create \l{QGraphicsObject}s +from the QML files. These \l{QGraphicsObject}s can then be placed into +your \l{QGraphicsScene} using \l{QGraphicsScene::addItem()} or by +reparenting them to an item already in the \l{QGraphicsScene}. Example, for local QML files: diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 9c72a9c..c2d63b2 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/measuring-performance.qdoc b/doc/src/declarative/measuring-performance.qdoc index bd1b0eb..5413c4a 100644 --- a/doc/src/declarative/measuring-performance.qdoc +++ b/doc/src/declarative/measuring-performance.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index 368595f..9eae572 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/network.qdoc b/doc/src/declarative/network.qdoc index ed20e66e..7b16b53 100644 --- a/doc/src/declarative/network.qdoc +++ b/doc/src/declarative/network.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/propertybinding.qdoc b/doc/src/declarative/propertybinding.qdoc index ad4f13e..b42c51f 100644 --- a/doc/src/declarative/propertybinding.qdoc +++ b/doc/src/declarative/propertybinding.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/qmldebugging.qdoc b/doc/src/declarative/qmldebugging.qdoc index a6def19..97bc2f8 100644 --- a/doc/src/declarative/qmldebugging.qdoc +++ b/doc/src/declarative/qmldebugging.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/qmldocument.qdoc b/doc/src/declarative/qmldocument.qdoc index deb6e1c..907dd10 100644 --- a/doc/src/declarative/qmldocument.qdoc +++ b/doc/src/declarative/qmldocument.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/qmli18n.qdoc b/doc/src/declarative/qmli18n.qdoc index 0c8b1d1..bc64ed7 100644 --- a/doc/src/declarative/qmli18n.qdoc +++ b/doc/src/declarative/qmli18n.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -85,8 +85,8 @@ Next we create a translation source file using lupdate: lupdate hello.qml -ts hello.ts \endcode -Then we open \c hello.ts in \l {Linguist}, provide a translation -and create the release file \c hello.qm. +Then we open \c hello.ts in \l{Qt Linguist Manual} {Linguist}, provide +a translation and create the release file \c hello.qm. Finally, we can test the translation in qmlviewer: \code diff --git a/doc/src/declarative/qmlintro.qdoc b/doc/src/declarative/qmlintro.qdoc index 3891515..0a503d7 100644 --- a/doc/src/declarative/qmlintro.qdoc +++ b/doc/src/declarative/qmlintro.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -168,7 +168,7 @@ Properties begin with a lowercase letter (with the exception of \l{Attached Prop \section2 Property types -QML supports properties of many types (see \l{Common QML Types}). The basic types include int, +QML supports properties of many types (see \l{QML Basic Types}). The basic types include int, real, bool, string, color, and lists. \code @@ -266,6 +266,7 @@ State { because \c changes is the default property of the \c State type. \section2 Grouped Properties +\target dot properties In some cases properties form a logical group and use a 'dot' or grouped notation to show this. diff --git a/doc/src/declarative/qmlmodels.qdoc b/doc/src/declarative/qmlmodels.qdoc index 008ea2a..c898c07 100644 --- a/doc/src/declarative/qmlmodels.qdoc +++ b/doc/src/declarative/qmlmodels.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -198,6 +198,10 @@ QAbstractItemModel provides the roles set via the QAbstractItemModel::setRoleNam QStringList provides the contents of the list via the \e modelData role: \table +\header +\o +\o +\row \o \code // main.cpp @@ -228,7 +232,7 @@ ListView { \endcode \endtable -Note: There is no way for the view to know that the contents of a QStringList +\note There is no way for the view to know that the contents of a QStringList have changed. If the QStringList is changed, it will be necessary to reset the model by calling QmlContext::setContextProperty() again. diff --git a/doc/src/declarative/qmlreference.qdoc b/doc/src/declarative/qmlreference.qdoc index a413c22..f52ff41 100644 --- a/doc/src/declarative/qmlreference.qdoc +++ b/doc/src/declarative/qmlreference.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/qmlstates.qdoc b/doc/src/declarative/qmlstates.qdoc index abf3c93..b178e718 100644 --- a/doc/src/declarative/qmlstates.qdoc +++ b/doc/src/declarative/qmlstates.qdoc @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + /*! \page qmlstates.html \target qmlstates diff --git a/doc/src/declarative/qmlviewer.qdoc b/doc/src/declarative/qmlviewer.qdoc index a5cb671..79877b9 100644 --- a/doc/src/declarative/qmlviewer.qdoc +++ b/doc/src/declarative/qmlviewer.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index cae0263..4909355 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc index 6a94b6e..709c212 100644 --- a/doc/src/declarative/qtdeclarative.qdoc +++ b/doc/src/declarative/qtdeclarative.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/qtprogrammers.qdoc b/doc/src/declarative/qtprogrammers.qdoc index 26f73cb..a203662 100644 --- a/doc/src/declarative/qtprogrammers.qdoc +++ b/doc/src/declarative/qtprogrammers.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -58,7 +58,7 @@ an application with a UI defined in QML also uses Qt for all the non-UI logic. QML provides direct access to the following concepts from Qt: \list - \o QAction - the \l {basicqmlaction}{action} type + \o QAction - the \l {QML Basic Types}{action} type \o QObject signals and slots - available as functions to call in JavaScript \o QObject properties - available as variables in JavaScript \o QWidget - QmlView is a QML-displaying widget diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index defb217..470e8f6 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/doc/src/declarative/tutorial.qdoc b/doc/src/declarative/tutorial.qdoc index 19921c0..54b6610 100644 --- a/doc/src/declarative/tutorial.qdoc +++ b/doc/src/declarative/tutorial.qdoc @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + /*! \page tutorial.html \title Tutorial diff --git a/doc/src/declarative/tutorial1.qdoc b/doc/src/declarative/tutorial1.qdoc index f7e44b0..b89c74a 100644 --- a/doc/src/declarative/tutorial1.qdoc +++ b/doc/src/declarative/tutorial1.qdoc @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + /*! \page tutorial1.html \title Tutorial 1 - Basic Types @@ -37,7 +78,7 @@ We add a \l Text element as a child of our root element that will display the te The \c y property is used to position the text vertically at 30 pixels from the top of its parent. -The \c font.pointSize and \c font.bold properties are related to fonts and use the \l{Dot Properties}{dot notation}. +The \c font.pointSize and \c font.bold properties are related to fonts and use the \l{dot properties}{dot notation}. The \c anchors.horizontalCenter property refers to the horizontal center of an element. In this case, we specify that our text element should be horizontally centered in the \e page element (see \l{anchor-layout}{Anchor-based Layout}). diff --git a/doc/src/declarative/tutorial2.qdoc b/doc/src/declarative/tutorial2.qdoc index dd0d428..3e92e37 100644 --- a/doc/src/declarative/tutorial2.qdoc +++ b/doc/src/declarative/tutorial2.qdoc @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + /*! \page tutorial2.html \title Tutorial 2 - QML Component diff --git a/doc/src/declarative/tutorial3.qdoc b/doc/src/declarative/tutorial3.qdoc index 290b535..e4d7995 100644 --- a/doc/src/declarative/tutorial3.qdoc +++ b/doc/src/declarative/tutorial3.qdoc @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + /*! \page tutorial3.html \title Tutorial 3 - States and Transitions diff --git a/doc/src/development/qtestlib.qdoc b/doc/src/development/qtestlib.qdoc index 4b9c657..2b38b2c 100644 --- a/doc/src/development/qtestlib.qdoc +++ b/doc/src/development/qtestlib.qdoc @@ -582,7 +582,7 @@ /*! \example qtestlib/tutorial3 - \previouspage {Chapter 2 Data Driven Testing}{Chapter 2} + \previouspage {Chapter 2: Data Driven Testing}{Chapter 2} \contentspage {QTestLib Tutorial}{Contents} \nextpage {Chapter 4: Replaying GUI Events}{Chapter 4} diff --git a/doc/src/examples/contextsensitivehelp.qdoc b/doc/src/examples/contextsensitivehelp.qdoc index 668fa36..92ace2d 100644 --- a/doc/src/examples/contextsensitivehelp.qdoc +++ b/doc/src/examples/contextsensitivehelp.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/doc/src/examples/editabletreemodel.qdoc b/doc/src/examples/editabletreemodel.qdoc index d925c43..38754b6 100644 --- a/doc/src/examples/editabletreemodel.qdoc +++ b/doc/src/examples/editabletreemodel.qdoc @@ -223,7 +223,7 @@ corresponding \c TreeItem, and return model indexes that correspond to its parents and children. - In the diagram, we show how the model's \l{TreeModel::parent()}{parent()} + In the diagram, we show how the model's \l{TreeModel::parent}{parent()} implementation obtains the model index corresponding to the parent of an item supplied by the caller, using the items shown in a \l{Relations-between-internal-items}{previous diagram}. diff --git a/doc/src/internationalization/i18n.qdoc b/doc/src/internationalization/i18n.qdoc index 1ca6ab3..d5f32e3 100644 --- a/doc/src/internationalization/i18n.qdoc +++ b/doc/src/internationalization/i18n.qdoc @@ -729,7 +729,7 @@ \section1 Further Reading - \l{Qt Linguist Manual}, \l{Hello tr Example}, \l{Translation Rules for Plurals} + \l{Qt Linguist Manual}, \l{Hello tr() Example}, \l{Translation Rules for Plurals} */ /*! diff --git a/doc/src/legal/licenses.qdoc b/doc/src/legal/licenses.qdoc index 9e680a6..344ebd4 100644 --- a/doc/src/legal/licenses.qdoc +++ b/doc/src/legal/licenses.qdoc @@ -276,14 +276,14 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\br - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer.\br - * 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.\br - * Neither the name of Research In Motion Limited nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer.\br + * 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.\br + * Neither the name of Research In Motion Limited 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 Research In Motion Limited ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED diff --git a/doc/src/legal/trademarks.qdoc b/doc/src/legal/trademarks.qdoc index a7b5764..23d0cf6 100644 --- a/doc/src/legal/trademarks.qdoc +++ b/doc/src/legal/trademarks.qdoc @@ -47,7 +47,7 @@ \brief Information about trademarks owned by Nokia and other organisations. Nokia, the Nokia logo, Qt, and the Qt logo are trademarks of Nokia - Corporation and/or its subsidiaries in Finland and other countries. + Corporation and/or its subsidiaries in Finland and other countries. \list \o Intel, Intel Inside (logos), MMX and Pentium are \reg trademarks of diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index 5344bcc..91593d3 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -225,9 +225,9 @@ \row \o \l{Qt3Support} \o Qt 3 support classes \row \o \l{QAxContainer} \o ActiveQt client extension \row \o \l{QAxServer} \o ActiveQt server extension - \row \o \l{QtAssistant} \o Classes for launching Qt Assistant + \row \o \l{QtHelp} \o Classes for integrating online documentation \row \o \l{QtDesigner} \o Classes for extending and embedding Qt Designer - \row \o \l{QtUiTools} \o Classes for dynamic GUI generation + \row \o \l{QtUiTools} \o Classes for dynamic GUI generation \row \o \l{QtTest} \o Tool classes for unit testing \endtable diff --git a/doc/src/tutorials/addressbook-fr.qdoc b/doc/src/tutorials/addressbook-fr.qdoc index d3bd1ca..98c44a3 100644 --- a/doc/src/tutorials/addressbook-fr.qdoc +++ b/doc/src/tutorials/addressbook-fr.qdoc @@ -47,47 +47,47 @@ \nextpage {tutorials/addressbook-fr/part1}{Chapitre 1} \title Tutoriel "Carnet d'adresses" - \brief Une introduction la programation d'interface graphique montrant comment construire une application simple avec Qt. + \brief Une introduction à la programation d'interface graphique montrant comment construire une application simple avec Qt. - Ce tutoriel est une introduction la programmation de GUI (interface utilisateur) - l'aide des outils fournis par la plateforme multiplate-forme Qt. + Ce tutoriel est une introduction à la programmation de GUI (interface utilisateur) + à l'aide des outils fournis par la plateforme multiplate-forme Qt. \image addressbook-tutorial-screenshot.png - Ce tutoriel va nous amener dcouvrir quelques technologies fondamentales fournies + Ce tutoriel va nous amener à découvrir quelques technologies fondamentales fournies par Qt, tel que: \list - \o Les Widgets et leur mise en page l'aide des layouts + \o Les Widgets et leur mise en page à l'aide des layouts \o Les signaux et slots - \o Les structures de donnes de collections - \o Les entres/sorties + \o Les structures de données de collections + \o Les entrées/sorties \endlist Si c'est votre premier contact avec Qt, lisez \l{How to Learn Qt}{Comment apprendre Qt} - si ce n'est dj fait. + si ce n'est déjà fait. - Le code source du tutoriel est distribu avec Qt dans le dossier \c examples/tutorials/addressbook + Le code source du tutoriel est distribué avec Qt dans le dossier \c examples/tutorials/addressbook Les chapitres du tutoriel: \list 1 \o \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur} \o \l{tutorials/addressbook-fr/part2}{Ajouter des adresses} - \o \l{tutorials/addressbook-fr/part3}{Navigation entre les lments} - \o \l{tutorials/addressbook-fr/part4}{diter et supprimer des adresses} + \o \l{tutorials/addressbook-fr/part3}{Navigation entre les éléments} + \o \l{tutorials/addressbook-fr/part4}{éditer et supprimer des adresses} \o \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche} \o \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement} - \o \l{tutorials/addressbook-fr/part7}{Fonctionnalits avances} + \o \l{tutorials/addressbook-fr/part7}{Fonctionnalités avancées} \endlist - La petite application que nous dvelopperons ici ne possde pas tous les lments + La petite application que nous développerons ici ne possède pas tous les éléments des interfaces dernier cri, elle va nous permettre d'utiliser les techniques de base - utilises dans les applications plus complexes. + utilisées dans les applications plus complexes. - Lorsque vous aurez termin ce tutoriel, nous vous recommandons de poursuivre avec l'exemple - "\l{mainwindows/application}{Application}", qui prsente une interface simple utilisant - les menus et barres d'outils, la barre d'tat, etc. + Lorsque vous aurez terminé ce tutoriel, nous vous recommandons de poursuivre avec l'exemple + "\l{mainwindows/application}{Application}", qui présente une interface simple utilisant + les menus et barres d'outils, la barre d'état, etc. */ @@ -98,156 +98,156 @@ \example tutorials/addressbook-fr/part1 \title Carnet d'adresses 1 - Conception de l'interface utilisateur - La premire partie de ce tutoriel traite de la conception d'une interface graphique + La première partie de ce tutoriel traite de la conception d'une interface graphique (GUI) basique, que l'on utilisera pour l'application Carnet d'adresses. - La premire tape dans la cration d'applications graphiques est la conception de - l'interface utilisateur. Dans ce chapitre, nous verrons comment crer les labels - et champs de saisie ncessaires l'implementation d'un carnet d'adresses de base. - Le rsultat attendu est illustr par la capture d'cran ci-dessous. + La première étape dans la création d'applications graphiques est la conception de + l'interface utilisateur. Dans ce chapitre, nous verrons comment créer les labels + et champs de saisie nécessaires à l'implementation d'un carnet d'adresses de base. + Le résultat attendu est illustré par la capture d'écran ci-dessous. \image addressbook-tutorial-part1-screenshot.png Nous allons avoir besoin de deux objets QLabel, \c nameLabel et \c addressLabel, ainsi que deux champs de saisie: un objet QLineEdit, \c nameLine, et un objet - QTextEdit, \c addressText, afin de permettre l'utilisateur d'entrer le nom d'un - contact et son adresse. Les widgets utiliss ainsi que leur placement sont visibles ci-dessous. + QTextEdit, \c addressText, afin de permettre à l'utilisateur d'entrer le nom d'un + contact et son adresse. Les widgets utilisés ainsi que leur placement sont visibles ci-dessous. \image addressbook-tutorial-part1-labeled-screenshot.png - Trois fichiers sont ncessaires l'implmentation de ce carnet d'adresses: + Trois fichiers sont nécessaires à l'implémentation de ce carnet d'adresses: \list - \o \c{addressbook.h} - le fichier de dfinition (header) pour la classe \c AddressBook, - \o \c{addressbook.cpp} - le fichier source, qui comprend l'implmentation de la classe + \o \c{addressbook.h} - le fichier de définition (header) pour la classe \c AddressBook, + \o \c{addressbook.cpp} - le fichier source, qui comprend l'implémentation de la classe \c AddressBook - \o \c{main.cpp} - le fichier qui contient la mthode \c main() , et + \o \c{main.cpp} - le fichier qui contient la méthode \c main() , et une instance de la classe \c AddressBook. \endlist - \section1 Programmation en Qt - hritage + \section1 Programmation en Qt - héritage - Lorsque l'on crit des programmes avec Qt, on a gnralement recours - l'hritage depuis des objets Qt, afin d'y ajouter des fonctionnalits. - C'est l'un des concepts fondamentaux de la cration de widgets personnaliss - ou de collections de widgets. Utiliser l'hritage afin de complter - ou modifier le comportement d'un widget prsente les avantages suivants: + Lorsque l'on écrit des programmes avec Qt, on a généralement recours à + l'héritage depuis des objets Qt, afin d'y ajouter des fonctionnalités. + C'est l'un des concepts fondamentaux de la création de widgets personnalisés + ou de collections de widgets. Utiliser l'héritage afin de compléter + ou modifier le comportement d'un widget présente les avantages suivants: \list - \o La possibilit d'implmenter des mthodes virtuelles et des mthodes - virtuelles pures pour obtenir exactement ce que l'on souhaite, avec la possibilit - d'utiliser l'implmentation de la classe mre si besoin est. + \o La possibilité d'implémenter des méthodes virtuelles et des méthodes + virtuelles pures pour obtenir exactement ce que l'on souhaite, avec la possibilité + d'utiliser l'implémentation de la classe mère si besoin est. \o Cela permet l'encapsulation partielle de l'interface utilisateur dans une classe, - afin que les autres parties de l'application n'aient pas se soucier de chacun des + afin que les autres parties de l'application n'aient pas à se soucier de chacun des widgets qui forment l'interface utilisateur. - \o La classe fille peut tre utilise pour crer de nombreux widgets personnaliss - dans une mme application ou bibliothque, et le code de la classe fille peut tre - rutilis dans d'autres projets + \o La classe fille peut être utilisée pour créer de nombreux widgets personnalisés + dans une même application ou bibliothèque, et le code de la classe fille peut être + réutilisé dans d'autres projets \endlist Comme Qt ne fournit pas de widget standard pour un carnet d'adresses, nous - partirons d'une classe de widget Qt standard et y ajouterons des fonctionnalits. - La classe \c AddressBook cre dans ce tutoriel peut tre rutilise si on a besoin d'un + partirons d'une classe de widget Qt standard et y ajouterons des fonctionnalités. + La classe \c AddressBook crée dans ce tutoriel peut être réutilisée si on a besoin d'un widget carnet d'adresses basique. \section1 La classe AddressBook Le fichier \l{tutorials/addressbook-fr/part1/addressbook.h}{\c addressbook.h} permet de - dfinir la classe \c AddressBook. + définir la classe \c AddressBook. - On commence par dfinir \c AddressBook comme une classe fille de QWidget et dclarer - un constructeur. On utilise galement la macro Q_OBJECT pour indiquer que la classe - exploite les fonctionnalits de signaux et slots offertes par Qt ainsi que - l'internationalisation, bien que nous ne les utilisions pas ce stade. + On commence par définir \c AddressBook comme une classe fille de QWidget et déclarer + un constructeur. On utilise également la macro Q_OBJECT pour indiquer que la classe + exploite les fonctionnalités de signaux et slots offertes par Qt ainsi que + l'internationalisation, bien que nous ne les utilisions pas à ce stade. \snippet tutorials/addressbook-fr/part1/addressbook.h class definition - La classe contient les dclarations de \c nameLine et \c addressText, - les instances prives de QLineEdit et QTextEdit mentionnes prcdemment. - Vous verrez, dans les chapitres venir que les informations contenues - dans \c nameLine et \c addressText sont ncessaires de nombreuses mthodes + La classe contient les déclarations de \c nameLine et \c addressText, + les instances privées de QLineEdit et QTextEdit mentionnées précédemment. + Vous verrez, dans les chapitres à venir que les informations contenues + dans \c nameLine et \c addressText sont nécessaires à de nombreuses méthodes du carnet d'adresses. - Il n'est pas ncessaire de dclarer les objets QLabel que nous allons utiliser - puisque nous n'aurons pas besoin d'y faire rfrence aprs leur cration. - La faon dont Qt gre la parent des objets est traite dans la section suivante. + Il n'est pas nécessaire de déclarer les objets QLabel que nous allons utiliser + puisque nous n'aurons pas besoin d'y faire référence après leur création. + La façon dont Qt gère la parenté des objets est traitée dans la section suivante. - La macro Q_OBJECT implmente des fonctionnalits parmi les plus avances de Qt. + La macro Q_OBJECT implémente des fonctionnalités parmi les plus avancées de Qt. Pour le moment, il est bon de voir la macro Q_OBJECT comme un raccourci nous - permettant d'utiliser les mthodes \l{QObject::}{tr()} et \l{QObject::}{connect()}. + permettant d'utiliser les méthodes \l{QObject::}{tr()} et \l{QObject::}{connect()}. - Nous en avons maintenant termin avec le fichier \c addressbook.h et allons - passer l'implmentation du fichier \c addressbook.cpp. + Nous en avons maintenant terminé avec le fichier \c addressbook.h et allons + passer à l'implémentation du fichier \c addressbook.cpp. - \section1 Implmentation de la classe AddressBook + \section1 Implémentation de la classe AddressBook - Le constructeur de la classe \c{AddressBook} prend en paramtre un QWidget, \e parent. - Par convention, on passe ce paramtre au constructeur de la classe mre. - Ce concept de parent, o un parent peut avoir un ou plusieurs enfants, est utile - pour regrouper les Widgets avec Qt. Par exemple, si vous dtruisez le parent, - tous ses enfants seront dtruits galament. + Le constructeur de la classe \c{AddressBook} prend en paramètre un QWidget, \e parent. + Par convention, on passe ce paramètre au constructeur de la classe mère. + Ce concept de parenté, où un parent peut avoir un ou plusieurs enfants, est utile + pour regrouper les Widgets avec Qt. Par exemple, si vous détruisez le parent, + tous ses enfants seront détruits égalament. \snippet tutorials/addressbook/part1/addressbook.cpp constructor and input fields - l'intrieur de ce constructeur, on dclare et instancie deux objets locaux - QLabel, \c nameLabel et \c addressLabel, de mme on instancie \c nameLine et - \c addressText. La mthode \l{QObject::tr()}{tr()} renvoie une version traduite - de la chane de caractres, si elle existe; dans le cas contraire, elle renvoie - la chane elle mme. On peut voir cette mthode comme un marqueur \tt{<insrer - la traduction ici>}, permettant de reprer les objets QString considrer - pour traduire une application. Vous remarquerez, dans les chapitres venir - comme dans les \l{Qt Examples}{exemples Qt}, qu'elle est utilise chaque fois - que l'on utilise une chane susceptible d'tre traduite. + à l'intérieur de ce constructeur, on déclare et instancie deux objets locaux + QLabel, \c nameLabel et \c addressLabel, de même on instancie \c nameLine et + \c addressText. La méthode \l{QObject::tr()}{tr()} renvoie une version traduite + de la chaîne de caractères, si elle existe; dans le cas contraire, elle renvoie + la chaîne elle même. On peut voir cette méthode comme un marqueur \tt{<insérer + la traduction ici>}, permettant de repérer les objets QString à considérer + pour traduire une application. Vous remarquerez, dans les chapitres à venir + comme dans les \l{Qt Examples}{exemples Qt}, qu'elle est utilisée chaque fois + que l'on utilise une chaîne susceptible d'être traduite. Lorsque l'on programme avec Qt, il est utile de savoir comment fonctionnent les agencements ou layouts. Qt fournit trois classes principales de layouts pour - contrler le placement des widgets: QHBoxLayout, QVBoxLayout et QGridLayout. + contrôler le placement des widgets: QHBoxLayout, QVBoxLayout et QGridLayout. \image addressbook-tutorial-part1-labeled-layout.png - On utilise un QGridLayout pour positionner nos labels et champs de saisie de manire - structure. QGridLayout divise l'espace disponible en une grille, et place les - widgets dans les cellules que l'on spcifie par les numros de ligne et de colonne. - Le diagramme ci-dessus prsente les cellules et la position des widgets, et cette - organisation est obtenue l'aide du code suivant: + On utilise un QGridLayout pour positionner nos labels et champs de saisie de manière + structurée. QGridLayout divise l'espace disponible en une grille, et place les + widgets dans les cellules que l'on spécifie par les numéros de ligne et de colonne. + Le diagramme ci-dessus présente les cellules et la position des widgets, et cette + organisation est obtenue à l'aide du code suivant: \snippet tutorials/addressbook/part1/addressbook.cpp layout - On remarque que le label \c AddressLabel est positionn en utilisant Qt::AlignTop - comme argument optionnel. Ceci est destin assurer qu'il ne sera pas centr - verticalement dans la cellule (1,0). Pour un aperu rapide des layouts de Qt, + On remarque que le label \c AddressLabel est positionné en utilisant Qt::AlignTop + comme argument optionnel. Ceci est destiné à assurer qu'il ne sera pas centré + verticalement dans la cellule (1,0). Pour un aperçu rapide des layouts de Qt, consultez la section \l{Layout Management}. - Afin d'installer l'objet layout dans un widget, il faut appeler la mthode + Afin d'installer l'objet layout dans un widget, il faut appeler la méthode \l{QWidget::setLayout()}{setLayout()} du widget en question: \snippet tutorials/addressbook/part1/addressbook.cpp setting the layout - Enfin, on initialise le titre du widget "Simple Address Book" + Enfin, on initialise le titre du widget à "Simple Address Book" - \section1 Excution de l'application + \section1 Exécution de l'application - Un fichier spar, \c main.cpp, est utilis pour la mthode \c main(). Dans cette - fonction, on cre une instance de QApplication, \c app. QApplication se charge de - des ressources communes l'ensemble de l'application, tel que les polices de - caractres et le curseur par dfaut, ainsi que de l'excution de la boucle d'vnements. + Un fichier séparé, \c main.cpp, est utilisé pour la méthode \c main(). Dans cette + fonction, on crée une instance de QApplication, \c app. QApplication se charge de + des ressources communes à l'ensemble de l'application, tel que les polices de + caractères et le curseur par défaut, ainsi que de l'exécution de la boucle d'évènements. De ce fait, il y a toujours un objet QApplication dans toute application graphique en Qt. \snippet tutorials/addressbook/part1/main.cpp main function On construit un nouveau widget \c AddressBook sur la pile et on invoque - sa mthode \l{QWidget::show()}{show()} pour l'afficher. - Cependant, le widget ne sera pas visible tant que la boucle d'vnements - n'aura pas t lance. On dmarre la boucle d'vnements en appelant la - mthode \l{QApplication::}{exec()} de l'application; le rsultat renvoy - par cette mthode est lui mme utilis comme valeur de retour pour la mthode + sa méthode \l{QWidget::show()}{show()} pour l'afficher. + Cependant, le widget ne sera pas visible tant que la boucle d'évènements + n'aura pas été lancée. On démarre la boucle d'évènements en appelant la + méthode \l{QApplication::}{exec()} de l'application; le résultat renvoyé + par cette méthode est lui même utilisé comme valeur de retour pour la méthode \c main(). - On comprend maintenant pourquoi \c AddressBook a t cr sur la pile: la fin + On comprend maintenant pourquoi \c AddressBook a été créé sur la pile: à la fin du programme, l'objet sort du scope de la fonction \c main() et tous ses widgets enfants - sont supprims, assurant ainsi qu'il n'y aura pas de fuites de mmoire. + sont supprimés, assurant ainsi qu'il n'y aura pas de fuites de mémoire. */ /*! @@ -258,53 +258,53 @@ \example tutorials/addressbook-fr/part2 \title Carnet d'adresses 2 - Ajouter des adresses - La prochaine tape pour crer notre carnet d'adresses est d'ajouter un soupon - d'interactivit. + La prochaine étape pour créer notre carnet d'adresses est d'ajouter un soupçon + d'interactivité. \image addressbook-tutorial-part2-add-contact.png Nous allons fournir un bouton que l'utilisateur peut - cliquer pour ajouter un nouveau contact. Une structure de donnes est aussi - ncessaire afin de pouvoir stocker les contacts en mmoire. + cliquer pour ajouter un nouveau contact. Une structure de données est aussi + nécessaire afin de pouvoir stocker les contacts en mémoire. - \section1 Dfinition de la classe AddressBook + \section1 Définition de la classe AddressBook Maintenant que nous avons mis en place les labels et les champs de saisie, - nous ajoutons les boutons pour complter le processus d'ajout d'un contact. + nous ajoutons les boutons pour compléter le processus d'ajout d'un contact. Cela veut dire que notre fichier \c addressbook.h a maintenant trois objets QPushButton et trois slots publics correspondant. \snippet tutorials/addressbook/part2/addressbook.h slots - Un slot est une mthode qui rpond un signal. Nous allons - voir ce concept en dtail lorsque nous implmenterons la classe \c{AddressBook}. - Pour une explication dtaille du concept de signal et slot, vous pouvez - vous rfrer au document \l{Signals and Slots}. + Un slot est une méthode qui répond à un signal. Nous allons + voir ce concept en détail lorsque nous implémenterons la classe \c{AddressBook}. + Pour une explication détaillée du concept de signal et slot, vous pouvez + vous référer au document \l{Signals and Slots}. Les trois objets QPushButton \c addButton, \c submitButton et \c cancelButton - sont maintenant inclus dans la dclaration des variables prives, avec - \c nameLine et \c addressText du chapitre prcdent. + sont maintenant inclus dans la déclaration des variables privées, avec + \c nameLine et \c addressText du chapitre précédent. \snippet tutorials/addressbook/part2/addressbook.h pushbutton declaration Nous avons besoin d'un conteneur pour stocker les contacts du carnet - d'adresses, de faon pouvoir les numrer et les afficher. - Un objet QMap, \c contacts, est utilis pour a, car il permet de stocker - des paires cl-valeur: le nom du contact est la \e{cl} et l'adresse du contact + d'adresses, de façon à pouvoir les énumérer et les afficher. + Un objet QMap, \c contacts, est utilisé pour ça, car il permet de stocker + des paires clé-valeur: le nom du contact est la \e{clé} et l'adresse du contact est la \e{valeur}. \snippet tutorials/addressbook/part2/addressbook.h remaining private variables - Nous dclarons aussi deux objects QString privs: \c oldName et \c oldAddress. - Ces objets sont ncessaires pour conserver le nom et l'adresse du dernier contact - affich avant que l'utilisateur ne clique sur le bouton "Add". Grce ces variables + Nous déclarons aussi deux objects QString privés: \c oldName et \c oldAddress. + Ces objets sont nécessaires pour conserver le nom et l'adresse du dernier contact + affiché avant que l'utilisateur ne clique sur le bouton "Add". Grâce à ces variables si l'utilisateur clique sur "Cancel", il est possible de revenir - l'affichage du dernier contact. + à l'affichage du dernier contact. - \section1 Implmentation de la classe AddressBook + \section1 Implémentation de la classe AddressBook Dans le constructeur de \c AddressBook, \c nameLine et - \c addressText sont mis en mode lecture seule, de faon autoriser l'affichage + \c addressText sont mis en mode lecture seule, de façon à autoriser l'affichage mais pas la modification du contact courant. \dots @@ -317,16 +317,16 @@ \snippet tutorials/addressbook/part2/addressbook.cpp pushbutton declaration - Le bouton \c addButton est affich en invoquant la mthode \l{QPushButton::show()} - {show()}, tandis que \c submitButton et \c cancelButton sont cachs en invoquant - \l{QPushButton::hide()}{hide()}. Ces deux boutons ne seront affichs que lorsque - l'utilisateur cliquera sur "Add", et ceci est gr par la mthode \c addContact() - dcrite plus loin. + Le bouton \c addButton est affiché en invoquant la méthode \l{QPushButton::show()} + {show()}, tandis que \c submitButton et \c cancelButton sont cachés en invoquant + \l{QPushButton::hide()}{hide()}. Ces deux boutons ne seront affichés que lorsque + l'utilisateur cliquera sur "Add", et ceci est géré par la méthode \c addContact() + décrite plus loin. \snippet tutorials/addressbook/part2/addressbook.cpp connecting signals and slots Nous connectons le signal \l{QPushButton::clicked()}{clicked()} de chaque bouton - au slot qui grera l'action. + au slot qui gèrera l'action. L'image ci-dessous illustre ceci: \image addressbook-tutorial-part2-signals-and-slots.png @@ -336,77 +336,77 @@ \snippet tutorials/addressbook/part2/addressbook.cpp vertical layout - La methode \l{QBoxLayout::addStretch()}{addStretch()} est utilise pour - assurer que les boutons ne sont pas rpartis uniformment, mais regroups - dans la partie supperieure du widget. La figure ci-dessous montre la diffrence - si \l{QBoxLayout::addStretch()}{addStretch()} est utilis ou pas. + La methode \l{QBoxLayout::addStretch()}{addStretch()} est utilisée pour + assurer que les boutons ne sont pas répartis uniformément, mais regroupés + dans la partie supperieure du widget. La figure ci-dessous montre la différence + si \l{QBoxLayout::addStretch()}{addStretch()} est utilisé ou pas. \image addressbook-tutorial-part2-stretch-effects.png - Ensuite nous ajoutons \c buttonLayout1 \c mainLayout, en utilisant + Ensuite nous ajoutons \c buttonLayout1 à \c mainLayout, en utilisant \l{QGridLayout::addLayout()}{addLayout()}. Ceci nous permet d'imbriquer les mises en page puisque \c buttonLayout1 est maintenant un enfant de \c mainLayout. \snippet tutorials/addressbook/part2/addressbook.cpp grid layout - Les coordonnes du layout global ressemblent maintenant a: + Les coordonnées du layout global ressemblent maintenant à ça: \image addressbook-tutorial-part2-labeled-layout.png - Dans la mthode \c addContact(), nous stockons les dtails du dernier - contact affich dans \c oldName et \c oldAddress. Ensuite, nous - vidons ces champs de saisie et nous dsactivons le mode - lecture seule. Le focus est plac sur \c nameLine et on affiche + Dans la méthode \c addContact(), nous stockons les détails du dernier + contact affiché dans \c oldName et \c oldAddress. Ensuite, nous + vidons ces champs de saisie et nous désactivons le mode + lecture seule. Le focus est placé sur \c nameLine et on affiche \c submitButton et \c cancelButton. \snippet tutorials/addressbook/part2/addressbook.cpp addContact - La mthode \c submitContact() peut tre divise en trois parties: + La méthode \c submitContact() peut être divisée en trois parties: \list 1 - \o Nous extrayons les dtails du contact depuis \c nameLine et \c addressText + \o Nous extrayons les détails du contact depuis \c nameLine et \c addressText et les stockons dans des objets QString. Nous les validons pour s'assurer - que l'utilisateur n'a pas cliqu sur "Add" avec des champs de saisie - vides; sinon un message est affich avec QMessageBox pour rappeller - l'utilisateur que les deux champs doivent tre complts. + que l'utilisateur n'a pas cliqué sur "Add" avec des champs de saisie + vides; sinon un message est affiché avec QMessageBox pour rappeller à + l'utilisateur que les deux champs doivent être complétés. \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1 - \o Ensuite, nous vrifions si le contact existe dj. Si aucun contacts - existant n'entre en conflit avec le nouveau, nous l'ajoutons + \o Ensuite, nous vérifions si le contact existe déjà. Si aucun contacts + existant n'entre en conflit avec le nouveau, nous l'ajoutons à \c contacts et nous affichons un QMessageBox pour informer l'utilisateur - que le contact a t ajout. + que le contact a été ajouté. \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part2 - Si le contact existe dj, nous affichons un QMessageBox pour informer - l'utilisateur du problme. - Notre objet \c contacts est bas sur des paires cl-valeur forms par - le nom et l'adresse, nous voulons nous assurer que la \e cl est unique. + Si le contact existe déjà, nous affichons un QMessageBox pour informer + l'utilisateur du problème. + Notre objet \c contacts est basé sur des paires clé-valeur formés par + le nom et l'adresse, nous voulons nous assurer que la \e clé est unique. - \o Une fois que les deux vrifications prcdentes ont t traites, - nous restaurons les boutons leur tat normal l'aide du code + \o Une fois que les deux vérifications précédentes ont été traitées, + nous restaurons les boutons à leur état normal à l'aide du code suivant: \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3 \endlist - La capture d'cran ci-dessous montre l'affichage fournit par un objet - QMessageBox, utilis ici pour afficher un message d'information - l'utilisateur: + La capture d'écran ci-dessous montre l'affichage fournit par un objet + QMessageBox, utilisé ici pour afficher un message d'information + à l'utilisateur: \image addressbook-tutorial-part2-add-successful.png - La mthode \c cancel() restaure les dtails du dernier contact, active + La méthode \c cancel() restaure les détails du dernier contact, active \c addButton, et cache \c submitButton et \c cancelButton. \snippet tutorials/addressbook/part2/addressbook.cpp cancel - L'ide gnrale pour augmenter la flexibilit lors de l'ajout d'un - contact est de donner la possiblit de cliquer sur "Add" - ou "Cancel" n'importe quel moment. - L'organigramme ci-dessous reprend l'ensemble des interactions dvelopes + L'idée générale pour augmenter la flexibilité lors de l'ajout d'un + contact est de donner la possiblité de cliquer sur "Add" + ou "Cancel" à n'importe quel moment. + L'organigramme ci-dessous reprend l'ensemble des interactions dévelopées jusqu'ici: \image addressbook-tutorial-part2-add-flowchart.png @@ -418,118 +418,118 @@ \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire} \nextpage {tutorials/addressbook-fr/part4}{Chapitre 4} \example tutorials/addressbook-fr/part3 - \title Carnet d'adresses 3 - Navigation entre les lments + \title Carnet d'adresses 3 - Navigation entre les éléments - L'application "Carnet d'adresses" est maintenant moiti termine. Il + L'application "Carnet d'adresses" est maintenant à moitié terminée. Il nous faut maintenant ajouter quelques fonctions pour naviguer entre - les contacts. Avant de commencer, il faut se dcider sur le type de structure de - donnes le plus appropri pour stocker les contacts. + les contacts. Avant de commencer, il faut se décider sur le type de structure de + données le plus approprié pour stocker les contacts. - Dans le chapitre 2, nous avons utilis un QMap utilisant des paires cl-valeur, - avec le nom du contact comme \e cl, et l'adresse du contact comme \e valeur. + Dans le chapitre 2, nous avons utilisé un QMap utilisant des paires clé-valeur, + avec le nom du contact comme \e clé, et l'adresse du contact comme \e valeur. Cela fonctionnait bien jusqu'ici, mais pour ajouter la navigation entre les - entres, quelques amliorations sont ncessaires. + entrées, quelques améliorations sont nécessaires. - Nous amliorerons le QMap en le faisant ressembler une structure de donnes - similaire une liste lie, o tous les lments sont connects, y compris - le premier et le dernier lment. La figure ci-dessous illustre cette structure - de donne. + Nous améliorerons le QMap en le faisant ressembler à une structure de données + similaire à une liste liée, où tous les éléments sont connectés, y compris + le premier et le dernier élément. La figure ci-dessous illustre cette structure + de donnée. \image addressbook-tutorial-part3-linkedlist.png - \section1 Dfinition de la classe AddressBook + \section1 Définition de la classe AddressBook Pour ajouter les fonctions de navigation au carnet d'adresses, nous avons - besoin de deux slots supplmentaires dans notre classe \c AddressBook: - \c next() et \c previous(). Ceux-ci sont ajouts au fichier addressbook.h: + besoin de deux slots supplémentaires dans notre classe \c AddressBook: + \c next() et \c previous(). Ceux-ci sont ajoutés au fichier addressbook.h: \snippet tutorials/addressbook/part3/addressbook.h navigation functions Nous avons aussi besoin de deux nouveaux objets QPushButton, nous ajoutons - donc les variables prives \c nextButton et \c previousButton. + donc les variables privées \c nextButton et \c previousButton. \snippet tutorials/addressbook/part3/addressbook.h navigation pushbuttons - \section1 Implmentation de la classe AddressBook + \section1 Implémentation de la classe AddressBook - A l'intrieur du constructeur de \c AddressBook, dans \c addressbook.cpp, nous - instancions \c nextButton et \c previousButton et nous les dsactivons - par dfaut. Nous faisons ceci car la navigation ne doit tre active + A l'intérieur du constructeur de \c AddressBook, dans \c addressbook.cpp, nous + instancions \c nextButton et \c previousButton et nous les désactivons + par défaut. Nous faisons ceci car la navigation ne doit être activée que lorsqu'il y a plus d'un contact dans le carnet d'adresses. \snippet tutorials/addressbook/part3/addressbook.cpp navigation pushbuttons - Nous connectons alors ces boutons leur slots respectifs: + Nous connectons alors ces boutons à leur slots respectifs: \snippet tutorials/addressbook/part3/addressbook.cpp connecting navigation signals - L'image ci-dessous montre l'interface utilisateur que nous allons crer. - Remarquez que cela ressemble de plus en plus l'interface du programme + L'image ci-dessous montre l'interface utilisateur que nous allons créer. + Remarquez que cela ressemble de plus en plus à l'interface du programme complet. \image addressbook-tutorial-part3-screenshot.png Nous suivons les conventions pour les fonctions \c next() et \c previous() - en plaant \c nextButton droite et \c previousButton gauche. Pour + en plaçant \c nextButton à droite et \c previousButton à gauche. Pour faire cette mise en page intuitive, nous utilisons un QHBoxLayout pour - placer les widgets cte cte: + placer les widgets côte à côte: \snippet tutorials/addressbook/part3/addressbook.cpp navigation layout - L'objet QHBoxLayout, \c buttonLayout2, est ensuite ajout \c mainLayout. + L'objet QHBoxLayout, \c buttonLayout2, est ensuite ajouté à \c mainLayout. \snippet tutorials/addressbook/part3/addressbook.cpp adding navigation layout - La figure ci-dessous montre les systmes de coordonnes pour les widgets du + La figure ci-dessous montre les systèmes de coordonnées pour les widgets du \c mainLayout. \image addressbook-tutorial-part3-labeled-layout.png - Dans notre mthode \c addContact(), nous avons desactiv ces boutons - pour tre sr que l'utilisateur n'utilise pas la navigation lors de + Dans notre méthode \c addContact(), nous avons desactivé ces boutons + pour être sûr que l'utilisateur n'utilise pas la navigation lors de l'ajout d'un contact. \snippet tutorials/addressbook/part3/addressbook.cpp disabling navigation - Dans notre mthode \c submitContact(), nous activons les boutons de + Dans notre méthode \c submitContact(), nous activons les boutons de navigation, \c nextButton et \c previousButton, en fonction de la - taille de \c contacts. Commen mentionn plus tt, la navigation n'est - active que si il y a plus d'un contact dans le carnet d'adresses. + taille de \c contacts. Commen mentionné plus tôt, la navigation n'est + activée que si il y a plus d'un contact dans le carnet d'adresses. Les lignes suivantes montrent comment faire cela: \snippet tutorials/addressbook/part3/addressbook.cpp enabling navigation Nous incluons aussi ces lignes de code dans le bouton \c cancel(). - Souvenez vous que nous voulons muler une liste-lie ciruculaire - l'aide de l'objet QMap, \c contacts. Pour faire cela, nous obtenons un itrateur - sur \c contact dans la mthode \c next(), et ensuite: + Souvenez vous que nous voulons émuler une liste-liée ciruculaire à + l'aide de l'objet QMap, \c contacts. Pour faire cela, nous obtenons un itérateur + sur \c contact dans la méthode \c next(), et ensuite: \list - \o Si l'itrateur n'est pas la fin de \c contacts, nous l'incrmentons - \o Si l'itrateur est la fin de \c contacts, nous changeons sa position - jusqu'au dbut de \c contacts. Cela donne l'illusion que notre QMap + \o Si l'itérateur n'est pas à la fin de \c contacts, nous l'incrémentons + \o Si l'itérateur est à la fin de \c contacts, nous changeons sa position + jusqu'au début de \c contacts. Cela donne l'illusion que notre QMap fonctionne comme une liste circulaire. \endlist \snippet tutorials/addressbook/part3/addressbook.cpp next() function - Une fois que nous avons itr jusqu' l'objet recherch dans \c contacts, + Une fois que nous avons itéré jusqu'à l'objet recherché dans \c contacts, nous affichons son contenu sur \c nameLine et \c addressText. - De la mme faon, pour la mthode \c previous(), nous obtenons un - itrateur sur \c contacts et ensuite: + De la même façon, pour la méthode \c previous(), nous obtenons un + itérateur sur \c contacts et ensuite: \list - \o Si l'itrateur est la fin de \c contacts, on rinitialise + \o Si l'itérateur est à la fin de \c contacts, on réinitialise l'affichage et on retourne. - \o Si l'itrateur est au dbut de \c contacts, on change sa - position jusqu' la fin - \o Ensuite, on dcrmente l'itrateur + \o Si l'itérateur est au début de \c contacts, on change sa + position jusqu'à la fin + \o Ensuite, on décrémente l'itérateur \endlist \snippet tutorials/addressbook/part3/addressbook.cpp previous() function - nouveau, nous affichons le contenu de l'objet courant dans \c contacts. + à nouveau, nous affichons le contenu de l'objet courant dans \c contacts. */ @@ -540,27 +540,27 @@ \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire} \nextpage {tutorials/addressbook-fr/part5}{Chapitre 5} \example tutorials/addressbook-fr/part4 - \title Carnet d'Adresses 4 - diter et supprimer des adresses + \title Carnet d'Adresses 4 - éditer et supprimer des adresses - Dans ce chapitre, nous verrons comment modifier les donnes des contacts + Dans ce chapitre, nous verrons comment modifier les données des contacts contenus dans l'application carnet d'adresses. \image addressbook-tutorial-screenshot.png Nous avons maintenant un carnet d'adresses qui ne se contente pas de - lister des contacts de faon ordonne, mais permet galement la - navigation. Il serait pratique d'inclure des fonctions telles qu'diter et - supprimer, afin que les dtails associs un contact puissent tre - modifis lorsque c'est ncessaire. Cependant, cela requiert une lgre - modification, sous la forme d'numrations. Au chapitre prcdent, nous avions deux - modes: \c {AddingMode} et \c {NavigationMode}, mais ils n'taient pas - dfinis en tant qu'numrations. Au lieu de a, on activait et dsactivait les + lister des contacts de façon ordonnée, mais permet également la + navigation. Il serait pratique d'inclure des fonctions telles qu'éditer et + supprimer, afin que les détails associés à un contact puissent être + modifiés lorsque c'est nécessaire. Cependant, cela requiert une légère + modification, sous la forme d'énumérations. Au chapitre précédent, nous avions deux + modes: \c {AddingMode} et \c {NavigationMode}, mais ils n'étaient pas + définis en tant qu'énumérations. Au lieu de ça, on activait et désactivait les boutons correspondants manuellement, au prix de multiples redondances dans le code. - Dans ce chapitre, on dfinit l'numration \c Mode avec trois valeurs possibles. + Dans ce chapitre, on définit l'énumération \c Mode avec trois valeurs possibles. \list \o \c{NavigationMode}, @@ -568,22 +568,22 @@ \o \c{EditingMode}. \endlist - \section1 Dfinition de la classe AddressBook + \section1 Définition de la classe AddressBook - Le fichier \c addressbook.h est mis a jour pour contenir l'numration \c Mode : + Le fichier \c addressbook.h est mis a jour pour contenir l'énumération \c Mode : \snippet tutorials/addressbook/part4/addressbook.h Mode enum - On ajoute galement deux nouveaux slots, \c editContact() et - \c removeContact(), notre liste de slots publics. + On ajoute également deux nouveaux slots, \c editContact() et + \c removeContact(), à notre liste de slots publics. \snippet tutorials/addressbook/part4/addressbook.h edit and remove slots - Afin de basculer d'un mode l'autre, on introduit la mthode - \c updateInterface() pour contrller l'activation et la dsactivation de - tous les objets QPushButton. On ajoute galement deux nouveaux boutons, - \c editButton et \c removeButton, pour les fonctions d'dition - et de suppression mentionnes plus haut. + Afin de basculer d'un mode à l'autre, on introduit la méthode + \c updateInterface() pour contrôller l'activation et la désactivation de + tous les objets QPushButton. On ajoute également deux nouveaux boutons, + \c editButton et \c removeButton, pour les fonctions d'édition + et de suppression mentionnées plus haut. \snippet tutorials/addressbook/part4/addressbook.h updateInterface() declaration \dots @@ -591,97 +591,97 @@ \dots \snippet tutorials/addressbook/part4/addressbook.h mode declaration - Enfin, on dclare \c currentMode pour garder une trace du mode - actuellement utilis. + Enfin, on déclare \c currentMode pour garder une trace du mode + actuellement utilisé. - \section1 Implmentation de la classe AddressBook + \section1 Implémentation de la classe AddressBook - Il nous faut maintenant implmenter les fonctionnalits de changement de + Il nous faut maintenant implémenter les fonctionnalités de changement de mode de l'application carnet d'adresses. Les boutons \c editButton et - \c removeButton sont instancis et dsactivs par dfaut, puisque le - carnet d'adresses dmarre sans aucun contact en mmoire. + \c removeButton sont instanciés et désactivés par défaut, puisque le + carnet d'adresses démarre sans aucun contact en mémoire. \snippet tutorials/addressbook/part4/addressbook.cpp edit and remove buttons - Ces boutons sont ensuite connects leurs slots respectifs, - \c editContact() et \c removeContact(), avant d'tre ajouts + Ces boutons sont ensuite connectés à leurs slots respectifs, + \c editContact() et \c removeContact(), avant d'être ajoutés à \c buttonLayout1. \snippet tutorials/addressbook/part4/addressbook.cpp connecting edit and remove \dots \snippet tutorials/addressbook/part4/addressbook.cpp adding edit and remove to the layout - La methode \c editContact() place les anciens dtails du contact dans + La methode \c editContact() place les anciens détails du contact dans \c oldName et \c oldAddress, avant de basculer vers le mode \c EditingMode. Dans ce mode, les boutons \c submitButton et - \c cancelButton sont tous deux activs, l'utilisateur peut par consquent - modifier les dtails du contact et cliquer sur l'un de ces deux boutons + \c cancelButton sont tous deux activés, l'utilisateur peut par conséquent + modifier les détails du contact et cliquer sur l'un de ces deux boutons par la suite. \snippet tutorials/addressbook/part4/addressbook.cpp editContact() function - La mthode \c submitContact() a t divise en deux avec un bloc + La méthode \c submitContact() a été divisée en deux avec un bloc \c{if-else}. On teste \c currentMode pour voir si le mode courant est - \c AddingMode. Si c'est le cas, on procde l'ajout. + \c AddingMode. Si c'est le cas, on procède à l'ajout. \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function beginning \dots \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part1 Sinon, on s'assure que \c currentMode est en \c EditingMode. Si c'est le - cas, on compare \c oldName et \c name. Si le nom a chang, on supprime - l'ancien contact de \c contacts et on insre le contact mis a jour. + cas, on compare \c oldName et \c name. Si le nom a changé, on supprime + l'ancien contact de \c contacts et on insère le contact mis a jour. \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part2 - Si seule l'adresse a chang (i.e. \c oldAddress n'est pas identique - \c address), on met jour l'adresse du contact. Enfin on rgle - \c currentMode \c NavigationMode. C'est une tape importante puisque - c'est cela qui ractive tous les boutons dsactivs. + Si seule l'adresse a changé (i.e. \c oldAddress n'est pas identique à + \c address), on met à jour l'adresse du contact. Enfin on règle + \c currentMode à \c NavigationMode. C'est une étape importante puisque + c'est cela qui réactive tous les boutons désactivés. - Afin de retirer un contact du carnet d'adresses, on implmente la mthode - \c removeContact(). Cette mthode vrifie que le contact est prsent dans + Afin de retirer un contact du carnet d'adresses, on implémente la méthode + \c removeContact(). Cette méthode vérifie que le contact est présent dans \c contacts. \snippet tutorials/addressbook/part4/addressbook.cpp removeContact() function - Si c'est le cas, on affiche une bote de dialogue QMessageBox, demandant - confirmation de la suppression l'utilisateur. Une fois la confirmation - effectue, on appelle \c previous(), afin de s'assurer que l'interface - utilisateur affiche une autre entre, et on supprime le contact en - utilisant le mthode \l{QMap::remove()}{remove()} de \l{QMap}. Dans un + Si c'est le cas, on affiche une boîte de dialogue QMessageBox, demandant + confirmation de la suppression à l'utilisateur. Une fois la confirmation + effectuée, on appelle \c previous(), afin de s'assurer que l'interface + utilisateur affiche une autre entrée, et on supprime le contact en + utilisant le méthode \l{QMap::remove()}{remove()} de \l{QMap}. Dans un souci pratique, on informe l'utilisateur de la suppression par le biais - d'une autre QMessageBox. Les deux botes de dialogue utilises dans cette - mthode sont reprsentes ci-dessous. + d'une autre QMessageBox. Les deux boîtes de dialogue utilisées dans cette + méthode sont représentées ci-dessous. \image addressbook-tutorial-part4-remove.png - \section2 Mise jour de l'Interface utilisateur + \section2 Mise à jour de l'Interface utilisateur - On a voqu plus haut la mthode \c updateInterface() comme moyen - d'activer et de dsactiver les diffrents boutons de l'interface en - fonction du mode. Cette mthode met jour le mode courant selon - l'argument \c mode qui lui est pass, en l'assignant \c currentMode, + On a évoqué plus haut la méthode \c updateInterface() comme moyen + d'activer et de désactiver les différents boutons de l'interface en + fonction du mode. Cette méthode met à jour le mode courant selon + l'argument \c mode qui lui est passé, en l'assignant à \c currentMode, avant de tester sa valeur. - Chacun des boutons est ensuite activ ou dsactiv, en fonction du mode. + Chacun des boutons est ensuite activé ou désactivé, en fonction du mode. Le code source pour les cas \c AddingMode et \c EditingMode est visible ci-dessous: \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 1 Dans le cas de \c NavigationMode, en revanche, des tests conditionnels - sont passs en paramtre de QPushButton::setEnabled(). Ceci permet de - s'assurer que les boutons \c editButton et \c removeButton ne sont activs + sont passés en paramètre de QPushButton::setEnabled(). Ceci permet de + s'assurer que les boutons \c editButton et \c removeButton ne sont activés que s'il existe au moins un contact dans le carnet d'adresses; - \c nextButton et \c previousButton ne sont activs que lorsqu'il existe + \c nextButton et \c previousButton ne sont activés que lorsqu'il existe plus d'un contact dans le carnet d'adresses. \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 2 - En effectuant les oprations de rglage du mode et de mise jour de - l'interface utilisateur au sein de la mme mthode, on est l'abri de - l'ventualit o l'interface utilisateur se "dsynchronise" de l'tat + En effectuant les opérations de réglage du mode et de mise à jour de + l'interface utilisateur au sein de la même méthode, on est à l'abri de + l'éventualité où l'interface utilisateur se "désynchronise" de l'état interne de l'application. */ @@ -694,7 +694,7 @@ \example tutorials/addressbook-fr/part5 \title Carnet d'adresse 5 - Ajout d'une fonction de recherche - Dans ce chapitre, nous allons voir les possibilits pour rechercher + Dans ce chapitre, nous allons voir les possibilités pour rechercher des contacts dans le carnet d'adresse. \image addressbook-tutorial-part5-screenshot.png @@ -703,110 +703,110 @@ il devient difficile de naviguer avec les boutons \e Next et \e Previous. Dans ce cas, une fonction de recherche serait plus efficace pour rechercher les contacts. - La capture d'cran ci-dessus montre le bouton de recherche \e Find et sa position + La capture d'écran ci-dessus montre le bouton de recherche \e Find et sa position dans le paneau de bouton. Lorsque l'utilisateur clique sur le bouton \e Find, il est courant d'afficher - une bote de dialogue qui demande l'utilisateur d'entrer un nom de contact. + une boîte de dialogue qui demande à l'utilisateur d'entrer un nom de contact. Qt fournit la classe QDialog, que nous sous-classons dans ce chapitre pour - implmenter la class \c FindDialog. + implémenter la class \c FindDialog. - \section1 Dfinition de la classe FindDialog + \section1 Définition de la classe FindDialog \image addressbook-tutorial-part5-finddialog.png - Pour sous-classer QDialog, nous commenons par inclure le header de - QDialog dans le fichier \c finddialog.h. De plus, nous dclarons les + Pour sous-classer QDialog, nous commençons par inclure le header de + QDialog dans le fichier \c finddialog.h. De plus, nous déclarons les classes QLineEdit et QPushButton car nous utilisons ces widgets dans notre classe dialogue. Tout comme dans la classe \c AddressBook, la classe \c FindDialog utilise - la macro Q_OBJECT et son constructeur est dfini de faon accepter - un QWidget parent, mme si cette bote de dialogue sera affiche dans une - fentre spare. + la macro Q_OBJECT et son constructeur est défini de façon à accepter + un QWidget parent, même si cette boîte de dialogue sera affichée dans une + fenêtre séparée. \snippet tutorials/addressbook/part5/finddialog.h FindDialog header - Nous dfinissons la mthode publique \c getFindText() pour tre utilise + Nous définissons la méthode publique \c getFindText() pour être utilisée par les classes qui instancient \c FindDialog, ce qui leur permet d'obtenir - le texte entr par l'utilisateur. Un slot public, \c findClicked(), est - dfini pour prendre en charge le texte lorsque l'utilisateur clique sur + le texte entré par l'utilisateur. Un slot public, \c findClicked(), est + défini pour prendre en charge le texte lorsque l'utilisateur clique sur le bouton \gui Find. - Finalement, nous dfinissons les variables prives \c findButton, + Finalement, nous définissons les variables privées \c findButton, \c lineEdit et \c findText, qui correspondent respectivement au bouton \gui Find, au champ de texte dans lequel l'utilisateur tape le texte - rechercher, et une variable interne stockant le texte pour une - utilisation ultrieure. + à rechercher, et à une variable interne stockant le texte pour une + utilisation ultérieure. - \section1 Implmentation de la classe FindDialog + \section1 Implémentation de la classe FindDialog Dans le constructeur de \c FindDialog, nous instancions les objets des - variables prives \c lineEdit, \c findButton et \c findText. Nous utilisons ensuite + variables privées \c lineEdit, \c findButton et \c findText. Nous utilisons ensuite un QHBoxLayout pour positionner les widgets. \snippet tutorials/addressbook/part5/finddialog.cpp constructor - Nous mettons en place la mise en page et le titre de la fentre, et + Nous mettons en place la mise en page et le titre de la fenêtre, et nous connectons les signaux aux slots. Remarquez que le signal - \l{QPushButton::clicked()}{clicked()} de \c{findButton} est connect - \c findClicked() et \l{QDialog::accept()}{accept()}. Le slot + \l{QPushButton::clicked()}{clicked()} de \c{findButton} est connecté + à \c findClicked() et \l{QDialog::accept()}{accept()}. Le slot \l{QDialog::accept()}{accept()} fourni par le QDialog ferme - la bote de dialogue et lui donne le code de retour \l{QDialog::}{Accepted}. - Nous utilisons cette fonction pour aider la mthode \c findContact() de la classe - \c{AddressBook} savoir si l'objet \c FindDialog a t ferm. Ceci sera - expliqu plus loin lorsque nous verrons la mthode \c findContact(). + la boîte de dialogue et lui donne le code de retour \l{QDialog::}{Accepted}. + Nous utilisons cette fonction pour aider la méthode \c findContact() de la classe + \c{AddressBook} à savoir si l'objet \c FindDialog a été fermé. Ceci sera + expliqué plus loin lorsque nous verrons la méthode \c findContact(). \image addressbook-tutorial-part5-signals-and-slots.png Dans \c findClicked(), nous validons le champ de texte pour nous - assurer que l'utilisateur n'a pas cliqu sur le bouton \gui Find sans - avoir entr un nom de contact. Ensuite, nous stockons le texte du champ - d'entre \c lineEdit dans \c findText. Et finalement nous vidons le - contenu de \c lineEdit et cachons la bote de dialogue. + assurer que l'utilisateur n'a pas cliqué sur le bouton \gui Find sans + avoir entré un nom de contact. Ensuite, nous stockons le texte du champ + d'entrée \c lineEdit dans \c findText. Et finalement nous vidons le + contenu de \c lineEdit et cachons la boîte de dialogue. \snippet tutorials/addressbook/part5/finddialog.cpp findClicked() function - La variable \c findText a un accesseur publique associ: \c getFindText(). - tant donn que nous ne modifions \c findText directement que dans le - constructeur et la mthode \c findClicked(), nous ne crons pas - de manipulateurs associ \c getFindText(). + La variable \c findText a un accesseur publique associé: \c getFindText(). + Étant donné que nous ne modifions \c findText directement que dans le + constructeur et la méthode \c findClicked(), nous ne créons pas + de manipulateurs associé à \c getFindText(). Puisque \c getFindText() est publique, les classes instanciant et - utilisant \c FindDialog peuvent toujours accder la chane de - caractres que l'utilisateur a entr et accept. + utilisant \c FindDialog peuvent toujours accéder à la chaîne de + caractères que l'utilisateur a entré et accepté. \snippet tutorials/addressbook/part5/finddialog.cpp getFindText() function - \section1 Dfinition de la classe AddressBook + \section1 Définition de la classe AddressBook Pour utiliser \c FindDialog depuis la classe \c AddressBook, nous incluons \c finddialog.h dans le fichier \c addressbook.h. \snippet tutorials/addressbook/part5/addressbook.h include finddialog's header - Jusqu'ici, toutes les fonctionnalits du carnet d'adresses ont un - QPushButton et un slot correspondant. De la mme faon, pour la - fonctionnalit \gui Find, nous avons \c findButton et \c findContact(). + Jusqu'ici, toutes les fonctionnalités du carnet d'adresses ont un + QPushButton et un slot correspondant. De la même façon, pour la + fonctionnalité \gui Find, nous avons \c findButton et \c findContact(). - Le \c findButton est dclar comme une variable prive et la - mthode \c findContact() est dclare comme un slot public. + Le \c findButton est déclaré comme une variable privée et la + méthode \c findContact() est déclarée comme un slot public. \snippet tutorials/addressbook/part5/addressbook.h findContact() declaration \dots \snippet tutorials/addressbook/part5/addressbook.h findButton declaration - Finalement, nous dclarons la variable prive \c dialog que nous allons - utiliser pour accder une instance de \c FindDialog. + Finalement, nous déclarons la variable privée \c dialog que nous allons + utiliser pour accéder à une instance de \c FindDialog. \snippet tutorials/addressbook/part5/addressbook.h FindDialog declaration - Une fois que nous avons instanci la bote de dialogue, nous voulons l'utiliser - plus qu'une fois. Utiliser une variable prive nous permet d'y rfrer - plus d'un endroit dans la classe. + Une fois que nous avons instancié la boîte de dialogue, nous voulons l'utiliser + plus qu'une fois. Utiliser une variable privée nous permet d'y référer + à plus d'un endroit dans la classe. - \section1 Implmentation de la classe AddressBook + \section1 Implémentation de la classe AddressBook - Dans le constructeur de \c AddressBook, nous instancions nos objets privs, + Dans le constructeur de \c AddressBook, nous instancions nos objets privés, \c findbutton et \c findDialog: \snippet tutorials/addressbook/part5/addressbook.cpp instantiating findButton @@ -814,25 +814,25 @@ \snippet tutorials/addressbook/part5/addressbook.cpp instantiating FindDialog Ensuite, nous connectons le signal \l{QPushButton::clicked()}{clicked()} de - \c{findButton} \c findContact(). + \c{findButton} à \c findContact(). \snippet tutorials/addressbook/part5/addressbook.cpp signals and slots for find - Maintenant, tout ce qui manque est le code de notre mthode \c findContact(): + Maintenant, tout ce qui manque est le code de notre méthode \c findContact(): \snippet tutorials/addressbook/part5/addressbook.cpp findContact() function - Nous commenons par afficher l'instance de \c FindDialog, \c dialog. - L'utilisateur peut alors entrer le nom du contact rechercher. Lorsque - l'utilisateur clique sur le bouton \c findButton, la bote de dialogue est - masque et le code de retour devient QDialog::Accepted. Ce code de retour + Nous commençons par afficher l'instance de \c FindDialog, \c dialog. + L'utilisateur peut alors entrer le nom du contact à rechercher. Lorsque + l'utilisateur clique sur le bouton \c findButton, la boîte de dialogue est + masquée et le code de retour devient QDialog::Accepted. Ce code de retour vient remplir la condition du premier if. Ensuite, nous extrayons le texte que nous utiliserons pour la recherche, - il s'agit ici de \c contactName obtenu l'aide de la mthode \c getFindText() + il s'agit ici de \c contactName obtenu à l'aide de la méthode \c getFindText() de \c FindDialog. Si le contact existe dans le carnet d'adresse, nous l'affichons directement. Sinon, nous affichons le QMessageBox suivant pour - indiquer que la recherche choue. + indiquer que la recherche à échouée. \image addressbook-tutorial-part5-notfound.png */ @@ -845,49 +845,49 @@ \example tutorials/addressbook-fr/part6 \title Carnet d'Adresses 6 - Sauvegarde et chargement - Ce chapitre couvre les fonctionnalits de gestion des fichiers de Qt que - l'on utilise pour crire les procdures de sauvegarde et chargement pour + Ce chapitre couvre les fonctionnalités de gestion des fichiers de Qt que + l'on utilise pour écrire les procédures de sauvegarde et chargement pour l'application carnet d'adresses. \image addressbook-tutorial-part6-screenshot.png Bien que la navigation et la recherche de contacts soient des - fonctionnalits importantes, notre carnet d'adresses ne sera pleinement + fonctionnalités importantes, notre carnet d'adresses ne sera pleinement utilisable qu'une fois que l'on pourra sauvegarder les contacts existants - et les charger nouveau par la suite. - Qt fournit de nombreuses classes pour grer les \l{Input/Output and - Networking}{entres et sorties}, mais nous avons choisi de nous contenter d'une - combinaison de deux classes simples utiliser ensemble: QFile et QDataStream. + et les charger à nouveau par la suite. + Qt fournit de nombreuses classes pour gérer les \l{Input/Output and + Networking}{entrées et sorties}, mais nous avons choisi de nous contenter d'une + combinaison de deux classes simples à utiliser ensemble: QFile et QDataStream. - Un objet QFile reprsente un fichier sur le disque qui peut tre lu, et - dans lequel on peut crire. QFile est une classe fille de la classe plus - gnrique QIODevice, qui peut reprsenter diffrents types de - priphriques. + Un objet QFile représente un fichier sur le disque qui peut être lu, et + dans lequel on peut écrire. QFile est une classe fille de la classe plus + générique QIODevice, qui peut représenter différents types de + périphériques. - Un objet QDataStream est utilis pour srialiser des donnes binaires - dans le but de les passer un QIODevice pour les rcuprer dans le - futur. Pour lire ou crire dans un QIODevice, il suffit d'ouvrir le - flux, avec le priphrique appropri en paramtre, et d'y lire ou - crire. + Un objet QDataStream est utilisé pour sérialiser des données binaires + dans le but de les passer à un QIODevice pour les récupérer dans le + futur. Pour lire ou écrire dans un QIODevice, il suffit d'ouvrir le + flux, avec le périphérique approprié en paramètre, et d'y lire ou + écrire. - \section1 Dfinition de la classe AddressBook + \section1 Définition de la classe AddressBook - On dclare deux slots publics, \c saveToFile() et \c loadFromFile(), + On déclare deux slots publics, \c saveToFile() et \c loadFromFile(), ainsi que deux objets QPushButton, \c loadButton et \c saveButton. \snippet tutorials/addressbook/part6/addressbook.h save and load functions declaration \dots \snippet tutorials/addressbook/part6/addressbook.h save and load buttons declaration - \section1 Implmentation de la classe AddressBook + \section1 Implémentation de la classe AddressBook Dans notre constructeur, on instancie \c loadButton et \c saveButton. - Idalement, l'interface serait plus conviviale avec des boutons + Idéalement, l'interface serait plus conviviale avec des boutons affichant "Load contacts from a file" et "Save contacts to a file". Mais compte tenu de la dimension des autres boutons, on initialise les labels - des boutons \gui{Load...} et \gui{Save...}. Heureusement, Qt offre une - faon simple d'ajouter des info-bulles avec - \l{QWidget::setToolTip()}{setToolTip()}, et nous l'exploitons de la faon + des boutons à \gui{Load...} et \gui{Save...}. Heureusement, Qt offre une + façon simple d'ajouter des info-bulles avec + \l{QWidget::setToolTip()}{setToolTip()}, et nous l'exploitons de la façon suivante pour nos boutons: \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 1 @@ -895,85 +895,85 @@ \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 2 Bien qu'on ne cite pas le code correspondant ici, nous ajoutons ces deux boutons au - layout de droite, \c button1Layout, comme pour les fonctionnalits prcdentes, et + layout de droite, \c button1Layout, comme pour les fonctionnalités précédentes, et nous connectons leurs signaux - \l{QPushButton::clicked()}{clicked()} leurs slots respectifs. + \l{QPushButton::clicked()}{clicked()} à leurs slots respectifs. - Pour la sauvegarde, on commence par rcuprer le nom de fichier + Pour la sauvegarde, on commence par récupérer le nom de fichier \c fileName, en utilisant QFileDialog::getSaveFileName(). C'est une - mthode pratique fournie par QFileDialog, qui ouvre une bote de - dialogue modale et permet l'utilisateur d'entrer un nom de fichier ou + méthode pratique fournie par QFileDialog, qui ouvre une boîte de + dialogue modale et permet à l'utilisateur d'entrer un nom de fichier ou de choisir un fichier \c{.abk} existant. Les fichiers \c{.abk} - correspondent l'extension choisie pour la sauvegarde des contacts de + correspondent à l'extension choisie pour la sauvegarde des contacts de notre carnet d'adresses. \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part1 - La bote de dialogue affiche est visible sur la capture d'cran ci- + La boîte de dialogue affichée est visible sur la capture d'écran ci- dessous. \image addressbook-tutorial-part6-save.png - Si \c fileName n'est pas vide, on cre un objet QFile, \c file, partir - de \c fileName. QFile fonctionne avec QDataStream puisqu'il drive de + Si \c fileName n'est pas vide, on crée un objet QFile, \c file, à partir + de \c fileName. QFile fonctionne avec QDataStream puisqu'il dérive de QIODevice. - Ensuite, on essaie d'ouvrir le fichier en criture, ce qui correspond au - mode \l{QIODevice::}{WriteOnly}. Si cela choue, on en informe + Ensuite, on essaie d'ouvrir le fichier en écriture, ce qui correspond au + mode \l{QIODevice::}{WriteOnly}. Si cela échoue, on en informe l'utilisateur avec une QMessageBox. \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part2 Dans le cas contraire, on instancie un objet QDataStream, \c out, afin - d'crire dans le fichier ouvert. QDataStream ncessite que la mme - version de flux soit utilise pour la lecture et l'criture. On s'assure - que c'est le cas en spcifiant explicitement d'utiliser la + d'écrire dans le fichier ouvert. QDataStream nécessite que la même + version de flux soit utilisée pour la lecture et l'écriture. On s'assure + que c'est le cas en spécifiant explicitement d'utiliser la \l{QDataStream::Qt_4_5}{version introduite avec Qt 4.5} avant de - srialiser les donnes vers le fichier \c file. + sérialiser les données vers le fichier \c file. \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part3 - Pour le chargement, on rcupre galement \c fileName en utilisant - QFileDialog::getOpenFileName(). Cette mthode est l'homologue de - QFileDialog::getSaveFileName() et affiche galement une bote de - dialogue modale permettant l'utilisateur d'entrer un nom de fichier ou + Pour le chargement, on récupère également \c fileName en utilisant + QFileDialog::getOpenFileName(). Cette méthode est l'homologue de + QFileDialog::getSaveFileName() et affiche également une boîte de + dialogue modale permettant à l'utilisateur d'entrer un nom de fichier ou de selectionner un fichier \c{.abk} existant, afin de le charger dans le carnet d'adresses. \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part1 - Sous Windows, par exemple, cette mthode affiche une bote de dialogue - native pour la slection de fichier, comme illustr sur la capture - d'cran suivante: + Sous Windows, par exemple, cette méthode affiche une boîte de dialogue + native pour la sélection de fichier, comme illustré sur la capture + d'écran suivante: \image addressbook-tutorial-part6-load.png Si \c fileName n'est pas vide, on utilise une fois de plus un objet QFile, \c file, et on tente de l'ouvrir en lecture, avec le mode - \l{QIODevice::}{ReadOnly}. De mme que prcdemment dans notre - implmentation de \c saveToFile(), si cette tentative s'avre + \l{QIODevice::}{ReadOnly}. De même que précédemment dans notre + implémentation de \c saveToFile(), si cette tentative s'avère infructueuse, on en informe l'utilisateur par le biais d'une QMessageBox. \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2 Dans le cas contraire, on instancie un objet QDataStream, \c in, en - spcifiant la version utiliser comme prcdemment, et on lit les - informations srialises vers la structure de donnes \c contacts. Notez + spécifiant la version à utiliser comme précédemment, et on lit les + informations sérialisées vers la structure de données \c contacts. Notez qu'on purge \c contacts avant d'y mettre les informations lues afin de - simplifier le processus de lecture de fichier. Une faon plus avance de - procder serait de lire les contacts dans un objet QMap temporaire, et + simplifier le processus de lecture de fichier. Une façon plus avancée de + procéder serait de lire les contacts dans un objet QMap temporaire, et de copier uniquement les contacts n'existant pas encore dans \c contacts. \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3 Pour afficher les contacts lus depuis le fichier, on doit d'abord - valider les donnes obtenues afin de s'assurer que le fichier lu - contient effectivement des entres de carnet d'adresses. Si c'est le + valider les données obtenues afin de s'assurer que le fichier lu + contient effectivement des entrées de carnet d'adresses. Si c'est le cas, on affiche le premier contact; sinon on informe l'utilisateur du - problme par une QMessageBox. Enfin, on met jour l'interface afin - d'activer et de dsactiver les boutons de faon approprie. + problème par une QMessageBox. Enfin, on met à jour l'interface afin + d'activer et de désactiver les boutons de façon appropriée. */ /*! @@ -981,86 +981,86 @@ \previouspage {tutorials/addressbook-fr/part6}{Chapitre 6} \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire} \example tutorials/addressbook-fr/part7 - \title Carnet d'adresse 7 - Fonctionnalits avances + \title Carnet d'adresse 7 - Fonctionnalités avancées - Ce chapitre couvre quelques fonctionnalits additionnelles qui + Ce chapitre couvre quelques fonctionnalités additionnelles qui feront de notre carnet d'adresses une application plus pratique pour une utilisation quotidienne. \image addressbook-tutorial-part7-screenshot.png Bien que notre application carnet d'adresses soit utile en tant que telle, - il serait pratique de pouvoir changer les contacts avec d'autres applications. - Le format vCard est un un format de fichier populaire pour changer - ce type de donnes. - Dans ce chapitre, nous tendrons notre carnet d'adresses pour permettre + il serait pratique de pouvoir échanger les contacts avec d'autres applications. + Le format vCard est un un format de fichier populaire pour échanger + ce type de données. + Dans ce chapitre, nous étendrons notre carnet d'adresses pour permettre d'exporter des contacts dans des fichiers vCard \c{.vcf}. - \section1 Dfinition de la classe AddressBook + \section1 Définition de la classe AddressBook Nous ajoutons un objet QPushButton, \c exportButton, et un slot - public correspondant, \c exportAsVCard(), notre classe \c AddressBook + public correspondant, \c exportAsVCard(), à notre classe \c AddressBook dans le fichier \c addressbook.h. \snippet tutorials/addressbook/part7/addressbook.h exportAsVCard() declaration \dots \snippet tutorials/addressbook/part7/addressbook.h exportButton declaration - \section1 Implmentation de la classe AddressBook + \section1 Implémentation de la classe AddressBook Dans le constructeur de \c AddressBook, nous connectons le signal \l{QPushButton::clicked()}{clicked()} de \c{exportButton} au slot \c exportAsVCard(). - Nous ajoutons aussi ce bouton \c buttonLayout1, le layout responsable + Nous ajoutons aussi ce bouton à \c buttonLayout1, le layout responsable du groupe de boutons sur la droite. - Dans la mthode \c exportAsVCard(), nous commenons par extraire le - nom du contact dans \n name. Nous dclarons \c firstname, \c lastName et + Dans la méthode \c exportAsVCard(), nous commençons par extraire le + nom du contact dans \n name. Nous déclarons \c firstname, \c lastName et \c nameList. Ensuite, nous cherchons la position du premier espace blanc de \c name. - Si il y a un espace, nous sparons le nom du contact en \c firstName et - \c lastName. Finalement, nous remplaons l'espace par un underscore ("_"). + Si il y a un espace, nous séparons le nom du contact en \c firstName et + \c lastName. Finalement, nous remplaçons l'espace par un underscore ("_"). Si il n'y a pas d'espace, nous supposons que le contact ne comprend que - le prnom. + le prénom. \snippet tutorials/addressbook/part7/addressbook.cpp export function part1 - Comme pour la mthode \c saveToFile(), nous ouvrons une bote de dialogue - pour donner la possibilit l'utilisateur de choisir un emplacement pour - le fichier. Avec le nom de fichier choisi, nous crons une instance de QFile - pour y crire. + Comme pour la méthode \c saveToFile(), nous ouvrons une boîte de dialogue + pour donner la possibilité à l'utilisateur de choisir un emplacement pour + le fichier. Avec le nom de fichier choisi, nous créons une instance de QFile + pour y écrire. Nous essayons d'ouvrir le fichier en mode \l{QIODevice::}{WriteOnly}. Si - cela choue, nous affichons un QMessageBox pour informer l'utilisateur - propos de l'origine du problme et nous quittons la mthode. Sinon, nous passons le - fichier comme paramtre pour crer un objet QTextStream, \c out. De la mme faon que - QDataStream, la classe QTextStream fournit les fonctionnalits pour - lire et crire des fichiers de texte. Grce cel, le fichier \c{.vcf} - gnr pourra tre ouvert et dit l'aide d'un simple diteur de texte. + cela échoue, nous affichons un QMessageBox pour informer l'utilisateur + à propos de l'origine du problème et nous quittons la méthode. Sinon, nous passons le + fichier comme paramètre pour créer un objet QTextStream, \c out. De la même façon que + QDataStream, la classe QTextStream fournit les fonctionnalités pour + lire et écrire des fichiers de texte. Grâce à celà, le fichier \c{.vcf} + généré pourra être ouvert et édité à l'aide d'un simple éditeur de texte. \snippet tutorials/addressbook/part7/addressbook.cpp export function part2 - Nous crivons ensuite un fichier vCard avec la balise \c{BEGIN:VCARD}, + Nous écrivons ensuite un fichier vCard avec la balise \c{BEGIN:VCARD}, suivit par \c{VERSION:2.1}. - Le nom d'un contact est crit l'aide de la balise \c{N:}. Pour la balise - \c{FN:}, qui remplit le titre du contact, nous devons vrifier si le contact - un nom de famille dfini ou non. Si oui, nous utilions les dtails de - \c nameList pour remplir le champ, dans le cas contraire on crit uniquement le contenu + Le nom d'un contact est écrit à l'aide de la balise \c{N:}. Pour la balise + \c{FN:}, qui remplit le titre du contact, nous devons vérifier si le contact + à un nom de famille défini ou non. Si oui, nous utilions les détails de + \c nameList pour remplir le champ, dans le cas contraire on écrit uniquement le contenu de \c firstName. \snippet tutorials/addressbook/part7/addressbook.cpp export function part3 - Nous continuons en crivant l'adresse du contact. Les points-virgules - dans l'adresse sont chapps l'aide de "\\", les retours de ligne sont - remplacs par des points-virgules, et les vigules sont remplaces par des espaces. - Finalement nous crivons les balises \c{ADR;HOME:;} suivies par l'adresse + Nous continuons en écrivant l'adresse du contact. Les points-virgules + dans l'adresse sont échappés à l'aide de "\\", les retours de ligne sont + remplacés par des points-virgules, et les vigules sont remplacées par des espaces. + Finalement nous écrivons les balises \c{ADR;HOME:;} suivies par l'adresse et la balise \c{END:VCARD}. \snippet tutorials/addressbook/part7/addressbook.cpp export function part4 - la fin de la mthode, un QMessageBox est affich pour informer l'utilisateur - que la vCard a t exporte avec succs. + À la fin de la méthode, un QMessageBox est affiché pour informer l'utilisateur + que la vCard a été exportée avec succès. - \e{vCard est une marque dpose de \l{http://www.imc.org} + \e{vCard est une marque déposée de \l{http://www.imc.org} {Internet Mail Consortium}}. */ diff --git a/doc/src/widgets-and-layouts/stylesheet.qdoc b/doc/src/widgets-and-layouts/stylesheet.qdoc index 5f42f28..4d55066 100644 --- a/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -934,8 +934,8 @@ subcontrol. For items with a sub menu, the arrow marks are styled using the - \l{::right-arrow-sub}{right-arrow} and - \l{::left-arrow-sub}{left-arrow}. + \l{right-arrow-sub}{right-arrow} and + \l{left-arrow-sub}{left-arrow}. The scroller is styled using the \l{#scroller-sub}{::scroller}. diff --git a/doc/src/xml-processing/xml-patterns.qdoc b/doc/src/xml-processing/xml-patterns.qdoc index 1a9f76d..408b2da 100644 --- a/doc/src/xml-processing/xml-patterns.qdoc +++ b/doc/src/xml-processing/xml-patterns.qdoc @@ -83,7 +83,7 @@ First, the query opens a \c{<bibliography>} element in the output. The - \l{xquery-introduction.html#using-path-expressions-to-match-select-items} + \l{xquery-introduction.html#using-path-expressions-to-match-and-select-items} {embedded path expression} then loads the XML document describing the contents of the library (\c{library.xml}) and begins the search. For each \c{<book>} element it finds, where the publisher diff --git a/doc/src/xml-processing/xquery-introduction.qdoc b/doc/src/xml-processing/xquery-introduction.qdoc index 84e21ab..9306420 100644 --- a/doc/src/xml-processing/xquery-introduction.qdoc +++ b/doc/src/xml-processing/xquery-introduction.qdoc @@ -75,7 +75,7 @@ It creates a new \c{<html>} element in the output and sets its \c{id} attribute to be the \c{id} attribute from an \c{<html>} element in the \c{other.html} file. -\section1 Using Path Expressions To Match & Select Items +\section1 Using Path Expressions To Match And Select Items In C++ and Java, we write nested \c{for} loops and recursive functions to traverse XML trees in search of elements of interest. In XQuery, we diff --git a/doc/src/zh_CN/getting-started/how-to-learn-qt.qdoc b/doc/src/zh_CN/getting-started/how-to-learn-qt.qdoc new file mode 100644 index 0000000..1c2f56b --- /dev/null +++ b/doc/src/zh_CN/getting-started/how-to-learn-qt.qdoc @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page how-to-learn-qt.html + \title 如何学习 Qt + \brief Links to guides and resources for learning Qt. + \nextpage 教程 + + \section1 Getting Started + + 我们假定您已了解 C++, 并将用于 Qt 开发。有关将 Qt 与其他编程语言一起使用的更多信息,请参见 \l{Qt website}{Qt 网站}。 + + 如果你想仅使用 C++ 编程, 不使用任何设计工具而仅使用代码设计用户界面,请观看\l{教程}。这些教程是为您了解 Qt 编程量身定做的,并侧重于编写可用代码,而并非功能简介。 + + 如果您想使用设计工具来设计用户界面,则至少要阅读 \l{Qt Designer manual}{Qt 设计者手册}的前几章。 + + 现在您已经编写了一些小型可用的应用程序,并对 Qt 编程有更加广泛的了解。您可以直接着手做自己的项目,但我们建议您阅读以下一些关键简介以加深您对 Qt 的了解:\l{Qt Object Model}Qt 对象模型}和\l{Signals and Slots}{信号和槽}。 + + \beginfloatleft + \inlineimage qtdemo-small.png + \endfloat + + \section1 了解概况 + + 在这个阶段,我们建议您浏览一下\l{All Overviews and HOWTOs}{简介},然后阅读与您项目相关的章节。您可能还会发现,浏览与您项目类似的\l{Qt Examples}{示例}的源代码也会对您有所帮助。由于 Qt 源代码已面向公众开放,您也可阅读 Qt 源代码。 + + 如果您运行\l{Examples and Demos Launcher}{示例和演示启动程序},您就会看到许多正在使用的 Qt widget。 + + \l{Qt Widget Gallery} 还按照在不同支持平台上的使用风格提供了精选 Qt widget 简介。 + \clearfloat + + \section1 Books and Learning Materials + + Qt 附带大量文档,并全文带有超文本交叉引用,可轻松地点击了解自己想知道的内容。您使用最多的文档可能是 \l{index.html}{API 引用}。每个链接都提供了浏览 API 引用的不同方式,您可每个都尝试一下,看哪个更适合自己。您还可以尝试 \l{Qt Assistant},这是随 Qt 附带的工具,可访问全部 Qt API,并提供全文本搜索功能。 + + 有大量的书籍是关于 Qt 编程的。有关 Qt 书籍的完整列表。 + We recommend the official Qt book, + \l{http://www.amazon.com/gp/product/0132354160/ref=ase_trolltech/}{C++ + GUI Programming with Qt 4, Second Edition} (ISBN 0-13-235416-0). + 本书从 "Hello Qt" 到高级功能(如多线程、2D 和 3D 图形、网络、内容视图类与 XML),全面详实地说明了 Qt 编程。(第一版基于 Qt 4.1,可\l{http://www.qtrac.eu/C++-GUI-Programming-with-Qt-4-1st-ed.zip}{在线}获得。) + + 包括不同语言的翻译版本,请参见\l{Books about Qt Programming}{有关 Qt 编程的书籍}。 + + 另一个有关实例代码和 Qt 功能说明的有用资源就是存档的 \l{Qt Quarterly}{Qt 季讯}文章,季讯是为 Qt 用户提供的新闻时讯。 + + 有关特定 Qt 模块和其他指南的文档,请参见\l{All Overviews and HOWTOs}。 + + \section1 Further Reading + + Qt has an active and helpful user community who communicate using + the \l{Qt Mailing Lists}{qt-interest} mailing list, the \l{Qt Centre} + Web site, and a number of other community Web sites and Weblogs. + In addition, many Qt developers are active members of the + \l{KDE}{KDE community}. + + 祝您好运并且学习愉快! +*/ diff --git a/doc/src/zh_CN/getting-started/tutorials.qdoc b/doc/src/zh_CN/getting-started/tutorials.qdoc new file mode 100644 index 0000000..dc371d8 --- /dev/null +++ b/doc/src/zh_CN/getting-started/tutorials.qdoc @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page tutorials.html + \title 教程 + + \contentspage 如何学习 Qt + + \brief Tutorials, guides and overviews to help you learn Qt. + + A collection of tutorials and "walkthrough" guides are provided with Qt to + help new users get started with Qt development. These documents cover a + range of topics, from basic use of widgets to step-by-step tutorials that + show how an application is put together. + + \table + \row + \o{2,1} \l{Widgets 教程}{\bold Widgets} + \o{2,1} \l{地址簿教程}{\bold {地址簿}} + \row + \o \image widget-examples.png Widgets + \o + A beginner's guide to getting started with widgets and layouts to create + GUI applications. + + \o \image addressbook-tutorial.png 地址簿 + \o + A seven part guide to creating a fully-functioning address book + application. This tutorial is also available with + \l{Tutoriel "Carnet d'adresses"}{French explanation}. + + \row + \o{2,1} \l{A Quick Start to Qt Designer}{\bold{Qt Designer}} + \o{2,1} \l{Qt Linguist Manual: Programmers#Tutorials}{\bold {Qt Linguist}} + \row + \o \image designer-examples.png QtDesigner + \o + A quick guide through \QD showing the basic steps to create a + form with this interactive tool. + + \o \image linguist-examples.png QtLinguist + \o + A guided tour through the translations process, explaining the + tools provided for developers, translators and release managers. + + \row + \o{2,1} \l{QTestLib Tutorial}{\bold QTestLib} + \o{2,1} \l{qmake Tutorial}{\bold qmake} + \row + \o{2,1} + This tutorial gives a short introduction to how to use some of the + features of Qt's unit-testing framework, QTestLib. It is divided into + four chapters. + + \o{2,1} + This tutorial teaches you how to use \c qmake. We recommend that + you read the \l{qmake Manual}{qmake user guide} after completing + this tutorial. + + \endtable +*/ diff --git a/doc/src/zh_CN/tutorials/addressbook.qdoc b/doc/src/zh_CN/tutorials/addressbook.qdoc new file mode 100644 index 0000000..72349af --- /dev/null +++ b/doc/src/zh_CN/tutorials/addressbook.qdoc @@ -0,0 +1,673 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page tutorials-addressbook.html + + \startpage {index.html}{Qt Reference Documentation} + \contentspage 教程 + \nextpage {tutorials/addressbook/part1}{第一章} + + \title 地址簿教程 + \brief 本教程介绍了使用 Qt 跨平台框架的 GUI 编程。 + + 本教程介绍了使用 Qt 跨平台框架的 GUI 编程。 + + \image addressbook-tutorial-screenshot.png + + \omit + It doesn't cover everything; the emphasis is on teaching the programming + philosophy of GUI programming, and Qt's features are introduced as needed. + Some commonly used features are never used in this tutorial. + \endomit + + 在学习过程中,我们将了解部分 Qt 基本技术,如 + + \list + \o Widget 和布局管理器 + \o 容器类 + \o 信号和槽 + \o 输入和输出设备 + \endlist + + 如果您完全不了解 Qt,请阅读\l{How to Learn Qt}{如何学习 Qt}(如果您还未阅读)。 + + 教程的源代码位于 Qt 的 \c examples/tutorials/addressbook 目录下。 + + 教程章节: + + \list 1 + \o \l{tutorials/addressbook/part1}{设计用户界面} + \o \l{tutorials/addressbook/part2}{添加地址} + \o \l{tutorials/addressbook/part3}{浏览地址簿条目} + \o \l{tutorials/addressbook/part4}{编辑和删除地址} + \o \l{tutorials/addressbook/part5}{添加查找功能} + \o \l{tutorials/addressbook/part6}{加载和保存} + \o \l{tutorials/addressbook/part7}{附加功能} + \endlist + + 虽然这个小型应用程序看起来并不象一个成熟的现代 GUI 应用程序,但它使用多种用于更复杂应用程序的基本技术。在您完成学习之后,我们建议您查看一下\l{mainwindows/application}{应用程序}示例,它提供带有菜单、工具栏、状态栏等项目的小型 GUI 应用程序。 +*/ + +/*! + \page tutorials-addressbook-part1.html + \contentspage {地址簿教程}{目录} + \nextpage {tutorials/addressbook/part2}{第二章} + \example tutorials/addressbook/part1 + \title 地址簿 1 — 设计用户界面 + + 本教程的第一部分讲述了用于地址簿应用程序的基本图形用户界面 (GUI) 的设计。 + + 创建 GUI 程序的第一步就是设计用户界面。在本章中,我们的目标是设置应用基本地址簿应用程序所需的标签和输入字段。下图为期望输出的屏幕截图。 + + \image addressbook-tutorial-part1-screenshot.png + + 我们需要使用两个 QLabel 对象:\c nameLabel 和 \c addressLabel,以及两个输入字段:QLineEdit 对象 \c nameLine 和 QTextEdit + 对象 \c addressText,这样用户才能输入联系人的姓名和地址。使用的 widget 及其位置如下图所示。 + + \image addressbook-tutorial-part1-labeled-screenshot.png + + 要应用地址簿需使用三个文件: + + \list + \o \c{addressbook.h} — AddressBook 类的定义文件, + \o \c{addressbook.cpp} — AddressBook 类的执行文件,以及 + \o \c{main.cpp} — 包含 \c main() 函数并带有 AddressBook 实例的文件。 + \endlist + + \section1 Qt 编程 — 使用子类 + + 在编写 Qt 程序时,我们通常使用 Qt 对象子类来添加功能。这是创建定制 widget 或标准 widget 集合的基本概念之一。使用子类扩展或改变 widget 的操作具有以下优势: + + \list + \o 我们可以编写虚函数或纯虚函数应用,以得到我们确切所需的功能,并在需要时再使用基本的类应用。 + \o 这样我们就可以在类中封装部分用户界面,应用程序的其他部分也就无需了解用户界面中单独使用的 widget。 + \o 可使用子类在同一应用程序或库中创建多个定制 widget,这样子类的代码可在其他项目重复使用。 + \endlist + + 由于 Qt 未提供特定的地址簿 widget,我们在标准的 Qt widget 类中使用子类,然后添加功能。我们在本教程中创建的 \c AddressBook 类在需要使用基本地址簿 widget 的情况下可重复使用。 + + \section1 定义 AddressBook 类 + + \l{tutorials/addressbook/part1/addressbook.h}{\c addressbook.h} 文件用于定义 \c AddressBook 类。 + + 我们从定义 \c AddressBook 为 QWidget 子类和声明构造器开始入手。我们还使用 Q_OBJECT 宏表明该类使用国际化功能与 Qt 信号和槽功能,即使在本阶段不会用到所有这些功能。 + + \snippet tutorials/addressbook/part1/addressbook.h class definition + + 该类包含了 \c nameLine 和 \c addressText 的声明、上文提到的 QLineEdit 和 QTextEdit 的私有实例。在以后章节中,您会看到储存在 \c nameLine 和 \c addressText 中的数据在地址簿的许多功能中都会用到。 + + 我们不必包含要使用的 QLabel 对象的声明,这是因为在创建这些对象后我们不必对其进行引用。在下一部分中,我们会说明 Qt 记录对象所属关系的方式。 + + Q_OBJECT 宏本身应用了部分更高级的 Qt 功能。 我们暂时把 Q_OBJECT 宏理解为使用 \l{QObject::}{tr()} 和 \l{QObject::}{connect()} 函数的快捷方式,这种理解对我们的学习更有用。 + + 我们现已完成 \c addressbook.h 文件,接下来我们来执行对应的 \c addressbook.cpp 文件。 + + \section1 应用 AddressBook 类 + + \c AddressBook 的构造器接收 QWidget 参数 \a parent。按惯例,我们将参数传递给基本类的构造器。这种父项可有一个或多个子项的所属概念对 Qt 中的 widget 分组十分有用。例如,如果删除父项,也会删除其所有子项。 + + \snippet tutorials/addressbook/part1/addressbook.cpp constructor and input fields + + 在该构造器中,我们声明并通过实例来表示两个局部 QLabel 对象 \c nameLabel 和 \c addressLabel,以及 \c nameLine 和 \c addressText。如果字符串已进行转换,则 \l{QObject::tr()}{tr()} 函数返回已转换的字符串,否则返回字符串本身。我们可以将此函数理解 \c{<insert translation here>} 标识来标记要进行转换 QString 对象。在以后章节和 \l{Qt Examples} 中,您会看到只要使用了可转换的字符串就是使用该函数。 + + 使用 Qt 编程时,了解布局是如何起作用的会对您很有帮助。Qt 提供三个主要布局类 QHBoxLayout、QVBoxLayout 和 QGridLayout 来处理 widget 的位置。 + + \image addressbook-tutorial-part1-labeled-layout.png + + 我们使用 QGridLayout 以结构化的方式放置标签和输入字段。QGridLayout 将可用空间分为网格,并将 widget 放置在指定了行列号的单元格中。上面的图表显示了布局单元格和 widget 的位置。我们通过以下代码指定这种排列方式: + + \snippet tutorials/addressbook/part1/addressbook.cpp layout + + 请注意,\c addressLabel 是使用作为附加参数的 Qt::AlignTop 来排放位置。这可确保其不会纵向放置在单元格 (1,0) 中央。有关 Qt 布局的基本简介,请参见\l{Layout Management}{布局类}文档。 + + 要在 widget 上安装布局对象,必须调用 widget 的 \l{QWidget::setLayout()}{setLayout()} 函数: + + \snippet tutorials/addressbook/part1/addressbook.cpp setting the layout + + 最后,我们将 widget 标题设置为“简单地址簿”。 + + \section1 运行应用程序 + + \c main() 函数使用单独的文件 \c main.cpp。在该函数中,我们实例化了 QApplication 对象 \c app。QApplication 负责管理多种应用范围的资源(如默认字体和光标),以及运行事件循环。因此,在每个使用 Qt 的 GUI 应用程序中都会有一个 QApplication 对象。 + + \snippet tutorials/addressbook/part1/main.cpp main function + + 我们使用 new 关键字在堆中构造一个新的 \c AddressBook widget,然后调用 \l{QWidget::show()}{show()} 函数对其进行显示。不过,该 widget 只有在应用程序事件循环开始时才会显示。我们通过调用应用程序的 \l{QApplication::}{exec()} 函数开始事件循环。该函数返回的结果作为 \c main() 函数的返回值。 +*/ + +/*! + \page tutorials-addressbook-part2.html + \previouspage 地址簿 1 — 设计用户界面 + \contentspage {地址簿教程}{目录} + \nextpage {tutorials/addressbook/part3}{第三章} + \example tutorials/addressbook/part2 + \title 地址簿 2 — 添加地址 + + 创建基本地址簿应用程序的下一步是添加少许用户互动操作。 + + \image addressbook-tutorial-part2-add-contact.png + + 我们将提供一个按钮,用户可点击该按钮来添加新联系人。此外,还需要对数据结构进行限定,以便有序地储存这些联系人。 + + \section1 定义 AddressBook 类 + + 由于已经设置了标签和输入字段,我们只需添加按钮就可完成添加联系人这一步骤。也就是说,在 \c addressbook.h 文件中已经声明了三个 QPushButton 对象和三个对应的公共槽。 + + \snippet tutorials/addressbook/part2/addressbook.h slots + + 槽是对特殊信号进行响应的函数。我们将在应用 \c AddressBook 类时进一步详细说明这一概念。如需有关 Qt 信号和槽概念的简介,请参见\l{Signals and Slots}{信号和槽}文档。 + + 三个 QPushButton 对象分别是 \c addButton、\c submitButton 和 \c cancelButton,已与要在上一章中说明的 \c nameLine 和 \c addressText 一同包含在私有变量声明中。 + + \snippet tutorials/addressbook/part2/addressbook.h pushbutton declaration + + 我们需要一个容器来储存地址簿联系人,这样才能搜索和显示联系人。QMap 对象 \c contacts 就可实现此功能,因为其带有一个键-值对:联系人姓名作为键,而联系人地址作为\e{值}。 + + \snippet tutorials/addressbook/part2/addressbook.h remaining private variables + + 我们还会声明两个私有 QString 对象:\c oldName 和 \c oldAddress。这些对象用来保留在用户点击\gui{添加}时最后显示的联系人姓名和地址。这样,当用户点击\gui{取消}时,我们就可以返回至上一个联系人的详细信息。 + + \section1 应用 AddressBook 类 + + 在 \c AddressBook 构造器中,我们将 \c nameLine 和 \c addressText 设置为只读,这样就可仅显示而不必编辑现有联系人的详细信息。 + + \dots + \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 1 + \dots + \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 2 + + 然后,我们实例化以下按钮:\c addButton、\c submitButton 和 \c cancelButton。 + + \snippet tutorials/addressbook/part2/addressbook.cpp pushbutton declaration + + 显示 \c addButton 是通过调用 \l{QPushButton::show()}{show()} 函数实现的,而隐藏 \c submitButton 和 \c cancelButton 则需调用 \l{QPushButton::hide()}{hide()}。这两个按钮仅当用户点击\gui{添加}时才会显示,而此操作是通过在下文中说明的\c addContact() 函数处理的。 + + \snippet tutorials/addressbook/part2/addressbook.cpp connecting signals and slots + + 我们将按钮的 \l{QPushButton::clicked()}{clicked()} 信号与其相应的槽关联。下面的图表说明了此过程。 + + \image addressbook-tutorial-part2-signals-and-slots.png + + 接下来,我们将按钮整齐的排列在地址簿 widget 的右侧,使用 QVBoxLayout 将其进行纵向排列。 + + \snippet tutorials/addressbook/part2/addressbook.cpp vertical layout + + \l{QBoxLayout::addStretch()}{addStretch()} 函数用来确保按钮并不是采用均匀间隔排列的,而是更靠近 widget 的顶部。下图显示了是否使用 \l{QBoxLayout::addStretch()}{addStretch()} 的差别。 + + \image addressbook-tutorial-part2-stretch-effects.png + + 然后,我们使用 \l{QGridLayout::addLayout()}{addLayout()} 将 \c buttonLayout1 增加至 \c mainLayout。 这样我们就有了嵌套布局,因为 \c buttonLayout1 现在是 \c mainLayout 的子项。 + + \snippet tutorials/addressbook/part2/addressbook.cpp grid layout + + 布局坐标显示如下: + + \image addressbook-tutorial-part2-labeled-layout.png + + 在 \c addContact() 函数中,我们使用 \c oldName 和 \c oldAddress 储存最后显示的联系人详细信息。然后,我们清空这些输入字段并关闭只读模式。输入焦点设置在 \c nameLine,显示 \c submitButton 和 \c cancelButton。 + + \snippet tutorials/addressbook/part2/addressbook.cpp addContact + + \c submitContact() 函数可分为三个部分: + + \list 1 + \o 我们从 \c nameLine 和 \c addressText 提取联系人的详细信息,然后将其储存在 QString 对象中。我们还要验证确保用户没有在输入字段为空时点击\gui{提交},否则,会显示 QMessageBox 提示用户输入姓名和地址。 + + \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1 + + \o 我们接着继续检查是否联系人已存在。如果不存在,将联系人添加至 \c contacts,然后显示 QMessageBox 提示用户已添加联系人。 + + \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part2 + + 如果联系人已存在,还是会显示 QMessageBox 以提示用户,以免添加重复的联系人。由于 \c contacts 对象是基于姓名地址的键-值对,因此要确保键唯一。 + + \o 在处理了上述两种情况后,使用以下代码将按钮恢复为正常状态: + + \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3 + + \endlist + + 下面的屏幕截图显示了用于向用户显示提示信息的 QMessageBox 对象。 + + \image addressbook-tutorial-part2-add-successful.png + + \c cancel() 函数恢复上次显示的联系人详细信息,并启用 \c addButton,还会隐藏 \c submitButton 和 + \c cancelButton。 + + \snippet tutorials/addressbook/part2/addressbook.cpp cancel + + 添加联系人的总体思想就是提高用户操作的灵活性,可在任何时候点击\gui{提交}或\gui{取消}。下面的流程图详细说明了此概念: + + \image addressbook-tutorial-part2-add-flowchart.png +*/ + +/*! + \page tutorials-addressbook-part3.html + \previouspage 地址簿 2 — 添加地址 + \contentspage {地址簿教程}{目录} + \nextpage {tutorials/addressbook/part4}{第四章} + \example tutorials/addressbook/part3 + \title 地址簿 3 — 浏览地址簿条目 + + 构建地址簿应用程序现已进展过半。我们需要增加一些函数,以便浏览联系人。但首先要决定采用何种数据结构方式来储存这些联系人。 + + 在第二章中,我们使用了 QMap 键-值对,即联系人姓名作为\e{键},而联系人地址作为\e{值}。这种方式很适合我们的实例。不过,要浏览和显示每个条目,还需要进行一些改进。 + + 我们改进 QMap 的方式是,将数据结构替换为类似循环链接的列表,其中所有元素都是相互关联的,包括第一个元素和最后一个元素。下图图解说明了该数据结构。 + + \image addressbook-tutorial-part3-linkedlist.png + + \section1 定义 AddressBook 类 + + 要给地址簿应用程序增加浏览功能,我们需要为 \c AddressBook 类再增加两个函数:\c next() 和 \c previous()。将这两个函数添加到 \c addressbook.h 文件中: + + \snippet tutorials/addressbook/part3/addressbook.h navigation functions + + 我们还需要使用其他两个 QPushButton 对象,因此将 \c nextButton 和 \c previousButton 声明为私有变量: + + \snippet tutorials/addressbook/part3/addressbook.h navigation pushbuttons + + \section1 应用 AddressBook 类 + + 在 \c AddressBook 的 \c addressbook.cpp 构造器中,我们实例化 \c nextButton 和 \c previousButton,并且这两项默认为禁用。这是因为仅当地址簿中有多个联系人时才会启用浏览功能。 + + \snippet tutorials/addressbook/part3/addressbook.cpp navigation pushbuttons + + 然后,我们将这两个按钮与其相应的槽关联: + + \snippet tutorials/addressbook/part3/addressbook.cpp connecting navigation signals + + 下图即为预期的图形用户界面。请注意,该用户界面已很接近应用程序最终的样子。 + + \image addressbook-tutorial-part3-screenshot.png + + 我们按照 \c next() 和 \c previous() 函数的基本规范,将 \c nextButton 放置在右侧,而 \c previousButton 放置在左侧。为了使布局更加直观,我们使用 QHBoxLayout 将 widget 并排放置: + + \snippet tutorials/addressbook/part3/addressbook.cpp navigation layout + + 然后,将 QHBoxLayout 对象 \c buttonLayout2 增加至 \c mainLayout。 + + \snippet tutorials/addressbook/part3/addressbook.cpp adding navigation layout + + 下图显示了 widget 在 \c mainLayout 中的坐标位置。 + + \image addressbook-tutorial-part3-labeled-layout.png + + 在 \c addContact() 函数中,我们必须禁用这几个按钮,这样用户就不会在增加联系人时尝试进行浏览。 + + \snippet tutorials/addressbook/part3/addressbook.cpp disabling navigation + + 此外,在 \c submitContact() 函数中,我们启用了浏览按钮 \c nextButton 和 \c previousButton,这取决于 \c contacts 的多少。如上文所述,浏览功能仅在地址簿中有多个联系人时才会启用。以下代码行说明了如何实现此功能: + + \snippet tutorials/addressbook/part3/addressbook.cpp enabling navigation + + 我们还在 \c cancel() 函数中加入这几行代码。 + + 记得我们曾使用 QMap 对象 \c contacts 模拟了一个循环链接的列表。因此,在 \c next() 函数中,我们获取 \c contacts 的迭代器,然后执行以下操作: + + \list + \o 如果迭代器未达到 \c contacts 结尾,就会增加一。 + \o 如果迭代器已达到 \c contacts 的结尾,就移至 \c contacts 的起始位置。这给人感觉 QMap 就像是一个循环链接的列表。 + \endlist + + \snippet tutorials/addressbook/part3/addressbook.cpp next() function + + 一旦在 \c contacts 中循环至正确的对象,就会通过 \c nameLine 和 \c addressText 显示对象的内容。 + + 同样,在 \c previous() 函数中,我们获取 \c contacts 的迭代器,然后执行以下操作: + + \list + \o 如果迭代器达到 \c contacts 的结尾,就清除显示内容,然后返回。 + \o 如果迭代器在 \c contacts 的起始位置,就将其移至结尾。 + \o 然后,将迭代器减一。 + \endlist + + \snippet tutorials/addressbook/part3/addressbook.cpp previous() function + + 接着,重新显示 \c contacts 中当前对象的内容。 +*/ + +/*! + \page tutorials-addressbook-part4.html + \previouspage 地址簿 3 — 浏览地址簿条目 + \contentspage {地址簿教程}{目录} + \nextpage {tutorials/addressbook/part5}{第五章} + \example tutorials/addressbook/part4 + \title 地址簿 4 — 编辑和删除地址 + + 在本章中,我们将了解如何修改储存在地址簿应用程序中的联系人的内容。 + + \image addressbook-tutorial-screenshot.png + + 现有的地址簿不仅可以井井有条地储存联系人,还可进行浏览。再添加上编辑和删除功能,以便在需要时更改联系人的详细信息,这样更易于使用。不过,还需使用 enum 类型进行一些改进。在前几章中,我们使用以下两种模式:\c{AddingMode} 和 \c{NavigationMode}。但是,他们并未定义为 enum。我们是采用手动方式启用和禁用相应的按钮,这就导致有多行重复的代码。 + + 在本章中,我们定义带有以下三种不同值的 \c{Mode} enum 类型: + + \list + \o \c{NavigationMode}、 + \o \c{AddingMode} 和 + \o \c{EditingMode}。 + \endlist + + \section1 定义 AddressBook 类 + + \c addressbook.h 文件已更新为包含 Mode \c enum 类型: + + \snippet tutorials/addressbook/part4/addressbook.h Mode enum + + 我们还要向当前的公有槽列表增加两个新槽:\c editContact() 和 \c removeContact()。 + + \snippet tutorials/addressbook/part4/addressbook.h edit and remove slots + + 为了在模式间切换,我们引入了 \c updateInterface() 函数来控制所有 QPushButton 对象的启用和禁用。要实现上文提及的编辑和删除功能,我们还要增加两个新按钮:\c editButton 和 \c removeButton。 + + \snippet tutorials/addressbook/part4/addressbook.h updateInterface() declaration + \dots + \snippet tutorials/addressbook/part4/addressbook.h buttons declaration + \dots + \snippet tutorials/addressbook/part4/addressbook.h mode declaration + + 最后,我们声明 \c currentMode 来跟踪 enum 的当前模式。 + + \section1 应用 AddressBook 类 + + 我们现在必须应用地址簿应用程序的模式更改功能。\c editButton 和 \c removeButton 已实例化并默认为禁用,这是因为地址簿启动时在内存中没有联系人。 + + \snippet tutorials/addressbook/part4/addressbook.cpp edit and remove buttons + + 这些按钮会与其相应的槽 \c editContact() 和 \c removeContact() 关联,然后我们将其添加至 \c buttonLayout1。 + + \snippet tutorials/addressbook/part4/addressbook.cpp connecting edit and remove + \dots + \snippet tutorials/addressbook/part4/addressbook.cpp adding edit and remove to the layout + + 在将模式切换到 \c EditingMode 之前,\c editContact() 函数使用 \c oldName 和 \c oldAddress 储存联系人旧的详细信息。 在该模式下,\c submitButton 和 \c cancelButton 均已启用,这样用户就可以更改联系人的详细信息并可点击任何一个按钮。 + + \snippet tutorials/addressbook/part4/addressbook.cpp editContact() function + + \c submitContact() 函数已被 \c{if-else} 语句分为两部分。我们查看 \c currentMode 是否在 \c AddingMode 模式下。如果是,我们继续添加操作。 + + \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function beginning + \dots + \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part1 + + 否则,我们查看 \c currentMode 是否在 \c EditingMode 模式下。如果是,我们比较 \c oldName 和 \c name。如果姓名已更改,我们从 \c contacts 中删除旧的联系人并插入已更新的联系人。 + + \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part2 + + 如果仅更改了地址(例如 \c oldAddress 与 \c address 不同),我们就更新联系人的地址。最后,我们将 \c currentMode 设置为 \c NavigationMode。这一步至关重要,因为它会重新启用所有已禁用的按钮。 + + 要从地址簿中删除联系人,我们采用 \c removeContact() 函数。该函数查看 \c contacts 中是否包含该联系人。 + + \snippet tutorials/addressbook/part4/addressbook.cpp removeContact() function + + 如果有,我们显示 QMessageBox,确认用户的删除操作。一旦用户确认操作,我们调用 \c previous() 确保用户界面显示其他联系人,然后我们使用 QMap 的 \l{QMap::remove()}{remove()} 函数删除已已确认的联系人。出于好意,我们会显示 QMessageBox 提示用户。在该函数中使用两种信息框显示如下: + + \image addressbook-tutorial-part4-remove.png + + \section2 更新用户界面 + + 我们在上文提到 \c updateInterface() 函数,它可根据当前的模式启用和禁用按钮。该函数会根据传递给它的 \c mode 参数更新当前的模式,在校验值之前将参数分配给 \c currentMode。 + + 这样,每个按钮就根据当前的模式进行启用或禁用。\c AddingMode 和 \c EditingMode 的代码显示如下: + + \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 1 + + 不过对于 \c NavigationMode,我们在 QPushButton::setEnabled() 函数的参数中加入了条件。这样可确保 \c editButton 和 \c removeButton 在地址簿中至少有一个联系人的情况下启用,而 \c nextButton 和 \c previousButton 仅在地址簿中有多个联系人时才启用。 + + \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 2 + + 通过在同一函数中设置模式和更新用户界面,我们可以避免用户界面与应用程序内部状态不同步的可能性。 +*/ + +/*! + \page tutorials-addressbook-part5.html + \previouspage 地址簿 4 — 编辑和删除地址 + \contentspage {地址簿教程}{目录} + \nextpage {tutorials/addressbook/part6}{第六章} + \example tutorials/addressbook/part5 + \title 地址簿 5 — 添加查找功能 + + 在本章中,我们将了解如何在地址簿应用程序中定位联系人和地址。 + + \image addressbook-tutorial-part5-screenshot.png + + 随着我们不断为地址簿应用程序添加联系人,使用下一个和上一个按钮浏览联系人就会变得很繁琐。在这种情况下,使用查找函数查找联系人就会更加有效。上面的屏幕截图显示了查找按钮及其在按钮面板上的位置。 + + 当用户点击查找按钮时,有必要显示一个对话框,用户可在其中输入联系人的姓名。Qt 提供了 QDialog(我们会在本章中将其用作子类),可使用 \c FindDialog 类。 + + \section1 定义 FindDialog 类 + + \image addressbook-tutorial-part5-finddialog.png + + 要使用 QDialog 的子类,我们首先要在 \c finddialog.h 文件中声明 QDialog 的头信息。此外,我们还使用向前 (forward) 声明来声明 QLineEdit 和 QPushButton,这样我们就能在对话框类中使用这些 widget。 + + 因为在 \c AddressBook 类中,\c FindDialog 类包含了 Q_OBJECT 宏,并且其构造器已定义为接收父级 QWidget,即使对话框以单独的窗口方式打开。 + + \snippet tutorials/addressbook/part5/finddialog.h FindDialog header + + 我们定义了公有函数 \c getFindText(),供实例化 \c FindDialog 的类使用,这样这些类可以获取用户输入的文本。公有槽 \c findClicked() 定义为在用户点击\gui{查找}按钮时处理搜索字符串。 + + 最后,我们定义私有变量 \c findButton、\c lineEdit 和 \c findText,分别对应\gui{查找}按钮、用户输入搜索字符串的行编辑框和储存搜索字符串供稍后使用的内部字符串。 + + \section1 应用 FindDialog 类 + + 在 \c FindDialog 的构造器中,我们设置私有变量 \c lineEdit、\c findButton 和 \c findText。使用 QHBoxLayout 放置 widget。 + + \snippet tutorials/addressbook/part5/finddialog.cpp constructor + + 我们设定布局和窗口标题,并将信号与其各自的槽关联。请注意,\c findButton 的 \l{QPushButton::clicked()}{clicked()} 信号已与 \c findClicked() 和 \l{QDialog::accept()}{accept()} 关联。QDialog 提供的 \l{QDialog::accept()}{accept()} 槽会隐藏对话框并将结果代码设置为 \l{QDialog::}{Accepted}。我们使用该函数有助于 \c AddressBook 的 \c findContact() 函数知晓 \c FindDialog 对象关闭的时间。我们在讨论 \c findContact() 函数时将对该函数做进一步说明。 + + \image addressbook-tutorial-part5-signals-and-slots.png + + 在 \c findClicked() 中,我们验证 \c lineEdit 以确保用户没有在尚未输入联系人姓名时就点击\gui{查找}按钮。然后,我们将 \c findText 设置为从 \c lineEdit 提取的搜索字符串。之后,我们清空 \c lineEdit 的内容并隐藏对话框。 + + \snippet tutorials/addressbook/part5/finddialog.cpp findClicked() function + + \c findText 变量已有公有 getter 函数 \c getFindText() 与其相关联。既然我们仅在构造器和 \c findClicked() 函数中直接设定了 \c findText, 我们就不在创建 \c getFindText() 的同时再创建 setter 函数。由于 \c getFindText() 是公有的,实例化和使用 \c FindDialog 的类可始终读取用户已输入并确认的搜索字符串。 + + \snippet tutorials/addressbook/part5/finddialog.cpp getFindText() function + + \section1 定义 AddressBook 类 + + 要确保我们可使用 \c AddressBook 类中的 \c FindDialog,我们要在 \c addressbook.h 文件中包含 \c finddialog.h。 + + \snippet tutorials/addressbook/part5/addressbook.h include finddialog's header + + 至此,所有地址簿功能都有了 QPushButton 和对应的槽。同样,\gui{Find} 功能有 \c findButton 和 \c findContact()。 + + \c findButton 声明为私有变量,而 \c findContact() 函数声明为公有槽。 + + \snippet tutorials/addressbook/part5/addressbook.h findContact() declaration + \dots + \snippet tutorials/addressbook/part5/addressbook.h findButton declaration + + 最后,我们声明私有变量 \c dialog,用于引用 \c FindDialog 的实例。 + + \snippet tutorials/addressbook/part5/addressbook.h FindDialog declaration + + 在实例化对话框后,我们可能会对其进行多次使用。使用私有变量可在类中不同位置对其进行多次引用。 + + \section1 应用 AddressBook 类 + + 在 \c AddressBook 类的构造器中,实例化私有对象 \c findButton 和 \c findDialog: + + \snippet tutorials/addressbook/part5/addressbook.cpp instantiating findButton + \dots + \snippet tutorials/addressbook/part5/addressbook.cpp instantiating FindDialog + + 接下来,将 \c findButton 的 \l{QPushButton::clicked()}{clicked()} 信号与 \c findContact() 关联。 + + \snippet tutorials/addressbook/part5/addressbook.cpp signals and slots for find + + 现在唯一要完成的就是 \c findContact() 函数的编码: + + \snippet tutorials/addressbook/part5/addressbook.cpp findContact() function + + 我们从显示 \c FindDialog 的实例 \c dialog 开始入手。这时用户开始输入联系人姓名进行查找。用户点击对话框的 \c findButton 后,对话框会隐藏,并且结果代码设置为 QDialog::Accepted.这样就确保了 \c if 语句始终为真。 + + 然后,我们就开始使用 \c FindDialog 的 \c getFindText() 函数提取搜索字符串,这个字符串也就是本例中的 \c contactName。如果地址簿中有联系人,就立即显示该联系人。否则,显示如下所示的 QMessageBox 表明搜索失败。 + + \image addressbook-tutorial-part5-notfound.png +*/ + +/*! + \page tutorials-addressbook-part6.html + \previouspage 地址簿 5 — 添加查找功能 + \contentspage {地址簿教程}{目录} + \nextpage {tutorials/addressbook/part7}{第七章} + \example tutorials/addressbook/part6 + \title 地址簿 6 — 加载和保存 + + 本章描述了用于编写地址簿应用程序的加载和保存程序所使用的 Qt 文件处理功能。 + + \image addressbook-tutorial-part6-screenshot.png + + 虽然浏览和搜索联系人是非常实用的功能,但只有在可以保存现有联系人并可以在以后加载的前提下地址簿才真正完全可用。Qt 提供大量用于\l{Input/Output and Networking}{输入和输出}的类,但我们只选择两个易于合并使用的类:QFile 和 QDataStream。 + + QFile 对象表示磁盘上可读取和写入的文件。QFile 是代表多种不同设备且应用更广的 QIODevice 类的子类。 + + QDataStream 对象用于按顺序排列二进制数据,以便储存在 QIODevice 中并供以后检索。读取或写入 QIODevice 就如同打开数据流,然后读取或写入一样简单,只是参数为不同的设备。 + + + \section1 定义 AddressBook 类 + + 我们声明两个公有槽 \c saveToFile() 和 \c loadFromFile(),以及两个 QPushButton 对象 \c loadButton 和 \c saveButton。 + + \snippet tutorials/addressbook/part6/addressbook.h save and load functions declaration + \dots + \snippet tutorials/addressbook/part6/addressbook.h save and load buttons declaration + + \section1 应用 AddressBook 类 + + 在构造器中,我们实例化 \c loadButton 和 \c saveButton。理想情况下,将按钮标签设置为“从文件加载联系人”和“将联系人保存至文件”会更方便用户使用。不过,由于其他按钮的大小限制,我们将标签设置为\gui{加载...}和\gui{保存...}。幸运的是,Qt 提供了使用 \l{QWidget::setToolTip()}{setToolTip()} 来设置工具提示的简单方式,我们可通过如下方式将其用于按钮: + + \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 1 + \dots + \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 2 + + 虽然此处没有显示,但与其他应用的功能一样,我们在右侧的布局面板 \c button1Layout 上添加按钮,然后将按钮的 \l{QPushButton::clicked()}{clicked()} 信号与其相应的槽关联。 + + 至于保存功能,我们首先使用 QFileDialog::getSaveFileName() 获取 \c fileName。 这是 QFileDialog 提供的一个便捷功能,可弹出样式文件对话框并允许用户输入文件名或选择现有的 \c{.abk} 文件。\c{.abk} 文件是保存联系人时创建的地址簿扩展名。 + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part1 + + 弹出的文件对话框屏幕截图显示如下: + + \image addressbook-tutorial-part6-save.png + + 如果 \c fileName 不为空,我们就使用 \c fileName 创建 QFile 对象 \c file。 QFile 与 QDataStream 一同使用,这是因为QFile 是 QIODevice。 + + 接下来,我们尝试以 \l{QIODevice::}{WriteOnly} 模式打开文件。如果未能打开,会显示 QMessageBox 提示用户。 + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part2 + + 否则,会用实例表示 QDataStream 对象 \c out,以写入打开的文件。QDataStream 要求读写操作需使用相同版本的数据流。在将数据按顺序写入 \c file 之前,将使用的版本设置为\l{QDataStream::Qt_4_5}{采用 Qt 4.5 的版本}就可确保版本相同。 + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part3 + + 至于加载功能,我们也是使用 QFileDialog::getOpenFileName() 获取 \c fileName。该函数与 QFileDialog::getSaveFileName() 相对应,也是弹出样式文件对话框并允许用户输入文件名或选择现有的 \c{.abk} 文件加载到地址簿中。 + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part1 + + 例如,在 Windows 上,该函数弹出本地文件对话框,如以下屏幕截图所示。 + + \image addressbook-tutorial-part6-load.png + + 如果 \c fileName 不为空,还是使用 QFile 对象 \c file,然后尝试在 \l{QIODevice::}{ReadOnly} 模式下打开文件。与 \c saveToFile() 的应用方式类似,如果尝试失败,会显示 QMessageBox 提示用户。 + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2 + + 否则,会用实例表示 QDataStream 对象 \c in,按上文所述设置其版本,然后将按顺序排列的数据读入 \c contacts 数据结构。请注意,在将数据读入之前清空 \c contacts 可简化文件读取过程。更高级的方法是将联系人读取至临时 QMap 对象,然后仅复制 \c contacts 中不存在的联系人。 + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3 + + 要显示从文件中读取的联系人,必须要先验证获取的数据,以确保读取的文件实际包含地址簿联系人。如果为真,显示第一个联系人,否则显示 QMessageBox 提示出现问题。最后,我们更新界面以相应地启用和禁用按钮。 +*/ + +/*! + \page tutorials-addressbook-part7.html + \previouspage 地址簿 6 — 加载和保存 + \contentspage {地址簿教程}{目录} + \example tutorials/addressbook/part7 + \title 地址簿 7 — 附加功能 + + 本章讲述了部分可使地址簿应用程序日常使用更加便捷的附加功能。 + + \image addressbook-tutorial-part7-screenshot.png + + 虽然地址簿应用程序其自身功能已经很实用,但是如果可和其他应用程序互换联系人数据就会更加有益。vCard 格式是一种流行的文件格式,就可用于此目的。在本章中,我们会扩展地址簿客户端,可将联系人导出到 vCard \c{.vcf} 文件中。 + + \section1 定义 AddressBook 类 + + 我们在 \c addressbook.h 文件的 \c AddressBook 类中添加 QPushButton 对象 \c exportButton 以及对应的公有槽 \c exportAsVCard()。 + + \snippet tutorials/addressbook/part7/addressbook.h exportAsVCard() declaration + \dots + \snippet tutorials/addressbook/part7/addressbook.h exportButton declaration + + \section1 应用 AddressBook 类 + + 在 \c AddressBook 构造器中,我们将 \c exportButton 的 \l{QPushButton::clicked()}{clicked()} 信号连接至 \c exportAsVCard()。我们还会将该按钮添加至 \c buttonLayout1,它是负责右侧按钮面板的布局类。 + + 在 \c exportAsVCard() 函数中,我们从提取 \c name 中联系人姓名开始入手。我们声明 \c firstName、\c lastName 和 \c nameList。接下来,我们查找 \c name 中第一处空白的索引。如果有空白,就将联系人的姓名分隔为 \c firstName 和 lastName。然后,将空白替换为下划线 ("_")。或者,如果没有空白,就认定联系人只有名字。 + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part1 + + 至于 \c saveToFile() 函数,会打开文件对话框,让用户选择文件的位置。通过选择的文件名称,我们创建要写入的 QFile 实例。 + + 我们尝试以 \l{QIODevice::}{WriteOnly} 模式打开文件。如果操作失败,会显示 QMessageBox 提示用户出现问题并返回。否则,将文件作为参数传递给 QTextStream 对象 \c out。与 QDataStream 类似,QTextStream 类提供了读取纯文本和将其写入到文件的功能。因此,所生成的 \c{.vcf} 文件可以在文本编辑器中打开进行编辑。 + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part2 + + 然后,我们写出依次带有 \c{BEGIN:VCARD} 和 \c{VERSION:2.1} 标记的 vCard 文件。联系人的姓名使用 \c{N:} 标记写入。至于写入 vCard “File as”属性的 FN: 标记,我们必须要查看是否联系人带有姓。如果联系人有姓,就使用 \c nameList 中的详细信息填入该标记。否则,仅写入 \c firstName。 + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part3 + + 我们继续写入联系人的地址。地址中的分号使用 "\\" 进行转义,新行使用分号进行替换,而逗号使用空白进行替换。最后,我们依次写入 \c{ADR;HOME:;}、\c address 和 \c{END:VCARD} 标记。 + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part4 + + 最后,会显示 QMessageBox 提示用户已成功导出 vCard。 + + \e{vCard 是 \l{http://www.imc.org}{Internet Mail Consortium} 的商标}。 +*/ diff --git a/doc/src/zh_CN/tutorials/widgets-tutorial.qdoc b/doc/src/zh_CN/tutorials/widgets-tutorial.qdoc new file mode 100644 index 0000000..90ef4f3 --- /dev/null +++ b/doc/src/zh_CN/tutorials/widgets-tutorial.qdoc @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page widgets-tutorial.html + \title Widgets 教程 + \brief This tutorial covers basic usage of widgets and layouts, showing how + they are used to build GUI applications. + + \startpage {index.html}{Qt Reference Documentation} + \contentspage 教程 + \nextpage {Widgets 教程 — 创建窗口} + + + \section1 简介 + + Widget 是使用 Qt 编写的图形用户界面 (GUI) 应用程序的基本生成块。每个 GUI 组件,如按钮、标签或文本编辑器,都是一个 widget ,并可以放置在现有的用户界面中或作为单独的窗口显示。每种类型的组件都是由 QWidget 的特殊子类提供的,而 QWidget 自身又是 QObject 的子类。 + + QWidget 不是一个抽象类;它可用作其他 widget 的容器,并很容易作为子类使用来创建定制 widget。它经常用来创建放置其他 widget 的窗口。 + + 至于 QObject,可使用父对象创建 widget 以表明其所属关系,这可确保删除不再使用的对象。使用 widget,这些父子关系就有了更多的意义:每个子类都显示在其父级所拥有的屏幕区域内。也就是说,当删除窗口时,其包含的所有 widget 也都自动删除。 + + \section1 Writing a main Function + + Many of the GUI examples in Qt follow the pattern of having a \c{main.cpp} + file containing code to initialize the application, and a number of other + source and header files containing the application logic and custom GUI + components. + + A typical \c main() function, written in \c{main.cpp}, looks like this: + + \snippet doc/src/snippets/widgets-tutorial/template.cpp main.cpp body + + We first construct a QApplication object which is configured using any + arguments passed in from the command line. After any widgets have been + created and shown, we call QApplication::exec() to start Qt's event loop. + Control passes to Qt until this function returns, at which point we return + the value we obtain from this function. + + In each part of this tutorial, we provide an example that is written + entirely within a \c main() function. In more sophisticated examples, the + code to set up widgets and layouts is written in other parts of the + example. For example, the GUI for a main window may be set up in the + constructor of a QMainWindow subclass. + + The \l{Widgets examples} are a good place to look for + more complex and complete examples and applications. + + \section1 Building Examples and Tutorials + + If you obtained a binary package of Qt or compiled it yourself, the + examples described in this tutorial should already be ready to run. + However, if you may wish to modify them and recompile them, you need to + perform the following steps: + + \list 1 + \o At the command line, enter the directory containing the example you + wish to recompile. + \o Type \c qmake and press \key{Return}. If this doesn't work, make sure + that the executable is on your path, or enter its full location. + \o On Linux/Unix and Mac OS X, type \c make and press \key{Return}; + on Windows with Visual Studio, type \c nmake and press \key{Return}. + \endlist + + An executable file should have been created within the current directory. + On Windows, this file may be located within a \c debug or \c release + subdirectory. You can run this file to see the example code at work. +*/ + +/*! + \page widgets-tutorial-toplevel.html + \contentspage {Widgets 教程}{目录} + \previouspage {Widgets 教程} + \nextpage {Widgets 教程 — Child Widgets} + \example tutorials/widgets/toplevel + \title Widgets 教程 — 创建窗口 + + 如果 widget 未使用父级进行创建,则在显示时视为窗口或\e{顶层 widget}。由于顶层 widget 没有父级对象类来确保在其不再使用时就删除,因此需要开发人员在应用程序中对其进行跟踪。 + + 在下例中,我们使用 QWidget 创建和显示具有默认大小的窗口: + + \raw HTML + <table align="left" width="100%"> + <tr class="qt-code"><td> + \endraw + \snippet tutorials/widgets/toplevel/main.cpp main program + \raw HTML + </td><td align="right"> + \endraw + \inlineimage widgets-tutorial-toplevel.png + \raw HTML + </td></tr> + </table> + \endraw + + To create a real GUI, we need to place widgets inside the window. To do + this, we pass a QWidget instance to a widget's constructor, as we will + demonstrate in the next part of this tutorial. +*/ + +/*! + \page widgets-tutorial-childwidget.html + \contentspage {Widgets 教程}{目录} + \previouspage {Widgets 教程 — 创建窗口} + \nextpage {Widgets 教程 — 使用布局} + \example tutorials/widgets/childwidget + \title Widgets 教程 — Child Widgets + + 我们可以通过将 \c window 作为父级传递给其构造器来向窗口添加子 widget。在这种情况下,我们向窗口添加按钮并将其放置在特定位置: + + \raw HTML + <table align="left" width="100%"> + <tr class="qt-code"><td> + \endraw + \snippet tutorials/widgets/childwidget/main.cpp main program + \raw HTML + </td><td align="right"> + \endraw + \inlineimage widgets-tutorial-childwidget.png + \raw HTML + </td></tr> + </table> + \endraw + + 该按钮现在为窗口的子项,并在删除窗口时一同删除。请注意,隐藏或关闭窗口不会自动删除该按钮。 +*/ + +/*! + \page widgets-tutorial-windowlayout.html + \contentspage {Widgets 教程}{目录} + \previouspage {Widgets 教程 — Child Widgets} + \nextpage {Widgets 教程 — Nested Layouts} + \example tutorials/widgets/windowlayout + \title Widgets 教程 — 使用布局 + + 通常,子 widget 是通过使用布局对象在窗口中进行排列,而不是通过指定位置和大小进行排列。在此处,我们构造要并排排列的标签和行编辑框 widget。 + + \raw HTML + <table align="left" width="100%"> + <tr class="qt-code"><td> + \endraw + \snippet tutorials/widgets/windowlayout/main.cpp main program + \raw HTML + </td><td align="right"> + \endraw + \inlineimage widgets-tutorial-windowlayout.png + \raw HTML + </td></tr> + </table> + \endraw + + 我们构造的布局对象管理通过 \l{QHBoxLayout::}{addWidget()} 函数提供的 widget 的位置和大小。布局本身是通过调用 \l{QWidget::}{setLayout()} 提供给窗口的。布局仅可通过其对所管理的 widget(和其他布局)的效果才可显示。 + + 在上文示例中,每个 widget 的所属关系并不明显。由于我们未使用父级对象构造 widget 和布局,我们会看到一个空窗口和两个包含了标签与行编辑框的窗口。不过,如果我们告知布局来管理标签和行编辑框,并在窗口中设置布局,两个 widget 与布局本身就都会成为窗口的子项。 +*/ + +/*! + \page widgets-tutorial-nestedlayouts.html + \contentspage {Widgets 教程}{目录} + \previouspage {Widgets 教程 — 使用布局} + \example tutorials/widgets/nestedlayouts + \title Widgets 教程 — Nested Layouts + + 由于 widget 可包含其他 widget,布局可用来提供按不同层次分组的 widget。这里,我们要在显示查询结果的表视图上方、窗口顶部的行编辑框旁,显示一个标签。 + + We achieve this by creating two layouts: \c{queryLayout} is a QHBoxLayout + that contains QLabel and QLineEdit widgets placed side-by-side; + \c{mainLayout} is a QVBoxLayout that contains \c{queryLayout} and a + QTableView arranged vertically. + + \raw HTML + <table align="left" width="100%"> + <tr class="qt-code"><td> + \endraw + \snippet tutorials/widgets/nestedlayouts/main.cpp first part + \snippet tutorials/widgets/nestedlayouts/main.cpp last part + \raw HTML + </td><td align="right"> + \endraw + \inlineimage widgets-tutorial-nestedlayouts.png + \raw HTML + </td></tr> + </table> + \endraw + + Note that we call the \c{mainLayout}'s \l{QBoxLayout::}{addLayout()} + function to insert the \c{queryLayout} above the \c{resultView} table. + + We have omitted the code that sets up the model containing the data shown + by the QTableView widget, \c resultView. For completeness, we show this below. + + 除了 QHBoxLayout 和 QVBoxLayout,Qt 还提供了 QGridLayout 和 QFormLayout 类来协助实现更复杂的用户界面。 + These can be seen if you run \l{Qt Designer}. + + \section1 Setting up the Model + + In the code above, we did not show where the table's data came from + because we wanted to concentrate on the use of layouts. Here, we see + that the model holds a number of items corresponding to rows, each of + which is set up to contain data for two columns. + + \snippet tutorials/widgets/nestedlayouts/main.cpp set up the model + + The use of models and views is covered in the + \l{Item Views Examples} and in the \l{Model/View Programming} overview. +*/ diff --git a/examples/dbus/remotecontrolledcar/car/car_adaptor.h b/examples/dbus/remotecontrolledcar/car/car_adaptor.h index d16972e..b8b5602 100644 --- a/examples/dbus/remotecontrolledcar/car/car_adaptor.h +++ b/examples/dbus/remotecontrolledcar/car/car_adaptor.h @@ -1,17 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -25,23 +25,23 @@ ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** ** $QT_END_LICENSE$ ** ** ** This file was generated by qdbusxml2cpp version 0.7 ** Command line was: qdbusxml2cpp -a car_adaptor.h: car.xml ** -** qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** This is an auto-generated file. ** This file may have been hand-edited. Look for HAND-EDIT comments diff --git a/examples/dbus/remotecontrolledcar/controller/car_interface.h b/examples/dbus/remotecontrolledcar/controller/car_interface.h index c2d281a..228481c 100644 --- a/examples/dbus/remotecontrolledcar/controller/car_interface.h +++ b/examples/dbus/remotecontrolledcar/controller/car_interface.h @@ -1,17 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -25,23 +25,23 @@ ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** ** $QT_END_LICENSE$ ** ** ** This file was generated by qdbusxml2cpp version 0.7 ** Command line was: qdbusxml2cpp -p car_interface.h: car.xml ** -** qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** This is an auto-generated file. ** Do not edit! All changes made to it will be lost. diff --git a/examples/declarative/extending/adding/main.cpp b/examples/declarative/extending/adding/main.cpp index 82e4946..74ea35c 100644 --- a/examples/declarative/extending/adding/main.cpp +++ b/examples/declarative/extending/adding/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/adding/person.cpp b/examples/declarative/extending/adding/person.cpp index 832bcdc..9efa2b8 100644 --- a/examples/declarative/extending/adding/person.cpp +++ b/examples/declarative/extending/adding/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/adding/person.h b/examples/declarative/extending/adding/person.h index 1a01586..691766b 100644 --- a/examples/declarative/extending/adding/person.h +++ b/examples/declarative/extending/adding/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/attached/birthdayparty.cpp b/examples/declarative/extending/attached/birthdayparty.cpp index c1f0fe8..9dc13de 100644 --- a/examples/declarative/extending/attached/birthdayparty.cpp +++ b/examples/declarative/extending/attached/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/attached/birthdayparty.h b/examples/declarative/extending/attached/birthdayparty.h index ffebe5f..bd8952b 100644 --- a/examples/declarative/extending/attached/birthdayparty.h +++ b/examples/declarative/extending/attached/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/attached/main.cpp b/examples/declarative/extending/attached/main.cpp index d99bfd3..2ec783f 100644 --- a/examples/declarative/extending/attached/main.cpp +++ b/examples/declarative/extending/attached/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/attached/person.cpp b/examples/declarative/extending/attached/person.cpp index 8105ee7..909505a 100644 --- a/examples/declarative/extending/attached/person.cpp +++ b/examples/declarative/extending/attached/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/attached/person.h b/examples/declarative/extending/attached/person.h index c5b7727..dd03091 100644 --- a/examples/declarative/extending/attached/person.h +++ b/examples/declarative/extending/attached/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/binding/birthdayparty.cpp b/examples/declarative/extending/binding/birthdayparty.cpp index 13d6bc8..8a409af 100644 --- a/examples/declarative/extending/binding/birthdayparty.cpp +++ b/examples/declarative/extending/binding/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/binding/birthdayparty.h b/examples/declarative/extending/binding/birthdayparty.h index 7fde54e..5651c65 100644 --- a/examples/declarative/extending/binding/birthdayparty.h +++ b/examples/declarative/extending/binding/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/binding/happybirthday.cpp b/examples/declarative/extending/binding/happybirthday.cpp index 9ce5a3d..38f3c08 100644 --- a/examples/declarative/extending/binding/happybirthday.cpp +++ b/examples/declarative/extending/binding/happybirthday.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/binding/happybirthday.h b/examples/declarative/extending/binding/happybirthday.h index 5a492c7..852bec7 100644 --- a/examples/declarative/extending/binding/happybirthday.h +++ b/examples/declarative/extending/binding/happybirthday.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/binding/main.cpp b/examples/declarative/extending/binding/main.cpp index c4090c4..4ad9929 100644 --- a/examples/declarative/extending/binding/main.cpp +++ b/examples/declarative/extending/binding/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/binding/person.cpp b/examples/declarative/extending/binding/person.cpp index 6ad62e9..50fb754 100644 --- a/examples/declarative/extending/binding/person.cpp +++ b/examples/declarative/extending/binding/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/binding/person.h b/examples/declarative/extending/binding/person.h index ad77d69..e8aa6a8 100644 --- a/examples/declarative/extending/binding/person.h +++ b/examples/declarative/extending/binding/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/coercion/birthdayparty.cpp b/examples/declarative/extending/coercion/birthdayparty.cpp index f3e0846..014d307 100644 --- a/examples/declarative/extending/coercion/birthdayparty.cpp +++ b/examples/declarative/extending/coercion/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/coercion/birthdayparty.h b/examples/declarative/extending/coercion/birthdayparty.h index 810cee3..8563ec3 100644 --- a/examples/declarative/extending/coercion/birthdayparty.h +++ b/examples/declarative/extending/coercion/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/coercion/main.cpp b/examples/declarative/extending/coercion/main.cpp index 1ad6d26..c6cc847 100644 --- a/examples/declarative/extending/coercion/main.cpp +++ b/examples/declarative/extending/coercion/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/coercion/person.cpp b/examples/declarative/extending/coercion/person.cpp index a897d8d..9eef8f7 100644 --- a/examples/declarative/extending/coercion/person.cpp +++ b/examples/declarative/extending/coercion/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/coercion/person.h b/examples/declarative/extending/coercion/person.h index 7cfd3d6..9bb9a3d 100644 --- a/examples/declarative/extending/coercion/person.h +++ b/examples/declarative/extending/coercion/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/default/birthdayparty.cpp b/examples/declarative/extending/default/birthdayparty.cpp index f3e0846..014d307 100644 --- a/examples/declarative/extending/default/birthdayparty.cpp +++ b/examples/declarative/extending/default/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/default/birthdayparty.h b/examples/declarative/extending/default/birthdayparty.h index cafe4c7..869b32c 100644 --- a/examples/declarative/extending/default/birthdayparty.h +++ b/examples/declarative/extending/default/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/default/main.cpp b/examples/declarative/extending/default/main.cpp index 1ad6d26..c6cc847 100644 --- a/examples/declarative/extending/default/main.cpp +++ b/examples/declarative/extending/default/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/default/person.cpp b/examples/declarative/extending/default/person.cpp index a5eafc4..a0b4960 100644 --- a/examples/declarative/extending/default/person.cpp +++ b/examples/declarative/extending/default/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/default/person.h b/examples/declarative/extending/default/person.h index 6fd9232..884dda3 100644 --- a/examples/declarative/extending/default/person.h +++ b/examples/declarative/extending/default/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/extended/lineedit.cpp b/examples/declarative/extending/extended/lineedit.cpp index 8a31004..ec86aad 100644 --- a/examples/declarative/extending/extended/lineedit.cpp +++ b/examples/declarative/extending/extended/lineedit.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/extended/lineedit.h b/examples/declarative/extending/extended/lineedit.h index 3f03ba1..ca96d05 100644 --- a/examples/declarative/extending/extended/lineedit.h +++ b/examples/declarative/extending/extended/lineedit.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/extended/main.cpp b/examples/declarative/extending/extended/main.cpp index c956ebc..9376af7 100644 --- a/examples/declarative/extending/extended/main.cpp +++ b/examples/declarative/extending/extended/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/grouped/birthdayparty.cpp b/examples/declarative/extending/grouped/birthdayparty.cpp index f3e0846..014d307 100644 --- a/examples/declarative/extending/grouped/birthdayparty.cpp +++ b/examples/declarative/extending/grouped/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/grouped/birthdayparty.h b/examples/declarative/extending/grouped/birthdayparty.h index ba8a68d..3f4a3a6 100644 --- a/examples/declarative/extending/grouped/birthdayparty.h +++ b/examples/declarative/extending/grouped/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/grouped/main.cpp b/examples/declarative/extending/grouped/main.cpp index baf5349..23ba8bf 100644 --- a/examples/declarative/extending/grouped/main.cpp +++ b/examples/declarative/extending/grouped/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/grouped/person.cpp b/examples/declarative/extending/grouped/person.cpp index 8105ee7..909505a 100644 --- a/examples/declarative/extending/grouped/person.cpp +++ b/examples/declarative/extending/grouped/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/grouped/person.h b/examples/declarative/extending/grouped/person.h index 5cd3e8f..89ccedc 100644 --- a/examples/declarative/extending/grouped/person.h +++ b/examples/declarative/extending/grouped/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/properties/birthdayparty.cpp b/examples/declarative/extending/properties/birthdayparty.cpp index b98a691..332b090 100644 --- a/examples/declarative/extending/properties/birthdayparty.cpp +++ b/examples/declarative/extending/properties/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/properties/birthdayparty.h b/examples/declarative/extending/properties/birthdayparty.h index 7bc3c3f..ceefd5b 100644 --- a/examples/declarative/extending/properties/birthdayparty.h +++ b/examples/declarative/extending/properties/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/properties/main.cpp b/examples/declarative/extending/properties/main.cpp index 590628e..229e59a 100644 --- a/examples/declarative/extending/properties/main.cpp +++ b/examples/declarative/extending/properties/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/properties/person.cpp b/examples/declarative/extending/properties/person.cpp index b41d0b6..d1b8bf4 100644 --- a/examples/declarative/extending/properties/person.cpp +++ b/examples/declarative/extending/properties/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/properties/person.h b/examples/declarative/extending/properties/person.h index 1c69f5a..8d665f0 100644 --- a/examples/declarative/extending/properties/person.h +++ b/examples/declarative/extending/properties/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/signal/birthdayparty.cpp b/examples/declarative/extending/signal/birthdayparty.cpp index 178ce0e..88c5459 100644 --- a/examples/declarative/extending/signal/birthdayparty.cpp +++ b/examples/declarative/extending/signal/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/signal/birthdayparty.h b/examples/declarative/extending/signal/birthdayparty.h index 56a809e..8ce5d7b 100644 --- a/examples/declarative/extending/signal/birthdayparty.h +++ b/examples/declarative/extending/signal/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/signal/main.cpp b/examples/declarative/extending/signal/main.cpp index d4e32a1..4e981c5 100644 --- a/examples/declarative/extending/signal/main.cpp +++ b/examples/declarative/extending/signal/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/signal/person.cpp b/examples/declarative/extending/signal/person.cpp index 8105ee7..909505a 100644 --- a/examples/declarative/extending/signal/person.cpp +++ b/examples/declarative/extending/signal/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/signal/person.h b/examples/declarative/extending/signal/person.h index c5b7727..dd03091 100644 --- a/examples/declarative/extending/signal/person.h +++ b/examples/declarative/extending/signal/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/valuesource/birthdayparty.cpp b/examples/declarative/extending/valuesource/birthdayparty.cpp index b0472d0..b483f68 100644 --- a/examples/declarative/extending/valuesource/birthdayparty.cpp +++ b/examples/declarative/extending/valuesource/birthdayparty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/valuesource/birthdayparty.h b/examples/declarative/extending/valuesource/birthdayparty.h index 11e1fdf..e7ca461 100644 --- a/examples/declarative/extending/valuesource/birthdayparty.h +++ b/examples/declarative/extending/valuesource/birthdayparty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/valuesource/happybirthday.cpp b/examples/declarative/extending/valuesource/happybirthday.cpp index b453944..fbbc9e9 100644 --- a/examples/declarative/extending/valuesource/happybirthday.cpp +++ b/examples/declarative/extending/valuesource/happybirthday.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/valuesource/happybirthday.h b/examples/declarative/extending/valuesource/happybirthday.h index 4e8e87c..c02a7d7 100644 --- a/examples/declarative/extending/valuesource/happybirthday.h +++ b/examples/declarative/extending/valuesource/happybirthday.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/valuesource/main.cpp b/examples/declarative/extending/valuesource/main.cpp index c4090c4..4ad9929 100644 --- a/examples/declarative/extending/valuesource/main.cpp +++ b/examples/declarative/extending/valuesource/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/valuesource/person.cpp b/examples/declarative/extending/valuesource/person.cpp index 8105ee7..909505a 100644 --- a/examples/declarative/extending/valuesource/person.cpp +++ b/examples/declarative/extending/valuesource/person.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/extending/valuesource/person.h b/examples/declarative/extending/valuesource/person.h index c5b7727..dd03091 100644 --- a/examples/declarative/extending/valuesource/person.h +++ b/examples/declarative/extending/valuesource/person.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/objectlistmodel/dataobject.cpp b/examples/declarative/objectlistmodel/dataobject.cpp index da85fe2..4c44ee4 100644 --- a/examples/declarative/objectlistmodel/dataobject.cpp +++ b/examples/declarative/objectlistmodel/dataobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/objectlistmodel/dataobject.h b/examples/declarative/objectlistmodel/dataobject.h index c0aa159..6804474 100644 --- a/examples/declarative/objectlistmodel/dataobject.h +++ b/examples/declarative/objectlistmodel/dataobject.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/objectlistmodel/main.cpp b/examples/declarative/objectlistmodel/main.cpp index 3f2ac6d..8231538 100644 --- a/examples/declarative/objectlistmodel/main.cpp +++ b/examples/declarative/objectlistmodel/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/examples/declarative/plugins/plugin.cpp b/examples/declarative/plugins/plugin.cpp index f4aa36b..820d4eb 100644 --- a/examples/declarative/plugins/plugin.cpp +++ b/examples/declarative/plugins/plugin.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/mkspecs/common/posix/qplatformdefs.h b/mkspecs/common/posix/qplatformdefs.h index e29bc6f..6310257 100644 --- a/mkspecs/common/posix/qplatformdefs.h +++ b/mkspecs/common/posix/qplatformdefs.h @@ -138,7 +138,9 @@ #define QT_OPENDIR ::opendir #define QT_CLOSEDIR ::closedir -#if defined(QT_USE_XOPEN_LFS_EXTENSIONS) && defined(QT_LARGEFILE_SUPPORT) +#if defined(QT_LARGEFILE_SUPPORT) \ + && defined(QT_USE_XOPEN_LFS_EXTENSIONS) \ + && !defined(QT_NO_READDIR64) #define QT_DIRENT struct dirent64 #define QT_READDIR ::readdir64 #define QT_READDIR_R ::readdir64_r diff --git a/mkspecs/hpux-acc-64/qplatformdefs.h b/mkspecs/hpux-acc-64/qplatformdefs.h index f9789a8..c1a9ab8 100644 --- a/mkspecs/hpux-acc-64/qplatformdefs.h +++ b/mkspecs/hpux-acc-64/qplatformdefs.h @@ -77,6 +77,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #undef QT_OPEN_LARGEFILE diff --git a/mkspecs/hpux-acc-o64/qplatformdefs.h b/mkspecs/hpux-acc-o64/qplatformdefs.h index 5237806..c622d80 100644 --- a/mkspecs/hpux-acc-o64/qplatformdefs.h +++ b/mkspecs/hpux-acc-o64/qplatformdefs.h @@ -78,6 +78,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #undef QT_SOCKLEN_T diff --git a/mkspecs/hpux-acc/qplatformdefs.h b/mkspecs/hpux-acc/qplatformdefs.h index 9ce08c6..c18ad49 100644 --- a/mkspecs/hpux-acc/qplatformdefs.h +++ b/mkspecs/hpux-acc/qplatformdefs.h @@ -80,6 +80,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #undef QT_OPEN_LARGEFILE diff --git a/mkspecs/hpux-g++-64/qplatformdefs.h b/mkspecs/hpux-g++-64/qplatformdefs.h index f3fbda5..e9a9e75 100644 --- a/mkspecs/hpux-g++-64/qplatformdefs.h +++ b/mkspecs/hpux-g++-64/qplatformdefs.h @@ -77,6 +77,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #endif // QPLATFORMDEFS_H diff --git a/mkspecs/hpux-g++/qplatformdefs.h b/mkspecs/hpux-g++/qplatformdefs.h index 38e9408..9296ac2 100644 --- a/mkspecs/hpux-g++/qplatformdefs.h +++ b/mkspecs/hpux-g++/qplatformdefs.h @@ -79,6 +79,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #undef QT_SOCKLEN_T diff --git a/mkspecs/hpuxi-acc-32/qplatformdefs.h b/mkspecs/hpuxi-acc-32/qplatformdefs.h index a0d2464..6aafed2 100644 --- a/mkspecs/hpuxi-acc-32/qplatformdefs.h +++ b/mkspecs/hpuxi-acc-32/qplatformdefs.h @@ -78,6 +78,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #undef QT_OPEN_LARGEFILE diff --git a/mkspecs/hpuxi-acc-64/qplatformdefs.h b/mkspecs/hpuxi-acc-64/qplatformdefs.h index a0d2464..6aafed2 100644 --- a/mkspecs/hpuxi-acc-64/qplatformdefs.h +++ b/mkspecs/hpuxi-acc-64/qplatformdefs.h @@ -78,6 +78,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #undef QT_OPEN_LARGEFILE diff --git a/mkspecs/hpuxi-g++-64/qplatformdefs.h b/mkspecs/hpuxi-g++-64/qplatformdefs.h index 288a331..f6789ee 100644 --- a/mkspecs/hpuxi-g++-64/qplatformdefs.h +++ b/mkspecs/hpuxi-g++-64/qplatformdefs.h @@ -77,6 +77,7 @@ #endif #define QT_USE_XOPEN_LFS_EXTENSIONS +#define QT_NO_READDIR64 #include "../common/posix/qplatformdefs.h" #undef QT_OPEN_LARGEFILE diff --git a/mkspecs/linux-g++-x11egl/qplatformdefs.h b/mkspecs/linux-g++-x11egl/qplatformdefs.h index 1430916..dd3b9a1 100644 --- a/mkspecs/linux-g++-x11egl/qplatformdefs.h +++ b/mkspecs/linux-g++-x11egl/qplatformdefs.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/mkspecs/qws/linux-arm-gnueabi-g++/qplatformdefs.h b/mkspecs/qws/linux-arm-gnueabi-g++/qplatformdefs.h index 60e0f5e..b0551e5 100644 --- a/mkspecs/qws/linux-arm-gnueabi-g++/qplatformdefs.h +++ b/mkspecs/qws/linux-arm-gnueabi-g++/qplatformdefs.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h index af04086..5912a51 100644 --- a/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h +++ b/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 99447a9..02a29d9 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -2543,6 +2543,11 @@ void MetaObjectGenerator::readFuncsInfo(ITypeInfo *typeinfo, ushort nFuncs) break; } if (funcdesc->invkind == INVOKE_PROPERTYPUT) { + // remove the typename guessed for property setters + // its done only for setter's with more than one parameter. + if (funcdesc->cParams - funcdesc->cParamsOpt > 1) { + type.clear(); + } QByteArray set; if (isupper(prototype.at(0))) { set = "Set"; diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index 5012b42..e37527d 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -171,11 +171,6 @@ public: private: const QTextCodec *c; QTextCodec::ConverterState state; - - friend class QXmlStreamWriter; - friend class QXmlStreamWriterPrivate; - friend class QCoreXmlStreamWriter; - friend class QCoreXmlStreamWriterPrivate; }; class Q_CORE_EXPORT QTextDecoder { diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 35ff8e7..6ee8ae9 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1725,7 +1725,8 @@ public: enum GestureFlag { DontStartGestureOnChildren = 0x01, - ReceivePartialGestures = 0x02 + ReceivePartialGestures = 0x02, + IgnoredGesturesPropagateToParent = 0x04 }; Q_DECLARE_FLAGS(GestureFlags, GestureFlag) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 1f1c8f7..db910ce 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -42,6 +42,7 @@ /*! \namespace Qt \inmodule QtCore + \target Qt Namespace \brief The Qt namespace contains miscellaneous identifiers used throughout the Qt library. diff --git a/src/corelib/io/qdataurl.cpp b/src/corelib/io/qdataurl.cpp index 9bb896e..4e2dec2 100644 --- a/src/corelib/io/qdataurl.cpp +++ b/src/corelib/io/qdataurl.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/corelib/io/qdataurl_p.h b/src/corelib/io/qdataurl_p.h index be5b10d..57cfd75 100644 --- a/src/corelib/io/qdataurl_p.h +++ b/src/corelib/io/qdataurl_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index f5d803e..7cfdddf 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -89,8 +89,6 @@ public: QDirPrivate(const QDir *copy = 0); ~QDirPrivate(); - QString initFileEngine(const QString &file); - void updateFileLists() const; void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *) const; @@ -146,6 +144,7 @@ public: } *data; inline void setPath(const QString &p) { + detach(false); QString path = p; if ((path.endsWith(QLatin1Char('/')) || path.endsWith(QLatin1Char('\\'))) && path.length() > 1) { @@ -155,8 +154,12 @@ public: path.truncate(path.length() - 1); } + delete data->fileEngine; + data->fileEngine = QAbstractFileEngine::create(path); + // set the path to be the qt friendly version so then we can operate on it using just / - data->path = initFileEngine(path); + data->path = data->fileEngine->fileName(QAbstractFileEngine::DefaultName); + data->clear(); } inline void reset() { detach(); @@ -310,15 +313,6 @@ inline void QDirPrivate::updateFileLists() const } } -inline QString QDirPrivate::initFileEngine(const QString &path) -{ - detach(false); - data->clear(); - delete data->fileEngine; - data->fileEngine = QAbstractFileEngine::create(path); - return data->fileEngine->fileName(QAbstractFileEngine::DefaultName); -} - void QDirPrivate::detach(bool createFileEngine) { qAtomicDetach(data); diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index ff10fa1..b4bfcaf 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2917,7 +2917,7 @@ QDate QLocale::toDate(const QString &string, FormatType format) const #ifndef QT_NO_DATESTRING QDateTime QLocale::toDateTime(const QString &string, FormatType format) const { - return toDateTime(string, dateFormat(format)); + return toDateTime(string, dateTimeFormat(format)); } #endif diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 8fbfcda..0dcea5f 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -653,6 +653,9 @@ public: T *value; }; +// +// operator== and operator!= +// template <class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) { @@ -674,7 +677,6 @@ bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2) { return ptr1 == ptr2.data(); } - template <class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2) { @@ -697,11 +699,54 @@ bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) return ptr2 != ptr1; } +// +// operator- +// template <class T, class X> -Q_INLINE_TEMPLATE typename T::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) +Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) { return ptr1.data() - ptr2.data(); } +template <class T, class X> +Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2) +{ + return ptr1.data() - ptr2; +} +template <class T, class X> +Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2) +{ + return ptr1 - ptr2.data(); +} + +// +// operator< +// +template <class T, class X> +Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) +{ + return ptr1.data() < ptr2.data(); +} +template <class T, class X> +Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2) +{ + return ptr1.data() < ptr2; +} +template <class T, class X> +Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2) +{ + return ptr1 < ptr2.data(); +} + +// +// qHash +// +template <class T> inline uint qHash(const T *key); // defined in qhash.h +template <class T> +Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr) +{ + return QT_PREPEND_NAMESPACE(qHash)<T>(ptr.data()); +} + template <class T> Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index 9ea05b2..7168e05 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -196,6 +196,8 @@ DEFINEFUNC(void , dbus_free, (void *memory), (memory), ) /* dbus-message.h */ DEFINEFUNC(DBusMessage* , dbus_message_copy, (const DBusMessage *message), (message), return) +DEFINEFUNC(dbus_bool_t , dbus_message_get_auto_start, (DBusMessage *message), + (message), return) DEFINEFUNC(const char* , dbus_message_get_error_name, (DBusMessage *message), (message), return) DEFINEFUNC(const char* , dbus_message_get_interface, (DBusMessage *message), @@ -268,6 +270,9 @@ DEFINEFUNC(DBusMessage* , dbus_message_new_signal, (const char *path, (path, interface, name), return) DEFINEFUNC(DBusMessage* , dbus_message_ref, (DBusMessage *message), (message), return) +DEFINEFUNC(void , dbus_message_set_auto_start, (DBusMessage *message, + dbus_bool_t auto_start), + (message, auto_start), return) DEFINEFUNC(dbus_bool_t , dbus_message_set_destination, (DBusMessage *message, const char *destination), (message, destination), return) diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index 83b5503..30ddc61 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -63,7 +63,7 @@ static inline const char *data(const QByteArray &arr) QDBusMessagePrivate::QDBusMessagePrivate() : msg(0), reply(0), type(DBUS_MESSAGE_TYPE_INVALID), timeout(-1), localReply(0), ref(1), delayedReply(false), localMessage(false), - parametersValidated(false) + parametersValidated(false), autoStartService(true) { } @@ -129,6 +129,7 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(), data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8()); + q_dbus_message_set_auto_start( msg, d_ptr->autoStartService ); break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); @@ -644,6 +645,45 @@ bool QDBusMessage::isDelayedReply() const } /*! + Sets the auto start flag to \a enable. This flag only makes sense + for method call messages, where it tells the D-Bus server to + either auto start the service responsible for the service name, or + not to auto start it. + + By default this flag is true, i.e. a service is autostarted. + This means: + + When the service that this method call is sent to is already + running, the method call is sent to it. If the service is not + running yet, the D-Bus daemon is requested to autostart the + service that is assigned to this service name. This is + handled by .service files that are placed in a directory known + to the D-Bus server. These files then each contain a service + name and the path to a program that should be executed when + this service name is requested. + + \since 4.7 +*/ +void QDBusMessage::setAutoStartService(bool enable) +{ + d_ptr->autoStartService = enable; +} + +/*! + Returns the auto start flag, as set by setAutoStartService(). By default, this + flag is true, which means QtDBus will auto start a service, if it is + not running already. + + \sa setAutoStartService() + + \since 4.7 +*/ +bool QDBusMessage::autoStartService() const +{ + return d_ptr->autoStartService; +} + +/*! Sets the arguments that are going to be sent over D-Bus to \a arguments. Those will be the arguments to a method call or the parameters in the signal. diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index 1a85983..6df5215 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -104,6 +104,9 @@ public: void setDelayedReply(bool enable) const; bool isDelayedReply() const; + void setAutoStartService(bool enable); + bool autoStartService() const; + void setArguments(const QList<QVariant> &arguments); QList<QVariant> arguments() const; diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index 6bf5448..b6da4a5 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -85,6 +85,7 @@ public: mutable uint delayedReply : 1; uint localMessage : 1; mutable uint parametersValidated : 1; + uint autoStartService : 1; static void setParametersValidated(QDBusMessage &msg, bool enable) { msg.d_ptr->parametersValidated = enable; } diff --git a/src/declarative/3rdparty/qlistmodelinterface.cpp b/src/declarative/3rdparty/qlistmodelinterface.cpp index cfd4cff..939e985 100644 --- a/src/declarative/3rdparty/qlistmodelinterface.cpp +++ b/src/declarative/3rdparty/qlistmodelinterface.cpp @@ -1,16 +1,17 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** This file is part of the QtDeclaractive module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/declarative/3rdparty/qlistmodelinterface_p.h b/src/declarative/3rdparty/qlistmodelinterface_p.h index a958ead..07592ad 100644 --- a/src/declarative/3rdparty/qlistmodelinterface_p.h +++ b/src/declarative/3rdparty/qlistmodelinterface_p.h @@ -1,7 +1,8 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtDeclarative module of the Qt Toolkit. ** @@ -9,8 +10,8 @@ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/declarative/debugger/qmldebug.cpp b/src/declarative/debugger/qmldebug.cpp index dc779ac..5e93d50 100644 --- a/src/declarative/debugger/qmldebug.cpp +++ b/src/declarative/debugger/qmldebug.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qmldebug_p.h b/src/declarative/debugger/qmldebug_p.h index cd2adf6..4e9d065 100644 --- a/src/declarative/debugger/qmldebug_p.h +++ b/src/declarative/debugger/qmldebug_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qmldebugclient.cpp b/src/declarative/debugger/qmldebugclient.cpp index 68e14c2..ae42b5b 100644 --- a/src/declarative/debugger/qmldebugclient.cpp +++ b/src/declarative/debugger/qmldebugclient.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qmldebugclient_p.h b/src/declarative/debugger/qmldebugclient_p.h index d64541b..c3e6eff 100644 --- a/src/declarative/debugger/qmldebugclient_p.h +++ b/src/declarative/debugger/qmldebugclient_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qmldebuggerstatus.cpp b/src/declarative/debugger/qmldebuggerstatus.cpp index dc1cfb0..0f2a973 100644 --- a/src/declarative/debugger/qmldebuggerstatus.cpp +++ b/src/declarative/debugger/qmldebuggerstatus.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qmldebuggerstatus_p.h b/src/declarative/debugger/qmldebuggerstatus_p.h index 7c8070b..42538f3 100644 --- a/src/declarative/debugger/qmldebuggerstatus_p.h +++ b/src/declarative/debugger/qmldebuggerstatus_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qmldebugservice.cpp b/src/declarative/debugger/qmldebugservice.cpp index 810fbed..7f28c0c 100644 --- a/src/declarative/debugger/qmldebugservice.cpp +++ b/src/declarative/debugger/qmldebugservice.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qmldebugservice_p.h b/src/declarative/debugger/qmldebugservice_p.h index b406a3c..55ecf1d 100644 --- a/src/declarative/debugger/qmldebugservice_p.h +++ b/src/declarative/debugger/qmldebugservice_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp index fb07c62..7440b87 100644 --- a/src/declarative/debugger/qpacketprotocol.cpp +++ b/src/declarative/debugger/qpacketprotocol.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/debugger/qpacketprotocol_p.h b/src/declarative/debugger/qpacketprotocol_p.h index 265af81..cfdce4e 100644 --- a/src/declarative/debugger/qpacketprotocol_p.h +++ b/src/declarative/debugger/qpacketprotocol_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index 945e7d3..3a6ec48 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h index 5a8f8c1..41911ff 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h index 5b02158..12197f0 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp b/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp index e01e569..eb60495 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanimatedimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p.h b/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p.h index a837702..a6cee0d 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p_p.h b/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p_p.h index 0d1c749..5e04a93 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanimatedimage_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp b/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp index 877e141..493b148 100644 --- a/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsborderimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsborderimage_p.h b/src/declarative/graphicsitems/qmlgraphicsborderimage_p.h index cf3c518..32dc388 100644 --- a/src/declarative/graphicsitems/qmlgraphicsborderimage_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsborderimage_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsborderimage_p_p.h b/src/declarative/graphicsitems/qmlgraphicsborderimage_p_p.h index 51ebb02..b97ae6d 100644 --- a/src/declarative/graphicsitems/qmlgraphicsborderimage_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsborderimage_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicseffects.cpp b/src/declarative/graphicsitems/qmlgraphicseffects.cpp index e1f5687..0160971 100644 --- a/src/declarative/graphicsitems/qmlgraphicseffects.cpp +++ b/src/declarative/graphicsitems/qmlgraphicseffects.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsevents.cpp b/src/declarative/graphicsitems/qmlgraphicsevents.cpp index 9958dea..d42708c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsevents.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsevents.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsevents_p_p.h b/src/declarative/graphicsitems/qmlgraphicsevents_p_p.h index b07fd88..0ed852a 100644 --- a/src/declarative/graphicsitems/qmlgraphicsevents_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsevents_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsflickable.cpp b/src/declarative/graphicsitems/qmlgraphicsflickable.cpp index 2ff3b30..2bf11a0 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflickable.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsflickable.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsflickable_p.h b/src/declarative/graphicsitems/qmlgraphicsflickable_p.h index ea07da4..5ff8e6f 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflickable_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsflickable_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsflickable_p_p.h b/src/declarative/graphicsitems/qmlgraphicsflickable_p_p.h index ae164cc..5eda22c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflickable_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsflickable_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsflipable.cpp b/src/declarative/graphicsitems/qmlgraphicsflipable.cpp index ff8995b..a30ba6c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflipable.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsflipable.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsflipable_p.h b/src/declarative/graphicsitems/qmlgraphicsflipable_p.h index c189786..2b9e44e 100644 --- a/src/declarative/graphicsitems/qmlgraphicsflipable_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsflipable_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp b/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp index 333b689..093e9de 100644 --- a/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsfocuspanel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsfocuspanel_p.h b/src/declarative/graphicsitems/qmlgraphicsfocuspanel_p.h index 4c5cc14..935b04e 100644 --- a/src/declarative/graphicsitems/qmlgraphicsfocuspanel_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsfocuspanel_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp b/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp index 828756c..084e244 100644 --- a/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsfocusscope.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsfocusscope_p.h b/src/declarative/graphicsitems/qmlgraphicsfocusscope_p.h index 0ea9da5..ca53b01 100644 --- a/src/declarative/graphicsitems/qmlgraphicsfocusscope_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsfocusscope_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp index a5a7935..e7206f1 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer_p.h b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer_p.h index 1091145..e263aa0 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp index 83911c0..24d9769 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgridview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsgridview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsgridview_p.h b/src/declarative/graphicsitems/qmlgraphicsgridview_p.h index d2ef70e..11dd3f2 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgridview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsgridview_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsimage.cpp b/src/declarative/graphicsitems/qmlgraphicsimage.cpp index 7e63c8b..d4ad3c8 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsimage_p.h b/src/declarative/graphicsitems/qmlgraphicsimage_p.h index dde5d79..b8befeb 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimage_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsimage_p_p.h b/src/declarative/graphicsitems/qmlgraphicsimage_p_p.h index 3a5acca..e404935 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimage_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimage_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp b/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp index 08617ac..c09b661 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsimagebase.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h b/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h index 61ea975..e8bda4c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimagebase_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsimagebase_p_p.h b/src/declarative/graphicsitems/qmlgraphicsimagebase_p_p.h index 44b2332..d86785f 100644 --- a/src/declarative/graphicsitems/qmlgraphicsimagebase_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsimagebase_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index 8973cb4..17362d0 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -1426,6 +1426,10 @@ QmlGraphicsKeysAttached *QmlGraphicsKeysAttached::qmlAttachedProperties(QObject \internal */ +/*! \fn void QmlGraphicsItem::transformOriginChanged(TransformOrigin) + \internal +*/ + /*! \fn void QmlGraphicsItem::childrenChanged() \internal diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.h b/src/declarative/graphicsitems/qmlgraphicsitem.h index 8ae2d5c..606cc56 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.h +++ b/src/declarative/graphicsitems/qmlgraphicsitem.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsitem_p.h b/src/declarative/graphicsitems/qmlgraphicsitem_p.h index 1741808..5ef07e3 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsitem_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsitemchangelistener_p.h b/src/declarative/graphicsitems/qmlgraphicsitemchangelistener_p.h index f430df0..a1c7b89 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitemchangelistener_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsitemchangelistener_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp b/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp index 7227eb0..b054ced 100644 --- a/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslayoutitem.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicslayoutitem_p.h b/src/declarative/graphicsitems/qmlgraphicslayoutitem_p.h index 3278b63..fbc891d 100644 --- a/src/declarative/graphicsitems/qmlgraphicslayoutitem_p.h +++ b/src/declarative/graphicsitems/qmlgraphicslayoutitem_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index d0b3739..1e2698c 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicslistview_p.h b/src/declarative/graphicsitems/qmlgraphicslistview_p.h index 79d678a..5a8ac9c 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicslistview_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsloader.cpp b/src/declarative/graphicsitems/qmlgraphicsloader.cpp index b3486ef..44932a2 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsloader.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsloader_p.h b/src/declarative/graphicsitems/qmlgraphicsloader_p.h index 87b6a52..bfc011d 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsloader_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h b/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h index 7f10eff..61dab58 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp b/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp index bd21e7a..1f8435e 100644 --- a/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsmouseregion.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsmouseregion_p.h b/src/declarative/graphicsitems/qmlgraphicsmouseregion_p.h index 0ddad1b..e01831e 100644 --- a/src/declarative/graphicsitems/qmlgraphicsmouseregion_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsmouseregion_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsmouseregion_p_p.h b/src/declarative/graphicsitems/qmlgraphicsmouseregion_p_p.h index 0f1b0d4..be27176 100644 --- a/src/declarative/graphicsitems/qmlgraphicsmouseregion_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsmouseregion_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp b/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp index e50e3e4..3daa0c6 100644 --- a/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspainteditem.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h b/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h index ab21f36..f2f9be0 100644 --- a/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspainteditem_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h b/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h index 6bcc51a..7d49914 100644 --- a/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspainteditem_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp index 8c5fb4f..95d4844 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsparticles.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h index c34d55b..7f0f9cd 100644 --- a/src/declarative/graphicsitems/qmlgraphicsparticles_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsparticles_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspath.cpp b/src/declarative/graphicsitems/qmlgraphicspath.cpp index 18f27af..6f04b75 100644 --- a/src/declarative/graphicsitems/qmlgraphicspath.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspath.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspath_p.h b/src/declarative/graphicsitems/qmlgraphicspath_p.h index 2b4b0fd..51b7262 100644 --- a/src/declarative/graphicsitems/qmlgraphicspath_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspath_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspath_p_p.h b/src/declarative/graphicsitems/qmlgraphicspath_p_p.h index 04342a8..acff7c8 100644 --- a/src/declarative/graphicsitems/qmlgraphicspath_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspath_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspathview.cpp b/src/declarative/graphicsitems/qmlgraphicspathview.cpp index 6718d25..4511820 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspathview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspathview_p.h b/src/declarative/graphicsitems/qmlgraphicspathview_p.h index 17106a2..8273ccc 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspathview_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h b/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h index 18cb205..723d2d5 100644 --- a/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspathview_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp index 5b081a2..ba26f62 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h index d6711f6..1fb687a 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h index 55a31c7..e9b6aa8 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp b/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp index cc09436..1fa63e0 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsrectangle.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsrectangle_p.h b/src/declarative/graphicsitems/qmlgraphicsrectangle_p.h index 4f4c1cf..c566027 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrectangle_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsrectangle_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsrectangle_p_p.h b/src/declarative/graphicsitems/qmlgraphicsrectangle_p_p.h index c4bbbe4..f91e7e2 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrectangle_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsrectangle_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp b/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp index 99f0faa..0c27f4c 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsrepeater.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsrepeater_p.h b/src/declarative/graphicsitems/qmlgraphicsrepeater_p.h index 61f82d7..f7a6b09 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrepeater_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsrepeater_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsrepeater_p_p.h b/src/declarative/graphicsitems/qmlgraphicsrepeater_p_p.h index e6d7bfd..5680288 100644 --- a/src/declarative/graphicsitems/qmlgraphicsrepeater_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsrepeater_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsscalegrid.cpp b/src/declarative/graphicsitems/qmlgraphicsscalegrid.cpp index f50b79b..58d6ab8 100644 --- a/src/declarative/graphicsitems/qmlgraphicsscalegrid.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsscalegrid.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h b/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h index 88938a7..650be62 100644 --- a/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsscalegrid_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstext.cpp b/src/declarative/graphicsitems/qmlgraphicstext.cpp index b13fb7c..e9e5924 100644 --- a/src/declarative/graphicsitems/qmlgraphicstext.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstext.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstext_p.h b/src/declarative/graphicsitems/qmlgraphicstext_p.h index 8fa2e65..ad35524 100644 --- a/src/declarative/graphicsitems/qmlgraphicstext_p.h +++ b/src/declarative/graphicsitems/qmlgraphicstext_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstext_p_p.h b/src/declarative/graphicsitems/qmlgraphicstext_p_p.h index 1e29e58..46d2d0e 100644 --- a/src/declarative/graphicsitems/qmlgraphicstext_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicstext_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp index fc80258..e8cde10 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextedit.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit_p.h b/src/declarative/graphicsitems/qmlgraphicstextedit_p.h index e95b077..337cd9d 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit_p.h +++ b/src/declarative/graphicsitems/qmlgraphicstextedit_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstextedit_p_p.h b/src/declarative/graphicsitems/qmlgraphicstextedit_p_p.h index 8914bfd..7d4ca88 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextedit_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicstextedit_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp index 6d79c7a..a7b25c5 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp +++ b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput_p.h b/src/declarative/graphicsitems/qmlgraphicstextinput_p.h index 4708381..794661c 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextinput_p.h +++ b/src/declarative/graphicsitems/qmlgraphicstextinput_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput_p_p.h b/src/declarative/graphicsitems/qmlgraphicstextinput_p_p.h index 9eb6e07..694ec93 100644 --- a/src/declarative/graphicsitems/qmlgraphicstextinput_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicstextinput_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp index 2fc143d..f9ebef9 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h index ef849b0..3321472 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicswebview.cpp b/src/declarative/graphicsitems/qmlgraphicswebview.cpp index 85fd0d7..a811506 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicswebview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicswebview_p.h b/src/declarative/graphicsitems/qmlgraphicswebview_p.h index f5edb7a..2162716 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicswebview_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/graphicsitems/qmlgraphicswebview_p_p.h b/src/declarative/graphicsitems/qmlgraphicswebview_p_p.h index 5659059..e132cae 100644 --- a/src/declarative/graphicsitems/qmlgraphicswebview_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicswebview_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsast.cpp b/src/declarative/qml/parser/qmljsast.cpp index e80b05e..d3ceba6 100644 --- a/src/declarative/qml/parser/qmljsast.cpp +++ b/src/declarative/qml/parser/qmljsast.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsast_p.h b/src/declarative/qml/parser/qmljsast_p.h index 032fbb1..9de733c 100644 --- a/src/declarative/qml/parser/qmljsast_p.h +++ b/src/declarative/qml/parser/qmljsast_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsastfwd_p.h b/src/declarative/qml/parser/qmljsastfwd_p.h index f571a2e..2c42fd9 100644 --- a/src/declarative/qml/parser/qmljsastfwd_p.h +++ b/src/declarative/qml/parser/qmljsastfwd_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsastvisitor.cpp b/src/declarative/qml/parser/qmljsastvisitor.cpp index 1290c89..bd7439c 100644 --- a/src/declarative/qml/parser/qmljsastvisitor.cpp +++ b/src/declarative/qml/parser/qmljsastvisitor.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsastvisitor_p.h b/src/declarative/qml/parser/qmljsastvisitor_p.h index 1b50bcc..9007a2c 100644 --- a/src/declarative/qml/parser/qmljsastvisitor_p.h +++ b/src/declarative/qml/parser/qmljsastvisitor_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsengine_p.cpp b/src/declarative/qml/parser/qmljsengine_p.cpp index b8ecd18..84bb1c5 100644 --- a/src/declarative/qml/parser/qmljsengine_p.cpp +++ b/src/declarative/qml/parser/qmljsengine_p.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsengine_p.h b/src/declarative/qml/parser/qmljsengine_p.h index 2c15af3..ebfeb1b 100644 --- a/src/declarative/qml/parser/qmljsengine_p.h +++ b/src/declarative/qml/parser/qmljsengine_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsglobal_p.h b/src/declarative/qml/parser/qmljsglobal_p.h index 49e50cf..4457450 100644 --- a/src/declarative/qml/parser/qmljsglobal_p.h +++ b/src/declarative/qml/parser/qmljsglobal_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsgrammar.cpp b/src/declarative/qml/parser/qmljsgrammar.cpp index b416959..12071db 100644 --- a/src/declarative/qml/parser/qmljsgrammar.cpp +++ b/src/declarative/qml/parser/qmljsgrammar.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsgrammar_p.h b/src/declarative/qml/parser/qmljsgrammar_p.h index c2e2693..21fddba 100644 --- a/src/declarative/qml/parser/qmljsgrammar_p.h +++ b/src/declarative/qml/parser/qmljsgrammar_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljslexer.cpp b/src/declarative/qml/parser/qmljslexer.cpp index cf3ed34..816542f 100644 --- a/src/declarative/qml/parser/qmljslexer.cpp +++ b/src/declarative/qml/parser/qmljslexer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljslexer_p.h b/src/declarative/qml/parser/qmljslexer_p.h index b830071..8f95a90 100644 --- a/src/declarative/qml/parser/qmljslexer_p.h +++ b/src/declarative/qml/parser/qmljslexer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsmemorypool_p.h b/src/declarative/qml/parser/qmljsmemorypool_p.h index 3da2678..5dffdc8 100644 --- a/src/declarative/qml/parser/qmljsmemorypool_p.h +++ b/src/declarative/qml/parser/qmljsmemorypool_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/parser/qmljsnodepool_p.h b/src/declarative/qml/parser/qmljsnodepool_p.h index abe4cc8..2055a7e 100644 --- a/src/declarative/qml/parser/qmljsnodepool_p.h +++ b/src/declarative/qml/parser/qmljsnodepool_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qbitfield_p.h b/src/declarative/qml/qbitfield_p.h index 8b3afdb..28afa40 100644 --- a/src/declarative/qml/qbitfield_p.h +++ b/src/declarative/qml/qbitfield_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp index 11b9f80..a518b03 100644 --- a/src/declarative/qml/qmetaobjectbuilder.cpp +++ b/src/declarative/qml/qmetaobjectbuilder.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmetaobjectbuilder_p.h b/src/declarative/qml/qmetaobjectbuilder_p.h index 3eff4ff..dbaf9e6 100644 --- a/src/declarative/qml/qmetaobjectbuilder_p.h +++ b/src/declarative/qml/qmetaobjectbuilder_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h index c009093..46eec67 100644 --- a/src/declarative/qml/qml.h +++ b/src/declarative/qml/qml.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp index 3e29a3c..c4be39e 100644 --- a/src/declarative/qml/qmlbinding.cpp +++ b/src/declarative/qml/qmlbinding.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlbinding.h b/src/declarative/qml/qmlbinding.h index cefb4fe..2b09414 100644 --- a/src/declarative/qml/qmlbinding.h +++ b/src/declarative/qml/qmlbinding.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlbinding_p.h b/src/declarative/qml/qmlbinding_p.h index c6c1935..b4f88b5 100644 --- a/src/declarative/qml/qmlbinding_p.h +++ b/src/declarative/qml/qmlbinding_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlboundsignal.cpp b/src/declarative/qml/qmlboundsignal.cpp index d42e7ba..a075899 100644 --- a/src/declarative/qml/qmlboundsignal.cpp +++ b/src/declarative/qml/qmlboundsignal.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlboundsignal_p.h b/src/declarative/qml/qmlboundsignal_p.h index 971fc89..51d21d7 100644 --- a/src/declarative/qml/qmlboundsignal_p.h +++ b/src/declarative/qml/qmlboundsignal_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlclassfactory.cpp b/src/declarative/qml/qmlclassfactory.cpp index 3c19c2f..2adff09 100644 --- a/src/declarative/qml/qmlclassfactory.cpp +++ b/src/declarative/qml/qmlclassfactory.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlclassfactory_p.h b/src/declarative/qml/qmlclassfactory_p.h index 91f616e..2ddadcf 100644 --- a/src/declarative/qml/qmlclassfactory_p.h +++ b/src/declarative/qml/qmlclassfactory_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcleanup.cpp b/src/declarative/qml/qmlcleanup.cpp index 599e4e7..fc01a90 100644 --- a/src/declarative/qml/qmlcleanup.cpp +++ b/src/declarative/qml/qmlcleanup.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcleanup_p.h b/src/declarative/qml/qmlcleanup_p.h index c140e43..50803f3 100644 --- a/src/declarative/qml/qmlcleanup_p.h +++ b/src/declarative/qml/qmlcleanup_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompiledbindings.cpp b/src/declarative/qml/qmlcompiledbindings.cpp index b5fbab9..fbf714d 100644 --- a/src/declarative/qml/qmlcompiledbindings.cpp +++ b/src/declarative/qml/qmlcompiledbindings.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompiledbindings_p.h b/src/declarative/qml/qmlcompiledbindings_p.h index 1d8fac4..38fb2a3 100644 --- a/src/declarative/qml/qmlcompiledbindings_p.h +++ b/src/declarative/qml/qmlcompiledbindings_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompileddata.cpp b/src/declarative/qml/qmlcompileddata.cpp index 48a0893..0120f56 100644 --- a/src/declarative/qml/qmlcompileddata.cpp +++ b/src/declarative/qml/qmlcompileddata.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 9990c06..2b1081e 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index f3f266b..744d397 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 9e06016..f15c364 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h index 342f503..8996481 100644 --- a/src/declarative/qml/qmlcomponent.h +++ b/src/declarative/qml/qmlcomponent.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcomponent_p.h b/src/declarative/qml/qmlcomponent_p.h index 4039a61..b7a3038 100644 --- a/src/declarative/qml/qmlcomponent_p.h +++ b/src/declarative/qml/qmlcomponent_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompositetypedata_p.h b/src/declarative/qml/qmlcompositetypedata_p.h index c8b9f25..e4e8007 100644 --- a/src/declarative/qml/qmlcompositetypedata_p.h +++ b/src/declarative/qml/qmlcompositetypedata_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp index 3504fe9..71d6f16 100644 --- a/src/declarative/qml/qmlcompositetypemanager.cpp +++ b/src/declarative/qml/qmlcompositetypemanager.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcompositetypemanager_p.h b/src/declarative/qml/qmlcompositetypemanager_p.h index 89e2353..2da5d34 100644 --- a/src/declarative/qml/qmlcompositetypemanager_p.h +++ b/src/declarative/qml/qmlcompositetypemanager_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index d9fc76b..4011d8d 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -428,7 +428,7 @@ void QmlContextPrivate::setIdPropertyData(QmlIntegerCache *data) } /*! - Set a the \a value of the \a name property on this context. + Set the \a value of the \a name property on this context. QmlContext does \bold not take ownership of \a value. */ @@ -452,6 +452,10 @@ void QmlContext::setContextProperty(const QString &name, QObject *value) } } +/*! + Returns the value of the \a name property for this context + as a QVariant. + */ QVariant QmlContext::contextProperty(const QString &name) const { Q_D(const QmlContext); diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h index bf389a0..21b1a1e 100644 --- a/src/declarative/qml/qmlcontext.h +++ b/src/declarative/qml/qmlcontext.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index cd7e1b6..bd4f5d5 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp index 80d52ad..be3bbc3 100644 --- a/src/declarative/qml/qmlcontextscriptclass.cpp +++ b/src/declarative/qml/qmlcontextscriptclass.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcontextscriptclass_p.h b/src/declarative/qml/qmlcontextscriptclass_p.h index f98d44f..c878f3c 100644 --- a/src/declarative/qml/qmlcontextscriptclass_p.h +++ b/src/declarative/qml/qmlcontextscriptclass_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcustomparser.cpp b/src/declarative/qml/qmlcustomparser.cpp index 116644a..d781110 100644 --- a/src/declarative/qml/qmlcustomparser.cpp +++ b/src/declarative/qml/qmlcustomparser.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcustomparser_p.h b/src/declarative/qml/qmlcustomparser_p.h index 9502b08..7aebb0d 100644 --- a/src/declarative/qml/qmlcustomparser_p.h +++ b/src/declarative/qml/qmlcustomparser_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlcustomparser_p_p.h b/src/declarative/qml/qmlcustomparser_p_p.h index c27a5bc..52e7b4f 100644 --- a/src/declarative/qml/qmlcustomparser_p_p.h +++ b/src/declarative/qml/qmlcustomparser_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h index e2717e0..efdc5fd 100644 --- a/src/declarative/qml/qmldeclarativedata_p.h +++ b/src/declarative/qml/qmldeclarativedata_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 52530db..c4eb062 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h index 8442f49..98c5eb8 100644 --- a/src/declarative/qml/qmldom.h +++ b/src/declarative/qml/qmldom.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmldom_p.h b/src/declarative/qml/qmldom_p.h index df6a980..4ddb9b0 100644 --- a/src/declarative/qml/qmldom_p.h +++ b/src/declarative/qml/qmldom_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index cdbe5f3..bb36035 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -383,6 +383,10 @@ QmlEngine::~QmlEngine() QmlEngineDebugServer::remEngine(this); } +/*! \fn void QmlEngine::quit() + This signal is emitted when the QmlEngine quits. + */ + /*! Clears the engine's internal component cache. @@ -999,7 +1003,7 @@ QScriptValue QmlEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e void QmlEnginePrivate::sendQuit () { Q_Q(QmlEngine); - emit q->quit (); + emit q->quit(); } QScriptValue QmlEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptEngine *e) diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h index 7ee014a..8916013 100644 --- a/src/declarative/qml/qmlengine.h +++ b/src/declarative/qml/qmlengine.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 13ed5ef..ce99e7c 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp index b0c1ec9..d3caa95 100644 --- a/src/declarative/qml/qmlenginedebug.cpp +++ b/src/declarative/qml/qmlenginedebug.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlenginedebug_p.h b/src/declarative/qml/qmlenginedebug_p.h index 7c48b8b..a6f296a 100644 --- a/src/declarative/qml/qmlenginedebug_p.h +++ b/src/declarative/qml/qmlenginedebug_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlerror.cpp b/src/declarative/qml/qmlerror.cpp index d9ca20d..5ba7719 100644 --- a/src/declarative/qml/qmlerror.cpp +++ b/src/declarative/qml/qmlerror.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlerror.h b/src/declarative/qml/qmlerror.h index c54f932..8c4d785 100644 --- a/src/declarative/qml/qmlerror.h +++ b/src/declarative/qml/qmlerror.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 6f32ef4..d428377 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index 4df7641..428eefa 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h index b19c60c..e52a199 100644 --- a/src/declarative/qml/qmlexpression_p.h +++ b/src/declarative/qml/qmlexpression_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlglobal_p.h b/src/declarative/qml/qmlglobal_p.h index dc282bc..06ae6e6 100644 --- a/src/declarative/qml/qmlglobal_p.h +++ b/src/declarative/qml/qmlglobal_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlglobalscriptclass.cpp b/src/declarative/qml/qmlglobalscriptclass.cpp index 13c1017..d2198b6 100644 --- a/src/declarative/qml/qmlglobalscriptclass.cpp +++ b/src/declarative/qml/qmlglobalscriptclass.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlglobalscriptclass_p.h b/src/declarative/qml/qmlglobalscriptclass_p.h index 56c91fe..d002da6 100644 --- a/src/declarative/qml/qmlglobalscriptclass_p.h +++ b/src/declarative/qml/qmlglobalscriptclass_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlguard_p.h b/src/declarative/qml/qmlguard_p.h index 1e55bcb..dae7d05 100644 --- a/src/declarative/qml/qmlguard_p.h +++ b/src/declarative/qml/qmlguard_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlinfo.cpp b/src/declarative/qml/qmlinfo.cpp index dabf944..1f3d434 100644 --- a/src/declarative/qml/qmlinfo.cpp +++ b/src/declarative/qml/qmlinfo.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlinfo.h b/src/declarative/qml/qmlinfo.h index fd56118..379f211 100644 --- a/src/declarative/qml/qmlinfo.h +++ b/src/declarative/qml/qmlinfo.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp index d99bf65..de01bfe 100644 --- a/src/declarative/qml/qmlinstruction.cpp +++ b/src/declarative/qml/qmlinstruction.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index 0639397..5613888 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlintegercache.cpp b/src/declarative/qml/qmlintegercache.cpp index 1968873..2c2d494 100644 --- a/src/declarative/qml/qmlintegercache.cpp +++ b/src/declarative/qml/qmlintegercache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlintegercache_p.h b/src/declarative/qml/qmlintegercache_p.h index d9df52a..f38138f 100644 --- a/src/declarative/qml/qmlintegercache_p.h +++ b/src/declarative/qml/qmlintegercache_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmllist.h b/src/declarative/qml/qmllist.h index ad2d874..261145d 100644 --- a/src/declarative/qml/qmllist.h +++ b/src/declarative/qml/qmllist.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmllistscriptclass.cpp b/src/declarative/qml/qmllistscriptclass.cpp index d4cdc6e..d74a9b0 100644 --- a/src/declarative/qml/qmllistscriptclass.cpp +++ b/src/declarative/qml/qmllistscriptclass.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmllistscriptclass_p.h b/src/declarative/qml/qmllistscriptclass_p.h index e484b34..92cf17f 100644 --- a/src/declarative/qml/qmllistscriptclass_p.h +++ b/src/declarative/qml/qmllistscriptclass_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index f23a50a..5938384 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h index 240f5a2..723fc50 100644 --- a/src/declarative/qml/qmlmetaproperty.h +++ b/src/declarative/qml/qmlmetaproperty.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h index 90b443e..b99e5be 100644 --- a/src/declarative/qml/qmlmetaproperty_p.h +++ b/src/declarative/qml/qmlmetaproperty_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp index e66f600..50a19e4 100644 --- a/src/declarative/qml/qmlmetatype.cpp +++ b/src/declarative/qml/qmlmetatype.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h index 45ec11d..3d082f8 100644 --- a/src/declarative/qml/qmlmetatype.h +++ b/src/declarative/qml/qmlmetatype.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlmoduleplugin.cpp b/src/declarative/qml/qmlmoduleplugin.cpp index 2f2cb25..8019805 100644 --- a/src/declarative/qml/qmlmoduleplugin.cpp +++ b/src/declarative/qml/qmlmoduleplugin.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE The plugin should register QML types with qmlRegisterType() when the defineModule() method is called. - \sa examples/declarative/plugins + See the example in \c{examples/declarative/plugins}. */ /*! diff --git a/src/declarative/qml/qmlmoduleplugin.h b/src/declarative/qml/qmlmoduleplugin.h index 384e05e..b28f1ad 100644 --- a/src/declarative/qml/qmlmoduleplugin.h +++ b/src/declarative/qml/qmlmoduleplugin.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp index 76f20d8..1ba0694 100644 --- a/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp +++ b/src/declarative/qml/qmlnetworkaccessmanagerfactory.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -62,6 +62,10 @@ QT_BEGIN_NAMESPACE Note: the create() method may be called by multiple threads, so ensure the implementation of this method is reentrant. */ + +/*! + The destructor is empty. + */ QmlNetworkAccessManagerFactory::~QmlNetworkAccessManagerFactory() { } diff --git a/src/declarative/qml/qmlnetworkaccessmanagerfactory.h b/src/declarative/qml/qmlnetworkaccessmanagerfactory.h index ce9860f..1660929 100644 --- a/src/declarative/qml/qmlnetworkaccessmanagerfactory.h +++ b/src/declarative/qml/qmlnetworkaccessmanagerfactory.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index c373a8e..76d1837 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlobjectscriptclass_p.h b/src/declarative/qml/qmlobjectscriptclass_p.h index 470c555..729f34f 100644 --- a/src/declarative/qml/qmlobjectscriptclass_p.h +++ b/src/declarative/qml/qmlobjectscriptclass_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp index 02a9e70..f2690e2 100644 --- a/src/declarative/qml/qmlparser.cpp +++ b/src/declarative/qml/qmlparser.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h index aa7a762..222229b 100644 --- a/src/declarative/qml/qmlparser_p.h +++ b/src/declarative/qml/qmlparser_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlparserstatus.cpp b/src/declarative/qml/qmlparserstatus.cpp index 69ccfda..435d620 100644 --- a/src/declarative/qml/qmlparserstatus.cpp +++ b/src/declarative/qml/qmlparserstatus.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlparserstatus.h b/src/declarative/qml/qmlparserstatus.h index e12c7b5..e4cfe8b 100644 --- a/src/declarative/qml/qmlparserstatus.h +++ b/src/declarative/qml/qmlparserstatus.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlprivate.cpp b/src/declarative/qml/qmlprivate.cpp index 01353cc..f85e280 100644 --- a/src/declarative/qml/qmlprivate.cpp +++ b/src/declarative/qml/qmlprivate.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlprivate.h b/src/declarative/qml/qmlprivate.h index dd98110..e087788 100644 --- a/src/declarative/qml/qmlprivate.h +++ b/src/declarative/qml/qmlprivate.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp index 04cffe1..2c79ceb 100644 --- a/src/declarative/qml/qmlpropertycache.cpp +++ b/src/declarative/qml/qmlpropertycache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h index efc4643..34b648d 100644 --- a/src/declarative/qml/qmlpropertycache_p.h +++ b/src/declarative/qml/qmlpropertycache_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlpropertyvalueinterceptor.cpp b/src/declarative/qml/qmlpropertyvalueinterceptor.cpp index 9d0d7f6..ea53e16 100644 --- a/src/declarative/qml/qmlpropertyvalueinterceptor.cpp +++ b/src/declarative/qml/qmlpropertyvalueinterceptor.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlpropertyvalueinterceptor.h b/src/declarative/qml/qmlpropertyvalueinterceptor.h index 71cc6c5..74cd5fa 100644 --- a/src/declarative/qml/qmlpropertyvalueinterceptor.h +++ b/src/declarative/qml/qmlpropertyvalueinterceptor.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlpropertyvaluesource.cpp b/src/declarative/qml/qmlpropertyvaluesource.cpp index 50f2f8c..bccdfb7 100644 --- a/src/declarative/qml/qmlpropertyvaluesource.cpp +++ b/src/declarative/qml/qmlpropertyvaluesource.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlpropertyvaluesource.h b/src/declarative/qml/qmlpropertyvaluesource.h index 2017fb2..fc53b8a 100644 --- a/src/declarative/qml/qmlpropertyvaluesource.h +++ b/src/declarative/qml/qmlpropertyvaluesource.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlproxymetaobject.cpp b/src/declarative/qml/qmlproxymetaobject.cpp index 983c350..29aad34 100644 --- a/src/declarative/qml/qmlproxymetaobject.cpp +++ b/src/declarative/qml/qmlproxymetaobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlproxymetaobject_p.h b/src/declarative/qml/qmlproxymetaobject_p.h index f983030..96cfbf5 100644 --- a/src/declarative/qml/qmlproxymetaobject_p.h +++ b/src/declarative/qml/qmlproxymetaobject_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlrefcount.cpp b/src/declarative/qml/qmlrefcount.cpp index 9422625..76a6ab6 100644 --- a/src/declarative/qml/qmlrefcount.cpp +++ b/src/declarative/qml/qmlrefcount.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlrefcount_p.h b/src/declarative/qml/qmlrefcount_p.h index 7448042..9b2f52b 100644 --- a/src/declarative/qml/qmlrefcount_p.h +++ b/src/declarative/qml/qmlrefcount_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlrewrite.cpp b/src/declarative/qml/qmlrewrite.cpp index 34bd198..d8a9350 100644 --- a/src/declarative/qml/qmlrewrite.cpp +++ b/src/declarative/qml/qmlrewrite.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlrewrite_p.h b/src/declarative/qml/qmlrewrite_p.h index a04a0db..27140ba 100644 --- a/src/declarative/qml/qmlrewrite_p.h +++ b/src/declarative/qml/qmlrewrite_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlscript.cpp b/src/declarative/qml/qmlscript.cpp index 10fc9a6..c0320cd 100644 --- a/src/declarative/qml/qmlscript.cpp +++ b/src/declarative/qml/qmlscript.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlscriptclass_p.h b/src/declarative/qml/qmlscriptclass_p.h index 847ee66..e7ccc13 100644 --- a/src/declarative/qml/qmlscriptclass_p.h +++ b/src/declarative/qml/qmlscriptclass_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp index a24ef51..c0d5cf9 100644 --- a/src/declarative/qml/qmlscriptparser.cpp +++ b/src/declarative/qml/qmlscriptparser.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlscriptparser_p.h b/src/declarative/qml/qmlscriptparser_p.h index 16888aa..b420b9a 100644 --- a/src/declarative/qml/qmlscriptparser_p.h +++ b/src/declarative/qml/qmlscriptparser_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlscriptstring.cpp b/src/declarative/qml/qmlscriptstring.cpp index 1ccad53..29118e6 100644 --- a/src/declarative/qml/qmlscriptstring.cpp +++ b/src/declarative/qml/qmlscriptstring.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlscriptstring.h b/src/declarative/qml/qmlscriptstring.h index 73a473f..3f61f5d 100644 --- a/src/declarative/qml/qmlscriptstring.h +++ b/src/declarative/qml/qmlscriptstring.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index 684caa2..4b132af 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlsqldatabase_p.h b/src/declarative/qml/qmlsqldatabase_p.h index 5a38bf0..95eb5ea 100644 --- a/src/declarative/qml/qmlsqldatabase_p.h +++ b/src/declarative/qml/qmlsqldatabase_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlstringconverters.cpp b/src/declarative/qml/qmlstringconverters.cpp index 2963ab5..6ba70d3 100644 --- a/src/declarative/qml/qmlstringconverters.cpp +++ b/src/declarative/qml/qmlstringconverters.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlstringconverters_p.h b/src/declarative/qml/qmlstringconverters_p.h index dfc59ce..5156b7d 100644 --- a/src/declarative/qml/qmlstringconverters_p.h +++ b/src/declarative/qml/qmlstringconverters_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmltypenamecache.cpp b/src/declarative/qml/qmltypenamecache.cpp index 7e68492..eef3bae 100644 --- a/src/declarative/qml/qmltypenamecache.cpp +++ b/src/declarative/qml/qmltypenamecache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmltypenamecache_p.h b/src/declarative/qml/qmltypenamecache_p.h index 754399f..e578277 100644 --- a/src/declarative/qml/qmltypenamecache_p.h +++ b/src/declarative/qml/qmltypenamecache_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmltypenamescriptclass.cpp b/src/declarative/qml/qmltypenamescriptclass.cpp index 14c8652..32a7a25 100644 --- a/src/declarative/qml/qmltypenamescriptclass.cpp +++ b/src/declarative/qml/qmltypenamescriptclass.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmltypenamescriptclass_p.h b/src/declarative/qml/qmltypenamescriptclass_p.h index cf8c621..fd5752d 100644 --- a/src/declarative/qml/qmltypenamescriptclass_p.h +++ b/src/declarative/qml/qmltypenamescriptclass_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvaluetype.cpp b/src/declarative/qml/qmlvaluetype.cpp index 058fd6e..33c3e76 100644 --- a/src/declarative/qml/qmlvaluetype.cpp +++ b/src/declarative/qml/qmlvaluetype.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvaluetype_p.h b/src/declarative/qml/qmlvaluetype_p.h index 800edee..0a152e8 100644 --- a/src/declarative/qml/qmlvaluetype_p.h +++ b/src/declarative/qml/qmlvaluetype_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvaluetypescriptclass.cpp b/src/declarative/qml/qmlvaluetypescriptclass.cpp index 5e222a1..0a92014 100644 --- a/src/declarative/qml/qmlvaluetypescriptclass.cpp +++ b/src/declarative/qml/qmlvaluetypescriptclass.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvaluetypescriptclass_p.h b/src/declarative/qml/qmlvaluetypescriptclass_p.h index 09af967..12aef49 100644 --- a/src/declarative/qml/qmlvaluetypescriptclass_p.h +++ b/src/declarative/qml/qmlvaluetypescriptclass_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index e9a0449..39de062 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvme_p.h b/src/declarative/qml/qmlvme_p.h index 9c45dc1..ae7dd7f 100644 --- a/src/declarative/qml/qmlvme_p.h +++ b/src/declarative/qml/qmlvme_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp index 8faa922..3858138 100644 --- a/src/declarative/qml/qmlvmemetaobject.cpp +++ b/src/declarative/qml/qmlvmemetaobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h index 497d8f6..7fa46fd 100644 --- a/src/declarative/qml/qmlvmemetaobject_p.h +++ b/src/declarative/qml/qmlvmemetaobject_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlwatcher.cpp b/src/declarative/qml/qmlwatcher.cpp index 507c11d..59503de 100644 --- a/src/declarative/qml/qmlwatcher.cpp +++ b/src/declarative/qml/qmlwatcher.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlwatcher_p.h b/src/declarative/qml/qmlwatcher_p.h index 5050949..57b358d 100644 --- a/src/declarative/qml/qmlwatcher_p.h +++ b/src/declarative/qml/qmlwatcher_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlworkerscript.cpp b/src/declarative/qml/qmlworkerscript.cpp index 5e39eaf..4e6bd4f 100644 --- a/src/declarative/qml/qmlworkerscript.cpp +++ b/src/declarative/qml/qmlworkerscript.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlworkerscript_p.h b/src/declarative/qml/qmlworkerscript_p.h index 3a29498..7698a21 100644 --- a/src/declarative/qml/qmlworkerscript_p.h +++ b/src/declarative/qml/qmlworkerscript_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp index 1883d1b..8bee751 100644 --- a/src/declarative/qml/qmlxmlhttprequest.cpp +++ b/src/declarative/qml/qmlxmlhttprequest.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qmlxmlhttprequest_p.h b/src/declarative/qml/qmlxmlhttprequest_p.h index dfed5d2..733cc03 100644 --- a/src/declarative/qml/qmlxmlhttprequest_p.h +++ b/src/declarative/qml/qmlxmlhttprequest_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/qpodvector_p.h b/src/declarative/qml/qpodvector_p.h index 42d6017..caf564a 100644 --- a/src/declarative/qml/qpodvector_p.h +++ b/src/declarative/qml/qpodvector_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/rewriter/rewriter.cpp b/src/declarative/qml/rewriter/rewriter.cpp index 237d33f..f848936 100644 --- a/src/declarative/qml/rewriter/rewriter.cpp +++ b/src/declarative/qml/rewriter/rewriter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/rewriter/rewriter_p.h b/src/declarative/qml/rewriter/rewriter_p.h index 57e7ea2..36e8df7 100644 --- a/src/declarative/qml/rewriter/rewriter_p.h +++ b/src/declarative/qml/rewriter/rewriter_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/rewriter/textwriter.cpp b/src/declarative/qml/rewriter/textwriter.cpp index 8f89f12..cd3f26a 100644 --- a/src/declarative/qml/rewriter/textwriter.cpp +++ b/src/declarative/qml/rewriter/textwriter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/qml/rewriter/textwriter_p.h b/src/declarative/qml/rewriter/textwriter_p.h index a19fa5e..43ef669 100644 --- a/src/declarative/qml/rewriter/textwriter_p.h +++ b/src/declarative/qml/rewriter/textwriter_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qfxperf.cpp b/src/declarative/util/qfxperf.cpp index f62f810..8f5617c 100644 --- a/src/declarative/util/qfxperf.cpp +++ b/src/declarative/util/qfxperf.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qfxperf_p_p.h b/src/declarative/util/qfxperf_p_p.h index e3f820c..106f761 100644 --- a/src/declarative/util/qfxperf_p_p.h +++ b/src/declarative/util/qfxperf_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index 6609c73..103a50f 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h index 6a69e4d..f9bbdf9 100644 --- a/src/declarative/util/qmlanimation_p.h +++ b/src/declarative/util/qmlanimation_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlanimation_p_p.h b/src/declarative/util/qmlanimation_p_p.h index d680194..1fe0375 100644 --- a/src/declarative/util/qmlanimation_p_p.h +++ b/src/declarative/util/qmlanimation_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlbehavior.cpp b/src/declarative/util/qmlbehavior.cpp index e8feeaa..2367694 100644 --- a/src/declarative/util/qmlbehavior.cpp +++ b/src/declarative/util/qmlbehavior.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlbehavior_p.h b/src/declarative/util/qmlbehavior_p.h index da3b40f..ee9e862 100644 --- a/src/declarative/util/qmlbehavior_p.h +++ b/src/declarative/util/qmlbehavior_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlbind.cpp b/src/declarative/util/qmlbind.cpp index c68cef2..fc1562b 100644 --- a/src/declarative/util/qmlbind.cpp +++ b/src/declarative/util/qmlbind.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlbind_p.h b/src/declarative/util/qmlbind_p.h index 4d7cd1f..6fdd2dc 100644 --- a/src/declarative/util/qmlbind_p.h +++ b/src/declarative/util/qmlbind_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlconnection.cpp b/src/declarative/util/qmlconnection.cpp index 800fd6b..9bec3bb 100644 --- a/src/declarative/util/qmlconnection.cpp +++ b/src/declarative/util/qmlconnection.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlconnection_p.h b/src/declarative/util/qmlconnection_p.h index 52bc247..2106cb0 100644 --- a/src/declarative/util/qmlconnection_p.h +++ b/src/declarative/util/qmlconnection_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmldatetimeformatter.cpp b/src/declarative/util/qmldatetimeformatter.cpp index 9d216cf..c44ca5e 100644 --- a/src/declarative/util/qmldatetimeformatter.cpp +++ b/src/declarative/util/qmldatetimeformatter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmldatetimeformatter_p.h b/src/declarative/util/qmldatetimeformatter_p.h index c90ee8c..2cd80b9 100644 --- a/src/declarative/util/qmldatetimeformatter_p.h +++ b/src/declarative/util/qmldatetimeformatter_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmleasefollow.cpp b/src/declarative/util/qmleasefollow.cpp index e3153b1..efa6faf 100644 --- a/src/declarative/util/qmleasefollow.cpp +++ b/src/declarative/util/qmleasefollow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmleasefollow_p.h b/src/declarative/util/qmleasefollow_p.h index ef095a3..dddf54f 100644 --- a/src/declarative/util/qmleasefollow_p.h +++ b/src/declarative/util/qmleasefollow_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlfontloader.cpp b/src/declarative/util/qmlfontloader.cpp index b56043b..4599b99 100644 --- a/src/declarative/util/qmlfontloader.cpp +++ b/src/declarative/util/qmlfontloader.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlfontloader_p.h b/src/declarative/util/qmlfontloader_p.h index aac8a71..3d27452 100644 --- a/src/declarative/util/qmlfontloader_p.h +++ b/src/declarative/util/qmlfontloader_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmllistaccessor.cpp b/src/declarative/util/qmllistaccessor.cpp index 6658949..c1b9247 100644 --- a/src/declarative/util/qmllistaccessor.cpp +++ b/src/declarative/util/qmllistaccessor.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmllistaccessor_p.h b/src/declarative/util/qmllistaccessor_p.h index 3c67e3a..8a0b06c 100644 --- a/src/declarative/util/qmllistaccessor_p.h +++ b/src/declarative/util/qmllistaccessor_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp index 61fc50d..ee35d2e 100644 --- a/src/declarative/util/qmllistmodel.cpp +++ b/src/declarative/util/qmllistmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmllistmodel_p.h b/src/declarative/util/qmllistmodel_p.h index e18d3fd..4cf6746 100644 --- a/src/declarative/util/qmllistmodel_p.h +++ b/src/declarative/util/qmllistmodel_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlnullablevalue_p_p.h b/src/declarative/util/qmlnullablevalue_p_p.h index 151a3d4..c426258 100644 --- a/src/declarative/util/qmlnullablevalue_p_p.h +++ b/src/declarative/util/qmlnullablevalue_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlnumberformatter.cpp b/src/declarative/util/qmlnumberformatter.cpp index 073dc68..f78abdf 100644 --- a/src/declarative/util/qmlnumberformatter.cpp +++ b/src/declarative/util/qmlnumberformatter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlnumberformatter_p.h b/src/declarative/util/qmlnumberformatter_p.h index 71fceb2..d08885b 100644 --- a/src/declarative/util/qmlnumberformatter_p.h +++ b/src/declarative/util/qmlnumberformatter_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp index 1be81de..0847c47 100644 --- a/src/declarative/util/qmlopenmetaobject.cpp +++ b/src/declarative/util/qmlopenmetaobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlopenmetaobject_p.h b/src/declarative/util/qmlopenmetaobject_p.h index c6da71a..3f9450d 100644 --- a/src/declarative/util/qmlopenmetaobject_p.h +++ b/src/declarative/util/qmlopenmetaobject_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpackage.cpp b/src/declarative/util/qmlpackage.cpp index 3214dc8..115f2fd 100644 --- a/src/declarative/util/qmlpackage.cpp +++ b/src/declarative/util/qmlpackage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpackage_p.h b/src/declarative/util/qmlpackage_p.h index ff42aad..2538bb9 100644 --- a/src/declarative/util/qmlpackage_p.h +++ b/src/declarative/util/qmlpackage_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpixmapcache.cpp b/src/declarative/util/qmlpixmapcache.cpp index c03b5df..f833501 100644 --- a/src/declarative/util/qmlpixmapcache.cpp +++ b/src/declarative/util/qmlpixmapcache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpixmapcache_p.h b/src/declarative/util/qmlpixmapcache_p.h index 462faf6..86908cc 100644 --- a/src/declarative/util/qmlpixmapcache_p.h +++ b/src/declarative/util/qmlpixmapcache_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp index f1f39da..84f1e9a 100644 --- a/src/declarative/util/qmlpropertychanges.cpp +++ b/src/declarative/util/qmlpropertychanges.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpropertychanges_p.h b/src/declarative/util/qmlpropertychanges_p.h index 461730d..19dcf9d 100644 --- a/src/declarative/util/qmlpropertychanges_p.h +++ b/src/declarative/util/qmlpropertychanges_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpropertymap.cpp b/src/declarative/util/qmlpropertymap.cpp index 226f82e..ccbec6f 100644 --- a/src/declarative/util/qmlpropertymap.cpp +++ b/src/declarative/util/qmlpropertymap.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlpropertymap.h b/src/declarative/util/qmlpropertymap.h index bb397fe..a56ed0f 100644 --- a/src/declarative/util/qmlpropertymap.h +++ b/src/declarative/util/qmlpropertymap.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlspringfollow.cpp b/src/declarative/util/qmlspringfollow.cpp index 764d7f9..6d4ecf2 100644 --- a/src/declarative/util/qmlspringfollow.cpp +++ b/src/declarative/util/qmlspringfollow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlspringfollow_p.h b/src/declarative/util/qmlspringfollow_p.h index 7731b9e..4a0ed1c 100644 --- a/src/declarative/util/qmlspringfollow_p.h +++ b/src/declarative/util/qmlspringfollow_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp index cae8054..7ecbd79 100644 --- a/src/declarative/util/qmlstate.cpp +++ b/src/declarative/util/qmlstate.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstate_p.h b/src/declarative/util/qmlstate_p.h index 5862c02..785a175 100644 --- a/src/declarative/util/qmlstate_p.h +++ b/src/declarative/util/qmlstate_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstate_p_p.h b/src/declarative/util/qmlstate_p_p.h index 235fe62..c389846 100644 --- a/src/declarative/util/qmlstate_p_p.h +++ b/src/declarative/util/qmlstate_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstategroup.cpp b/src/declarative/util/qmlstategroup.cpp index d4db2b9..c53b0e5 100644 --- a/src/declarative/util/qmlstategroup.cpp +++ b/src/declarative/util/qmlstategroup.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstategroup_p.h b/src/declarative/util/qmlstategroup_p.h index 112c9eb..48b9c66 100644 --- a/src/declarative/util/qmlstategroup_p.h +++ b/src/declarative/util/qmlstategroup_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp index cefe2bc..d1b2339 100644 --- a/src/declarative/util/qmlstateoperations.cpp +++ b/src/declarative/util/qmlstateoperations.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstateoperations_p.h b/src/declarative/util/qmlstateoperations_p.h index 1a9f76f..dc1974b 100644 --- a/src/declarative/util/qmlstateoperations_p.h +++ b/src/declarative/util/qmlstateoperations_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstyledtext.cpp b/src/declarative/util/qmlstyledtext.cpp index 36b5e49..1dc7bce 100644 --- a/src/declarative/util/qmlstyledtext.cpp +++ b/src/declarative/util/qmlstyledtext.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlstyledtext_p.h b/src/declarative/util/qmlstyledtext_p.h index 0cfb43e..a746594 100644 --- a/src/declarative/util/qmlstyledtext_p.h +++ b/src/declarative/util/qmlstyledtext_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlsystempalette.cpp b/src/declarative/util/qmlsystempalette.cpp index 39d8f3e..cc4fb3e 100644 --- a/src/declarative/util/qmlsystempalette.cpp +++ b/src/declarative/util/qmlsystempalette.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlsystempalette_p.h b/src/declarative/util/qmlsystempalette_p.h index 7c39d4a..e25bf7f 100644 --- a/src/declarative/util/qmlsystempalette_p.h +++ b/src/declarative/util/qmlsystempalette_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltimeline.cpp b/src/declarative/util/qmltimeline.cpp index 130e02d..58c87e8 100644 --- a/src/declarative/util/qmltimeline.cpp +++ b/src/declarative/util/qmltimeline.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltimeline_p_p.h b/src/declarative/util/qmltimeline_p_p.h index 09d46ba..f335e7d 100644 --- a/src/declarative/util/qmltimeline_p_p.h +++ b/src/declarative/util/qmltimeline_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltimer.cpp b/src/declarative/util/qmltimer.cpp index 046dfe9..d3a1a7c 100644 --- a/src/declarative/util/qmltimer.cpp +++ b/src/declarative/util/qmltimer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltimer_p.h b/src/declarative/util/qmltimer_p.h index fcd6c84..d1c5ee5 100644 --- a/src/declarative/util/qmltimer_p.h +++ b/src/declarative/util/qmltimer_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltransition.cpp b/src/declarative/util/qmltransition.cpp index 215fc91..22826ce 100644 --- a/src/declarative/util/qmltransition.cpp +++ b/src/declarative/util/qmltransition.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltransition_p.h b/src/declarative/util/qmltransition_p.h index c1a6f66..5a989bc 100644 --- a/src/declarative/util/qmltransition_p.h +++ b/src/declarative/util/qmltransition_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltransitionmanager.cpp b/src/declarative/util/qmltransitionmanager.cpp index a3a16ca..f2a4d64 100644 --- a/src/declarative/util/qmltransitionmanager.cpp +++ b/src/declarative/util/qmltransitionmanager.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmltransitionmanager_p_p.h b/src/declarative/util/qmltransitionmanager_p_p.h index cb4111c..19ee706 100644 --- a/src/declarative/util/qmltransitionmanager_p_p.h +++ b/src/declarative/util/qmltransitionmanager_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlview.cpp b/src/declarative/util/qmlview.cpp index 690924f..702b054 100644 --- a/src/declarative/util/qmlview.cpp +++ b/src/declarative/util/qmlview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -394,6 +394,10 @@ void QmlView::continueExecute() This signal is emitted when the qml loaded contains \a errors. */ +/*! \fn void QmlView::quit() + \internal + */ + /*! \internal */ diff --git a/src/declarative/util/qmlview.h b/src/declarative/util/qmlview.h index f4f58fd..3fa9d37 100644 --- a/src/declarative/util/qmlview.h +++ b/src/declarative/util/qmlview.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -90,7 +90,7 @@ Q_SIGNALS: void initialSize(QSize size); void sceneResized(QSize size); void errors(const QList<QmlError> &error); - void quit (); + void quit(); private Q_SLOTS: void continueExecute(); diff --git a/src/declarative/util/qmlxmllistmodel.cpp b/src/declarative/util/qmlxmllistmodel.cpp index d586792..7975959 100644 --- a/src/declarative/util/qmlxmllistmodel.cpp +++ b/src/declarative/util/qmlxmllistmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qmlxmllistmodel_p.h b/src/declarative/util/qmlxmllistmodel_p.h index e4b8cab..51d942d 100644 --- a/src/declarative/util/qmlxmllistmodel_p.h +++ b/src/declarative/util/qmlxmllistmodel_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qnumberformat.cpp b/src/declarative/util/qnumberformat.cpp index fd44db1..42c12fe 100644 --- a/src/declarative/util/qnumberformat.cpp +++ b/src/declarative/util/qnumberformat.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qnumberformat_p.h b/src/declarative/util/qnumberformat_p.h index c73ef8a..902dcde 100644 --- a/src/declarative/util/qnumberformat_p.h +++ b/src/declarative/util/qnumberformat_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qperformancelog.cpp b/src/declarative/util/qperformancelog.cpp index 2f91dfb..83cc919 100644 --- a/src/declarative/util/qperformancelog.cpp +++ b/src/declarative/util/qperformancelog.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/util/qperformancelog_p_p.h b/src/declarative/util/qperformancelog_p_p.h index e7a3b5e..a212f28 100644 --- a/src/declarative/util/qperformancelog_p_p.h +++ b/src/declarative/util/qperformancelog_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/widgets/graphicslayouts.cpp b/src/declarative/widgets/graphicslayouts.cpp index 065040f..a8b5f70 100644 --- a/src/declarative/widgets/graphicslayouts.cpp +++ b/src/declarative/widgets/graphicslayouts.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/widgets/graphicslayouts_p.h b/src/declarative/widgets/graphicslayouts_p.h index 34e2556..030be90 100644 --- a/src/declarative/widgets/graphicslayouts_p.h +++ b/src/declarative/widgets/graphicslayouts_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/widgets/graphicswidgets.cpp b/src/declarative/widgets/graphicswidgets.cpp index 4c13865..5c7f093 100644 --- a/src/declarative/widgets/graphicswidgets.cpp +++ b/src/declarative/widgets/graphicswidgets.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/declarative/widgets/graphicswidgets_p.h b/src/declarative/widgets/graphicswidgets_p.h index 0de5c89..6255d2b 100644 --- a/src/declarative/widgets/graphicswidgets_p.h +++ b/src/declarative/widgets/graphicswidgets_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/gui/dialogs/qfiledialog_win_p.h b/src/gui/dialogs/qfiledialog_win_p.h index 527ab3f..44b7e43 100644 --- a/src/gui/dialogs/qfiledialog_win_p.h +++ b/src/gui/dialogs/qfiledialog_win_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9a36d46..3280e86 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5936,6 +5936,9 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) typedef QHash<QGraphicsObject *, QList<QGesture *> > GesturesPerItem; GesturesPerItem gesturesPerItem; + // gestures that are only supposed to propagate to parent items. + QSet<QGesture *> parentPropagatedGestures; + QSet<QGesture *> startedGestures; foreach (QGesture *gesture, allGestures) { QGraphicsObject *target = gestureTargets.value(gesture, 0); @@ -5946,6 +5949,10 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) startedGestures.insert(gesture); } else { gesturesPerItem[target].append(gesture); + Qt::GestureFlags flags = + target->QGraphicsItem::d_func()->gestureContext.value(gesture->gestureType()); + if (flags & Qt::IgnoredGesturesPropagateToParent) + parentPropagatedGestures.insert(gesture); } } @@ -6035,6 +6042,10 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) Q_ASSERT(!gestureTargets.contains(g)); gestureTargets.insert(g, receiver); gesturesPerItem[receiver].append(g); + Qt::GestureFlags flags = + receiver->QGraphicsItem::d_func()->gestureContext.value(g->gestureType()); + if (flags & Qt::IgnoredGesturesPropagateToParent) + parentPropagatedGestures.insert(g); } it = ignoredConflictedGestures.begin(); e = ignoredConflictedGestures.end(); @@ -6044,13 +6055,17 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) Q_ASSERT(!gestureTargets.contains(g)); gestureTargets.insert(g, receiver); gesturesPerItem[receiver].append(g); + Qt::GestureFlags flags = + receiver->QGraphicsItem::d_func()->gestureContext.value(g->gestureType()); + if (flags & Qt::IgnoredGesturesPropagateToParent) + parentPropagatedGestures.insert(g); } DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" << "Started gestures:" << normalGestures.keys() << "All gestures:" << gesturesPerItem.values(); - // deliver all events + // deliver all gesture events QList<QGesture *> alreadyIgnoredGestures; QHash<QGraphicsObject *, QSet<QGesture *> > itemIgnoredGestures; QList<QGraphicsObject *> targetItems = gesturesPerItem.keys(); @@ -6070,9 +6085,26 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) foreach(QGesture *g, alreadyIgnoredGestures) { QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit = gid->gestureContext.find(g->gestureType()); - bool deliver = contextit != gid->gestureContext.end() && - (g->state() == Qt::GestureStarted || - (contextit.value() & Qt::ReceivePartialGestures)); + bool deliver = false; + if (contextit != gid->gestureContext.end()) { + if (g->state() == Qt::GestureStarted) { + deliver = true; + } else { + const Qt::GestureFlags flags = contextit.value(); + if (flags & Qt::ReceivePartialGestures) { + QGraphicsObject *originalTarget = gestureTargets.value(g); + Q_ASSERT(originalTarget); + QGraphicsItemPrivate *otd = originalTarget->QGraphicsItem::d_func(); + const Qt::GestureFlags originalTargetFlags = otd->gestureContext.value(g->gestureType()); + if (originalTargetFlags & Qt::IgnoredGesturesPropagateToParent) { + // only deliver to parents of the original target item + deliver = item->isAncestorOf(originalTarget); + } else { + deliver = true; + } + } + } + } if (deliver) gestures += g; } @@ -6100,18 +6132,52 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) << "item has ignored the event, will propagate." << item << ignoredGestures; itemIgnoredGestures[item] += ignoredGestures; + alreadyIgnoredGestures = ignoredGestures.toList(); + + // remove gestures that are supposed to be propagated to + // parent items only. + QSet<QGesture *> parentGestures; + for (QSet<QGesture *>::iterator it = ignoredGestures.begin(); + it != ignoredGestures.end();) { + if (parentPropagatedGestures.contains(*it)) { + parentGestures.insert(*it); + it = ignoredGestures.erase(it); + } else { + ++it; + } + } + + QSet<QGraphicsObject *> itemsSet = targetItems.toSet(); + + foreach(QGesture *g, parentGestures) { + // get the original target for the gesture + QGraphicsItem *item = gestureTargets.value(g, 0); + Q_ASSERT(item); + const Qt::GestureType gestureType = g->gestureType(); + // iterate through parent items of the original gesture + // target item and collect potential receivers + do { + if (QGraphicsObject *obj = item->toGraphicsObject()) { + if (item->d_func()->gestureContext.contains(gestureType)) + itemsSet.insert(obj); + } + if (item->isPanel()) + break; + } while ((item = item->parentItem())); + } + QMap<Qt::GestureType, QGesture *> conflictedGestures; QList<QList<QGraphicsObject *> > itemsForConflictedGestures; QHash<QGesture *, QGraphicsObject *> normalGestures; getGestureTargets(ignoredGestures, viewport, &conflictedGestures, &itemsForConflictedGestures, &normalGestures); - QSet<QGraphicsObject *> itemsSet = targetItems.toSet(); for (int k = 0; k < itemsForConflictedGestures.size(); ++k) itemsSet += itemsForConflictedGestures.at(k).toSet(); + targetItems = itemsSet.toList(); + qSort(targetItems.begin(), targetItems.end(), qt_closestItemFirst); - alreadyIgnoredGestures = conflictedGestures.values(); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" << "new targets:" << targetItems; i = -1; // start delivery again diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 25c98c5..e511c3a 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1237,7 +1237,7 @@ void qt_init(QApplicationPrivate *priv, int) // Cocoa application delegate #ifdef QT_MAC_USE_COCOA - NSApplication *cocoaApp = [NSApplication sharedApplication]; + NSApplication *cocoaApp = [QNSApplication sharedApplication]; QMacCocoaAutoReleasePool pool; NSObject *oldDelegate = [cocoaApp delegate]; QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]; diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 0a4869b..31d245f 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -2551,6 +2551,17 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam result = true; break; } +#ifndef QT_NO_CURSOR + case WM_SETCURSOR: { + QCursor *ovr = QApplication::overrideCursor(); + if (ovr) { + SetCursor(ovr->handle()); + RETURN(TRUE); + } + result = false; + break; + } +#endif default: result = false; // event was not processed break; @@ -2973,7 +2984,10 @@ bool QETWidget::translateMouseEvent(const MSG &msg) // most recent one. msgPtr->lParam = mouseMsg.lParam; msgPtr->wParam = mouseMsg.wParam; - msgPtr->pt = mouseMsg.pt; + // Extract the x,y coordinates from the lParam as we do in the WndProc + msgPtr->pt.x = GET_X_LPARAM(mouseMsg.lParam); + msgPtr->pt.y = GET_Y_LPARAM(mouseMsg.lParam); + ClientToScreen(msg.hwnd, &(msgPtr->pt)); // Remove the mouse move message PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE); diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm index 5b98420..5629940 100644 --- a/src/gui/kernel/qcocoaapplication_mac.mm +++ b/src/gui/kernel/qcocoaapplication_mac.mm @@ -107,5 +107,50 @@ | NSFontPanelStrikethroughEffectModeMask; } + +- (void)qt_sendPostedMessage:(NSEvent *)event +{ + // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5! + // That is why we need to split the address in two parts: + quint64 lower = [event data1]; + quint64 upper = [event data2]; + QCocoaPostMessageArgs *args = reinterpret_cast<QCocoaPostMessageArgs *>(lower | (upper << 32)); + [args->target performSelector:args->selector]; + delete args; +} + +- (BOOL)qt_sendEvent:(NSEvent *)event +{ + if ([event type] == NSApplicationDefined) { + switch ([event subtype]) { + case QtCocoaEventSubTypePostMessage: + [NSApp qt_sendPostedMessage:event]; + return true; + default: + break; + } + } + return false; +} + @end + +@implementation QNSApplication + +// WARNING: If Qt did not create NSApplication (this can e.g. +// happend if Qt is used as a plugin from a 3rd-party cocoa +// application), QNSApplication::sendEvent will never be called. +// SO DO NOT RELY ON THIS FUNCTION BEING AVAILABLE. +// Plugin developers that _do_ control the NSApplication sub-class +// implementation of the 3rd-party application can call qt_sendEvent +// from the sub-class event handler (like we do here) to work around +// any issues. +- (void)sendEvent:(NSEvent *)event +{ + if (![self qt_sendEvent:event]) + [super sendEvent:event]; +} + +@end + #endif diff --git a/src/gui/kernel/qcocoaapplication_mac_p.h b/src/gui/kernel/qcocoaapplication_mac_p.h index e845d58..5569feb 100644 --- a/src/gui/kernel/qcocoaapplication_mac_p.h +++ b/src/gui/kernel/qcocoaapplication_mac_p.h @@ -99,5 +99,13 @@ QT_FORWARD_DECLARE_CLASS(QApplicationPrivate) - (QApplicationPrivate *)QT_MANGLE_NAMESPACE(qt_qappPrivate); - (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader); - (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel; + +- (void)qt_sendPostedMessage:(NSEvent *)event; +- (BOOL)qt_sendEvent:(NSEvent *)event; +@end + +@interface QNSApplication : NSApplication { +} @end + #endif diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 18b3772..573b763 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -46,6 +46,7 @@ #include <private/qcocoamenuloader_mac_p.h> #include <private/qapplication_p.h> #include <private/qt_mac_p.h> +#include <private/qmenubar_p.h> #include <qmenubar.h> QT_FORWARD_DECLARE_CLASS(QCFString) @@ -208,6 +209,11 @@ QT_USE_NAMESPACE [NSApp hide:sender]; } +- (void)qtUpdateMenubar +{ + QMenuBarPrivate::macUpdateMenuBarImmediatly(); +} + - (IBAction)qtDispatcherToQAction:(id)sender { QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData); diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h index 81c136e..2504b8c 100644 --- a/src/gui/kernel/qcocoamenuloader_mac_p.h +++ b/src/gui/kernel/qcocoamenuloader_mac_p.h @@ -85,6 +85,7 @@ - (IBAction)unhideAllApplications:(id)sender; - (IBAction)hide:(id)sender; - (IBAction)qtDispatcherToQAction:(id)sender; +- (void)qtUpdateMenubar; @end #endif // QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index a1d2c61..9fe5ae0 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -183,8 +183,18 @@ QT_END_NAMESPACE - (void)sendEvent:(NSEvent *)event { - QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; + if ([event type] == NSApplicationDefined) { + switch ([event subtype]) { + case QtCocoaEventSubTypePostMessage: + [NSApp qt_sendPostedMessage:event]; + return; + default: + break; + } + return; + } + QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; // Cocoa can hold onto the window after we've disavowed its knowledge. So, // if we get sent an event afterwards just have it go through the super's // version and don't do any stuff with Qt. diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 873fb7e..d5e7534 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -84,21 +84,6 @@ extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp -Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) -{ - if (buttonNum == 0) - return Qt::LeftButton; - if (buttonNum == 1) - return Qt::RightButton; - if (buttonNum == 2) - return Qt::MidButton; - if (buttonNum == 3) - return Qt::XButton1; - if (buttonNum == 4) - return Qt::XButton2; - return Qt::NoButton; -} - struct dndenum_mapper { NSDragOperation mac_code; @@ -489,7 +474,15 @@ extern "C" { qWarning("QWidget::repaint: Recursive repaint detected"); const QRect qrect = QRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height); - QRegion qrgn(qrect); + QRegion qrgn; + + const NSRect *rects; + NSInteger count; + [self getRectsBeingDrawn:&rects count:&count]; + for (int i = 0; i < count; ++i) { + QRect tmpRect = QRect(rects[i].origin.x, rects[i].origin.y, rects[i].size.width, rects[i].size.height); + qrgn += tmpRect; + } if (!qwidget->isWindow() && !qobject_cast<QAbstractScrollArea *>(qwidget->parent())) { const QRegion &parentMask = qwidget->window()->mask(); @@ -699,6 +692,7 @@ extern "C" { qt_button_down = 0; } +extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); - (void)otherMouseDown:(NSEvent *)theEvent { if (!qt_button_down) diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index c7d042d..8a67dee 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -1064,10 +1064,9 @@ void QEventDispatcherMacPrivate::cancelWaitForMoreEvents() // In case the event dispatcher is waiting for more // events somewhere, we post a dummy event to wake it up: QMacCocoaAutoReleasePool pool; - static const short NSAppShouldStopForQt = SHRT_MAX; [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:0. windowNumber:0 context:0 - subtype:NSAppShouldStopForQt data1:0 data2:0] atStart:NO]; + subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO]; } #endif diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 4e51cf4..901bf0e 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -83,6 +83,7 @@ #include <private/qt_cocoa_helpers_mac_p.h> #include <private/qt_mac_p.h> #include <private/qapplication_p.h> +#include <private/qcocoaapplication_mac_p.h> #include <private/qcocoawindow_mac_p.h> #include <private/qcocoaview_mac_p.h> #include <private/qkeymapper_p.h> @@ -647,6 +648,21 @@ bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widge } #endif +Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) +{ + if (buttonNum == 0) + return Qt::LeftButton; + if (buttonNum == 1) + return Qt::RightButton; + if (buttonNum == 2) + return Qt::MidButton; + if (buttonNum == 3) + return Qt::XButton1; + if (buttonNum == 4) + return Qt::XButton2; + return Qt::NoButton; +} + // Helper to share code between QCocoaWindow and QCocoaView bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent) { @@ -1279,22 +1295,42 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor) QMacCocoaAutoReleasePool pool; [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) set]; } -#endif -@implementation DebugNSApplication { -} -- (void)sendEvent:(NSEvent *)event +// WARNING: If Qt did not create NSApplication (e.g. in case it is +// used as a plugin), and at the same time, there is no window on +// screen (or the window that the event is sendt to becomes hidden etc +// before the event gets delivered), the message will not be performed. +bool qt_cocoaPostMessage(id target, SEL selector) { - NSLog(@"NSAppDebug: sendEvent: %@", event); - return [super sendEvent:event]; -} + if (!target) + return false; -- (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)sender -{ - NSLog(@"NSAppDebug: sendAction: %s to %@ from %@", anAction, aTarget, sender); - return [super sendAction:anAction to:aTarget from:sender]; + NSInteger windowNumber = 0; + if (![NSApp isMemberOfClass:[QNSApplication class]]) { + // INVARIANT: Cocoa is not using our NSApplication subclass. That means + // we don't control the main event handler either. So target the event + // for one of the windows on screen: + NSWindow *nswin = [NSApp mainWindow]; + if (!nswin) { + nswin = [NSApp keyWindow]; + if (!nswin) + return false; + } + windowNumber = [nswin windowNumber]; + } + + // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5! + // That is why we need to split the address in two parts: + QCocoaPostMessageArgs *args = new QCocoaPostMessageArgs(target, selector); + quint32 lower = quintptr(args); + quint32 upper = quintptr(args) >> 32; + NSEvent *e = [NSEvent otherEventWithType:NSApplicationDefined + location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:windowNumber + context:nil subtype:QtCocoaEventSubTypePostMessage data1:lower data2:upper]; + [NSApp postEvent:e atStart:NO]; + return true; } -@end +#endif QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool() { diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index ace8255..c43ea55 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -114,6 +114,12 @@ typedef struct CGPoint NSPoint; #endif QT_BEGIN_NAMESPACE + +enum { + QtCocoaEventSubTypeWakeup = SHRT_MAX, + QtCocoaEventSubTypePostMessage = SHRT_MAX-1 +}; + Qt::MouseButtons qt_mac_get_buttons(int buttons); Qt::MouseButton qt_mac_get_button(EventMouseButton button); void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0.15); @@ -182,8 +188,23 @@ inline QString qt_mac_NSStringToQString(const NSString *nsstr) inline NSString *qt_mac_QStringToNSString(const QString &qstr) { return [reinterpret_cast<const NSString *>(QCFString::toCFStringRef(qstr)) autorelease]; } -@interface DebugNSApplication : NSApplication {} -@end +#ifdef QT_MAC_USE_COCOA +class QCocoaPostMessageArgs { +public: + id target; + SEL selector; + QCocoaPostMessageArgs(id target, SEL selector) : target(target), selector(selector) + { + [target retain]; + } + + ~QCocoaPostMessageArgs() + { + [target release]; + } +}; +bool qt_cocoaPostMessage(id target, SEL selector); +#endif #endif diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index a5633d3..9e642b9 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3346,38 +3346,20 @@ void QWidgetPrivate::show_sys() return; bool realWindow = isRealWindow(); +#ifndef QT_MAC_USE_COCOA if (realWindow && !q->testAttribute(Qt::WA_Moved)) { + if (qt_mac_is_macsheet(q)) + recreateMacWindow(); q->createWinId(); if (QWidget *p = q->parentWidget()) { p->createWinId(); -#ifndef QT_MAC_USE_COCOA RepositionWindow(qt_mac_window_for(q), qt_mac_window_for(p), kWindowCenterOnParentWindow); -#else - CGRect parentFrame = NSRectToCGRect([qt_mac_window_for(p) frame]); - OSWindowRef windowRef = qt_mac_window_for(q); - NSRect windowFrame = [windowRef frame]; - NSPoint parentCenter = NSMakePoint(CGRectGetMidX(parentFrame), CGRectGetMidY(parentFrame)); - [windowRef setFrameTopLeftPoint:NSMakePoint(parentCenter.x - (windowFrame.size.width / 2), - (parentCenter.y + (windowFrame.size.height / 2)))]; -#endif } else { -#ifndef QT_MAC_USE_COCOA RepositionWindow(qt_mac_window_for(q), 0, kWindowCenterOnMainScreen); -#else - // Ideally we would do a "center" here, but NSWindow's center is more equivalent to - // kWindowAlertPositionOnMainScreen instead of kWindowCenterOnMainScreen. - QRect availGeo = QApplication::desktop()->availableGeometry(q); - // Center the content only. - data.crect.moveCenter(availGeo.center()); - QRect fStrut = frameStrut(); - QRect frameRect(data.crect.x() - fStrut.left(), data.crect.y() - fStrut.top(), - fStrut.left() + fStrut.right() + data.crect.width(), - fStrut.top() + fStrut.bottom() + data.crect.height()); - NSRect cocoaFrameRect = NSMakeRect(frameRect.x(), flipYCoordinate(frameRect.bottom() + 1), frameRect.width(), frameRect.height()); - [qt_mac_window_for(q) setFrame:cocoaFrameRect display:NO]; -#endif } } +#endif + data.fstrut_dirty = true; if (realWindow) { // Delegates can change window state, so record some things earlier. @@ -4270,6 +4252,22 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) setGeometry_sys_helper(x, y, w, h, isMove); } #else + if (!isMove && !q->testAttribute(Qt::WA_Moved) && !q->isVisible()) { + // INVARIANT: The location of the window has not yet been set. The default will + // instead be to center it on the desktop, or over the parent, if any. Since we now + // resize the window, we need to adjust the top left position to keep the window + // centeralized. And we need to to this now (and before show) in case the positioning + // of other windows (e.g. sub-windows) depend on this position: + if (QWidget *p = q->parentWidget()) { + x = p->geometry().center().x() - (w / 2); + y = p->geometry().center().y() - (h / 2); + } else { + QRect availGeo = QApplication::desktop()->availableGeometry(q); + x = availGeo.center().x() - (w / 2); + y = availGeo.center().y() - (h / 2); + } + } + QSize olds = q->size(); const bool isResize = (olds != QSize(w, h)); NSWindow *window = qt_mac_window_for(q); diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 44e6ba5..9a1b70c 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -435,16 +435,23 @@ void QTextDocument::redo(QTextCursor *cursor) } } +/*! \enum QTextDocument::Stacks + + \value UndoStack The undo stack. + \value RedoStack The redo stack. + \value UndoAndRedoStacks Both the undo and redo stacks. +*/ + /*! \since 4.7 - Clears the specified stacks. + Clears the stacks specified by \a stacksToClear. - This method clears any commands on the undo stack, the redo stack, or both (the - default). If any commands got cleared, the appropriate signals - (\a QTextDocument::undoAvailable or \a QTextDocument::redoAvailable) get - emitted. + This method clears any commands on the undo stack, the redo stack, + or both (the default). If commands are cleared, the appropriate + signals are emitted, QTextDocument::undoAvailable() or + QTextDocument::redoAvailable(). - \sa QTextDocument::undoAvailable QTextDocument::redoAvailable + \sa QTextDocument::undoAvailable() QTextDocument::redoAvailable() */ void QTextDocument::clearUndoRedoStacks(Stacks stacksToClear) { diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm index 0265a83..5cadbbd 100644 --- a/src/gui/util/qsystemtrayicon_mac.mm +++ b/src/gui/util/qsystemtrayicon_mac.mm @@ -110,7 +110,7 @@ QT_USE_NAMESPACE -(QSystemTrayIcon*)icon; -(NSStatusItem*)item; -(QRectF)geometry; -- (void)triggerSelector:(id)sender; +- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton; - (void)doubleClickSelector:(id)sender; @end @@ -121,7 +121,7 @@ QT_USE_NAMESPACE -(id)initWithParent:(QNSStatusItem*)myParent; -(QSystemTrayIcon*)icon; -(void)menuTrackingDone:(NSNotification*)notification; --(void)mousePressed:(NSEvent *)mouseEvent; +-(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton; @end @@ -333,12 +333,10 @@ QT_END_NAMESPACE [self setNeedsDisplay:YES]; } --(void)mousePressed:(NSEvent *)mouseEvent +-(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton { - int clickCount = [mouseEvent clickCount]; - down = !down; - if(!down && [self icon]->contextMenu()) - [self icon]->contextMenu()->hide(); + down = YES; + int clickCount = [mouseEvent clickCount]; [self setNeedsDisplay:YES]; #ifndef QT_MAC_USE_COCOA @@ -348,47 +346,53 @@ QT_END_NAMESPACE const short scale = hgt - 4; #endif - if( down && ![self icon]->icon().isNull() ) { + if (![self icon]->icon().isNull() ) { NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage([self icon]->icon().pixmap(QSize(scale, scale), QIcon::Selected))); [self setImage: nsaltimage]; [nsaltimage release]; } - - if (down) - [parent triggerSelector:self]; - else if ((clickCount%2)) + if ((clickCount == 2)) { + [self menuTrackingDone:nil]; [parent doubleClickSelector:self]; - while (down) { - mouseEvent = [[self window] nextEventMatchingMask:NSLeftMouseDownMask | NSLeftMouseUpMask - | NSLeftMouseDraggedMask | NSRightMouseDownMask | NSRightMouseUpMask - | NSRightMouseDraggedMask]; - switch ([mouseEvent type]) { - case NSRightMouseDown: - case NSRightMouseUp: - case NSLeftMouseDown: - case NSLeftMouseUp: - [self menuTrackingDone:nil]; - break; - case NSRightMouseDragged: - case NSLeftMouseDragged: - default: - /* Ignore any other kind of event. */ - break; - } - }; + } else { + [parent triggerSelector:self button:mouseButton]; + } } -(void)mouseDown:(NSEvent *)mouseEvent { - [self mousePressed:mouseEvent]; + [self mousePressed:mouseEvent button:Qt::LeftButton]; +} + +-(void)mouseUp:(NSEvent *)mouseEvent +{ + Q_UNUSED(mouseEvent); + [self menuTrackingDone:nil]; } - (void)rightMouseDown:(NSEvent *)mouseEvent { - [self mousePressed:mouseEvent]; + [self mousePressed:mouseEvent button:Qt::RightButton]; +} + +-(void)rightMouseUp:(NSEvent *)mouseEvent +{ + Q_UNUSED(mouseEvent); + [self menuTrackingDone:nil]; } +extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); +- (void)otherMouseDown:(NSEvent *)mouseEvent +{ + [self mousePressed:mouseEvent button:cocoaButton2QtButton([mouseEvent buttonNumber])]; +} + +-(void)otherMouseUp:(NSEvent *)mouseEvent +{ + Q_UNUSED(mouseEvent); + [self menuTrackingDone:nil]; +} -(void)drawRect:(NSRect)rect { [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down]; @@ -433,45 +437,40 @@ QT_END_NAMESPACE } return QRectF(); } -- (void)triggerSelector:(id)sender { + +- (void)triggerSelector:(id)sender button:(Qt::MouseButton)mouseButton { Q_UNUSED(sender); - if(!icon) + if (!icon) return; - qtsystray_sendActivated(icon, QSystemTrayIcon::Trigger); + + if (mouseButton == Qt::MidButton) + qtsystray_sendActivated(icon, QSystemTrayIcon::MiddleClick); + else + qtsystray_sendActivated(icon, QSystemTrayIcon::Trigger); + if (icon->contextMenu()) { -#if 0 - const QRectF geom = [self geometry]; - if(!geom.isNull()) { - [[NSNotificationCenter defaultCenter] addObserver:imageCell - selector:@selector(menuTrackingDone:) - name:nil - object:self]; - icon->contextMenu()->exec(geom.topLeft().toPoint(), 0); - [imageCell menuTrackingDone:nil]; - } else -#endif - { #ifndef QT_MAC_USE_COCOA - [[[self item] view] removeAllToolTips]; - iconPrivate->updateToolTip_sys(); + [[[self item] view] removeAllToolTips]; + iconPrivate->updateToolTip_sys(); #endif - NSMenu *m = [[QNSMenu alloc] initWithQMenu:icon->contextMenu()]; - [m setAutoenablesItems: NO]; - [[NSNotificationCenter defaultCenter] addObserver:imageCell - selector:@selector(menuTrackingDone:) - name:NSMenuDidEndTrackingNotification - object:m]; - [item popUpStatusItemMenu: m]; - [m release]; - } + NSMenu *m = [[QNSMenu alloc] initWithQMenu:icon->contextMenu()]; + [m setAutoenablesItems: NO]; + [[NSNotificationCenter defaultCenter] addObserver:imageCell + selector:@selector(menuTrackingDone:) + name:NSMenuDidEndTrackingNotification + object:m]; + [item popUpStatusItemMenu: m]; + [m release]; } } + - (void)doubleClickSelector:(id)sender { Q_UNUSED(sender); if(!icon) return; qtsystray_sendActivated(icon, QSystemTrayIcon::DoubleClick); } + @end class QSystemTrayIconQMenu : public QMenu diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index 6a0e363..cc74a53 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -103,7 +103,7 @@ QT_BEGIN_NAMESPACE You can mix and match normal buttons and standard buttons. Currently the buttons are laid out in the following way if the button box is horizontal: - \table 100% + \table \row \o \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal \o Button box laid out in horizontal GnomeLayout \row \o \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal @@ -116,25 +116,23 @@ QT_BEGIN_NAMESPACE The buttons are laid out the following way if the button box is vertical: - \table 100% + \table + \row \o GnomeLayout + \o KdeLayout + \o MacLayout + \o WinLayout \row \o \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical - \o Button box laid out in vertical GnomeLayout - \row \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical - \o Button box laid out in vertical KdeLayout - \row \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical - \o Button box laid out in vertical MacLayout - \row \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical - \o Button box laid out in vertical WinLayout + \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical + \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical + \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical \endtable Additionally, button boxes that contain only buttons with ActionRole or - HelpRole can be considered modeless and have an alternate look on the mac: + HelpRole can be considered modeless and have an alternate look on Mac OS X: - \table 100% - \row \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout - \o modeless horizontal MacLayout - \row \o \inlineimage buttonbox-mac-modeless-vertical.png Screenshot of modeless vertical MacLayout - \o modeless vertical MacLayout + \table + \row \o modeless horizontal MacLayout + \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout \endtable When a button is clicked in the button box, the clicked() signal is emitted diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 658a020..99c550f 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -2030,6 +2030,18 @@ void qt_mac_clear_menubar() */ bool QMenuBar::macUpdateMenuBar() { +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + if (!qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar))) + return QMenuBarPrivate::macUpdateMenuBarImmediatly(); + return true; +#else + return QMenuBarPrivate::macUpdateMenuBarImmediatly(); +#endif +} + +bool QMenuBarPrivate::macUpdateMenuBarImmediatly() +{ bool ret = false; cancelAllMenuTracking(); QWidget *w = findWindowThatShouldDisplayMenubar(); @@ -2095,8 +2107,9 @@ bool QMenuBar::macUpdateMenuBar() } } - if(!ret) + if (!ret) { qt_mac_clear_menubar(); + } return ret; } diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index f2e5357..819aee4 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -196,6 +196,7 @@ public: return 0; } } *mac_menubar; + static bool macUpdateMenuBarImmediatly(); bool macWidgetHasNativeMenubar(QWidget *widget); void macCreateMenuBar(QWidget *); void macDestroyMenuBar(); diff --git a/src/multimedia/base/base.pri b/src/multimedia/base/base.pri new file mode 100644 index 0000000..5aebbf0 --- /dev/null +++ b/src/multimedia/base/base.pri @@ -0,0 +1,63 @@ + +QT += network +contains(QT_CONFIG, opengl):QT += opengl + +HEADERS += \ + $$PWD/qmediaresource.h \ + $$PWD/qmediacontent.h \ + $$PWD/qmediaobject.h \ + $$PWD/qmediaobject_p.h \ + $$PWD/qmediapluginloader_p.h \ + $$PWD/qmediaservice.h \ + $$PWD/qmediaservice_p.h \ + $$PWD/qmediaserviceprovider.h \ + $$PWD/qmediaserviceproviderplugin.h \ + $$PWD/qmediacontrol.h \ + $$PWD/qmediacontrol_p.h \ + $$PWD/qmetadatacontrol.h \ + $$PWD/qvideooutputcontrol.h \ + $$PWD/qvideowindowcontrol.h \ + $$PWD/qvideorenderercontrol.h \ + $$PWD/qvideodevicecontrol.h \ + $$PWD/qvideowidgetcontrol.h \ + $$PWD/qvideowidget.h \ + $$PWD/qvideowidget_p.h \ + $$PWD/qgraphicsvideoitem.h \ + $$PWD/qmediaplaylistcontrol.h \ + $$PWD/qmediaplaylist.h \ + $$PWD/qmediaplaylist_p.h \ + $$PWD/qmediaplaylistprovider.h \ + $$PWD/qmediaplaylistprovider_p.h \ + $$PWD/qmediaplaylistioplugin.h \ + $$PWD/qlocalmediaplaylistprovider.h \ + $$PWD/qmediaplaylistnavigator.h \ + $$PWD/qpaintervideosurface_p.h \ + $$PWD/qmediatimerange.h \ + $$PWD/qtmedianamespace.h + +SOURCES += \ + $$PWD/qmediaresource.cpp \ + $$PWD/qmediacontent.cpp \ + $$PWD/qmediaobject.cpp \ + $$PWD/qmediapluginloader.cpp \ + $$PWD/qmediaservice.cpp \ + $$PWD/qmediaserviceprovider.cpp \ + $$PWD/qmediacontrol.cpp \ + $$PWD/qmetadatacontrol.cpp \ + $$PWD/qvideooutputcontrol.cpp \ + $$PWD/qvideowindowcontrol.cpp \ + $$PWD/qvideorenderercontrol.cpp \ + $$PWD/qvideodevicecontrol.cpp \ + $$PWD/qvideowidgetcontrol.cpp \ + $$PWD/qvideowidget.cpp \ + $$PWD/qgraphicsvideoitem.cpp \ + $$PWD/qmediaplaylistcontrol.cpp \ + $$PWD/qmediaplaylist.cpp \ + $$PWD/qmediaplaylistprovider.cpp \ + $$PWD/qmediaplaylistioplugin.cpp \ + $$PWD/qlocalmediaplaylistprovider.cpp \ + $$PWD/qmediaplaylistnavigator.cpp \ + $$PWD/qpaintervideosurface.cpp \ + $$PWD/qmediatimerange.cpp + + diff --git a/src/multimedia/base/qgraphicsvideoitem.cpp b/src/multimedia/base/qgraphicsvideoitem.cpp new file mode 100644 index 0000000..21ba8c9 --- /dev/null +++ b/src/multimedia/base/qgraphicsvideoitem.cpp @@ -0,0 +1,417 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qgraphicsvideoitem.h> + +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/private/qpaintervideosurface_p.h> +#include <QtMultimedia/qvideooutputcontrol.h> +#include <QtMultimedia/qvideorenderercontrol.h> +#include <QtMultimedia/qvideosurfaceformat.h> + +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) +#include <QtOpenGL/qgl.h> +#endif + +QT_BEGIN_NAMESPACE + + +class QGraphicsVideoItemPrivate +{ +public: + QGraphicsVideoItemPrivate() + : q_ptr(0) + , surface(0) + , mediaObject(0) + , service(0) + , outputControl(0) + , rendererControl(0) + , aspectRatioMode(Qt::KeepAspectRatio) + , updatePaintDevice(true) + , rect(0.0, 0.0, 320, 240) + { + } + + QGraphicsVideoItem *q_ptr; + + QPainterVideoSurface *surface; + QMediaObject *mediaObject; + QMediaService *service; + QVideoOutputControl *outputControl; + QVideoRendererControl *rendererControl; + Qt::AspectRatioMode aspectRatioMode; + bool updatePaintDevice; + QRectF rect; + QRectF boundingRect; + QRectF sourceRect; + QSizeF nativeSize; + + void clearService(); + void updateRects(); + + void _q_present(); + void _q_formatChanged(const QVideoSurfaceFormat &format); + void _q_serviceDestroyed(); + void _q_mediaObjectDestroyed(); +}; + +void QGraphicsVideoItemPrivate::clearService() +{ + if (outputControl) { + outputControl->setOutput(QVideoOutputControl::NoOutput); + outputControl = 0; + } + if (rendererControl) { + surface->stop(); + rendererControl->setSurface(0); + rendererControl = 0; + } + if (service) { + QObject::disconnect(service, SIGNAL(destroyed()), q_ptr, SLOT(_q_serviceDestroyed())); + service = 0; + } +} + +void QGraphicsVideoItemPrivate::updateRects() +{ + q_ptr->prepareGeometryChange(); + + if (nativeSize.isEmpty()) { + boundingRect = QRectF(); + } else if (aspectRatioMode == Qt::IgnoreAspectRatio) { + boundingRect = rect; + sourceRect = QRectF(0, 0, 1, 1); + } else if (aspectRatioMode == Qt::KeepAspectRatio) { + QSizeF size = nativeSize; + size.scale(rect.size(), Qt::KeepAspectRatio); + + boundingRect = QRectF(0, 0, size.width(), size.height()); + boundingRect.moveCenter(rect.center()); + + sourceRect = QRectF(0, 0, 1, 1); + } else if (aspectRatioMode == Qt::KeepAspectRatioByExpanding) { + boundingRect = rect; + + QSizeF size = rect.size(); + size.scale(nativeSize, Qt::KeepAspectRatio); + + sourceRect = QRectF( + 0, 0, size.width() / nativeSize.width(), size.height() / nativeSize.height()); + sourceRect.moveCenter(QPointF(0.5, 0.5)); + } +} + +void QGraphicsVideoItemPrivate::_q_present() +{ + if (q_ptr->isObscured()) { + q_ptr->update(boundingRect); + surface->setReady(true); + } else { + q_ptr->update(boundingRect); + } +} + +void QGraphicsVideoItemPrivate::_q_formatChanged(const QVideoSurfaceFormat &format) +{ + nativeSize = format.sizeHint(); + + updateRects(); + + emit q_ptr->nativeSizeChanged(nativeSize); +} + +void QGraphicsVideoItemPrivate::_q_serviceDestroyed() +{ + rendererControl = 0; + outputControl = 0; + service = 0; + + surface->stop(); +} + +void QGraphicsVideoItemPrivate::_q_mediaObjectDestroyed() +{ + mediaObject = 0; + + clearService(); +} + +/*! + \class QGraphicsVideoItem + + \brief The QGraphicsVideoItem class provides a graphics item which display video produced by a QMediaObject. + + \ingroup multimedia + + Attaching a QGraphicsVideoItem to a QMediaObject allows it to display + the video or image output of that media object. A QGraphicsVideoItem + is attached to a media object by passing a pointer to the QMediaObject + to the setMediaObject() function. + + \code + player = new QMediaPlayer(this); + + QGraphicsVideoItem *item = new QGraphicsVideoItem; + item->setMediaObject(player); + graphicsView->scence()->addItem(item); + graphicsView->show(); + + player->setMedia(video); + player->play(); + \endcode + + \bold {Note}: Only a single display output can be attached to a media + object at one time. + + \sa QMediaObject, QMediaPlayer, QVideoWidget +*/ + +/*! + Constructs a graphics item that displays video. + + The \a parent is passed to QGraphicsItem. +*/ +QGraphicsVideoItem::QGraphicsVideoItem(QGraphicsItem *parent) + : QGraphicsObject(parent) + , d_ptr(new QGraphicsVideoItemPrivate) +{ + d_ptr->q_ptr = this; + d_ptr->surface = new QPainterVideoSurface; + + connect(d_ptr->surface, SIGNAL(frameChanged()), this, SLOT(_q_present())); + connect(d_ptr->surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)), + this, SLOT(_q_formatChanged(QVideoSurfaceFormat))); +} + +/*! + Destroys a video graphics item. +*/ +QGraphicsVideoItem::~QGraphicsVideoItem() +{ + if (d_ptr->outputControl) + d_ptr->outputControl->setOutput(QVideoOutputControl::NoOutput); + + if (d_ptr->rendererControl) + d_ptr->rendererControl->setSurface(0); + + delete d_ptr->surface; + delete d_ptr; +} + +/*! + \property QGraphicsVideoItem::mediaObject + \brief the media object which provides the video displayed by a graphics + item. +*/ + +QMediaObject *QGraphicsVideoItem::mediaObject() const +{ + return d_func()->mediaObject; +} + +void QGraphicsVideoItem::setMediaObject(QMediaObject *object) +{ + Q_D(QGraphicsVideoItem); + + if (object == d->mediaObject) + return; + + d->clearService(); + + if (d->mediaObject) { + disconnect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed())); + d->mediaObject->unbind(this); + } + + d->mediaObject = object; + + if (d->mediaObject) { + d->mediaObject->bind(this); + + connect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed())); + + d->service = d->mediaObject->service(); + + if (d->service) { + connect(d->service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed())); + + d->outputControl = qobject_cast<QVideoOutputControl *>( + d->service->control(QVideoOutputControl_iid)); + d->rendererControl = qobject_cast<QVideoRendererControl *>( + d->service->control(QVideoRendererControl_iid)); + + if (d->outputControl != 0 && d->rendererControl != 0) { + d->rendererControl->setSurface(d->surface); + + if (isVisible()) + d->outputControl->setOutput(QVideoOutputControl::RendererOutput); + } + } + } +} + +/*! + \property QGraphicsVideoItem::aspectRatioMode + \brief how a video is scaled to fit the graphics item's size. +*/ + +Qt::AspectRatioMode QGraphicsVideoItem::aspectRatioMode() const +{ + return d_func()->aspectRatioMode; +} + +void QGraphicsVideoItem::setAspectRatioMode(Qt::AspectRatioMode mode) +{ + Q_D(QGraphicsVideoItem); + + d->aspectRatioMode = mode; + d->updateRects(); +} + +/*! + \property QGraphicsVideoItem::offset + \brief the video item's offset. + + QGraphicsVideoItem will draw video using the offset for its top left + corner. +*/ + +QPointF QGraphicsVideoItem::offset() const +{ + return d_func()->rect.topLeft(); +} + +void QGraphicsVideoItem::setOffset(const QPointF &offset) +{ + Q_D(QGraphicsVideoItem); + + d->rect.moveTo(offset); + d->updateRects(); +} + +/*! + \property QGraphicsVideoItem::size + \brief the video item's size. + + QGraphicsVideoItem will draw video scaled to fit size according to its + fillMode. +*/ + +QSizeF QGraphicsVideoItem::size() const +{ + return d_func()->rect.size(); +} + +void QGraphicsVideoItem::setSize(const QSizeF &size) +{ + Q_D(QGraphicsVideoItem); + + d->rect.setSize(size.isValid() ? size : QSizeF(0, 0)); + d->updateRects(); +} + +/*! + \property QGraphicsVideoItem::nativeSize + \brief the native size of the video. +*/ + +QSizeF QGraphicsVideoItem::nativeSize() const +{ + return d_func()->nativeSize; +} + +/*! + \fn QGraphicsVideoItem::nativeSizeChanged(const QSizeF &size) + + Signals that the native \a size of the video has changed. +*/ + +/*! + \reimp +*/ +QRectF QGraphicsVideoItem::boundingRect() const +{ + return d_func()->boundingRect; +} + +/*! + \reimp +*/ +void QGraphicsVideoItem::paint( + QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_D(QGraphicsVideoItem); + + Q_UNUSED(option); + Q_UNUSED(widget); + + if (d->surface && d->surface->isActive()) { + d->surface->paint(painter, d->boundingRect, d->sourceRect); + d->surface->setReady(true); +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + } else if (d->updatePaintDevice && (painter->paintEngine()->type() == QPaintEngine::OpenGL + || painter->paintEngine()->type() == QPaintEngine::OpenGL2)) { + d->updatePaintDevice = false; + + d->surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext())); + if (d->surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) { + d->surface->setShaderType(QPainterVideoSurface::GlslShader); + } else { + d->surface->setShaderType(QPainterVideoSurface::FragmentProgramShader); + } +#endif + } +} + +/*! + \reimp + + \internal +*/ +QVariant QGraphicsVideoItem::itemChange(GraphicsItemChange change, const QVariant &value) +{ + return QGraphicsItem::itemChange(change, value); +} + +QT_END_NAMESPACE + +#include "moc_qgraphicsvideoitem.cpp" diff --git a/src/multimedia/base/qgraphicsvideoitem.h b/src/multimedia/base/qgraphicsvideoitem.h new file mode 100644 index 0000000..c339606 --- /dev/null +++ b/src/multimedia/base/qgraphicsvideoitem.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGRAPHICSVIDEOITEM_H +#define QGRAPHICSVIDEOITEM_H + +#include <QtGui/qgraphicsitem.h> + +#include <QtMultimedia/qvideowidget.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QVideoSurfaceFormat; + +class QGraphicsVideoItemPrivate; +class Q_MULTIMEDIA_EXPORT QGraphicsVideoItem : public QGraphicsObject +{ + Q_OBJECT + Q_PROPERTY(QMediaObject* mediaObject READ mediaObject WRITE setMediaObject) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode) + Q_PROPERTY(QPointF offset READ offset WRITE setOffset) + Q_PROPERTY(QSizeF size READ size WRITE setSize) + Q_PROPERTY(QSizeF nativeSize READ nativeSize NOTIFY nativeSizeChanged) +public: + QGraphicsVideoItem(QGraphicsItem *parent = 0); + ~QGraphicsVideoItem(); + + QMediaObject *mediaObject() const; + void setMediaObject(QMediaObject *object); + + Qt::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(Qt::AspectRatioMode mode); + + QPointF offset() const; + void setOffset(const QPointF &offset); + + QSizeF size() const; + void setSize(const QSizeF &size); + + QSizeF nativeSize() const; + + QRectF boundingRect() const; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +Q_SIGNALS: + void nativeSizeChanged(const QSizeF &size); + +protected: + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + + QGraphicsVideoItemPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QGraphicsVideoItem) + Q_PRIVATE_SLOT(d_func(), void _q_present()) + Q_PRIVATE_SLOT(d_func(), void _q_formatChanged(const QVideoSurfaceFormat &)) + Q_PRIVATE_SLOT(d_func(), void _q_serviceDestroyed()) + Q_PRIVATE_SLOT(d_func(), void _q_mediaObjectDestroyed()) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qlocalmediaplaylistprovider.cpp b/src/multimedia/base/qlocalmediaplaylistprovider.cpp new file mode 100644 index 0000000..40ff1fc --- /dev/null +++ b/src/multimedia/base/qlocalmediaplaylistprovider.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qlocalmediaplaylistprovider.h> +#include "qmediaplaylistprovider_p.h" +#include <QtMultimedia/qmediacontent.h> + + +QT_BEGIN_NAMESPACE + +class QLocalMediaPlaylistProviderPrivate: public QMediaPlaylistProviderPrivate +{ +public: + QList<QMediaContent> resources; +}; + +QLocalMediaPlaylistProvider::QLocalMediaPlaylistProvider(QObject *parent) + :QMediaPlaylistProvider(*new QLocalMediaPlaylistProviderPrivate, parent) +{ +} + +QLocalMediaPlaylistProvider::~QLocalMediaPlaylistProvider() +{ +} + +bool QLocalMediaPlaylistProvider::isReadOnly() const +{ + return false; +} + +int QLocalMediaPlaylistProvider::mediaCount() const +{ + return d_func()->resources.size(); +} + +QMediaContent QLocalMediaPlaylistProvider::media(int pos) const +{ + return d_func()->resources.value(pos); +} + +bool QLocalMediaPlaylistProvider::addMedia(const QMediaContent &content) +{ + Q_D(QLocalMediaPlaylistProvider); + + int pos = d->resources.count(); + + emit mediaAboutToBeInserted(pos, pos); + d->resources.append(content); + emit mediaInserted(pos, pos); + + return true; +} + +bool QLocalMediaPlaylistProvider::addMedia(const QList<QMediaContent> &items) +{ + Q_D(QLocalMediaPlaylistProvider); + + if (items.isEmpty()) + return true; + + int pos = d->resources.count(); + int end = pos+items.count()-1; + + emit mediaAboutToBeInserted(pos, end); + d->resources.append(items); + emit mediaInserted(pos, end); + + return true; +} + + +bool QLocalMediaPlaylistProvider::insertMedia(int pos, const QMediaContent &content) +{ + Q_D(QLocalMediaPlaylistProvider); + + emit mediaAboutToBeInserted(pos, pos); + d->resources.insert(pos, content); + emit mediaInserted(pos,pos); + + return true; +} + +bool QLocalMediaPlaylistProvider::insertMedia(int pos, const QList<QMediaContent> &items) +{ + Q_D(QLocalMediaPlaylistProvider); + + if (items.isEmpty()) + return true; + + const int last = pos+items.count()-1; + + emit mediaAboutToBeInserted(pos, last); + for (int i=0; i<items.count(); i++) + d->resources.insert(pos+i, items.at(i)); + emit mediaInserted(pos, last); + + return true; +} + +bool QLocalMediaPlaylistProvider::removeMedia(int fromPos, int toPos) +{ + Q_D(QLocalMediaPlaylistProvider); + + Q_ASSERT(fromPos >= 0); + Q_ASSERT(fromPos <= toPos); + Q_ASSERT(toPos < mediaCount()); + + emit mediaAboutToBeRemoved(fromPos, toPos); + d->resources.erase(d->resources.begin()+fromPos, d->resources.begin()+toPos+1); + emit mediaRemoved(fromPos, toPos); + + return true; +} + +bool QLocalMediaPlaylistProvider::removeMedia(int pos) +{ + Q_D(QLocalMediaPlaylistProvider); + + emit mediaAboutToBeRemoved(pos, pos); + d->resources.removeAt(pos); + emit mediaRemoved(pos, pos); + + return true; +} + +bool QLocalMediaPlaylistProvider::clear() +{ + Q_D(QLocalMediaPlaylistProvider); + if (!d->resources.isEmpty()) { + int lastPos = mediaCount()-1; + emit mediaAboutToBeRemoved(0, lastPos); + d->resources.clear(); + emit mediaRemoved(0, lastPos); + } + + return true; +} + +void QLocalMediaPlaylistProvider::shuffle() +{ + Q_D(QLocalMediaPlaylistProvider); + if (!d->resources.isEmpty()) { + QList<QMediaContent> resources; + + while (!d->resources.isEmpty()) { + resources.append(d->resources.takeAt(qrand() % d->resources.size())); + } + + d->resources = resources; + emit mediaChanged(0, mediaCount()-1); + } + +} + +#include "moc_qlocalmediaplaylistprovider.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qlocalmediaplaylistprovider.h b/src/multimedia/base/qlocalmediaplaylistprovider.h new file mode 100644 index 0000000..db8deb1 --- /dev/null +++ b/src/multimedia/base/qlocalmediaplaylistprovider.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QLOCALMEDIAPAYLISTPROVIDER_H +#define QLOCALMEDIAPAYLISTPROVIDER_H + +#include <QtMultimedia/qmediaplaylistprovider.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QLocalMediaPlaylistProviderPrivate; +class Q_MULTIMEDIA_EXPORT QLocalMediaPlaylistProvider : public QMediaPlaylistProvider +{ + Q_OBJECT + +public: + QLocalMediaPlaylistProvider(QObject *parent=0); + virtual ~QLocalMediaPlaylistProvider(); + + virtual int mediaCount() const; + virtual QMediaContent media(int pos) const; + + virtual bool isReadOnly() const; + + virtual bool addMedia(const QMediaContent &content); + virtual bool addMedia(const QList<QMediaContent> &items); + virtual bool insertMedia(int pos, const QMediaContent &content); + virtual bool insertMedia(int pos, const QList<QMediaContent> &items); + virtual bool removeMedia(int pos); + virtual bool removeMedia(int start, int end); + virtual bool clear(); + +public Q_SLOTS: + virtual void shuffle(); + +private: + Q_DECLARE_PRIVATE(QLocalMediaPlaylistProvider) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QLOCALMEDIAPAYLISTSOURCE_H diff --git a/src/multimedia/base/qmediacontent.cpp b/src/multimedia/base/qmediacontent.cpp new file mode 100644 index 0000000..3e32af0 --- /dev/null +++ b/src/multimedia/base/qmediacontent.cpp @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qurl.h> +#include <QtCore/qvariant.h> + +#include <qmediacontent.h> + + +QT_BEGIN_NAMESPACE + + +class QMediaContentPrivate : public QSharedData +{ +public: + QMediaContentPrivate() {} + QMediaContentPrivate(const QMediaResourceList &r): + resources(r) {} + + QMediaContentPrivate(const QMediaContentPrivate &other): + QSharedData(other), + resources(other.resources) + {} + + bool operator==(const QMediaContentPrivate &other) const + { + return resources == other.resources; + } + + QMediaResourceList resources; + +private: + QMediaContentPrivate& operator=(const QMediaContentPrivate &other); +}; + + +/*! + \class QMediaContent + \preliminary + \brief The QMediaContent class provides access to the resources relating to a media content. + + \ingroup multimedia + + QMediaContent is used within the multimedia framework as the logical handle + to media content. A QMediaContent object is composed of one or more + \l {QMediaResource}s where each resource provides the URL and format + information of a different encoding of the content. + + A non-null QMediaContent will always have a primary or canonical reference to + the content available through the canonicalUrl() or canonicalResource() + methods, any additional resources are optional. +*/ + + +/*! + Constructs a null QMediaContent. +*/ + +QMediaContent::QMediaContent() +{ +} + +/*! + Constructs a media content with \a url providing a reference to the content. +*/ + +QMediaContent::QMediaContent(const QUrl &url): + d(new QMediaContentPrivate) +{ + d->resources << QMediaResource(url); +} + +/*! + Constructs a media content with \a resource providing a reference to the content. +*/ + +QMediaContent::QMediaContent(const QMediaResource &resource): + d(new QMediaContentPrivate) +{ + d->resources << resource; +} + +/*! + Constructs a media content with \a resources providing a reference to the content. +*/ + +QMediaContent::QMediaContent(const QMediaResourceList &resources): + d(new QMediaContentPrivate(resources)) +{ +} + +/*! + Constructs a copy of the media content \a other. +*/ + +QMediaContent::QMediaContent(const QMediaContent &other): + d(other.d) +{ +} + +/*! + Destroys the media content object. +*/ + +QMediaContent::~QMediaContent() +{ +} + +/*! + Assigns the value of \a other to this media content. +*/ + +QMediaContent& QMediaContent::operator=(const QMediaContent &other) +{ + d = other.d; + return *this; +} + +/*! + Returns true if \a other is equivalent to this media content; false otherwise. +*/ + +bool QMediaContent::operator==(const QMediaContent &other) const +{ + return (d.constData() == 0 && other.d.constData() == 0) || + (d.constData() != 0 && other.d.constData() != 0 && + *d.constData() == *other.d.constData()); +} + +/*! + Returns true if \a other is not equivalent to this media content; false otherwise. +*/ + +bool QMediaContent::operator!=(const QMediaContent &other) const +{ + return !(*this == other); +} + +/*! + Returns true if this media content is null (uninitialized); false otherwise. +*/ + +bool QMediaContent::isNull() const +{ + return d.constData() == 0; +} + +/*! + Returns a QUrl that represents that canonical resource for this media content. +*/ + +QUrl QMediaContent::canonicalUrl() const +{ + return canonicalResource().url(); +} + +/*! + Returns a QMediaResource that represents that canonical resource for this media content. +*/ + +QMediaResource QMediaContent::canonicalResource() const +{ + return d.constData() != 0 + ? d->resources.value(0) + : QMediaResource(); +} + +/*! + Returns a list of alternative resources for this media content. The first item in this list + is always the canonical resource. +*/ + +QMediaResourceList QMediaContent::resources() const +{ + return d.constData() != 0 + ? d->resources + : QMediaResourceList(); +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediacontent.h b/src/multimedia/base/qmediacontent.h new file mode 100644 index 0000000..1ea4898 --- /dev/null +++ b/src/multimedia/base/qmediacontent.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIACONTENT_H +#define QMEDIACONTENT_H + +#include <QtCore/qmetatype.h> +#include <QtCore/qshareddata.h> + +#include <QtMultimedia/qmediaresource.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMediaContentPrivate; +class Q_MULTIMEDIA_EXPORT QMediaContent +{ +public: + QMediaContent(); + QMediaContent(const QUrl &contentUrl); + QMediaContent(const QMediaResource &contentResource); + QMediaContent(const QMediaResourceList &resources); + QMediaContent(const QMediaContent &other); + ~QMediaContent(); + + QMediaContent& operator=(const QMediaContent &other); + + bool operator==(const QMediaContent &other) const; + bool operator!=(const QMediaContent &other) const; + + bool isNull() const; + + QUrl canonicalUrl() const; + QMediaResource canonicalResource() const; + + QMediaResourceList resources() const; + +private: + QSharedDataPointer<QMediaContentPrivate> d; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QMediaContent) + +QT_END_HEADER + +#endif // QMEDIACONTENT_H diff --git a/src/multimedia/base/qmediacontrol.cpp b/src/multimedia/base/qmediacontrol.cpp new file mode 100644 index 0000000..c8bbfd4 --- /dev/null +++ b/src/multimedia/base/qmediacontrol.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qmetaobject.h> +#include <QtCore/qtimer.h> + +#include <QtMultimedia/qmediacontrol.h> +#include "qmediacontrol_p.h" + + + +QT_BEGIN_NAMESPACE + +/*! + \class QMediaControl + \ingroup multimedia-serv + + \preliminary + \brief The QMediaControl class provides a base interface for media service controls. + + Media controls provide an interface to individual features provided by a media service. Most + services implement a principal control which exposes the core functionality of the service and + a number optional controls which expose any additional functionality. + + A pointer to a control implemented by a media service can be obtained using the + \l {QMediaService::control()}{control()} member of QMediaService. If the service doesn't + implement a control it will instead return a null pointer. + + \code + QMediaPlayerControl *control = qobject_cast<QMediaPlayerControl *>( + service->control("com.nokia.Qt.QMediaPlayerControl/1.0")); + \endcode + + Alternatively if the IId of the control has been declared using Q_MEDIA_DECLARE_CONTROL + the template version of QMediaService::control() can be used to request the service without + explicitly passing the IId. + + \code + QMediaPlayerControl *control = service->control<QMediaPlayerControl *>(); + \endcode + + Most application code will not interface directly with a media service's controls, instead the + QMediaObject which owns the service acts as an intermeditary between one or more controls and + the application. + + \sa QMediaService, QMediaObject +*/ + +/*! + \macro Q_MEDIA_DECLARE_CONTROL(Class, IId) + \relates QMediaControl + + The Q_MEDIA_DECLARE_CONTROL macro declares an \a IId for a \a Class that inherits from + QMediaControl. + + Declaring an IId for a QMediaControl allows an instance of that control to be requested from + QMediaService::control() without explicitly passing the IId. + + \code + QMediaPlayerControl *control = service->control<QMediaPlayerControl *>(); + \endcode + + \sa QMediaService::control() +*/ + +/*! + Destroys a media control. +*/ + +QMediaControl::~QMediaControl() +{ + delete d_ptr; +} + +/*! + Constructs a media control with the given \a parent. +*/ + +QMediaControl::QMediaControl(QObject *parent) + : QObject(parent) + , d_ptr(new QMediaControlPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + \internal +*/ + +QMediaControl::QMediaControl(QMediaControlPrivate &dd, QObject *parent) + : QObject(parent) + , d_ptr(&dd) + +{ + d_ptr->q_ptr = this; +} + +#include "moc_qmediacontrol.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediacontrol.h b/src/multimedia/base/qmediacontrol.h new file mode 100644 index 0000000..8ed9fe8 --- /dev/null +++ b/src/multimedia/base/qmediacontrol.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTMEDIACONTROL_H +#define QABSTRACTMEDIACONTROL_H + +#include <QtCore/qobject.h> +#include <QtCore/qstring.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMediaControlPrivate; +class Q_MULTIMEDIA_EXPORT QMediaControl : public QObject +{ + Q_OBJECT + +public: + ~QMediaControl(); + +protected: + QMediaControl(QObject *parent = 0); + QMediaControl(QMediaControlPrivate &dd, QObject *parent = 0); + + QMediaControlPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QMediaControl) +}; + +template <typename T> const char *qmediacontrol_iid() { return 0; } + +#define Q_MEDIA_DECLARE_CONTROL(Class, IId) \ + template <> inline const char *qmediacontrol_iid<Class *>() { return IId; } + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QABSTRACTMEDIACONTROL_H diff --git a/src/multimedia/base/qmediacontrol_p.h b/src/multimedia/base/qmediacontrol_p.h new file mode 100644 index 0000000..4d00f11 --- /dev/null +++ b/src/multimedia/base/qmediacontrol_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTMEDIACONTROL_P_H +#define QABSTRACTMEDIACONTROL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaControl; + +class QMediaControlPrivate +{ +public: + virtual ~QMediaControlPrivate() {} + + QMediaControl *q_ptr; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qmediaobject.cpp b/src/multimedia/base/qmediaobject.cpp new file mode 100644 index 0000000..b2b8c1b --- /dev/null +++ b/src/multimedia/base/qmediaobject.cpp @@ -0,0 +1,418 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qmetaobject.h> + +#include "qmediaobject_p.h" + +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmetadatacontrol.h> + + +QT_BEGIN_NAMESPACE + +void QMediaObjectPrivate::_q_notify() +{ + Q_Q(QMediaObject); + + const QMetaObject* m = q->metaObject(); + + foreach (int pi, notifyProperties) { + QMetaProperty p = m->property(pi); + p.notifySignal().invoke( + q, QGenericArgument(QMetaType::typeName(p.userType()), p.read(q).data())); + } +} + + +/*! + \class QMediaObject + \preliminary + \brief The QMediaObject class provides a common base for multimedia objects. + + \ingroup multimedia + + QMediaObject derived classes provide access to the functionality of a + QMediaService. Each media object hosts a QMediaService and uses the + QMediaControl interfaces implemented by the service to implement its + API. Most media objects when constructed will request a new + QMediaService instance from a QMediaServiceProvider, but some like + QMediaRecorder will share a service with another object. + + QMediaObject itself provides an API for accessing a media service's \l {metaData()}{meta-data} and a means of connecting other media objects, + and peripheral classes like QVideoWidget and QMediaPlaylist. + + \sa QMediaService, QMediaControl +*/ + +/*! + Destroys a media object. +*/ + +QMediaObject::~QMediaObject() +{ + delete d_ptr; +} + +/*! + Returns the service availability error state. +*/ + +QtMultimedia::AvailabilityError QMediaObject::availabilityError() const +{ + return QtMultimedia::ServiceMissingError; +} + +/*! + Returns true if the service is available for use. +*/ + +bool QMediaObject::isAvailable() const +{ + return false; +} + +/*! + Returns the media service that provides the functionality of a multimedia object. +*/ + +QMediaService* QMediaObject::service() const +{ + return d_func()->service; +} + +int QMediaObject::notifyInterval() const +{ + return d_func()->notifyTimer->interval(); +} + +void QMediaObject::setNotifyInterval(int milliSeconds) +{ + Q_D(QMediaObject); + + if (d->notifyTimer->interval() != milliSeconds) { + d->notifyTimer->setInterval(milliSeconds); + + emit notifyIntervalChanged(milliSeconds); + } +} + +/*! + \internal +*/ +void QMediaObject::bind(QObject*) +{ +} + +/*! + \internal +*/ +void QMediaObject::unbind(QObject*) +{ +} + + +/*! + Constructs a media object which uses the functionality provided by a media \a service. + + The \a parent is passed to QObject. + + This class is meant as a base class for Multimedia objects so this + constructor is protected. +*/ + +QMediaObject::QMediaObject(QObject *parent, QMediaService *service): + QObject(parent), + d_ptr(new QMediaObjectPrivate) + +{ + Q_D(QMediaObject); + + d->q_ptr = this; + + d->notifyTimer = new QTimer(this); + d->notifyTimer->setInterval(1000); + connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify())); + + d->service = service; + + setupMetaData(); +} + +/*! + \internal +*/ + +QMediaObject::QMediaObject(QMediaObjectPrivate &dd, QObject *parent, + QMediaService *service): + QObject(parent), + d_ptr(&dd) +{ + Q_D(QMediaObject); + d->q_ptr = this; + + d->notifyTimer = new QTimer(this); + d->notifyTimer->setInterval(1000); + connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify())); + + d->service = service; + + setupMetaData(); +} + +/*! + Watch the property \a name. The property's notify signal will be emitted + once every notifyInterval milliseconds. + + \sa notifyInterval +*/ + +void QMediaObject::addPropertyWatch(QByteArray const &name) +{ + Q_D(QMediaObject); + + const QMetaObject* m = metaObject(); + + int index = m->indexOfProperty(name.constData()); + + if (index != -1 && m->property(index).hasNotifySignal()) { + d->notifyProperties.insert(index); + + if (!d->notifyTimer->isActive()) + d->notifyTimer->start(); + } +} + +/*! + Remove property \a name from the list of properties whose changes are + regularly signaled. + + \sa notifyInterval +*/ + +void QMediaObject::removePropertyWatch(QByteArray const &name) +{ + Q_D(QMediaObject); + + int index = metaObject()->indexOfProperty(name.constData()); + + if (index != -1) { + d->notifyProperties.remove(index); + + if (d->notifyProperties.isEmpty()) + d->notifyTimer->stop(); + } +} + +/*! + \property QMediaObject::notifyInterval + + The interval at which notifiable properties will update. + + The interval is expressed in milliseconds, the default value is 1000. + + \sa addPropertyWatch(), removePropertyWatch() +*/ + +/*! + \fn void QMediaObject::notifyIntervalChanged(int milliseconds) + + Signal a change in the notify interval period to \a milliseconds. +*/ + +/*! + \property QMediaObject::metaDataAvailable + \brief whether access to a media object's meta-data is available. + + If this is true there is meta-data available, otherwise there is no meta-data available. +*/ + +bool QMediaObject::isMetaDataAvailable() const +{ + Q_D(const QMediaObject); + + return d->metaDataControl + ? d->metaDataControl->isMetaDataAvailable() + : false; +} + +/*! + \fn QMediaObject::metaDataAvailableChanged(bool available) + + Signals that the \a available state of a media object's meta-data has changed. +*/ + +/*! + \property QMediaObject::metaDataWritable + \brief whether a media object's meta-data is writable. + + If this is true the meta-data is writable, otherwise the meta-data is read-only. +*/ + +bool QMediaObject::isMetaDataWritable() const +{ + Q_D(const QMediaObject); + + return d->metaDataControl + ? d->metaDataControl->isWritable() + : false; +} + +/*! + \fn QMediaObject::metaDataWritableChanged(bool writable) + + Signals that the \a writable state of a media object's meta-data has changed. +*/ + +/*! + Returns the value associated with a meta-data \a key. +*/ +QVariant QMediaObject::metaData(QtMultimedia::MetaData key) const +{ + Q_D(const QMediaObject); + + return d->metaDataControl + ? d->metaDataControl->metaData(key) + : QVariant(); +} + +/*! + Sets a \a value for a meta-data \a key. +*/ +void QMediaObject::setMetaData(QtMultimedia::MetaData key, const QVariant &value) +{ + Q_D(QMediaObject); + + if (d->metaDataControl) + d->metaDataControl->setMetaData(key, value); +} + +/*! + Returns a list of keys there is meta-data available for. +*/ +QList<QtMultimedia::MetaData> QMediaObject::availableMetaData() const +{ + Q_D(const QMediaObject); + + return d->metaDataControl + ? d->metaDataControl->availableMetaData() + : QList<QtMultimedia::MetaData>(); +} + +/*! + \fn QMediaObject::metaDataChanged() + + Signals that a media object's meta-data has changed. +*/ + +/*! + Returns the value associated with a meta-data \a key. + + The naming and type of extended meta-data is not standardized, so the values and meaning + of keys may vary between backends. +*/ +QVariant QMediaObject::extendedMetaData(const QString &key) const +{ + Q_D(const QMediaObject); + + return d->metaDataControl + ? d->metaDataControl->extendedMetaData(key) + : QVariant(); +} + +/*! + Sets a \a value for a meta-data \a key. + + The naming and type of extended meta-data is not standardized, so the values and meaning + of keys may vary between backends. +*/ +void QMediaObject::setExtendedMetaData(const QString &key, const QVariant &value) +{ + Q_D(QMediaObject); + + if (d->metaDataControl) + d->metaDataControl->setExtendedMetaData(key, value); +} + +/*! + Returns a list of keys there is extended meta-data available for. +*/ +QStringList QMediaObject::availableExtendedMetaData() const +{ + Q_D(const QMediaObject); + + return d->metaDataControl + ? d->metaDataControl->availableExtendedMetaData() + : QStringList(); +} + + +void QMediaObject::setupMetaData() +{ + Q_D(QMediaObject); + + if (d->service != 0) { + d->metaDataControl = + qobject_cast<QMetaDataControl*>(d->service->control(QMetaDataControl_iid)); + + if (d->metaDataControl) { + connect(d->metaDataControl, SIGNAL(metaDataChanged()), SIGNAL(metaDataChanged())); + connect(d->metaDataControl, + SIGNAL(metaDataAvailableChanged(bool)), + SIGNAL(metaDataAvailableChanged(bool))); + connect(d->metaDataControl, + SIGNAL(writableChanged(bool)), + SIGNAL(metaDataWritableChanged(bool))); + } + } +} + +/*! + \fn QMediaObject::availabilityChanged(bool available) + + Signal emitted when the availability state has changed to \a available +*/ + + +#include "moc_qmediaobject.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediaobject.h b/src/multimedia/base/qmediaobject.h new file mode 100644 index 0000000..d09b1af --- /dev/null +++ b/src/multimedia/base/qmediaobject.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTMEDIAOBJECT_H +#define QABSTRACTMEDIAOBJECT_H + +#include <QtCore/qobject.h> +#include <QtCore/qstringlist.h> + +#include <QtMultimedia/qtmedianamespace.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMediaService; + +class QMediaObjectPrivate; +class Q_MULTIMEDIA_EXPORT QMediaObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int notifyInterval READ notifyInterval WRITE setNotifyInterval NOTIFY notifyIntervalChanged) + Q_PROPERTY(bool metaDataAvailable READ isMetaDataAvailable NOTIFY metaDataAvailableChanged) + Q_PROPERTY(bool metaDataWritable READ isMetaDataWritable NOTIFY metaDataWritableChanged) + +public: + ~QMediaObject(); + + virtual bool isAvailable() const; + virtual QtMultimedia::AvailabilityError availabilityError() const; + + virtual QMediaService* service() const; + + int notifyInterval() const; + void setNotifyInterval(int milliSeconds); + + virtual void bind(QObject*); + virtual void unbind(QObject*); + + bool isMetaDataAvailable() const; + bool isMetaDataWritable() const; + + QVariant metaData(QtMultimedia::MetaData key) const; + void setMetaData(QtMultimedia::MetaData key, const QVariant &value); + QList<QtMultimedia::MetaData> availableMetaData() const; + + QVariant extendedMetaData(const QString &key) const; + void setExtendedMetaData(const QString &key, const QVariant &value); + QStringList availableExtendedMetaData() const; + +Q_SIGNALS: + void notifyIntervalChanged(int milliSeconds); + + void metaDataAvailableChanged(bool available); + void metaDataWritableChanged(bool writable); + void metaDataChanged(); + + void availabilityChanged(bool available); + +protected: + QMediaObject(QObject *parent, QMediaService *service); + QMediaObject(QMediaObjectPrivate &dd, QObject *parent, QMediaService *service); + + void addPropertyWatch(QByteArray const &name); + void removePropertyWatch(QByteArray const &name); + + QMediaObjectPrivate *d_ptr; + +private: + void setupMetaData(); + + Q_DECLARE_PRIVATE(QMediaObject) + Q_PRIVATE_SLOT(d_func(), void _q_notify()) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif // QABSTRACTMEDIAOBJECT_H diff --git a/src/multimedia/base/qmediaobject_p.h b/src/multimedia/base/qmediaobject_p.h new file mode 100644 index 0000000..ec2f75a --- /dev/null +++ b/src/multimedia/base/qmediaobject_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTMEDIAOBJECT_P_H +#define QABSTRACTMEDIAOBJECT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qbytearray.h> +#include <QtCore/qset.h> +#include <QtCore/qtimer.h> + +#include <QtMultimedia/qmediaobject.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMetaDataControl; + +#define Q_DECLARE_NON_CONST_PUBLIC(Class) \ + inline Class* q_func() { return static_cast<Class *>(q_ptr); } \ + friend class Class; + + +class QMediaObjectPrivate +{ + Q_DECLARE_PUBLIC(QMediaObject) + +public: + QMediaObjectPrivate():metaDataControl(0), notifyTimer(0) {} + virtual ~QMediaObjectPrivate() {} + + void _q_notify(); + + QMediaService *service; + QMetaDataControl *metaDataControl; + QTimer* notifyTimer; + QSet<int> notifyProperties; + + QMediaObject *q_ptr; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qmediaplaylist.cpp b/src/multimedia/base/qmediaplaylist.cpp new file mode 100644 index 0000000..8a0de80 --- /dev/null +++ b/src/multimedia/base/qmediaplaylist.cpp @@ -0,0 +1,719 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qlist.h> +#include <QtCore/qfile.h> +#include <QtCore/qurl.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qcoreapplication.h> + +#include <QtMultimedia/qmediaplaylist.h> +#include "qmediaplaylist_p.h" +#include <QtMultimedia/qmediaplaylistprovider.h> +#include <QtMultimedia/qlocalmediaplaylistprovider.h> +#include <QtMultimedia/qmediaplaylistioplugin.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediaplaylistcontrol.h> +#include <QtMultimedia/qmediaplayercontrol.h> + +#include "qmediapluginloader_p.h" + + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, playlistIOLoader, + (QMediaPlaylistIOInterface_iid, QLatin1String("/playlistformats"), Qt::CaseInsensitive)) + + +/*! + \class QMediaPlaylist + \ingroup multimedia + + \preliminary + \brief The QMediaPlaylist class provides a list of media content to play. + + QMediaPlaylist is intended to be used with other media objects, + like QMediaPlayer or QMediaImageViewer. + QMediaPlaylist allows to access the service intrinsic playlist functionality + if available, otherwise it provides the the local memory playlist implementation. + +\code + player = new QMediaPlayer; + + playlist = new QMediaPlaylist; + playlist->setMediaObject(player); + playlist->append(QUrl("http://example.com/movie1.mp4")); + playlist->append(QUrl("http://example.com/movie2.mp4")); + playlist->append(QUrl("http://example.com/movie3.mp4")); + + playlist->setCurrentIndex(1); + + player->play(); +\endcode + + Depending on playlist source implementation, + most of playlist modifcation operations can be asynchronous. + + \sa QMediaContent +*/ + + +/*! + \enum QMediaPlaylist::PlaybackMode + + The QMediaPlaylist::PlaybackMode describes the order items in playlist are played. + + \value CurrentItemOnce The current item is played only once. + + \value CurrentItemInLoop The current item is played in the loop. + + \value Linear Playback starts from the first to the last items and stops. + next item is a null item when the last one is currently playing. + + \value Loop Playback continues from the first item after the last one finished playing. + + \value Random Play items in random order. +*/ + + + +/*! + Create a new playlist object for with the given \a parent. +*/ + +QMediaPlaylist::QMediaPlaylist(QObject *parent) + : QObject(parent) + , d_ptr(new QMediaPlaylistPrivate) +{ + Q_D(QMediaPlaylist); + + d->q_ptr = this; + d->localPlaylistControl = new QLocalMediaPlaylistControl(this); + + setMediaObject(0); +} + +/*! + Destroys the playlist. + */ + +QMediaPlaylist::~QMediaPlaylist() +{ + Q_D(QMediaPlaylist); + + if (d->mediaObject) + d->mediaObject->unbind(this); + + delete d_ptr; +} + +QMediaObject *QMediaPlaylist::mediaObject() const +{ + return d_func()->mediaObject; +} + +/*! + If \a mediaObject is null or doesn't have an intrinsic playlist, + internal local memory playlist source will be created. +*/ +void QMediaPlaylist::setMediaObject(QMediaObject *mediaObject) +{ + Q_D(QMediaPlaylist); + + if (mediaObject && mediaObject == d->mediaObject) + return; + + QMediaService *service = mediaObject + ? mediaObject->service() : 0; + + QMediaPlaylistControl *newControl = 0; + + if (service) + newControl = qobject_cast<QMediaPlaylistControl*>(service->control(QMediaPlaylistControl_iid)); + + if (!newControl) + newControl = d->localPlaylistControl; + + if (d->control != newControl) { + int oldSize = 0; + if (d->control) { + QMediaPlaylistProvider *playlist = d->control->playlistProvider(); + oldSize = playlist->mediaCount(); + disconnect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)), + this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString))); + + disconnect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int))); + disconnect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int))); + disconnect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int))); + disconnect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int))); + disconnect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int))); + + disconnect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded())); + + disconnect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)), + this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); + disconnect(d->control, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(currentIndexChanged(int))); + disconnect(d->control, SIGNAL(currentMediaChanged(QMediaContent)), + this, SIGNAL(currentMediaChanged(QMediaContent))); + } + + d->control = newControl; + QMediaPlaylistProvider *playlist = d->control->playlistProvider(); + connect(playlist, SIGNAL(loadFailed(QMediaPlaylist::Error,QString)), + this, SLOT(_q_loadFailed(QMediaPlaylist::Error,QString))); + + connect(playlist, SIGNAL(mediaChanged(int,int)), this, SIGNAL(mediaChanged(int,int))); + connect(playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SIGNAL(mediaAboutToBeInserted(int,int))); + connect(playlist, SIGNAL(mediaInserted(int,int)), this, SIGNAL(mediaInserted(int,int))); + connect(playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SIGNAL(mediaAboutToBeRemoved(int,int))); + connect(playlist, SIGNAL(mediaRemoved(int,int)), this, SIGNAL(mediaRemoved(int,int))); + + connect(playlist, SIGNAL(loaded()), this, SIGNAL(loaded())); + + connect(d->control, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode)), + this, SIGNAL(playbackModeChanged(QMediaPlaylist::PlaybackMode))); + connect(d->control, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(currentIndexChanged(int))); + connect(d->control, SIGNAL(currentMediaChanged(QMediaContent)), + this, SIGNAL(currentMediaChanged(QMediaContent))); + + if (oldSize) + emit mediaRemoved(0, oldSize-1); + + if (playlist->mediaCount()) { + emit mediaAboutToBeInserted(0,playlist->mediaCount()-1); + emit mediaInserted(0,playlist->mediaCount()-1); + } + } + + if (d->mediaObject) + d->mediaObject->unbind(this); + + d->mediaObject = mediaObject; + if (d->mediaObject) + d->mediaObject->bind(this); +} + +/*! + \property QMediaPlaylist::playbackMode + + This property defines the order, items in playlist are played. + + \sa QMediaPlaylist::PlaybackMode +*/ + +QMediaPlaylist::PlaybackMode QMediaPlaylist::playbackMode() const +{ + return d_func()->control->playbackMode(); +} + +void QMediaPlaylist::setPlaybackMode(QMediaPlaylist::PlaybackMode mode) +{ + Q_D(QMediaPlaylist); + d->control->setPlaybackMode(mode); +} + +/*! + Returns position of the current media source in the playlist. +*/ +int QMediaPlaylist::currentIndex() const +{ + return d_func()->control->currentIndex(); +} + +/*! + Returns the current media content. +*/ + +QMediaContent QMediaPlaylist::currentMedia() const +{ + return d_func()->playlist()->media(currentIndex()); +} + +/*! + Returns the index of item, which were current after calling next() + \a steps times. + + Returned value depends on the size of playlist, current position + and playback mode. + + \sa QMediaPlaylist::playbackMode +*/ +int QMediaPlaylist::nextIndex(int steps) const +{ + return d_func()->control->nextIndex(steps); +} + +/*! + Returns the index of item, which were current after calling previous() + \a steps times. + + \sa QMediaPlaylist::playbackMode +*/ + +int QMediaPlaylist::previousIndex(int steps) const +{ + return d_func()->control->previousIndex(steps); +} + + +/*! + Returns the number of items in the playlist. + + \sa isEmpty() + */ +int QMediaPlaylist::mediaCount() const +{ + return d_func()->playlist()->mediaCount(); +} + +/*! + Returns true if the playlist contains no items; otherwise returns false. + \sa size() + */ +bool QMediaPlaylist::isEmpty() const +{ + return mediaCount() == 0; +} + +/*! + Returns true if the playlist can be modified; otherwise returns false. + \sa size() + */ +bool QMediaPlaylist::isReadOnly() const +{ + return d_func()->playlist()->isReadOnly(); +} + +/*! + Returns the media content at \a index in the playlist. +*/ + +QMediaContent QMediaPlaylist::media(int index) const +{ + return d_func()->playlist()->media(index); +} + +/*! + Append the media \a content to the playlist. + + Returns true if the operation is successfull, other wise return false. + */ +bool QMediaPlaylist::addMedia(const QMediaContent &content) +{ + return d_func()->control->playlistProvider()->addMedia(content); +} + +/*! + Append multiple media content \a items to the playlist. + + Returns true if the operation is successfull, other wise return false. + */ +bool QMediaPlaylist::addMedia(const QList<QMediaContent> &items) +{ + return d_func()->control->playlistProvider()->addMedia(items); +} + +/*! + Insert the media \a content to the playlist at position \a pos. + + Returns true if the operation is successful, otherwise false. +*/ + +bool QMediaPlaylist::insertMedia(int pos, const QMediaContent &content) +{ + return d_func()->playlist()->insertMedia(pos, content); +} + +/*! + Insert multiple media content \a items to the playlist at position \a pos. + + Returns true if the operation is successful, otherwise false. +*/ + +bool QMediaPlaylist::insertMedia(int pos, const QList<QMediaContent> &items) +{ + return d_func()->playlist()->insertMedia(pos, items); +} + +/*! + Remove the item from the playlist at position \a pos. + + Returns true if the operation is successfull, other wise return false. + */ +bool QMediaPlaylist::removeMedia(int pos) +{ + Q_D(QMediaPlaylist); + return d->playlist()->removeMedia(pos); +} + +/*! + Remove the items from the playlist from position \a start to \a end inclusive. + + Returns true if the operation is successfull, other wise return false. + */ +bool QMediaPlaylist::removeMedia(int start, int end) +{ + Q_D(QMediaPlaylist); + return d->playlist()->removeMedia(start, end); +} + +/*! + Remove all the items from the playlist. + + Returns true if the operation is successfull, other wise return false. + */ +bool QMediaPlaylist::clear() +{ + Q_D(QMediaPlaylist); + return d->playlist()->clear(); +} + +bool QMediaPlaylistPrivate::readItems(QMediaPlaylistReader *reader) +{ + while (!reader->atEnd()) + playlist()->addMedia(reader->readItem()); + + return true; +} + +bool QMediaPlaylistPrivate::writeItems(QMediaPlaylistWriter *writer) +{ + for (int i=0; i<playlist()->mediaCount(); i++) { + if (!writer->writeItem(playlist()->media(i))) + return false; + } + writer->close(); + return true; +} + +/*! + Load playlist from \a location. If \a format is specified, it is used, + otherwise format is guessed from location name and data. + + New items are appended to playlist. + + QMediaPlaylist::loaded() signal is emited if playlist was loaded succesfully, + otherwise the playlist emits loadFailed(). +*/ +void QMediaPlaylist::load(const QUrl &location, const char *format) +{ + Q_D(QMediaPlaylist); + + d->error = NoError; + d->errorString.clear(); + + if (d->playlist()->load(location,format)) + return; + + if (isReadOnly()) { + d->error = AccessDeniedError; + d->errorString = tr("Could not add items to read only playlist."); + emit loadFailed(); + return; + } + + foreach (QString const& key, playlistIOLoader()->keys()) { + QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key)); + if (plugin && plugin->canRead(location,format)) { + QMediaPlaylistReader *reader = plugin->createReader(location,QByteArray(format)); + if (reader && d->readItems(reader)) { + delete reader; + emit loaded(); + return; + } + delete reader; + } + } + + d->error = FormatNotSupportedError; + d->errorString = tr("Playlist format is not supported"); + emit loadFailed(); + + return; +} + +/*! + Load playlist from QIODevice \a device. If \a format is specified, it is used, + otherwise format is guessed from device data. + + New items are appended to playlist. + + QMediaPlaylist::loaded() signal is emited if playlist was loaded succesfully, + otherwise the playlist emits loadFailed(). +*/ +void QMediaPlaylist::load(QIODevice * device, const char *format) +{ + Q_D(QMediaPlaylist); + + d->error = NoError; + d->errorString.clear(); + + if (d->playlist()->load(device,format)) + return; + + if (isReadOnly()) { + d->error = AccessDeniedError; + d->errorString = tr("Could not add items to read only playlist."); + emit loadFailed(); + return; + } + + foreach (QString const& key, playlistIOLoader()->keys()) { + QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key)); + if (plugin && plugin->canRead(device,format)) { + QMediaPlaylistReader *reader = plugin->createReader(device,QByteArray(format)); + if (reader && d->readItems(reader)) { + delete reader; + emit loaded(); + return; + } + delete reader; + } + } + + d->error = FormatNotSupportedError; + d->errorString = tr("Playlist format is not supported"); + emit loadFailed(); + + return; +} + +/*! + Save playlist to \a location. If \a format is specified, it is used, + otherwise format is guessed from location name. + + Returns true if playlist was saved succesfully, otherwise returns false. + */ +bool QMediaPlaylist::save(const QUrl &location, const char *format) +{ + Q_D(QMediaPlaylist); + + d->error = NoError; + d->errorString.clear(); + + if (d->playlist()->save(location,format)) + return true; + + QFile file(location.toLocalFile()); + + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + d->error = AccessDeniedError; + d->errorString = tr("The file could not be accessed."); + return false; + } + + return save(&file, format); +} + +/*! + Save playlist to QIODevice \a device using format \a format. + + Returns true if playlist was saved succesfully, otherwise returns false. +*/ +bool QMediaPlaylist::save(QIODevice * device, const char *format) +{ + Q_D(QMediaPlaylist); + + d->error = NoError; + d->errorString.clear(); + + if (d->playlist()->save(device,format)) + return true; + + foreach (QString const& key, playlistIOLoader()->keys()) { + QMediaPlaylistIOInterface* plugin = qobject_cast<QMediaPlaylistIOInterface*>(playlistIOLoader()->instance(key)); + if (plugin && plugin->canWrite(device,format)) { + QMediaPlaylistWriter *writer = plugin->createWriter(device,QByteArray(format)); + if (writer && d->writeItems(writer)) { + delete writer; + return true; + } + delete writer; + } + } + + d->error = FormatNotSupportedError; + d->errorString = tr("Playlist format is not supported."); + + return false; +} + +/*! + Returns the last error condition. +*/ +QMediaPlaylist::Error QMediaPlaylist::error() const +{ + return d_func()->error; +} + +/*! + Returns the string describing the last error condition. +*/ +QString QMediaPlaylist::errorString() const +{ + return d_func()->errorString; +} + +/*! + Shuffle items in the playlist. +*/ +void QMediaPlaylist::shuffle() +{ + d_func()->playlist()->shuffle(); +} + + +/*! + Advance to the next media content in playlist. +*/ +void QMediaPlaylist::next() +{ + d_func()->control->next(); +} + +/*! + Return to the previous media content in playlist. +*/ +void QMediaPlaylist::previous() +{ + d_func()->control->previous(); +} + +/*! + Activate media content from playlist at position \a playlistPosition. +*/ + +void QMediaPlaylist::setCurrentIndex(int playlistPosition) +{ + d_func()->control->setCurrentIndex(playlistPosition); +} + +/*! + \fn void QMediaPlaylist::mediaInserted(int start, int end) + + This signal is emitted after media has been inserted into the playlist. + The new items are those between \a start and \a end inclusive. + */ + +/*! + \fn void QMediaPlaylist::mediaRemoved(int start, int end) + + This signal is emitted after media has been removed from the playlist. + The removed items are those between \a start and \a end inclusive. + */ + +/*! + \fn void QMediaPlaylist::mediaChanged(int start, int end) + + This signal is emitted after media has been changed in the playlist + between \a start and \a end positions inclusive. + */ + +/*! + \fn void QMediaPlaylist::currentIndexChanged(int position) + + Signal emitted when playlist position changed to \a position. +*/ + +/*! + \fn void QMediaPlaylist::playbackModeChanged(QMediaPlaylist::PlaybackMode mode) + + Signal emitted when playback mode changed to \a mode. +*/ + +/*! + \fn void QMediaPlaylist::mediaAboutToBeInserted(int start, int end) + + Signal emitted when item to be inserted at \a start and ending at \a end. +*/ + +/*! + \fn void QMediaPlaylist::mediaAboutToBeRemoved(int start, int end) + + Signal emitted when item to de deleted ar \a start and ending at \a end. +*/ + +/*! + \fn void QMediaPlaylist::currentMediaChanged(const QMediaContent &content) + + Signal emitted when current media changes to \a content. +*/ + +/*! + \property QMediaPlaylist::currentIndex + \brief Current position. +*/ + +/*! + \property QMediaPlaylist::currentMedia + \brief Current media content. +*/ + +/*! + \fn QMediaPlaylist::loaded() + + Signal emitted when playlist finished loading. +*/ + +/*! + \fn QMediaPlaylist::loadFailed() + + Signal emitted if failed to load playlist. +*/ + +/*! + \enum QMediaPlaylist::Error + + This enum describes the QMediaPlaylist error codes. + + \value NoError No errors. + \value FormatError Format error. + \value FormatNotSupportedError Format not supported. + \value NetworkError Network error. + \value AccessDeniedError Access denied error. +*/ + +QT_END_NAMESPACE + +#include "moc_qmediaplaylist.cpp" +#include "moc_qmediaplaylist_p.cpp" diff --git a/src/multimedia/base/qmediaplaylist.h b/src/multimedia/base/qmediaplaylist.h new file mode 100644 index 0000000..494cf11 --- /dev/null +++ b/src/multimedia/base/qmediaplaylist.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYLIST_H +#define QMEDIAPLAYLIST_H + +#include <QtCore/qobject.h> + +#include <QtMultimedia/qmediacontent.h> +#include <QtMultimedia/qmediaobject.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMediaPlaylistProvider; + +class QMediaPlaylistPrivate; +class Q_MULTIMEDIA_EXPORT QMediaPlaylist : public QObject +{ + Q_OBJECT + Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged) + Q_PROPERTY(QMediaContent currentMedia READ currentMedia NOTIFY currentMediaChanged) + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_ENUMS(PlaybackMode Error) + +public: + enum PlaybackMode { CurrentItemOnce, CurrentItemInLoop, Linear, Loop, Random }; + enum Error { NoError, FormatError, FormatNotSupportedError, NetworkError, AccessDeniedError }; + + QMediaPlaylist(QObject *parent = 0); + virtual ~QMediaPlaylist(); + + QMediaObject *mediaObject() const; + void setMediaObject(QMediaObject *object); + + PlaybackMode playbackMode() const; + void setPlaybackMode(PlaybackMode mode); + + int currentIndex() const; + QMediaContent currentMedia() const; + + int nextIndex(int steps = 1) const; + int previousIndex(int steps = 1) const; + + QMediaContent media(int index) const; + + int mediaCount() const; + bool isEmpty() const; + bool isReadOnly() const; + + bool addMedia(const QMediaContent &content); + bool addMedia(const QList<QMediaContent> &items); + bool insertMedia(int index, const QMediaContent &content); + bool insertMedia(int index, const QList<QMediaContent> &items); + bool removeMedia(int pos); + bool removeMedia(int start, int end); + bool clear(); + + void load(const QUrl &location, const char *format = 0); + void load(QIODevice * device, const char *format = 0); + + bool save(const QUrl &location, const char *format = 0); + bool save(QIODevice * device, const char *format); + + Error error() const; + QString errorString() const; + +public Q_SLOTS: + void shuffle(); + + void next(); + void previous(); + + void setCurrentIndex(int index); + +Q_SIGNALS: + void currentIndexChanged(int index); + void playbackModeChanged(QMediaPlaylist::PlaybackMode mode); + void currentMediaChanged(const QMediaContent&); + + void mediaAboutToBeInserted(int start, int end); + void mediaInserted(int start, int end); + void mediaAboutToBeRemoved(int start, int end); + void mediaRemoved(int start, int end); + void mediaChanged(int start, int end); + + void loaded(); + void loadFailed(); + +protected: + QMediaPlaylistPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QMediaPlaylist) + Q_PRIVATE_SLOT(d_func(), void _q_loadFailed(QMediaPlaylist::Error, const QString &)) +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QMediaPlaylist::PlaybackMode) +Q_DECLARE_METATYPE(QMediaPlaylist::Error) + +QT_END_HEADER + +#endif // QMEDIAPLAYLIST_H diff --git a/src/multimedia/base/qmediaplaylist_p.h b/src/multimedia/base/qmediaplaylist_p.h new file mode 100644 index 0000000..da529b7 --- /dev/null +++ b/src/multimedia/base/qmediaplaylist_p.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYLIST_P_H +#define QMEDIAPLAYLIST_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtMultimedia/qmediaplaylist.h> +#include <QtMultimedia/qmediaplaylistcontrol.h> +#include <QtMultimedia/qmediaplayer.h> +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qlocalmediaplaylistprovider.h> +#include "qmediaobject_p.h" + +#include <QtCore/qdebug.h> + +#ifdef Q_MOC_RUN +# pragma Q_MOC_EXPAND_MACROS +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaPlaylistControl; +class QMediaPlaylistProvider; +class QMediaPlaylistReader; +class QMediaPlaylistWriter; +class QMediaPlayerControl; + +class QMediaPlaylistPrivate +{ + Q_DECLARE_PUBLIC(QMediaPlaylist) +public: + QMediaPlaylistPrivate() + :mediaObject(0), + control(0), + localPlaylistControl(0), + error(QMediaPlaylist::NoError) + { + } + + virtual ~QMediaPlaylistPrivate() {} + + void _q_loadFailed(QMediaPlaylist::Error error, const QString &errorString) + { + this->error = error; + this->errorString = errorString; + + emit q_ptr->loadFailed(); + } + + void _q_mediaObjectDeleted() + { + Q_Q(QMediaPlaylist); + mediaObject = 0; + if (control != localPlaylistControl) + control = 0; + q->setMediaObject(0); + } + + QMediaObject *mediaObject; + + QMediaPlaylistControl *control; + QMediaPlaylistProvider *playlist() const { return control->playlistProvider(); } + + QMediaPlaylistControl *localPlaylistControl; + + bool readItems(QMediaPlaylistReader *reader); + bool writeItems(QMediaPlaylistWriter *writer); + + QMediaPlaylist::Error error; + QString errorString; + + QMediaPlaylist *q_ptr; +}; + + +class QLocalMediaPlaylistControl : public QMediaPlaylistControl +{ + Q_OBJECT +public: + QLocalMediaPlaylistControl(QObject *parent) + :QMediaPlaylistControl(parent) + { + QMediaPlaylistProvider *playlist = new QLocalMediaPlaylistProvider(this); + m_navigator = new QMediaPlaylistNavigator(playlist,this); + m_navigator->setPlaybackMode(QMediaPlaylist::Linear); + + connect(m_navigator, SIGNAL(currentIndexChanged(int)), SIGNAL(currentIndexChanged(int))); + connect(m_navigator, SIGNAL(activated(QMediaContent)), SIGNAL(currentMediaChanged(QMediaContent))); + } + + virtual ~QLocalMediaPlaylistControl() {}; + + QMediaPlaylistProvider* playlistProvider() const { return m_navigator->playlist(); } + bool setPlaylistProvider(QMediaPlaylistProvider *mediaPlaylist) + { + m_navigator->setPlaylist(mediaPlaylist); + emit playlistProviderChanged(); + return true; + } + + int currentIndex() const { return m_navigator->currentIndex(); } + void setCurrentIndex(int position) { m_navigator->jump(position); } + int nextIndex(int steps) const { return m_navigator->nextIndex(steps); } + int previousIndex(int steps) const { return m_navigator->previousIndex(steps); } + + void next() { m_navigator->next(); } + void previous() { m_navigator->previous(); } + + QMediaPlaylist::PlaybackMode playbackMode() const { return m_navigator->playbackMode(); } + void setPlaybackMode(QMediaPlaylist::PlaybackMode mode) { m_navigator->setPlaybackMode(mode); } + +private: + QMediaPlaylistNavigator *m_navigator; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLAYLIST_P_H diff --git a/src/multimedia/base/qmediaplaylistcontrol.cpp b/src/multimedia/base/qmediaplaylistcontrol.cpp new file mode 100644 index 0000000..2ae03ad --- /dev/null +++ b/src/multimedia/base/qmediaplaylistcontrol.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtMultimedia/qmediaplaylistcontrol.h> +#include "qmediacontrol_p.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QMediaPlaylistControl + \ingroup multimedia-serv + + \preliminary + \brief The QMediaPlaylistControl class provides access to the playlist functionality of a + QMediaService. + + If a QMediaService contains an internal playlist it will implement QMediaPlaylistControl. This + control provides access to the contents of the \l {playlistProvider()}{playlist}, as well as the + \l {currentIndex()}{position} of the current media, and a means of navigating to the + \l {next()}{next} and \l {previous()}{previous} media. + + The functionality provided by the control is exposed to application code through the + QMediaPlaylist class. + + The interface name of QMediaPlaylistControl is \c com.nokia.Qt.QMediaPlaylistControl/1.0 as + defined in QMediaPlaylistControl_iid. + + \sa QMediaService::control(), QMediaPlayer +*/ + +/*! + \macro QMediaPlaylistControl_iid + + \c com.nokia.Qt.QMediaPlaylistControl/1.0 + + Defines the interface name of the QMediaPlaylistControl class. + + \relates QMediaPlaylistControl +*/ + +/*! + Create a new playlist control object with the given \a parent. +*/ +QMediaPlaylistControl::QMediaPlaylistControl(QObject *parent): + QMediaControl(*new QMediaControlPrivate, parent) +{ +} + +/*! + Destroys the playlist control. +*/ +QMediaPlaylistControl::~QMediaPlaylistControl() +{ +} + + +/*! + \fn QMediaPlaylistControl::playlistProvider() const + + Returns the playlist used by this media player. +*/ + +/*! + \fn QMediaPlaylistControl::setPlaylistProvider(QMediaPlaylistProvider *playlist) + + Set the playlist of this media player to \a playlist. + + In many cases it is possible just to use the playlist + constructed by player, but sometimes replacing the whole + playlist allows to avoid copyting of all the items bettween playlists. + + Returns true if player can use this passed playlist; otherwise returns false. + +*/ + +/*! + \fn QMediaPlaylistControl::currentIndex() const + + Returns position of the current media source in the playlist. +*/ + +/*! + \fn QMediaPlaylistControl::setCurrentIndex(int position) + + Jump to the item at the given \a position. +*/ + +/*! + \fn QMediaPlaylistControl::nextIndex(int step) const + + Returns the index of item, which were current after calling next() + \a step times. + + Returned value depends on the size of playlist, current position + and playback mode. + + \sa QMediaPlaylist::playbackMode +*/ + +/*! + \fn QMediaPlaylistControl::previousIndex(int step) const + + Returns the index of item, which were current after calling previous() + \a step times. + + \sa QMediaPlaylist::playbackMode +*/ + +/*! + \fn QMediaPlaylistControl::next() + + Moves to the next item in playlist. +*/ + +/*! + \fn QMediaPlaylistControl::previous() + + Returns to the previous item in playlist. +*/ + +/*! + \fn QMediaPlaylistControl::playbackMode() const + + Returns the playlist navigation mode. + + \sa QMediaPlaylist::PlaybackMode +*/ + +/*! + \fn QMediaPlaylistControl::setPlaybackMode(QMediaPlaylist::PlaybackMode mode) + + Sets the playback \a mode. + + \sa QMediaPlaylist::PlaybackMode +*/ + +/*! + \fn QMediaPlaylistControl::playlistProviderChanged() + + Signal emited when the playlist provider has changed. +*/ + +/*! + \fn QMediaPlaylistControl::currentIndexChanged(int position) + + Signal emited when the playlist \a position is changed. +*/ + +/*! + \fn QMediaPlaylistControl::playbackModeChanged(QMediaPlaylist::PlaybackMode mode) + + Signal emited when the playback \a mode is changed. +*/ + +/*! + \fn QMediaPlaylistControl::currentMediaChanged(const QMediaContent& content) + + Signal emitted when current media changes to \a content. +*/ + +#include "moc_qmediaplaylistcontrol.cpp" +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediaplaylistcontrol.h b/src/multimedia/base/qmediaplaylistcontrol.h new file mode 100644 index 0000000..228ee19 --- /dev/null +++ b/src/multimedia/base/qmediaplaylistcontrol.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QMEDIAPLAYLISTCONTROL_H +#define QMEDIAPLAYLISTCONTROL_H + +#include <QtMultimedia/qmediacontrol.h> +#include <QtMultimedia/qmediaplaylistnavigator.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QMediaPlaylistProvider; + +class Q_MULTIMEDIA_EXPORT QMediaPlaylistControl : public QMediaControl +{ + Q_OBJECT + +public: + virtual ~QMediaPlaylistControl(); + + virtual QMediaPlaylistProvider* playlistProvider() const = 0; + virtual bool setPlaylistProvider(QMediaPlaylistProvider *playlist) = 0; + + virtual int currentIndex() const = 0; + virtual void setCurrentIndex(int position) = 0; + virtual int nextIndex(int steps) const = 0; + virtual int previousIndex(int steps) const = 0; + + virtual void next() = 0; + virtual void previous() = 0; + + virtual QMediaPlaylist::PlaybackMode playbackMode() const = 0; + virtual void setPlaybackMode(QMediaPlaylist::PlaybackMode mode) = 0; + +Q_SIGNALS: + void playlistProviderChanged(); + void currentIndexChanged(int position); + void currentMediaChanged(const QMediaContent&); + void playbackModeChanged(QMediaPlaylist::PlaybackMode mode); + +protected: + QMediaPlaylistControl(QObject* parent = 0); +}; + +#define QMediaPlaylistControl_iid "com.nokia.Qt.QMediaPlaylistControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QMediaPlaylistControl, QMediaPlaylistControl_iid) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLAYLISTCONTROL_H diff --git a/src/multimedia/base/qmediaplaylistioplugin.cpp b/src/multimedia/base/qmediaplaylistioplugin.cpp new file mode 100644 index 0000000..5f11e38 --- /dev/null +++ b/src/multimedia/base/qmediaplaylistioplugin.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qmediaplaylistioplugin.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QMediaPlaylistReader + \preliminary + \brief The QMediaPlaylistReader class provides an interface for reading a playlist file. + + \sa QMediaPlaylistIOPlugin +*/ + +/*! + Destroys a media playlist reader. +*/ +QMediaPlaylistReader::~QMediaPlaylistReader() +{ +} + +/*! + \fn QMediaPlaylistReader::atEnd() const + + Identifies if a playlist reader has reached the end of its input. + + Returns true if the reader has reached the end; and false otherwise. +*/ + +/*! + \fn QMediaPlaylistReader::readItem() + + Reads an item of media from a playlist file. + + Returns the read media, or a null QMediaContent if no more media is available. +*/ + +/*! + \fn QMediaPlaylistReader::close() + + Closes a playlist reader's input device. +*/ + +/*! + \class QMediaPlaylistWriter + \preliminary + \brief The QMediaPlaylistWriter class provides an interface for writing a playlist file. + + \sa QMediaPlaylistIOPlugin +*/ + +/*! + Destroys a media playlist writer. +*/ +QMediaPlaylistWriter::~QMediaPlaylistWriter() +{ +} + +/*! + \fn QMediaPlaylistWriter::writeItem(const QMediaContent &media) + + Writes an item of \a media to a playlist file. + + Returns true if the media was written succesfully; and false otherwise. +*/ + +/*! + \fn QMediaPlaylistWriter::close() + + Finalizes the writing of a playlist and closes the output device. +*/ + +/*! + \class QMediaPlaylistIOPlugin + \brief The QMediaPlaylistIOPlugin class provides an interface for media playlist I/O plug-ins. +*/ + +/*! + Constructs a media playlist I/O plug-in with the given \a parent. +*/ +QMediaPlaylistIOPlugin::QMediaPlaylistIOPlugin(QObject *parent) + :QObject(parent) +{ +} + +/*! + Destroys a media playlist I/O plug-in. +*/ +QMediaPlaylistIOPlugin::~QMediaPlaylistIOPlugin() +{ +} + +/*! + \fn QMediaPlaylistIOPlugin::canRead(QIODevice *device, const QByteArray &format) const + + Identifies if plug-in can read \a format data from an I/O \a device. + + Returns true if the data can be read; and false otherwise. +*/ + +/*! + \fn QMediaPlaylistIOPlugin::canRead(const QUrl& location, const QByteArray &format) const + + Identifies if a plug-in can read \a format data from a URL \a location. + + Returns true if the data can be read; and false otherwise. +*/ + +/*! + \fn QMediaPlaylistIOPlugin::canWrite(QIODevice *device, const QByteArray &format) const + + Identifies if a plug-in can write \a format data to an I/O \a device. + + Returns true if the data can be written; and false otherwise. +*/ + +/*! + \fn QMediaPlaylistIOPlugin::keys() const + + Returns a list of format keys supported by a plug-in. +*/ + +/*! + \fn QMediaPlaylistIOPlugin::createReader(QIODevice *device, const QByteArray &format) + + Returns a new QMediaPlaylistReader which reads \a format data from an I/O \a device. + + If the device is invalid or the format is unsupported this will return a null pointer. +*/ + +/*! + \fn QMediaPlaylistIOPlugin::createReader(const QUrl& location, const QByteArray &format) + + Returns a new QMediaPlaylistReader which reads \a format data from a URL \a location. + + If the location or the format is unsupported this will return a null pointer. +*/ + +/*! + \fn QMediaPlaylistIOPlugin::createWriter(QIODevice *device, const QByteArray &format) + + Returns a new QMediaPlaylistWriter which writes \a format data to an I/O \a device. + + If the device is invalid or the format is unsupported this will return a null pointer. +*/ + +QT_END_NAMESPACE + +#include "moc_qmediaplaylistioplugin.cpp" + diff --git a/src/multimedia/base/qmediaplaylistioplugin.h b/src/multimedia/base/qmediaplaylistioplugin.h new file mode 100644 index 0000000..e55298d --- /dev/null +++ b/src/multimedia/base/qmediaplaylistioplugin.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYLISTIOPLUGIN_H +#define QMEDIAPLAYLISTIOPLUGIN_H + +#include <QtCore/qobject.h> +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> + +#include <QtMultimedia/qmediacontent.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QString; +class QUrl; +class QByteArray; +class QIODevice; +class QStringList; + +class Q_MULTIMEDIA_EXPORT QMediaPlaylistReader +{ +public: + virtual ~QMediaPlaylistReader(); + + virtual bool atEnd() const = 0; + virtual QMediaContent readItem() = 0; + virtual void close() = 0; +}; + +class Q_MULTIMEDIA_EXPORT QMediaPlaylistWriter +{ +public: + virtual ~QMediaPlaylistWriter(); + + virtual bool writeItem(const QMediaContent &content) = 0; + virtual void close() = 0; +}; + +struct Q_MULTIMEDIA_EXPORT QMediaPlaylistIOInterface : public QFactoryInterface +{ + virtual bool canRead(QIODevice *device, const QByteArray &format = QByteArray() ) const = 0; + virtual bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const = 0; + + virtual bool canWrite(QIODevice *device, const QByteArray &format) const = 0; + + virtual QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()) = 0; + virtual QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()) = 0; + + virtual QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format) = 0; +}; + +#define QMediaPlaylistIOInterface_iid "com.nokia.Qt.QMediaPlaylistIOInterface" +Q_DECLARE_INTERFACE(QMediaPlaylistIOInterface, QMediaPlaylistIOInterface_iid); + +class Q_MULTIMEDIA_EXPORT QMediaPlaylistIOPlugin : public QObject, public QMediaPlaylistIOInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaPlaylistIOInterface:QFactoryInterface) + +public: + explicit QMediaPlaylistIOPlugin(QObject *parent = 0); + virtual ~QMediaPlaylistIOPlugin(); + + virtual bool canRead(QIODevice *device, const QByteArray &format = QByteArray() ) const = 0; + virtual bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const = 0; + + virtual bool canWrite(QIODevice *device, const QByteArray &format) const = 0; + + virtual QStringList keys() const = 0; + + virtual QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()) = 0; + virtual QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()) = 0; + + virtual QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format) = 0; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLAYLISTIOPLUGIN_H diff --git a/src/multimedia/base/qmediaplaylistnavigator.cpp b/src/multimedia/base/qmediaplaylistnavigator.cpp new file mode 100644 index 0000000..3c22ea4 --- /dev/null +++ b/src/multimedia/base/qmediaplaylistnavigator.cpp @@ -0,0 +1,544 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qmediaplaylistnavigator.h> +#include <QtMultimedia/qmediaplaylistprovider.h> +#include <QtMultimedia/qmediaplaylist.h> +#include "qmediaobject_p.h" + +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +class QMediaPlaylistNullProvider : public QMediaPlaylistProvider +{ +public: + QMediaPlaylistNullProvider() :QMediaPlaylistProvider() {} + virtual ~QMediaPlaylistNullProvider() {} + virtual int mediaCount() const {return 0;} + virtual QMediaContent media(int) const { return QMediaContent(); } +}; + +Q_GLOBAL_STATIC(QMediaPlaylistNullProvider, _q_nullMediaPlaylist) + +class QMediaPlaylistNavigatorPrivate +{ + Q_DECLARE_NON_CONST_PUBLIC(QMediaPlaylistNavigator) +public: + QMediaPlaylistNavigatorPrivate() + :playlist(0), + currentPos(-1), + lastValidPos(-1), + playbackMode(QMediaPlaylist::Linear), + randomPositionsOffset(-1) + { + } + + QMediaPlaylistProvider *playlist; + int currentPos; + int lastValidPos; //to be used with CurrentItemOnce playback mode + QMediaPlaylist::PlaybackMode playbackMode; + QMediaContent currentItem; + + mutable QList<int> randomModePositions; + mutable int randomPositionsOffset; + + int nextItemPos(int steps = 1) const; + int previousItemPos(int steps = 1) const; + + void _q_mediaInserted(int start, int end); + void _q_mediaRemoved(int start, int end); + void _q_mediaChanged(int start, int end); + + QMediaPlaylistNavigator *q_ptr; +}; + + +int QMediaPlaylistNavigatorPrivate::nextItemPos(int steps) const +{ + if (playlist->mediaCount() == 0) + return -1; + + if (steps == 0) + return currentPos; + + switch (playbackMode) { + case QMediaPlaylist::CurrentItemOnce: + return /*currentPos == -1 ? lastValidPos :*/ -1; + case QMediaPlaylist::CurrentItemInLoop: + return currentPos; + case QMediaPlaylist::Linear: + { + int nextPos = currentPos+steps; + return nextPos < playlist->mediaCount() ? nextPos : -1; + } + case QMediaPlaylist::Loop: + return (currentPos+steps) % playlist->mediaCount(); + case QMediaPlaylist::Random: + { + //TODO: limit the history size + + if (randomPositionsOffset == -1) { + randomModePositions.clear(); + randomModePositions.append(currentPos); + randomPositionsOffset = 0; + } + + while (randomModePositions.size() < randomPositionsOffset+steps+1) + randomModePositions.append(-1); + int res = randomModePositions[randomPositionsOffset+steps]; + if (res<0 || res >= playlist->mediaCount()) { + res = qrand() % playlist->mediaCount(); + randomModePositions[randomPositionsOffset+steps] = res; + } + + return res; + } + } + + return -1; +} + +int QMediaPlaylistNavigatorPrivate::previousItemPos(int steps) const +{ + if (playlist->mediaCount() == 0) + return -1; + + if (steps == 0) + return currentPos; + + switch (playbackMode) { + case QMediaPlaylist::CurrentItemOnce: + return /*currentPos == -1 ? lastValidPos :*/ -1; + case QMediaPlaylist::CurrentItemInLoop: + return currentPos; + case QMediaPlaylist::Linear: + { + int prevPos = currentPos == -1 ? playlist->mediaCount() - steps : currentPos - steps; + return prevPos>=0 ? prevPos : -1; + } + case QMediaPlaylist::Loop: + { + int prevPos = currentPos - steps; + while (prevPos<0) + prevPos += playlist->mediaCount(); + return prevPos; + } + case QMediaPlaylist::Random: + { + //TODO: limit the history size + + if (randomPositionsOffset == -1) { + randomModePositions.clear(); + randomModePositions.append(currentPos); + randomPositionsOffset = 0; + } + + while (randomPositionsOffset-steps < 0) { + randomModePositions.prepend(-1); + randomPositionsOffset++; + } + + int res = randomModePositions[randomPositionsOffset-steps]; + if (res<0 || res >= playlist->mediaCount()) { + res = qrand() % playlist->mediaCount(); + randomModePositions[randomPositionsOffset-steps] = res; + } + + return res; + } + } + + return -1; +} + +/*! + \class QMediaPlaylistNavigator + \preliminary + \brief The QMediaPlaylistNavigator class provides navigation for a media playlist. + + \sa QMediaPlaylist, QMediaPlaylistProvider +*/ + + +/*! + Constructs a media playlist navigator for a \a playlist. + + The \a parent is passed to QObject. + */ +QMediaPlaylistNavigator::QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent) + : QObject(parent) + , d_ptr(new QMediaPlaylistNavigatorPrivate) +{ + d_ptr->q_ptr = this; + + setPlaylist(playlist ? playlist : _q_nullMediaPlaylist()); +} + +/*! + Destroys a media playlist navigator. + */ + +QMediaPlaylistNavigator::~QMediaPlaylistNavigator() +{ + delete d_ptr; +} + + +/*! \property QMediaPlaylistNavigator::playbackMode + Contains the playback mode. + */ +QMediaPlaylist::PlaybackMode QMediaPlaylistNavigator::playbackMode() const +{ + return d_func()->playbackMode; +} + +/*! + Sets the playback \a mode. + */ +void QMediaPlaylistNavigator::setPlaybackMode(QMediaPlaylist::PlaybackMode mode) +{ + Q_D(QMediaPlaylistNavigator); + if (d->playbackMode == mode) + return; + + if (mode == QMediaPlaylist::Random) { + d->randomPositionsOffset = 0; + d->randomModePositions.append(d->currentPos); + } else if (d->playbackMode == QMediaPlaylist::Random) { + d->randomPositionsOffset = -1; + d->randomModePositions.clear(); + } + + d->playbackMode = mode; + + emit playbackModeChanged(mode); + emit surroundingItemsChanged(); +} + +/*! + Returns the playlist being navigated. +*/ + +QMediaPlaylistProvider *QMediaPlaylistNavigator::playlist() const +{ + return d_func()->playlist; +} + +/*! + Sets the \a playlist to navigate. +*/ +void QMediaPlaylistNavigator::setPlaylist(QMediaPlaylistProvider *playlist) +{ + Q_D(QMediaPlaylistNavigator); + + if (d->playlist == playlist) + return; + + if (d->playlist) { + d->playlist->disconnect(this); + } + + if (playlist) { + d->playlist = playlist; + } else { + //assign to shared readonly null playlist + d->playlist = _q_nullMediaPlaylist(); + } + + connect(d->playlist, SIGNAL(mediaInserted(int,int)), SLOT(_q_mediaInserted(int,int))); + connect(d->playlist, SIGNAL(mediaRemoved(int,int)), SLOT(_q_mediaRemoved(int,int))); + connect(d->playlist, SIGNAL(mediaChanged(int,int)), SLOT(_q_mediaChanged(int,int))); + + d->randomPositionsOffset = -1; + d->randomModePositions.clear(); + + if (d->currentPos != -1) { + d->currentPos = -1; + emit currentIndexChanged(-1); + } + + if (!d->currentItem.isNull()) { + d->currentItem = QMediaContent(); + emit activated(d->currentItem); //stop playback + } +} + +/*! \property QMediaPlaylistNavigator::currentItem + + Contains the media at the current position in the playlist. + + \sa currentIndex() +*/ + +QMediaContent QMediaPlaylistNavigator::currentItem() const +{ + return itemAt(d_func()->currentPos); +} + +/*! \fn QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const + + Returns the media that is \a steps positions ahead of the current + position in the playlist. + + \sa nextIndex() +*/ +QMediaContent QMediaPlaylistNavigator::nextItem(int steps) const +{ + return itemAt(nextIndex(steps)); +} + +/*! + Returns the media that is \a steps positions behind the current + position in the playlist. + + \sa previousIndex() + */ +QMediaContent QMediaPlaylistNavigator::previousItem(int steps) const +{ + return itemAt(previousIndex(steps)); +} + +/*! + Returns the media at a \a position in the playlist. + */ +QMediaContent QMediaPlaylistNavigator::itemAt(int position) const +{ + return d_func()->playlist->media(position); +} + +/*! \property QMediaPlaylistNavigator::currentIndex + + Contains the position of the current media. + + If no media is current, the property contains -1. + + \sa nextIndex(), previousIndex() +*/ + +int QMediaPlaylistNavigator::currentIndex() const +{ + return d_func()->currentPos; +} + +/*! + Returns a position \a steps ahead of the current position + accounting for the playbackMode(). + + If the position is beyond the end of the playlist, this value + returned is -1. + + \sa currentIndex(), previousIndex(), playbackMode() +*/ + +int QMediaPlaylistNavigator::nextIndex(int steps) const +{ + return d_func()->nextItemPos(steps); +} + +/*! + + Returns a position \a steps behind the current position accounting + for the playbackMode(). + + If the position is prior to the beginning of the playlist this will + return -1. + + \sa currentIndex(), nextIndex(), playbackMode() +*/ +int QMediaPlaylistNavigator::previousIndex(int steps) const +{ + return d_func()->previousItemPos(steps); +} + +/*! + Advances to the next item in the playlist. + + \sa previous(), jump(), playbackMode() + */ +void QMediaPlaylistNavigator::next() +{ + Q_D(QMediaPlaylistNavigator); + + int nextPos = d->nextItemPos(); + + if ( playbackMode() == QMediaPlaylist::Random ) + d->randomPositionsOffset++; + + jump(nextPos); +} + +/*! + Returns to the previous item in the playlist, + + \sa next(), jump(), playbackMode() + */ +void QMediaPlaylistNavigator::previous() +{ + Q_D(QMediaPlaylistNavigator); + + int prevPos = d->previousItemPos(); + if ( playbackMode() == QMediaPlaylist::Random ) + d->randomPositionsOffset--; + + jump(prevPos); +} + +/*! + Jumps to a new \a position in the playlist. + */ +void QMediaPlaylistNavigator::jump(int position) +{ + Q_D(QMediaPlaylistNavigator); + + if (position<-1 || position>=d->playlist->mediaCount()) { + qWarning() << "QMediaPlaylistNavigator: Jump outside playlist range"; + position = -1; + } + + if (position != -1) + d->lastValidPos = position; + + if (playbackMode() == QMediaPlaylist::Random) { + if (d->randomModePositions[d->randomPositionsOffset] != position) { + d->randomModePositions.clear(); + d->randomModePositions.append(position); + d->randomPositionsOffset = 0; + } + } + + if (position != -1) + d->currentItem = d->playlist->media(position); + else + d->currentItem = QMediaContent(); + + if (position != d->currentPos) { + d->currentPos = position; + emit currentIndexChanged(d->currentPos); + emit surroundingItemsChanged(); + } + + emit activated(d->currentItem); +} + +/*! + \internal +*/ +void QMediaPlaylistNavigatorPrivate::_q_mediaInserted(int start, int end) +{ + Q_Q(QMediaPlaylistNavigator); + + if (currentPos >= start) { + currentPos = end-start+1; + q->jump(currentPos); + } + + //TODO: check if they really changed + emit q->surroundingItemsChanged(); +} + +/*! + \internal +*/ +void QMediaPlaylistNavigatorPrivate::_q_mediaRemoved(int start, int end) +{ + Q_Q(QMediaPlaylistNavigator); + + if (currentPos > end) { + currentPos = currentPos - end-start+1; + q->jump(currentPos); + } else if (currentPos >= start) { + //current item was removed + currentPos = qMin(start, playlist->mediaCount()-1); + q->jump(currentPos); + } + + //TODO: check if they really changed + emit q->surroundingItemsChanged(); +} + +/*! + \internal +*/ +void QMediaPlaylistNavigatorPrivate::_q_mediaChanged(int start, int end) +{ + Q_Q(QMediaPlaylistNavigator); + + if (currentPos >= start && currentPos<=end) { + QMediaContent src = playlist->media(currentPos); + if (src != currentItem) { + currentItem = src; + emit q->activated(src); + } + } + + //TODO: check if they really changed + emit q->surroundingItemsChanged(); +} + +/*! + \fn QMediaPlaylistNavigator::activated(const QMediaContent &media) + + Signals that the current \a media has changed. +*/ + +/*! + \fn QMediaPlaylistNavigator::currentIndexChanged(int position) + + Signals the \a position of the current media has changed. +*/ + +/*! + \fn QMediaPlaylistNavigator::playbackModeChanged(QMediaPlaylist::PlaybackMode mode) + + Signals that the playback \a mode has changed. +*/ + +/*! + \fn QMediaPlaylistNavigator::surroundingItemsChanged() + + Signals that media immediately surrounding the current position has changed. +*/ + +#include "moc_qmediaplaylistnavigator.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediaplaylistnavigator.h b/src/multimedia/base/qmediaplaylistnavigator.h new file mode 100644 index 0000000..73789af --- /dev/null +++ b/src/multimedia/base/qmediaplaylistnavigator.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYLISTNAVIGATOR_H +#define QMEDIAPLAYLISTNAVIGATOR_H + +#include <QtCore/qobject.h> + +#include <QtMultimedia/qmediaplaylistprovider.h> +#include <QtMultimedia/qmediaplaylist.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QMediaPlaylistNavigatorPrivate; +class Q_MULTIMEDIA_EXPORT QMediaPlaylistNavigator : public QObject +{ + Q_OBJECT + Q_PROPERTY(QMediaPlaylist::PlaybackMode playbackMode READ playbackMode WRITE setPlaybackMode NOTIFY playbackModeChanged) + Q_PROPERTY(int currentIndex READ currentIndex WRITE jump NOTIFY currentIndexChanged) + Q_PROPERTY(QMediaContent currentItem READ currentItem NOTIFY currentItemChanged) + +public: + QMediaPlaylistNavigator(QMediaPlaylistProvider *playlist, QObject *parent = 0); + virtual ~QMediaPlaylistNavigator(); + + QMediaPlaylistProvider *playlist() const; + void setPlaylist(QMediaPlaylistProvider *playlist); + + QMediaPlaylist::PlaybackMode playbackMode() const; + + QMediaContent currentItem() const; + QMediaContent nextItem(int steps = 1) const; + QMediaContent previousItem(int steps = 1) const; + + QMediaContent itemAt(int position) const; + + int currentIndex() const; + int nextIndex(int steps = 1) const; + int previousIndex(int steps = 1) const; + +public Q_SLOTS: + void next(); + void previous(); + + void jump(int); + + void setPlaybackMode(QMediaPlaylist::PlaybackMode mode); + +Q_SIGNALS: + void activated(const QMediaContent &content); + void currentIndexChanged(int); + void playbackModeChanged(QMediaPlaylist::PlaybackMode mode); + + void surroundingItemsChanged(); + +protected: + QMediaPlaylistNavigatorPrivate *d_ptr; + +private: + Q_DISABLE_COPY(QMediaPlaylistNavigator) + Q_DECLARE_PRIVATE(QMediaPlaylistNavigator) + + Q_PRIVATE_SLOT(d_func(), void _q_mediaInserted(int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_mediaRemoved(int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_mediaChanged(int start, int end)) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLAYLISTNAVIGATOR_H diff --git a/src/multimedia/base/qmediaplaylistprovider.cpp b/src/multimedia/base/qmediaplaylistprovider.cpp new file mode 100644 index 0000000..65105dc --- /dev/null +++ b/src/multimedia/base/qmediaplaylistprovider.cpp @@ -0,0 +1,307 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qurl.h> + +#include <QtMultimedia/qmediaplaylistprovider.h> +#include "qmediaplaylistprovider_p.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QMediaPlaylistProvider + \preliminary + \brief The QMediaPlaylistProvider class provides an abstract list of media. + + \sa QMediaPlaylist +*/ + +/*! + Constructs a playlist provider with the given \a parent. +*/ +QMediaPlaylistProvider::QMediaPlaylistProvider(QObject *parent) + :QObject(parent), d_ptr(new QMediaPlaylistProviderPrivate) +{ +} + +/*! + \internal +*/ +QMediaPlaylistProvider::QMediaPlaylistProvider(QMediaPlaylistProviderPrivate &dd, QObject *parent) + :QObject(parent), d_ptr(&dd) +{ +} + +/*! + Destroys a playlist provider. +*/ +QMediaPlaylistProvider::~QMediaPlaylistProvider() +{ + delete d_ptr; +} + +/*! + \fn QMediaPlaylistProvider::mediaCount() const; + + Returns the size of playlist. +*/ + +/*! + \fn QMediaPlaylistProvider::media(int index) const; + + Returns the media at \a index in the playlist. + + If the index is invalid this will return a null media content. +*/ + + +/*! + Loads a playlist from from a URL \a location. If no playlist \a format is specified the loader + will inspect the URL or probe the headers to guess the format. + + New items are appended to playlist. + + Returns true if the provider supports the format and loading from the locations URL protocol, + otherwise this will return false. +*/ +bool QMediaPlaylistProvider::load(const QUrl &location, const char *format) +{ + Q_UNUSED(location); + Q_UNUSED(format); + return false; +} + +/*! + Loads a playlist from from an I/O \a device. If no playlist \a format is specified the loader + will probe the headers to guess the format. + + New items are appended to playlist. + + Returns true if the provider supports the format and loading from an I/O device, otherwise this + will return false. +*/ +bool QMediaPlaylistProvider::load(QIODevice * device, const char *format) +{ + Q_UNUSED(device); + Q_UNUSED(format); + return false; +} + +/*! + Saves the contents of a playlist to a URL \a location. If no playlist \a format is specified + the writer will inspect the URL to guess the format. + + Returns true if the playlist was saved succesfully; and false otherwise. + */ +bool QMediaPlaylistProvider::save(const QUrl &location, const char *format) +{ + Q_UNUSED(location); + Q_UNUSED(format); + return false; +} + +/*! + Saves the contents of a playlist to an I/O \a device in the specified \a format. + + Returns true if the playlist was saved succesfully; and false otherwise. +*/ +bool QMediaPlaylistProvider::save(QIODevice * device, const char *format) +{ + Q_UNUSED(device); + Q_UNUSED(format); + return false; +} + +/*! + Returns true if a playlist is read-only; otherwise returns false. +*/ +bool QMediaPlaylistProvider::isReadOnly() const +{ + return true; +} + +/*! + Append \a media to a playlist. + + Returns true if the media was appended; and false otherwise. +*/ +bool QMediaPlaylistProvider::addMedia(const QMediaContent &media) +{ + Q_UNUSED(media); + return false; +} + +/*! + Append multiple media \a items to a playlist. + + Returns true if the media items were appended; and false otherwise. +*/ +bool QMediaPlaylistProvider::addMedia(const QList<QMediaContent> &items) +{ + foreach(const QMediaContent &item, items) { + if (!addMedia(item)) + return false; + } + + return true; +} + +/*! + Inserts \a media into a playlist at \a position. + + Returns true if the media was inserted; and false otherwise. +*/ +bool QMediaPlaylistProvider::insertMedia(int position, const QMediaContent &media) +{ + Q_UNUSED(position); + Q_UNUSED(media); + return false; +} + +/*! + Inserts multiple media \a items into a playlist at \a position. + + Returns true if the media \a items were inserted; and false otherwise. +*/ +bool QMediaPlaylistProvider::insertMedia(int position, const QList<QMediaContent> &items) +{ + for (int i=0; i<items.count(); i++) { + if (!insertMedia(position+i,items.at(i))) + return false; + } + + return true; +} + + +/*! + Removes the media at \a position from a playlist. + + Returns true if the media was removed; and false otherwise. +*/ +bool QMediaPlaylistProvider::removeMedia(int position) +{ + Q_UNUSED(position); + return false; +} + +/*! + Removes the media between the given \a start and \a end positions from a playlist. + + Returns true if the media was removed; and false otherwise. + */ +bool QMediaPlaylistProvider::removeMedia(int start, int end) +{ + for (int pos=start; pos<=end; pos++) { + if (!removeMedia(pos)) + return false; + } + + return true; +} + +/*! + Removes all media from a playlist. + + Returns true if the media was removed; and false otherwise. +*/ +bool QMediaPlaylistProvider::clear() +{ + return removeMedia(0, mediaCount()-1); +} + +/*! + Shuffles the contents of a playlist. +*/ +void QMediaPlaylistProvider::shuffle() +{ +} + +/*! + \fn void QMediaPlaylistProvider::mediaAboutToBeInserted(int start, int end); + + Signals that new media is about to be inserted into a playlist between the \a start and \a end + positions. +*/ + +/*! + \fn void QMediaPlaylistProvider::mediaInserted(int start, int end); + + Signals that new media has been inserted into a playlist between the \a start and \a end + positions. +*/ + +/*! + \fn void QMediaPlaylistProvider::mediaAboutToBeRemoved(int start, int end); + + Signals that media is about to be removed from a playlist between the \a start and \a end + positions. +*/ + +/*! + \fn void QMediaPlaylistProvider::mediaRemoved(int start, int end); + + Signals that media has been removed from a playlist between the \a start and \a end positions. +*/ + +/*! + \fn void QMediaPlaylistProvider::mediaChanged(int start, int end); + + Signals that media in playlist between the \a start and \a end positions inclusive has changed. +*/ + +/*! + \fn void QMediaPlaylistProvider::loaded() + + Signals that a load() finished successfully. +*/ + +/*! + \fn void QMediaPlaylistProvider::loadFailed(QMediaPlaylist::Error error, const QString& errorMessage) + + Signals that a load failed() due to an \a error. The \a errorMessage provides more information. +*/ + +#include "moc_qmediaplaylistprovider.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediaplaylistprovider.h b/src/multimedia/base/qmediaplaylistprovider.h new file mode 100644 index 0000000..b8f07d1 --- /dev/null +++ b/src/multimedia/base/qmediaplaylistprovider.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYLISTPROVIDER_H +#define QMEDIAPLAYLISTPROVIDER_H + +#include <QtCore/qobject.h> + +#include <QtMultimedia/qmediacontent.h> +#include <QtMultimedia/qmediaplaylist.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QString; + + +class QMediaPlaylistProviderPrivate; +class Q_MULTIMEDIA_EXPORT QMediaPlaylistProvider : public QObject +{ + Q_OBJECT + +public: + QMediaPlaylistProvider(QObject *parent=0); + virtual ~QMediaPlaylistProvider(); + + virtual bool load(const QUrl &location, const char *format = 0); + virtual bool load(QIODevice * device, const char *format = 0); + virtual bool save(const QUrl &location, const char *format = 0); + virtual bool save(QIODevice * device, const char *format); + + virtual int mediaCount() const = 0; + virtual QMediaContent media(int index) const = 0; + + virtual bool isReadOnly() const; + + virtual bool addMedia(const QMediaContent &content); + virtual bool addMedia(const QList<QMediaContent> &contentList); + virtual bool insertMedia(int index, const QMediaContent &content); + virtual bool insertMedia(int index, const QList<QMediaContent> &content); + virtual bool removeMedia(int pos); + virtual bool removeMedia(int start, int end); + virtual bool clear(); + +public Q_SLOTS: + virtual void shuffle(); + +Q_SIGNALS: + void mediaAboutToBeInserted(int start, int end); + void mediaInserted(int start, int end); + + void mediaAboutToBeRemoved(int start, int end); + void mediaRemoved(int start, int end); + + void mediaChanged(int start, int end); + + void loaded(); + void loadFailed(QMediaPlaylist::Error, const QString& errorMessage); + +protected: + QMediaPlaylistProviderPrivate *d_ptr; + QMediaPlaylistProvider(QMediaPlaylistProviderPrivate &dd, QObject *parent); + +private: + Q_DECLARE_PRIVATE(QMediaPlaylistProvider) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLAYLISTPROVIDER_H diff --git a/src/multimedia/base/qmediaplaylistprovider_p.h b/src/multimedia/base/qmediaplaylistprovider_p.h new file mode 100644 index 0000000..aaf6deb --- /dev/null +++ b/src/multimedia/base/qmediaplaylistprovider_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYLISTPROVIDER_P_H +#define QMEDIAPLAYLISTPROVIDER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtMultimedia/qmediaplaylist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaPlaylistProviderPrivate +{ +public: + QMediaPlaylistProviderPrivate() + {} + virtual ~QMediaPlaylistProviderPrivate() + {} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLAYLISTSOURCE_P_H diff --git a/src/multimedia/base/qmediapluginloader.cpp b/src/multimedia/base/qmediapluginloader.cpp new file mode 100644 index 0000000..24c5aba --- /dev/null +++ b/src/multimedia/base/qmediapluginloader.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmediapluginloader_p.h" +#include <QtCore/qcoreapplication.h> +#include <QtCore/qpluginloader.h> +#include <QtCore/qdir.h> +#include <QtCore/qdebug.h> + +#include <QtMultimedia/qmediaserviceproviderplugin.h> + + +QT_BEGIN_NAMESPACE + + +typedef QMap<QString,QObjectList> ObjectListMap; +Q_GLOBAL_STATIC(ObjectListMap, staticMediaPlugins); + +QMediaPluginLoader::QMediaPluginLoader(const char *iid, const QString &location, Qt::CaseSensitivity): + m_iid(iid) +{ + m_location = location + QLatin1String("/"); + load(); +} + +QStringList QMediaPluginLoader::keys() const +{ + return m_instances.keys(); +} + +QObject* QMediaPluginLoader::instance(QString const &key) +{ + return m_instances.value(key); +} + +QList<QObject*> QMediaPluginLoader::instances(QString const &key) +{ + return m_instances.values(key); +} + +//to be used for testing purposes only +void QMediaPluginLoader::setStaticPlugins(const QString &location, const QObjectList& objects) +{ + staticMediaPlugins()->insert(location + QLatin1String("/"), objects); +} + +void QMediaPluginLoader::load() +{ + if (!m_instances.isEmpty()) + return; + + if (staticMediaPlugins() && staticMediaPlugins()->contains(m_location)) { + foreach(QObject *o, staticMediaPlugins()->value(m_location)) { + if (o != 0 && o->qt_metacast(m_iid) != 0) { + QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o); + if (p != 0) { + foreach (QString const &key, p->keys()) + m_instances.insertMulti(key, o); + } + } + } + } else { + QStringList paths = QCoreApplication::libraryPaths(); + + foreach (QString const &path, paths) { + QString pluginPathName(path + m_location); + QDir pluginDir(pluginPathName); + + if (!pluginDir.exists()) + continue; + + foreach (QString pluginLib, pluginDir.entryList(QDir::Files)) { + QPluginLoader loader(pluginPathName + pluginLib); + + QObject *o = loader.instance(); + if (o != 0 && o->qt_metacast(m_iid) != 0) { + QFactoryInterface* p = qobject_cast<QFactoryInterface*>(o); + if (p != 0) { + foreach (QString const &key, p->keys()) + m_instances.insertMulti(key, o); + } + + continue; + } else { + qWarning() << "QMediaPluginLoader: Failed to load plugin: " << pluginLib << loader.errorString(); + } + delete o; + loader.unload(); + } + } + } +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediapluginloader_p.h b/src/multimedia/base/qmediapluginloader_p.h new file mode 100644 index 0000000..351d2f1 --- /dev/null +++ b/src/multimedia/base/qmediapluginloader_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLUGINLOADER_H +#define QMEDIAPLUGINLOADER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtCore/qstring.h> +#include <QtCore/qmap.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaServiceProviderPlugin; + +class Q_AUTOTEST_EXPORT QMediaPluginLoader +{ +public: + QMediaPluginLoader(const char *iid, + const QString &suffix = QString(), + Qt::CaseSensitivity = Qt::CaseSensitive); + + QStringList keys() const; + QObject* instance(QString const &key); + QList<QObject*> instances(QString const &key); + + static void setStaticPlugins(const QString &location, const QObjectList& objects); + +private: + void load(); + + QByteArray m_iid; + QString m_location; + QMap<QString, QObject*> m_instances; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLUGINLOADER_H diff --git a/src/multimedia/base/qmediaresource.cpp b/src/multimedia/base/qmediaresource.cpp new file mode 100644 index 0000000..515e432 --- /dev/null +++ b/src/multimedia/base/qmediaresource.cpp @@ -0,0 +1,398 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qsize.h> +#include <QtCore/qurl.h> +#include <QtCore/qvariant.h> + +#include <QtMultimedia/qmediaresource.h> + + +QT_BEGIN_NAMESPACE + +/*! + \class QMediaResource + \preliminary + \brief The QMediaResource class provides a description of a media resource. + \ingroup multimedia + + A media resource is composed of a \l {url()}{URL} containing the + location of the resource and a set of properties that describe the + format of the resource. The properties provide a means to assess a + resource without first attempting to load it, and in situations where + media be represented by multiple alternative representations provide a + means to select the appropriate resource. + + Media made available by a remote services can often be available in + multiple encodings or quality levels, this allows a client to select + an appropriate resource based on considerations such as codecs supported, + network bandwidth, and display constraints. QMediaResource includes + information such as the \l {mimeType()}{MIME type}, \l {audioCodec()}{audio} + and \l {videoCodec()}{video} codecs, \l {audioBitRate()}{audio} and + \l {videoBitRate()}{video} bit rates, and \l {resolution()}{resolution} + so these constraints and others can be evaluated. + + The only mandatory property of a QMediaResource is the url(). + + \sa QMediaContent +*/ + +/*! + \typedef QMediaResourceList + + Synonym for \c QList<QMediaResource> +*/ + +/*! + Constructs a null media resource. +*/ +QMediaResource::QMediaResource() +{ +} + +/*! + Constructs a media resource with the given \a mimeType from a \a url. +*/ +QMediaResource::QMediaResource(const QUrl &url, const QString &mimeType) +{ + values.insert(Url, url); + values.insert(MimeType, mimeType); +} + +/*! + Constructs a media resource with the given \a mimeType from a network \a request. +*/ +QMediaResource::QMediaResource(const QNetworkRequest &request, const QString &mimeType) +{ + values.insert(Request, QVariant::fromValue(request)); + values.insert(Url, request.url()); + values.insert(MimeType, mimeType); +} + +/*! + Constructs a copy of a media resource \a other. +*/ +QMediaResource::QMediaResource(const QMediaResource &other) + : values(other.values) +{ +} + +/*! + Assigns the value of \a other to a media resource. +*/ +QMediaResource &QMediaResource::operator =(const QMediaResource &other) +{ + values = other.values; + + return *this; +} + +/*! + Destroys a media resource. +*/ +QMediaResource::~QMediaResource() +{ +} + + +/*! + Compares a media resource to \a other. + + Returns true if the resources are identical, and false otherwise. +*/ +bool QMediaResource::operator ==(const QMediaResource &other) const +{ + return values == other.values; +} + +/*! + Compares a media resource to \a other. + + Returns true if they are different, and false otherwise. +*/ +bool QMediaResource::operator !=(const QMediaResource &other) const +{ + return values != other.values; +} + +/*! + Identifies if a media resource is null. + + Returns true if the resource is null, and false otherwise. +*/ +bool QMediaResource::isNull() const +{ + return values.isEmpty(); +} + +/*! + Returns the URL of a media resource. +*/ +QUrl QMediaResource::url() const +{ + return qvariant_cast<QUrl>(values.value(Url)); +} + +/*! + Returns the network request associated with this media resource. +*/ +QNetworkRequest QMediaResource::request() const +{ + if(values.contains(Request)) + return qvariant_cast<QNetworkRequest>(values.value(Request)); + + return QNetworkRequest(url()); +} + +/*! + Returns the MIME type of a media resource. + + This may be null if the MIME type is unknown. +*/ +QString QMediaResource::mimeType() const +{ + return qvariant_cast<QString>(values.value(MimeType)); +} + +/*! + Returns the language of a media resource as an ISO 639-2 code. + + This may be null if the language is unknown. +*/ +QString QMediaResource::language() const +{ + return qvariant_cast<QString>(values.value(Language)); +} + +/*! + Sets the \a language of a media resource. +*/ +void QMediaResource::setLanguage(const QString &language) +{ + if (!language.isNull()) + values.insert(Language, language); + else + values.remove(Language); +} + +/*! + Returns the audio codec of a media resource. + + This may be null if the media resource does not contain an audio stream, or the codec is + unknown. +*/ +QString QMediaResource::audioCodec() const +{ + return qvariant_cast<QString>(values.value(AudioCodec)); +} + +/*! + Sets the audio \a codec of a media resource. +*/ +void QMediaResource::setAudioCodec(const QString &codec) +{ + if (!codec.isNull()) + values.insert(AudioCodec, codec); + else + values.remove(AudioCodec); +} + +/*! + Returns the video codec of a media resource. + + This may be null if the media resource does not contain a video stream, or the codec is + unknonwn. +*/ +QString QMediaResource::videoCodec() const +{ + return qvariant_cast<QString>(values.value(VideoCodec)); +} + +/*! + Sets the video \a codec of media resource. +*/ +void QMediaResource::setVideoCodec(const QString &codec) +{ + if (!codec.isNull()) + values.insert(VideoCodec, codec); + else + values.remove(VideoCodec); +} + +/*! + Returns the size in bytes of a media resource. + + This may be zero if the size is unknown. +*/ +qint64 QMediaResource::dataSize() const +{ + return qvariant_cast<qint64>(values.value(DataSize)); +} + +/*! + Sets the \a size in bytes of a media resource. +*/ +void QMediaResource::setDataSize(const qint64 size) +{ + if (size != 0) + values.insert(DataSize, size); + else + values.remove(DataSize); +} + +/*! + Returns the bit rate in bits per second of a media resource's audio stream. + + This may be zero if the bit rate is unknown, or the resource contains no audio stream. +*/ +int QMediaResource::audioBitRate() const +{ + return values.value(AudioBitRate).toInt(); +} + +/*! + Sets the bit \a rate in bits per second of a media resource's video stream. +*/ +void QMediaResource::setAudioBitRate(int rate) +{ + if (rate != 0) + values.insert(AudioBitRate, rate); + else + values.remove(AudioBitRate); +} + +/*! + Returns the audio sample rate of a media resource. + + This may be zero if the sample size is unknown, or the resource contains no audio stream. +*/ +int QMediaResource::sampleRate() const +{ + return qvariant_cast<int>(values.value(SampleRate)); +} + +/*! + Sets the audio \a sampleRate of a media resource. +*/ +void QMediaResource::setSampleRate(int sampleRate) +{ + if (sampleRate != 0) + values.insert(SampleRate, sampleRate); + else + values.remove(SampleRate); +} + +/*! + Returns the number of audio channels in a media resource. + + This may be zero if the sample size is unknown, or the resource contains no audio stream. +*/ +int QMediaResource::channelCount() const +{ + return qvariant_cast<int>(values.value(ChannelCount)); +} + +/*! + Sets the number of audio \a channels in a media resource. +*/ +void QMediaResource::setChannelCount(int channels) +{ + if (channels != 0) + values.insert(ChannelCount, channels); + else + values.remove(ChannelCount); +} + +/*! + Returns the bit rate in bits per second of a media resource's video stream. + + This may be zero if the bit rate is unknown, or the resource contains no video stream. +*/ +int QMediaResource::videoBitRate() const +{ + return values.value(VideoBitRate).toInt(); +} + +/*! + Sets the bit \a rate in bits per second of a media resource's video stream. +*/ +void QMediaResource::setVideoBitRate(int rate) +{ + if (rate != 0) + values.insert(VideoBitRate, rate); + else + values.remove(VideoBitRate); +} + +/*! + Returns the resolution in pixels of a media resource. + + This may be null is the resolution is unknown, or the resource contains no pixel data (i.e. the + resource is an audio stream. +*/ +QSize QMediaResource::resolution() const +{ + return qvariant_cast<QSize>(values.value(Resolution)); +} + +/*! + Sets the \a resolution in pixels of a media resource. +*/ +void QMediaResource::setResolution(const QSize &resolution) +{ + if (resolution.width() != -1 || resolution.height() != -1) + values.insert(Resolution, resolution); + else + values.remove(Resolution); +} + +/*! + Sets the \a width and \a height in pixels of a media resource. +*/ +void QMediaResource::setResolution(int width, int height) +{ + if (width != -1 || height != -1) + values.insert(Resolution, QSize(width, height)); + else + values.remove(Resolution); +} +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediaresource.h b/src/multimedia/base/qmediaresource.h new file mode 100644 index 0000000..a535bbd --- /dev/null +++ b/src/multimedia/base/qmediaresource.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIARESOURCE_H +#define QMEDIARESOURCE_H + +#include <QtCore/qmap.h> +#include <QtCore/qmetatype.h> +#include <QtNetwork/qnetworkrequest.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class Q_MULTIMEDIA_EXPORT QMediaResource +{ +public: + QMediaResource(); + QMediaResource(const QUrl &url, const QString &mimeType = QString()); + QMediaResource(const QNetworkRequest &request, const QString &mimeType = QString()); + QMediaResource(const QMediaResource &other); + QMediaResource &operator =(const QMediaResource &other); + ~QMediaResource(); + + bool isNull() const; + + bool operator ==(const QMediaResource &other) const; + bool operator !=(const QMediaResource &other) const; + + QUrl url() const; + QNetworkRequest request() const; + QString mimeType() const; + + QString language() const; + void setLanguage(const QString &language); + + QString audioCodec() const; + void setAudioCodec(const QString &codec); + + QString videoCodec() const; + void setVideoCodec(const QString &codec); + + qint64 dataSize() const; + void setDataSize(const qint64 size); + + int audioBitRate() const; + void setAudioBitRate(int rate); + + int sampleRate() const; + void setSampleRate(int frequency); + + int channelCount() const; + void setChannelCount(int channels); + + int videoBitRate() const; + void setVideoBitRate(int rate); + + QSize resolution() const; + void setResolution(const QSize &resolution); + void setResolution(int width, int height); + + +private: + enum Property + { + Url, + Request, + MimeType, + Language, + AudioCodec, + VideoCodec, + DataSize, + AudioBitRate, + VideoBitRate, + SampleRate, + ChannelCount, + Resolution + }; + QMap<int, QVariant> values; +}; + +typedef QList<QMediaResource> QMediaResourceList; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QMediaResource) +Q_DECLARE_METATYPE(QMediaResourceList) + +QT_END_HEADER + + +#endif diff --git a/src/multimedia/base/qmediaservice.cpp b/src/multimedia/base/qmediaservice.cpp new file mode 100644 index 0000000..e40688e --- /dev/null +++ b/src/multimedia/base/qmediaservice.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qtimer.h> + +#include <QtMultimedia/qmediaservice.h> +#include "qmediaservice_p.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +/*! + \class QMediaService + \brief The QMediaService class provides a common base class for media + service implementations. + \ingroup multimedia-serv + \preliminary + + Media services provide implementations of the functionality promised + by media objects, and allow multiple providers to implement a QMediaObject. + + To provide the functionality of a QMediaObject media services implement + QMediaControl interfaces. Services typically implement one core media + control which provides the core feature of a media object, and some + number of additional controls which provide either optional features of + the media object, or features of a secondary media object or peripheral + object. + + A pointer to media service's QMediaControl implementation can be + obtained by passing the control's interface name to the control() function. + + \code + QMediaPlayerControl *control = qobject_cast<QMediaPlayerControl *>( + service->control("com.nokia.Qt.QMediaPlayerControl/1.0")); + \endcode + + Media objects can use services loaded dynamically from plug-ins or + implemented statically within an applications. Plug-in based services + should also implement the QMediaServiceProviderPlugin interface. Static + services should implement the QMediaServiceProvider interface. + + \sa QMediaObject, QMediaControl, QMediaServiceProvider, QMediaServiceProviderPlugin +*/ + +/*! + Construct a media service with the given \a parent. This class is meant as a + base class for Multimedia services so this constructor is protected. +*/ + +QMediaService::QMediaService(QObject *parent) + : QObject(parent) + , d_ptr(new QMediaServicePrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + \internal +*/ +QMediaService::QMediaService(QMediaServicePrivate &dd, QObject *parent) + : QObject(parent) + , d_ptr(&dd) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys a media service. +*/ + +QMediaService::~QMediaService() +{ + delete d_ptr; +} + +/*! + \fn QMediaService::control(const char *interface) const + + Returns a pointer to the media control implementing \a interface. + + If the service does not implement the control a null pointer is returned instead. +*/ + +/*! + \fn QMediaService::control() const + + Returns a pointer to the media control of type T implemented by a media service. + + If the service does not implment the control a null pointer is returned instead. +*/ + +#include "moc_qmediaservice.cpp" + +QT_END_NAMESPACE + +QT_END_HEADER + diff --git a/src/multimedia/base/qmediaservice.h b/src/multimedia/base/qmediaservice.h new file mode 100644 index 0000000..c53a15f --- /dev/null +++ b/src/multimedia/base/qmediaservice.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTMEDIASERVICE_H +#define QABSTRACTMEDIASERVICE_H + +#include <QtCore/qobject.h> +#include <QtCore/qstringlist.h> + +#include <QtMultimedia/qmediacontrol.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMediaServicePrivate; +class Q_MULTIMEDIA_EXPORT QMediaService : public QObject +{ + Q_OBJECT + +public: + ~QMediaService(); + + virtual QMediaControl* control(const char *name) const = 0; + +#ifndef QT_NO_MEMBER_TEMPLATES + template <typename T> inline T control() const { + if (QObject *object = control(qmediacontrol_iid<T>())) { + return qobject_cast<T>(object); + } + return 0; + } +#endif + +protected: + QMediaService(QObject* parent); + QMediaService(QMediaServicePrivate &dd, QObject *parent); + + QMediaServicePrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QMediaService) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QABSTRACTMEDIASERVICE_H + diff --git a/src/multimedia/base/qmediaservice_p.h b/src/multimedia/base/qmediaservice_p.h new file mode 100644 index 0000000..7dbcd8a --- /dev/null +++ b/src/multimedia/base/qmediaservice_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTMEDIASERVICE_P_H +#define QABSTRACTMEDIASERVICE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAudioDeviceControl; + +class QMediaServicePrivate +{ +public: + QMediaServicePrivate(): q_ptr(0) {} + virtual ~QMediaServicePrivate() {} + + QMediaService *q_ptr; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qmediaserviceprovider.cpp b/src/multimedia/base/qmediaserviceprovider.cpp new file mode 100644 index 0000000..8d1e0fa --- /dev/null +++ b/src/multimedia/base/qmediaserviceprovider.cpp @@ -0,0 +1,701 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qdebug.h> +#include <QtCore/qmap.h> + +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediaserviceprovider.h> +#include <QtMultimedia/qmediaserviceproviderplugin.h> +#include "qmediapluginloader_p.h" +#include <QtMultimedia/qmediaplayer.h> + + + +class QMediaServiceProviderHintPrivate : public QSharedData +{ +public: + QMediaServiceProviderHintPrivate(QMediaServiceProviderHint::Type type) + :type(type), features(0) + { + } + + QMediaServiceProviderHintPrivate(const QMediaServiceProviderHintPrivate &other) + :QSharedData(other), + type(other.type), + device(other.device), + mimeType(other.mimeType), + codecs(other.codecs), + features(other.features) + { + } + + ~QMediaServiceProviderHintPrivate() + { + } + + QMediaServiceProviderHint::Type type; + QByteArray device; + QString mimeType; + QStringList codecs; + QMediaServiceProviderHint::Features features; +}; + +/*! + \class QMediaServiceProviderHint + \preliminary + \brief The QMediaServiceProviderHint class describes what is required of a QMediaService. + + \ingroup multimedia-serv + + The QMediaServiceProvider class uses hints to select an appropriate media service. +*/ + +/*! + \enum QMediaServiceProviderHint::Feature + + Enumerates features a media service may provide. + + \value LowLatencyPlayback + The service is expected to play simple audio formats, + but playback should start without significant delay. + Such playback service can be used for beeps, ringtones, etc. + + \value RecordingSupport + The service provides audio or video recording functions. +*/ + +/*! + \enum QMediaServiceProviderHint::Type + + Enumerates the possible types of media service provider hint. + + \value Null En empty hint, use the default service. + \value ContentType Select media service most suitable for certain content type. + \value Device Select media service which supports certain device. + \value SupportedFeatures Select media service supporting the set of optional features. +*/ + + +/*! + Constructs an empty media service provider hint. +*/ +QMediaServiceProviderHint::QMediaServiceProviderHint() + :d(new QMediaServiceProviderHintPrivate(Null)) +{ +} + +/*! + Constructs a ContentType media service provider hint. + + This type of hint describes a service that is able to play content of a specific MIME \a type + encoded with one or more of the listed \a codecs. +*/ +QMediaServiceProviderHint::QMediaServiceProviderHint(const QString &type, const QStringList& codecs) + :d(new QMediaServiceProviderHintPrivate(ContentType)) +{ + d->mimeType = type; + d->codecs = codecs; +} + +/*! + Constructs a Device media service provider hint. + + This type of hint describes a media service that utilizes a specific \a device. +*/ +QMediaServiceProviderHint::QMediaServiceProviderHint(const QByteArray &device) + :d(new QMediaServiceProviderHintPrivate(Device)) +{ + d->device = device; +} + +/*! + Constructs a SupportedFeatures media service provider hint. + + This type of hint describes a service which supports a specific set of \a features. +*/ +QMediaServiceProviderHint::QMediaServiceProviderHint(QMediaServiceProviderHint::Features features) + :d(new QMediaServiceProviderHintPrivate(SupportedFeatures)) +{ + d->features = features; +} + +/*! + Constructs a copy of the media service provider hint \a other. +*/ +QMediaServiceProviderHint::QMediaServiceProviderHint(const QMediaServiceProviderHint &other) + :d(other.d) +{ +} + +/*! + Destroys a media service provider hint. +*/ +QMediaServiceProviderHint::~QMediaServiceProviderHint() +{ +} + +/*! + Assigns the value \a other to a media service provider hint. +*/ +QMediaServiceProviderHint& QMediaServiceProviderHint::operator=(const QMediaServiceProviderHint &other) +{ + d = other.d; + return *this; +} + +/*! + Identifies if \a other is of equal value to a media service provider hint. + + Returns true if the hints are equal, and false if they are not. +*/ +bool QMediaServiceProviderHint::operator == (const QMediaServiceProviderHint &other) const +{ + return (d == other.d) || + (d->type == other.d->type && + d->device == other.d->device && + d->mimeType == other.d->mimeType && + d->codecs == other.d->codecs && + d->features == other.d->features); +} + +/*! + Identifies if \a other is not of equal value to a media service provider hint. + + Returns true if the hints are not equal, and false if they are. +*/ +bool QMediaServiceProviderHint::operator != (const QMediaServiceProviderHint &other) const +{ + return !(*this == other); +} + +/*! + Returns true if a media service provider is null. +*/ +bool QMediaServiceProviderHint::isNull() const +{ + return d->type == Null; +} + +/*! + Returns the type of a media service provider hint. +*/ +QMediaServiceProviderHint::Type QMediaServiceProviderHint::type() const +{ + return d->type; +} + +/*! + Returns the mime type of the media a service is expected to be able play. +*/ +QString QMediaServiceProviderHint::mimeType() const +{ + return d->mimeType; +} + +/*! + Returns a list of codes a media service is expected to be able to decode. +*/ +QStringList QMediaServiceProviderHint::codecs() const +{ + return d->codecs; +} + +/*! + Returns the name of a device a media service is expected to utilize. +*/ +QByteArray QMediaServiceProviderHint::device() const +{ + return d->device; +} + +/*! + Returns a set of features a media service is expected to provide. +*/ +QMediaServiceProviderHint::Features QMediaServiceProviderHint::features() const +{ + return d->features; +} + + +Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, loader, + (QMediaServiceProviderFactoryInterface_iid, QLatin1String("/mediaservices"), Qt::CaseInsensitive)) + + +class QPluginServiceProvider : public QMediaServiceProvider +{ + QMap<QMediaService*, QMediaServiceProviderPlugin*> pluginMap; + +public: + QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &hint) + { + QString key(type); + + QList<QMediaServiceProviderPlugin *>plugins; + foreach (QObject *obj, loader()->instances(key)) { + QMediaServiceProviderPlugin *plugin = + qobject_cast<QMediaServiceProviderPlugin*>(obj); + if (plugin) + plugins << plugin; + } + + if (!plugins.isEmpty()) { + QMediaServiceProviderPlugin *plugin = 0; + + switch (hint.type()) { + case QMediaServiceProviderHint::Null: + plugin = plugins[0]; + //special case for media player, if low latency was not asked, + //prefer services not offering it, since they are likely to support + //more formats + if (type == QByteArray(Q_MEDIASERVICE_MEDIAPLAYER)) { + foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) { + QMediaServiceFeaturesInterface *iface = + qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin); + + if (!iface || !(iface->supportedFeatures(type) & + QMediaServiceProviderHint::LowLatencyPlayback)) { + plugin = currentPlugin; + break; + } + + } + } + break; + case QMediaServiceProviderHint::SupportedFeatures: + plugin = plugins[0]; + foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) { + QMediaServiceFeaturesInterface *iface = + qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin); + + if (iface) { + if ((iface->supportedFeatures(type) & hint.features()) == hint.features()) { + plugin = currentPlugin; + break; + } + } + } + break; + case QMediaServiceProviderHint::Device: { + foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) { + QMediaServiceSupportedDevicesInterface *iface = + qobject_cast<QMediaServiceSupportedDevicesInterface*>(currentPlugin); + + if (!iface) { + // the plugin may support the device, + // but this choice still can be overridden + plugin = currentPlugin; + } else { + if (iface->devices(type).contains(hint.device())) { + plugin = currentPlugin; + break; + } + } + } + } + break; + case QMediaServiceProviderHint::ContentType: { + QtMultimedia::SupportEstimate estimate = QtMultimedia::NotSupported; + foreach (QMediaServiceProviderPlugin *currentPlugin, plugins) { + QtMultimedia::SupportEstimate currentEstimate = QtMultimedia::MaybeSupported; + QMediaServiceSupportedFormatsInterface *iface = + qobject_cast<QMediaServiceSupportedFormatsInterface*>(currentPlugin); + + if (iface) + currentEstimate = iface->hasSupport(hint.mimeType(), hint.codecs()); + + if (currentEstimate > estimate) { + estimate = currentEstimate; + plugin = currentPlugin; + + if (currentEstimate == QtMultimedia::PreferedService) + break; + } + } + } + break; + } + + if (plugin != 0) { + QMediaService *service = plugin->create(key); + if (service != 0) + pluginMap.insert(service, plugin); + + return service; + } + } + + qWarning() << "defaultServiceProvider::requestService(): no service found for -" << key; + return 0; + } + + void releaseService(QMediaService *service) + { + if (service != 0) { + QMediaServiceProviderPlugin *plugin = pluginMap.take(service); + + if (plugin != 0) + plugin->release(service); + } + } + + QtMultimedia::SupportEstimate hasSupport(const QByteArray &serviceType, + const QString &mimeType, + const QStringList& codecs, + int flags) const + { + QList<QObject*> instances = loader()->instances(serviceType); + + if (instances.isEmpty()) + return QtMultimedia::NotSupported; + + bool allServicesProvideInterface = true; + QtMultimedia::SupportEstimate supportEstimate = QtMultimedia::NotSupported; + + foreach(QObject *obj, instances) { + QMediaServiceSupportedFormatsInterface *iface = + qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj); + + //if low latency playback was asked, skip services known + //not to provide low latency playback + if (flags & QMediaPlayer::LowLatency) { + QMediaServiceFeaturesInterface *iface = + qobject_cast<QMediaServiceFeaturesInterface*>(obj); + + if (iface && !(iface->supportedFeatures(serviceType) & QMediaServiceProviderHint::LowLatencyPlayback)) + continue; + } + + if (iface) + supportEstimate = qMax(supportEstimate, iface->hasSupport(mimeType, codecs)); + else + allServicesProvideInterface = false; + } + + //don't return PreferedService + supportEstimate = qMin(supportEstimate, QtMultimedia::ProbablySupported); + + //Return NotSupported only if no services are available of serviceType + //or all the services returned NotSupported, otherwise return at least MaybeSupported + if (!allServicesProvideInterface) + supportEstimate = qMax(QtMultimedia::MaybeSupported, supportEstimate); + + return supportEstimate; + } + + QStringList supportedMimeTypes(const QByteArray &serviceType, int flags) const + { + QList<QObject*> instances = loader()->instances(serviceType); + + QStringList supportedTypes; + + foreach(QObject *obj, instances) { + QMediaServiceSupportedFormatsInterface *iface = + qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj); + + // If low latency playback was asked for, skip MIME types from services known + // not to provide low latency playback + if (flags & QMediaPlayer::LowLatency) { + QMediaServiceFeaturesInterface *iface = + qobject_cast<QMediaServiceFeaturesInterface*>(obj); + + if (iface && !(iface->supportedFeatures(serviceType) & QMediaServiceProviderHint::LowLatencyPlayback)) + continue; + } + + if (iface) { + supportedTypes << iface->supportedMimeTypes(); + } + } + + // Multiple services may support the same MIME type + supportedTypes.removeDuplicates(); + + return supportedTypes; + } + + QList<QByteArray> devices(const QByteArray &serviceType) const + { + QList<QByteArray> res; + + foreach(QObject *obj, loader()->instances(serviceType)) { + QMediaServiceSupportedDevicesInterface *iface = + qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj); + + if (iface) { + res.append(iface->devices(serviceType)); + } + } + + return res; + } + + QString deviceDescription(const QByteArray &serviceType, const QByteArray &device) + { + foreach(QObject *obj, loader()->instances(serviceType)) { + QMediaServiceSupportedDevicesInterface *iface = + qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj); + + if (iface) { + if (iface->devices(serviceType).contains(device)) + return iface->deviceDescription(serviceType, device); + } + } + + return QString(); + } +}; + +Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider); + +/*! + \class QMediaServiceProvider + \preliminary + \brief The QMediaServiceProvider class provides an abstract allocator for media services. +*/ + +/*! + \fn QMediaServiceProvider::requestService(const QByteArray &type, const QMediaServiceProviderHint &hint) + + Requests an instance of a \a type service which best matches the given \a hint. + + Returns a pointer to the requested service, or a null pointer if there is no suitable service. + + The returned service must be released with releaseService when it is finished with. +*/ + +/*! + \fn QMediaServiceProvider::releaseService(QMediaService *service) + + Releases a media \a service requested with requestService(). +*/ + +/*! + \fn QtMultimedia::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray &serviceType, const QString &mimeType, const QStringList& codecs, int flags) const + + Returns how confident a media service provider is that is can provide a \a serviceType + service that is able to play media of a specific \a mimeType that is encoded using the listed + \a codecs while adhearing to constraints identified in \a flags. +*/ +QtMultimedia::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray &serviceType, + const QString &mimeType, + const QStringList& codecs, + int flags) const +{ + Q_UNUSED(serviceType); + Q_UNUSED(mimeType); + Q_UNUSED(codecs); + Q_UNUSED(flags); + + return QtMultimedia::MaybeSupported; +} + +/*! + \fn QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const + + Returns a list of MIME types supported by the service provider for the specified \a serviceType. + + The resultant list is restricted to MIME types which can be supported given the constraints in \a flags. +*/ +QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const +{ + Q_UNUSED(serviceType); + Q_UNUSED(flags); + + return QStringList(); +} + +/*! + Returns the list of devices related to \a service type. +*/ +QList<QByteArray> QMediaServiceProvider::devices(const QByteArray &service) const +{ + Q_UNUSED(service); + return QList<QByteArray>(); +} + +/*! + Returns the description of \a device related to \a serviceType, + suitable to be displayed to user. +*/ +QString QMediaServiceProvider::deviceDescription(const QByteArray &serviceType, const QByteArray &device) +{ + Q_UNUSED(serviceType); + Q_UNUSED(device); + return QString(); +} + + +#ifdef QT_BUILD_INTERNAL + +static QMediaServiceProvider *qt_defaultMediaServiceProvider = 0; + +/*! + Sets a media service \a provider as the default. + + \internal +*/ +void QMediaServiceProvider::setDefaultServiceProvider(QMediaServiceProvider *provider) +{ + qt_defaultMediaServiceProvider = provider; +} + +#endif + +/*! + Returns a default provider of media services. +*/ +QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider() +{ +#ifdef QT_BUILD_INTERNAL + return qt_defaultMediaServiceProvider != 0 + ? qt_defaultMediaServiceProvider + : static_cast<QMediaServiceProvider *>(pluginProvider()); +#else + return pluginProvider(); +#endif +} + +/*! + \class QMediaServiceProviderPlugin + \preliminary + \brief The QMediaServiceProviderPlugin class interface provides an interface for QMediaService + plug-ins. + + A media service provider plug-in may implement one or more of + QMediaServiceSupportedFormatsInterface, QMediaServiceSupportedDevicesInterface, + and QMediaServiceFeaturesInterface to identify the features it supports. +*/ + +/*! + \fn QMediaServiceProviderPlugin::keys() const + + Returns a list of keys for media services a plug-in can create. +*/ + +/*! + \fn QMediaServiceProviderPlugin::create(const QString &key) + + Constructs a new instance of the QMediaService identified by \a key. + + The QMediaService returned must be destroyed with release(). +*/ + +/*! + \fn QMediaServiceProviderPlugin::release(QMediaService *service) + + Destroys a media \a service constructed with create(). +*/ + + +/*! + \class QMediaServiceSupportedFormatsInterface + \brief The QMediaServiceSupportedFormatsInterface class interface + identifies if a media service plug-in supports a media format. + + A QMediaServiceProviderPlugin may implement this interface. +*/ + +/*! + \fn QMediaServiceSupportedFormatsInterface::~QMediaServiceSupportedFormatsInterface() + + Destroys a media service supported formats interface. +*/ + +/*! + \fn QMediaServiceSupportedFormatsInterface::hasSupport(const QString &mimeType, const QStringList& codecs) const + + Returns the level of support a media service plug-in has for a \a mimeType and set of \a codecs. +*/ + +/*! + \fn QMediaServiceSupportedFormatsInterface::supportedMimeTypes() const + + Returns a list of MIME types supported by the media service plug-in. +*/ + +/*! + \class QMediaServiceSupportedDevicesInterface + \brief The QMediaServiceSupportedDevicesInterface class interface + identifies the devices supported by a media service plug-in. + + A QMediaServiceProviderPlugin may implement this interface. +*/ + +/*! + \fn QMediaServiceSupportedDevicesInterface::~QMediaServiceSupportedDevicesInterface() + + Destroys a media service supported devices interface. +*/ + +/*! + \fn QMediaServiceSupportedDevicesInterface::devices(const QByteArray &service) const + + Returns a list of devices supported by a plug-in \a service. +*/ + +/*! + \fn QMediaServiceSupportedDevicesInterface::deviceDescription(const QByteArray &service, const QByteArray &device) + + Returns a description of a \a device supported by a plug-in \a service. +*/ + +/*! + \class QMediaServiceFeaturesInterface + \brief The QMediaServiceFeaturesInterface class interface identifies + features supported by a media service plug-in. + + A QMediaServiceProviderPlugin may implement this interface. +*/ + +/*! + \fn QMediaServiceFeaturesInterface::~QMediaServiceFeaturesInterface() + + Destroys a media service features interface. +*/ +/*! + \fn QMediaServiceFeaturesInterface::supportedFeatures(const QByteArray &service) const + + Returns a set of features supported by a plug-in \a service. +*/ + +#include "moc_qmediaserviceprovider.cpp" +#include "moc_qmediaserviceproviderplugin.cpp" diff --git a/src/multimedia/base/qmediaserviceprovider.h b/src/multimedia/base/qmediaserviceprovider.h new file mode 100644 index 0000000..2ee0ae4 --- /dev/null +++ b/src/multimedia/base/qmediaserviceprovider.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIASERVICEPROVIDER_H +#define QMEDIASERVICEPROVIDER_H + +#include <QtCore/qobject.h> +#include <QtCore/qshareddata.h> + +#include <QtMultimedia/qtmedianamespace.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QMediaService; + +class QMediaServiceProviderHintPrivate; +class Q_MULTIMEDIA_EXPORT QMediaServiceProviderHint +{ +public: + enum Type { Null, ContentType, Device, SupportedFeatures }; + + enum Feature { + LowLatencyPlayback = 0x01, + RecordingSupport = 0x02 + }; + Q_DECLARE_FLAGS(Features, Feature) + + QMediaServiceProviderHint(); + QMediaServiceProviderHint(const QString &mimeType, const QStringList& codecs); + QMediaServiceProviderHint(const QByteArray &device); + QMediaServiceProviderHint(Features features); + QMediaServiceProviderHint(const QMediaServiceProviderHint &other); + ~QMediaServiceProviderHint(); + + QMediaServiceProviderHint& operator=(const QMediaServiceProviderHint &other); + + bool operator == (const QMediaServiceProviderHint &other) const; + bool operator != (const QMediaServiceProviderHint &other) const; + + bool isNull() const; + + Type type() const; + + QString mimeType() const; + QStringList codecs() const; + + QByteArray device() const; + + Features features() const; + + //to be extended, if necessary + +private: + QSharedDataPointer<QMediaServiceProviderHintPrivate> d; +}; + +class Q_MULTIMEDIA_EXPORT QMediaServiceProvider : public QObject +{ + Q_OBJECT + +public: + virtual QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &hint = QMediaServiceProviderHint()) = 0; + virtual void releaseService(QMediaService *service) = 0; + + virtual QtMultimedia::SupportEstimate hasSupport(const QByteArray &serviceType, + const QString &mimeType, + const QStringList& codecs, + int flags = 0) const; + virtual QStringList supportedMimeTypes(const QByteArray &serviceType, int flags = 0) const; + + virtual QList<QByteArray> devices(const QByteArray &serviceType) const; + virtual QString deviceDescription(const QByteArray &serviceType, const QByteArray &device); + + static QMediaServiceProvider* defaultServiceProvider(); + +#ifdef QT_BUILD_INTERNAL + static void setDefaultServiceProvider(QMediaServiceProvider *provider); +#endif +}; + +/*! + Service with support for media playback + Required Controls: QMediaPlayerControl + Optional Controls: QMediaPlaylistControl, QAudioDeviceControl + Video Output Controls (used by QWideoWidget and QGraphicsVideoItem): + Required: QVideoOutputControl + Optional: QVideoWindowControl, QVideoRendererControl, QVideoWidgetControl +*/ +#define Q_MEDIASERVICE_MEDIAPLAYER "com.nokia.qt.mediaplayer" + +/*! + Service with support for recording from audio sources + Required Controls: QAudioDeviceControl + Recording Controls (QMediaRecorder): + Required: QMediaRecorderControl + Recommended: QAudioEncoderControl + Optional: QMediaContainerControl +*/ +#define Q_MEDIASERVICE_AUDIOSOURCE "com.nokia.qt.audiosource" + +/*! + Service with support for camera use. + Required Controls: QCameraControl + Optional Controls: QCameraExposureControl, QCameraFocusControl, QImageProcessingControl + Still Capture Controls: QImageCaptureControl + Recording Controls (QMediaRecorder): + Required: QMediaRecorderControl + Recommended: QAudioEncoderControl, QVideoEncoderControl, QMediaContainerControl + Viewfinder Video Output Controls (used by QWideoWidget and QGraphicsVideoItem): + Required: QVideoOutputControl + Optional: QVideoWindowControl, QVideoRendererControl, QVideoWidgetControl +*/ +#define Q_MEDIASERVICE_CAMERA "com.nokia.qt.camera" + +/*! + Service with support for radio tuning. + Required Controls: QRadioTunerControl + Recording Controls (Optional, used by QMediaRecorder): + Required: QMediaRecorderControl + Recommended: QAudioEncoderControl + Optional: QMediaContainerControl +*/ +#define Q_MEDIASERVICE_RADIO "com.nokia.qt.radio" + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIASERVICEPROVIDER_H diff --git a/src/multimedia/base/qmediaserviceproviderplugin.h b/src/multimedia/base/qmediaserviceproviderplugin.h new file mode 100644 index 0000000..b1e728b --- /dev/null +++ b/src/multimedia/base/qmediaserviceproviderplugin.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIASERVICEPROVIDERPLUGIN_H +#define QMEDIASERVICEPROVIDERPLUGIN_H + +#include <QtCore/qstringlist.h> +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> + +#include <QtMultimedia/qmediaserviceprovider.h> + +#ifdef Q_MOC_RUN +# pragma Q_MOC_EXPAND_MACROS +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMediaService; + + +struct Q_MULTIMEDIA_EXPORT QMediaServiceProviderFactoryInterface : public QFactoryInterface +{ + virtual QStringList keys() const = 0; + virtual QMediaService* create(QString const& key) = 0; + virtual void release(QMediaService *service) = 0; +}; + +#define QMediaServiceProviderFactoryInterface_iid \ + "com.nokia.Qt.QMediaServiceProviderFactoryInterface/1.0" +Q_DECLARE_INTERFACE(QMediaServiceProviderFactoryInterface, QMediaServiceProviderFactoryInterface_iid) + + +struct Q_MULTIMEDIA_EXPORT QMediaServiceSupportedFormatsInterface +{ + virtual ~QMediaServiceSupportedFormatsInterface() {} + virtual QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const = 0; + virtual QStringList supportedMimeTypes() const = 0; +}; + +#define QMediaServiceSupportedFormatsInterface_iid \ + "com.nokia.Qt.QMediaServiceSupportedFormatsInterface/1.0" +Q_DECLARE_INTERFACE(QMediaServiceSupportedFormatsInterface, QMediaServiceSupportedFormatsInterface_iid) + + +struct Q_MULTIMEDIA_EXPORT QMediaServiceSupportedDevicesInterface +{ + virtual ~QMediaServiceSupportedDevicesInterface() {} + virtual QList<QByteArray> devices(const QByteArray &service) const = 0; + virtual QString deviceDescription(const QByteArray &service, const QByteArray &device) = 0; +}; + +#define QMediaServiceSupportedDevicesInterface_iid \ + "com.nokia.Qt.QMediaServiceSupportedDevicesInterface/1.0" +Q_DECLARE_INTERFACE(QMediaServiceSupportedDevicesInterface, QMediaServiceSupportedDevicesInterface_iid) + + +struct Q_MULTIMEDIA_EXPORT QMediaServiceFeaturesInterface +{ + virtual ~QMediaServiceFeaturesInterface() {} + virtual QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const = 0; +}; + +#define QMediaServiceFeaturesInterface_iid \ + "com.nokia.Qt.QMediaServiceFeaturesInterface/1.0" +Q_DECLARE_INTERFACE(QMediaServiceFeaturesInterface, QMediaServiceFeaturesInterface_iid) + +class Q_MULTIMEDIA_EXPORT QMediaServiceProviderPlugin : public QObject, public QMediaServiceProviderFactoryInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceProviderFactoryInterface:QFactoryInterface) + +public: + virtual QStringList keys() const = 0; + virtual QMediaService* create(const QString& key) = 0; + virtual void release(QMediaService *service) = 0; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIASERVICEPROVIDERPLUGIN_H diff --git a/src/multimedia/base/qmediatimerange.cpp b/src/multimedia/base/qmediatimerange.cpp new file mode 100644 index 0000000..0ca1948 --- /dev/null +++ b/src/multimedia/base/qmediatimerange.cpp @@ -0,0 +1,706 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qmediatimerange.h> + + +QT_BEGIN_NAMESPACE + +/*! + \class QMediaTimeInterval + \brief The QMediaTimeInterval class represents a time interval with integer precision. + \ingroup multimedia + + An interval is specified by an inclusive start() and end() time. + These must be set in the constructor, as this is an immutable class. + The specific units of time represented by the class have not been defined - + it is suitable for any times which can be represented by a signed 64 bit integer. + + The isNormal() method determines if a time interval is normal + (a normal time interval has start() <= end()). An abnormal interval can be converted + in to a normal interval by calling the normalized() method. + + The contains() method determines if a specified time lies within + the time interval. + + The translated() method returns a time interval which has been translated + forwards or backwards through time by a specified offset. + + \sa QMediaTimeRange +*/ + +/*! + \fn QMediaTimeInterval::QMediaTimeInterval() + + Constructs an empty interval. +*/ +QMediaTimeInterval::QMediaTimeInterval() + : s(0) + , e(0) +{ + +} + +/*! + \fn QMediaTimeInterval::QMediaTimeInterval(qint64 start, qint64 end) + + Constructs an interval with the specified \a start and \a end times. +*/ +QMediaTimeInterval::QMediaTimeInterval(qint64 start, qint64 end) + : s(start) + , e(end) +{ + +} + +/*! + \fn QMediaTimeInterval::QMediaTimeInterval(const QMediaTimeInterval &other) + + Constructs an interval by taking a copy of \a other. +*/ +QMediaTimeInterval::QMediaTimeInterval(const QMediaTimeInterval &other) + : s(other.s) + , e(other.e) +{ + +} + +/*! + \fn QMediaTimeInterval::start() const + + Returns the start time of the interval. + + \sa end() +*/ +qint64 QMediaTimeInterval::start() const +{ + return s; +} + +/*! + \fn QMediaTimeInterval::end() const + + Returns the end time of the interval. + + \sa start() +*/ +qint64 QMediaTimeInterval::end() const +{ + return e; +} + +/*! + \fn QMediaTimeInterval::contains(qint64 time) const + + Returns true if the time interval contains the specified \a time. + That is, start() <= time <= end(). +*/ +bool QMediaTimeInterval::contains(qint64 time) const +{ + return isNormal() ? (s <= time && time <= e) + : (e <= time && time <= s); +} + +/*! + \fn QMediaTimeInterval::isNormal() const + + Returns true if this time interval is normal. + A normal time interval has start() <= end(). + + \sa normalized() +*/ +bool QMediaTimeInterval::isNormal() const +{ + return s <= e; +} + +/*! + \fn QMediaTimeInterval::normalized() const + + Returns a normalized version of this interval. + + If the start() time of the interval is greater than the end() time, + then the returned interval has the start and end times swapped. +*/ +QMediaTimeInterval QMediaTimeInterval::normalized() const +{ + if(s > e) + return QMediaTimeInterval(e, s); + + return *this; +} + +/*! + \fn QMediaTimeInterval::translated(qint64 offset) const + + Returns a copy of this time interval, translated by a value of \a offset. + An interval can be moved forward through time with a positive offset, or backward + through time with a negative offset. +*/ +QMediaTimeInterval QMediaTimeInterval::translated(qint64 offset) const +{ + return QMediaTimeInterval(s + offset, e + offset); +} + +/*! + \fn operator==(const QMediaTimeInterval &a, const QMediaTimeInterval &b) + \relates QMediaTimeRange + + Returns true if \a a is exactly equal to \a b. +*/ +bool operator==(const QMediaTimeInterval &a, const QMediaTimeInterval &b) +{ + return a.start() == b.start() && a.end() == b.end(); +} + +/*! + \fn operator!=(const QMediaTimeInterval &a, const QMediaTimeInterval &b) + \relates QMediaTimeRange + + Returns true if \a a is not exactly equal to \a b. +*/ +bool operator!=(const QMediaTimeInterval &a, const QMediaTimeInterval &b) +{ + return a.start() != b.start() || a.end() != b.end(); +} + +class QMediaTimeRangePrivate : public QSharedData +{ +public: + + QMediaTimeRangePrivate(); + QMediaTimeRangePrivate(const QMediaTimeRangePrivate &other); + QMediaTimeRangePrivate(const QMediaTimeInterval &interval); + + QList<QMediaTimeInterval> intervals; + + void addInterval(const QMediaTimeInterval &interval); + void removeInterval(const QMediaTimeInterval &interval); +}; + +QMediaTimeRangePrivate::QMediaTimeRangePrivate() + : QSharedData() +{ + +} + +QMediaTimeRangePrivate::QMediaTimeRangePrivate(const QMediaTimeRangePrivate &other) + : QSharedData() + , intervals(other.intervals) +{ + +} + +QMediaTimeRangePrivate::QMediaTimeRangePrivate(const QMediaTimeInterval &interval) + : QSharedData() +{ + if(interval.isNormal()) + intervals << interval; +} + +void QMediaTimeRangePrivate::addInterval(const QMediaTimeInterval &interval) +{ + // Handle normalized intervals only + if(!interval.isNormal()) + return; + + // Find a place to insert the interval + int i; + for (i = 0; i < intervals.count(); i++) { + // Insert before this element + if(interval.s < intervals[i].s) { + intervals.insert(i, interval); + break; + } + } + + // Interval needs to be added to the end of the list + if (i == intervals.count()) + intervals.append(interval); + + // Do we need to correct the element before us? + if(i > 0 && intervals[i - 1].e >= interval.s - 1) + i--; + + // Merge trailing ranges + while (i < intervals.count() - 1 + && intervals[i].e >= intervals[i + 1].s - 1) { + intervals[i].e = qMax(intervals[i].e, intervals[i + 1].e); + intervals.removeAt(i + 1); + } +} + +void QMediaTimeRangePrivate::removeInterval(const QMediaTimeInterval &interval) +{ + // Handle normalized intervals only + if(!interval.isNormal()) + return; + + for (int i = 0; i < intervals.count(); i++) { + QMediaTimeInterval r = intervals[i]; + + if (r.e < interval.s) { + // Before the removal interval + continue; + } else if (interval.e < r.s) { + // After the removal interval - stop here + break; + } else if (r.s < interval.s && interval.e < r.e) { + // Split case - a single range has a chunk removed + intervals[i].e = interval.s -1; + addInterval(QMediaTimeInterval(interval.e + 1, r.e)); + break; + } else if (r.s < interval.s) { + // Trimming Tail Case + intervals[i].e = interval.s - 1; + } else if (interval.e < r.e) { + // Trimming Head Case - we can stop after this + intervals[i].s = interval.e + 1; + break; + } else { + // Complete coverage case + intervals.removeAt(i); + --i; + } + } +} + +/*! + \class QMediaTimeRange + \brief The QMediaTimeRange class represents a set of zero or more disjoint + time intervals. + \ingroup multimedia + + \reentrant + + The earliestTime(), latestTime(), intervals() and isEmpty() + methods are used to get information about the current time range. + + The addInterval(), removeInterval() and clear() methods are used to modify + the current time range. + + When adding or removing intervals from the time range, existing intervals + within the range may be expanded, trimmed, deleted, merged or split to ensure + that all intervals within the time range remain distinct and disjoint. As a + consequence, all intervals added or removed from a time range must be + \l{QMediaTimeInterval::isNormal()}{normal}. + + \sa QMediaTimeInterval +*/ + +/*! + \fn QMediaTimeRange::QMediaTimeRange() + + Constructs an empty time range. +*/ +QMediaTimeRange::QMediaTimeRange() + : d(new QMediaTimeRangePrivate) +{ + +} + +/*! + \fn QMediaTimeRange::QMediaTimeRange(qint64 start, qint64 end) + + Constructs a time range that contains an initial interval from + \a start to \a end inclusive. + + If the interval is not \l{QMediaTimeInterval::isNormal()}{normal}, + the resulting time range will be empty. + + \sa addInterval() +*/ +QMediaTimeRange::QMediaTimeRange(qint64 start, qint64 end) + : d(new QMediaTimeRangePrivate(QMediaTimeInterval(start, end))) +{ + +} + +/*! + \fn QMediaTimeRange::QMediaTimeRange(const QMediaTimeInterval &interval) + + Constructs a time range that contains an intitial interval, \a interval. + + If \a interval is not \l{QMediaTimeInterval::isNormal()}{normal}, + the resulting time range will be empty. + + \sa addInterval() +*/ +QMediaTimeRange::QMediaTimeRange(const QMediaTimeInterval &interval) + : d(new QMediaTimeRangePrivate(interval)) +{ + +} + +/*! + \fn QMediaTimeRange::QMediaTimeRange(const QMediaTimeRange &range) + + Constructs a time range by copying another time \a range. +*/ +QMediaTimeRange::QMediaTimeRange(const QMediaTimeRange &range) + : d(range.d) +{ + +} + +/*! + \fn QMediaTimeRange::~QMediaTimeRange() + + Destructor. +*/ +QMediaTimeRange::~QMediaTimeRange() +{ + +} + +/*! + \fn QMediaTimeRange::operator=(const QMediaTimeRange &other) + + Takes a copy of the \a other time range and returns itself. +*/ +QMediaTimeRange &QMediaTimeRange::operator=(const QMediaTimeRange &other) +{ + d = other.d; + return *this; +} + +/*! + \fn QMediaTimeRange::operator=(const QMediaTimeInterval &interval) + + Sets the time range to a single continuous interval, \a interval. +*/ +QMediaTimeRange &QMediaTimeRange::operator=(const QMediaTimeInterval &interval) +{ + d = new QMediaTimeRangePrivate(interval); + return *this; +} + +/*! + \fn QMediaTimeRange::earliestTime() const + + Returns the earliest time within the time range. + + For empty time ranges, this value is equal to zero. + + \sa latestTime() +*/ +qint64 QMediaTimeRange::earliestTime() const +{ + if (!d->intervals.isEmpty()) + return d->intervals[0].s; + + return 0; +} + +/*! + \fn QMediaTimeRange::latestTime() const + + Returns the latest time within the time range. + + For empty time ranges, this value is equal to zero. + + \sa earliestTime() +*/ +qint64 QMediaTimeRange::latestTime() const +{ + if (!d->intervals.isEmpty()) + return d->intervals[d->intervals.count() - 1].e; + + return 0; +} + +/*! + \fn QMediaTimeRange::addInterval(qint64 start, qint64 end) + \overload + + Adds the interval specified by \a start and \a end + to the time range. + + \sa addInterval() +*/ +void QMediaTimeRange::addInterval(qint64 start, qint64 end) +{ + d->addInterval(QMediaTimeInterval(start, end)); +} + +/*! + \fn QMediaTimeRange::addInterval(const QMediaTimeInterval &interval) + + Adds the specified \a interval to the time range. + + Adding intervals which are not \l{QMediaTimeInterval::isNormal()}{normal} + is invalid, and will be ignored. + + If the specified interval is adjacent to, or overlaps existing + intervals within the time range, these intervals will be merged. + + This operation takes \l{linear time} + + \sa removeInterval() +*/ +void QMediaTimeRange::addInterval(const QMediaTimeInterval &interval) +{ + d->addInterval(interval); +} + +/*! + \fn QMediaTimeRange::addTimeRange(const QMediaTimeRange &range) + + Adds each of the intervals in \a range to this time range. + + Equivalent to calling addInterval() for each interval in \a range. +*/ +void QMediaTimeRange::addTimeRange(const QMediaTimeRange &range) +{ + foreach(const QMediaTimeInterval &i, range.intervals()) { + d->addInterval(i); + } +} + +/*! + \fn QMediaTimeRange::removeInterval(qint64 start, qint64 end) + \overload + + Removes the interval specified by \a start and \a end + from the time range. + + \sa removeInterval() +*/ +void QMediaTimeRange::removeInterval(qint64 start, qint64 end) +{ + d->removeInterval(QMediaTimeInterval(start, end)); +} + +/*! + \fn QMediaTimeRange::removeInterval(const QMediaTimeInterval &interval) + + Removes the specified \a interval from the time range. + + Removing intervals which are not \l{QMediaTimeInterval::isNormal()}{normal} + is invalid, and will be ignored. + + Intervals within the time range will be trimmed, split or deleted + such that no intervals within the time range include any part of the + target interval. + + This operation takes \l{linear time} + + \sa addInterval() +*/ +void QMediaTimeRange::removeInterval(const QMediaTimeInterval &interval) +{ + d->removeInterval(interval); +} + +/*! + \fn QMediaTimeRange::removeTimeRange(const QMediaTimeRange &range) + + Removes each of the intervals in \a range from this time range. + + Equivalent to calling removeInterval() for each interval in \a range. +*/ +void QMediaTimeRange::removeTimeRange(const QMediaTimeRange &range) +{ + foreach(const QMediaTimeInterval &i, range.intervals()) { + d->removeInterval(i); + } +} + +/*! + \fn QMediaTimeRange::operator+=(const QMediaTimeRange &other) + + Adds each interval in \a other to the time range and returns the result. +*/ +QMediaTimeRange& QMediaTimeRange::operator+=(const QMediaTimeRange &other) +{ + addTimeRange(other); + return *this; +} + +/*! + \fn QMediaTimeRange::operator+=(const QMediaTimeInterval &interval) + + Adds the specified \a interval to the time range and returns the result. +*/ +QMediaTimeRange& QMediaTimeRange::operator+=(const QMediaTimeInterval &interval) +{ + addInterval(interval); + return *this; +} + +/*! + \fn QMediaTimeRange::operator-=(const QMediaTimeRange &other) + + Removes each interval in \a other from the time range and returns the result. +*/ +QMediaTimeRange& QMediaTimeRange::operator-=(const QMediaTimeRange &other) +{ + removeTimeRange(other); + return *this; +} + +/*! + \fn QMediaTimeRange::operator-=(const QMediaTimeInterval &interval) + + Removes the specified \a interval from the time range and returns the result. +*/ +QMediaTimeRange& QMediaTimeRange::operator-=(const QMediaTimeInterval &interval) +{ + removeInterval(interval); + return *this; +} + +/*! + \fn QMediaTimeRange::clear() + + Removes all intervals from the time range. + + \sa removeInterval() +*/ +void QMediaTimeRange::clear() +{ + d->intervals.clear(); +} + +/*! + \fn QMediaTimeRange::intervals() const + + Returns the list of intervals covered by this time range. +*/ +QList<QMediaTimeInterval> QMediaTimeRange::intervals() const +{ + return d->intervals; +} + +/*! + \fn QMediaTimeRange::isEmpty() const + + Returns true if there are no intervals within the time range. + + \sa intervals() +*/ +bool QMediaTimeRange::isEmpty() const +{ + return d->intervals.isEmpty(); +} + +/*! + \fn QMediaTimeRange::isContinuous() const + + Returns true if the time range consists of a continuous interval. + That is, there is one or fewer disjoint intervals within the time range. +*/ +bool QMediaTimeRange::isContinuous() const +{ + return (d->intervals.count() <= 1); +} + +/*! + \fn QMediaTimeRange::contains(qint64 time) const + + Returns true if the specified \a time lies within the time range. +*/ +bool QMediaTimeRange::contains(qint64 time) const +{ + for (int i = 0; i < d->intervals.count(); i++) { + if (d->intervals[i].contains(time)) + return true; + + if (time < d->intervals[i].s) + break; + } + + return false; +} + +/*! + \fn operator==(const QMediaTimeRange &a, const QMediaTimeRange &b) + \relates QMediaTimeRange + + Returns true if all intervals in \a a are present in \a b. +*/ +bool operator==(const QMediaTimeRange &a, const QMediaTimeRange &b) +{ + if (a.intervals().count() != b.intervals().count()) + return false; + + for (int i = 0; i < a.intervals().count(); i++) + { + if(a.intervals()[i] != b.intervals()[i]) + return false; + } + + return true; +} + +/*! + \fn operator!=(const QMediaTimeRange &a, const QMediaTimeRange &b) + \relates QMediaTimeRange + + Returns true if one or more intervals in \a a are not present in \a b. +*/ +bool operator!=(const QMediaTimeRange &a, const QMediaTimeRange &b) +{ + return !(a == b); +} + +/*! + \fn operator+(const QMediaTimeRange &r1, const QMediaTimeRange &r2) + + Returns a time range containing the union between \a r1 and \a r2. + */ +QMediaTimeRange operator+(const QMediaTimeRange &r1, const QMediaTimeRange &r2) +{ + return (QMediaTimeRange(r1) += r2); +} + +/*! + \fn operator-(const QMediaTimeRange &r1, const QMediaTimeRange &r2) + + Returns a time range containing \a r2 subtracted from \a r1. + */ +QMediaTimeRange operator-(const QMediaTimeRange &r1, const QMediaTimeRange &r2) +{ + return (QMediaTimeRange(r1) -= r2); +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmediatimerange.h b/src/multimedia/base/qmediatimerange.h new file mode 100644 index 0000000..a65629e --- /dev/null +++ b/src/multimedia/base/qmediatimerange.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIATIMERANGE_H +#define QMEDIATIMERANGE_H + +#include <QtCore/qshareddata.h> +#include <QtMultimedia/qtmedianamespace.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMediaTimeRangePrivate; + +class Q_MULTIMEDIA_EXPORT QMediaTimeInterval +{ +public: + QMediaTimeInterval(); + QMediaTimeInterval(qint64 start, qint64 end); + QMediaTimeInterval(const QMediaTimeInterval&); + + qint64 start() const; + qint64 end() const; + + bool contains(qint64 time) const; + + bool isNormal() const; + QMediaTimeInterval normalized() const; + QMediaTimeInterval translated(qint64 offset) const; + +private: + friend class QMediaTimeRangePrivate; + friend class QMediaTimeRange; + + qint64 s; + qint64 e; +}; + +Q_MULTIMEDIA_EXPORT bool operator==(const QMediaTimeInterval&, const QMediaTimeInterval&); +Q_MULTIMEDIA_EXPORT bool operator!=(const QMediaTimeInterval&, const QMediaTimeInterval&); + +class Q_MULTIMEDIA_EXPORT QMediaTimeRange +{ +public: + + QMediaTimeRange(); + QMediaTimeRange(qint64 start, qint64 end); + QMediaTimeRange(const QMediaTimeInterval&); + QMediaTimeRange(const QMediaTimeRange &range); + ~QMediaTimeRange(); + + QMediaTimeRange &operator=(const QMediaTimeRange&); + QMediaTimeRange &operator=(const QMediaTimeInterval&); + + qint64 earliestTime() const; + qint64 latestTime() const; + + QList<QMediaTimeInterval> intervals() const; + bool isEmpty() const; + bool isContinuous() const; + + bool contains(qint64 time) const; + + void addInterval(qint64 start, qint64 end); + void addInterval(const QMediaTimeInterval &interval); + void addTimeRange(const QMediaTimeRange&); + + void removeInterval(qint64 start, qint64 end); + void removeInterval(const QMediaTimeInterval &interval); + void removeTimeRange(const QMediaTimeRange&); + + QMediaTimeRange& operator+=(const QMediaTimeRange&); + QMediaTimeRange& operator+=(const QMediaTimeInterval&); + QMediaTimeRange& operator-=(const QMediaTimeRange&); + QMediaTimeRange& operator-=(const QMediaTimeInterval&); + + void clear(); + +private: + QSharedDataPointer<QMediaTimeRangePrivate> d; +}; + +Q_MULTIMEDIA_EXPORT bool operator==(const QMediaTimeRange&, const QMediaTimeRange&); +Q_MULTIMEDIA_EXPORT bool operator!=(const QMediaTimeRange&, const QMediaTimeRange&); +Q_MULTIMEDIA_EXPORT QMediaTimeRange operator+(const QMediaTimeRange&, const QMediaTimeRange&); +Q_MULTIMEDIA_EXPORT QMediaTimeRange operator-(const QMediaTimeRange&, const QMediaTimeRange&); + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIATIMERANGE_H diff --git a/src/multimedia/base/qmetadatacontrol.cpp b/src/multimedia/base/qmetadatacontrol.cpp new file mode 100644 index 0000000..3ecbe8d --- /dev/null +++ b/src/multimedia/base/qmetadatacontrol.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qmetadatacontrol.h> +#include "qmediacontrol_p.h" + + +QT_BEGIN_NAMESPACE + + +/*! + \class QMetaDataControl + \ingroup multimedia-serv + + \preliminary + \brief The QMetaDataControl class provides access to the meta-data of a + QMediaService's media. + + If a QMediaService can provide read or write access to the meta-data of + its current media it will implement QMetaDataControl. This control + provides functions for both retrieving and setting meta-data values. + Meta-data may be addressed by the well defined keys in the + QtMultimedia::MetaData enumeration using the metaData() functions, or by + string keys using the extendedMetaData() functions. + + The functionality provided by this control is exposed to application + code by the meta-data members of QMediaObject, and so meta-data access + is potentially available in any of the media object classes. Any media + service may implement QMetaDataControl. + + The interface name of QMetaDataControl is \c com.nokia.Qt.QMetaDataControl/1.0 as + defined in QMetaDataControl_iid. + + \sa QMediaService::control(), QMediaObject +*/ + +/*! + \macro QMetaDataControl_iid + + \c com.nokia.Qt.QMetaDataControl/1.0 + + Defines the interface name of the QMetaDataControl class. + + \relates QMetaDataControl +*/ + +/*! + Construct a QMetaDataControl with \a parent. This class is meant as a base class + for service specific meta data providers so this constructor is protected. +*/ + +QMetaDataControl::QMetaDataControl(QObject *parent): + QMediaControl(*new QMediaControlPrivate, parent) +{ +} + +/*! + Destroy the meta-data object. +*/ + +QMetaDataControl::~QMetaDataControl() +{ +} + +/*! + \fn bool QMetaDataControl::isMetaDataAvailable() const + + Identifies if meta-data is available from a media service. + + Returns true if the meta-data is available and false otherwise. +*/ + +/*! + \fn bool QMetaDataControl::isWritable() const + + Identifies if a media service's meta-data can be edited. + + Returns true if the meta-data is writable and false otherwise. +*/ + +/*! + \fn QVariant QMetaDataControl::metaData(QtMultimedia::MetaData key) const + + Returns the meta-data for the given \a key. +*/ + +/*! + \fn void QMetaDataControl::setMetaData(QtMultimedia::MetaData key, const QVariant &value) + + Sets the \a value of the meta-data element with the given \a key. +*/ + +/*! + \fn QMetaDataControl::availableMetaData() const + + Returns a list of keys there is meta-data available for. +*/ + +/*! + \fn QMetaDataControl::extendedMetaData(const QString &key) const + + Returns the metaData for an abitrary string \a key. + + The valid selection of keys for extended meta-data is determined by the provider and the meaning + and type may differ between providers. +*/ + +/*! + \fn QMetaDataControl::setExtendedMetaData(const QString &key, const QVariant &value) + + Change the value of the meta-data element with an abitrary string \a key to \a value. + + The valid selection of keys for extended meta-data is determined by the provider and the meaning + and type may differ between providers. +*/ + +/*! + \fn QMetaDataControl::availableExtendedMetaData() const + + Returns a list of keys there is extended meta-data available for. +*/ + + +/*! + \fn void QMetaDataControl::metaDataChanged() + + Signal the changes of meta-data. +*/ + +/*! + \fn void QMetaDataControl::metaDataAvailableChanged(bool available) + + Signal the availability of meta-data has changed, \a available will + be true if the multimedia object has meta-data. +*/ + +/*! + \fn void QMetaDataControl::writableChanged(bool writable) + + Signal a change in the writable status of meta-data, \a writable will be + true if meta-data elements can be added or adjusted. +*/ + +#include "moc_qmetadatacontrol.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qmetadatacontrol.h b/src/multimedia/base/qmetadatacontrol.h new file mode 100644 index 0000000..8e18c16 --- /dev/null +++ b/src/multimedia/base/qmetadatacontrol.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMETADATACONTROL_H +#define QMETADATACONTROL_H + +#include <QtMultimedia/qmediacontrol.h> +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediaresource.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class Q_MULTIMEDIA_EXPORT QMetaDataControl : public QMediaControl +{ + Q_OBJECT + +public: + ~QMetaDataControl(); + + virtual bool isWritable() const = 0; + virtual bool isMetaDataAvailable() const = 0; + + virtual QVariant metaData(QtMultimedia::MetaData key) const = 0; + virtual void setMetaData(QtMultimedia::MetaData key, const QVariant &value) = 0; + virtual QList<QtMultimedia::MetaData> availableMetaData() const = 0; + + virtual QVariant extendedMetaData(const QString &key) const = 0; + virtual void setExtendedMetaData(const QString &key, const QVariant &value) = 0; + virtual QStringList availableExtendedMetaData() const = 0; + +Q_SIGNALS: + void metaDataChanged(); + + void writableChanged(bool writable); + void metaDataAvailableChanged(bool available); + +protected: + QMetaDataControl(QObject *parent = 0); +}; + +#define QMetaDataControl_iid "com.nokia.Qt.QMetaDataControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QMetaDataControl, QMetaDataControl_iid) + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif // QMETADATAPROVIDER_H diff --git a/src/multimedia/base/qpaintervideosurface.cpp b/src/multimedia/base/qpaintervideosurface.cpp new file mode 100644 index 0000000..97fddc9 --- /dev/null +++ b/src/multimedia/base/qpaintervideosurface.cpp @@ -0,0 +1,1568 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpaintervideosurface_p.h" + +#include <qmath.h> + +#include <qpainter.h> +#include <qvariant.h> +#include <QtMultimedia/qvideosurfaceformat.h> + +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) +#include <qglshaderprogram.h> +#endif + +#include <QtDebug> + + +QT_BEGIN_NAMESPACE + +class QVideoSurfacePainter +{ +public: + virtual ~QVideoSurfacePainter(); + + virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const = 0; + + virtual bool isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const = 0; + + virtual QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) = 0; + virtual void stop() = 0; + + virtual QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame) = 0; + + virtual QAbstractVideoSurface::Error paint( + const QRectF &target, QPainter *painter, const QRectF &source) = 0; + + virtual void updateColors(int brightness, int contrast, int hue, int saturation) = 0; +}; + +QVideoSurfacePainter::~QVideoSurfacePainter() +{ +} + +class QVideoSurfaceRasterPainter : public QVideoSurfacePainter +{ +public: + QVideoSurfaceRasterPainter(); + + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const; + + bool isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const; + + QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format); + void stop(); + + QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame); + + QAbstractVideoSurface::Error paint( + const QRectF &target, QPainter *painter, const QRectF &source); + + void updateColors(int brightness, int contrast, int hue, int saturation); + +private: + QList<QVideoFrame::PixelFormat> m_imagePixelFormats; + QVideoFrame m_frame; + QSize m_imageSize; + QImage::Format m_imageFormat; + QVideoSurfaceFormat::Direction m_scanLineDirection; +}; + +QVideoSurfaceRasterPainter::QVideoSurfaceRasterPainter() + : m_imageFormat(QImage::Format_Invalid) + , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom) +{ + m_imagePixelFormats + << QVideoFrame::Format_RGB32 +#ifndef QT_OPENGL_ES // The raster formats should be a subset of the GL formats. + << QVideoFrame::Format_RGB24 +#endif + << QVideoFrame::Format_ARGB32 + << QVideoFrame::Format_RGB565; +} + +QList<QVideoFrame::PixelFormat> QVideoSurfaceRasterPainter::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + return handleType == QAbstractVideoBuffer::NoHandle + ? m_imagePixelFormats + : QList<QVideoFrame::PixelFormat>(); +} + +bool QVideoSurfaceRasterPainter::isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *) const +{ + return format.handleType() == QAbstractVideoBuffer::NoHandle + && m_imagePixelFormats.contains(format.pixelFormat()) + && !format.frameSize().isEmpty(); +} + +QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::start(const QVideoSurfaceFormat &format) +{ + m_frame = QVideoFrame(); + m_imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); + m_imageSize = format.frameSize(); + m_scanLineDirection = format.scanLineDirection(); + + return format.handleType() == QAbstractVideoBuffer::NoHandle + && m_imageFormat != QImage::Format_Invalid + && !m_imageSize.isEmpty() + ? QAbstractVideoSurface::NoError + : QAbstractVideoSurface::UnsupportedFormatError; +} + +void QVideoSurfaceRasterPainter::stop() +{ + m_frame = QVideoFrame(); +} + +QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::setCurrentFrame(const QVideoFrame &frame) +{ + m_frame = frame; + + return QAbstractVideoSurface::NoError; +} + +QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::paint( + const QRectF &target, QPainter *painter, const QRectF &source) +{ + if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) { + QImage image( + m_frame.bits(), + m_imageSize.width(), + m_imageSize.height(), + m_frame.bytesPerLine(), + m_imageFormat); + + if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) { + const QTransform oldTransform = painter->transform(); + + painter->scale(1, -1); + painter->translate(0, -target.bottom()); + painter->drawImage( + QRectF(target.x(), 0, target.width(), target.height()), image, source); + painter->setTransform(oldTransform); + } else { + painter->drawImage(target, image, source); + } + + m_frame.unmap(); + } else if (m_frame.isValid()) { + return QAbstractVideoSurface::IncorrectFormatError; + } else { + painter->fillRect(target, Qt::black); + } + return QAbstractVideoSurface::NoError; +} + +void QVideoSurfaceRasterPainter::updateColors(int, int, int, int) +{ +} + +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + +#ifndef Q_WS_MAC +# ifndef APIENTRYP +# ifdef APIENTRY +# define APIENTRYP APIENTRY * +# else +# define APIENTRY +# define APIENTRYP * +# endif +# endif +#else +# define APIENTRY +# define APIENTRYP * +#endif + +#ifndef GL_TEXTURE0 +# define GL_TEXTURE0 0x84C0 +# define GL_TEXTURE1 0x84C1 +# define GL_TEXTURE2 0x84C2 +#endif +#ifndef GL_PROGRAM_ERROR_STRING_ARB +# define GL_PROGRAM_ERROR_STRING_ARB 0x8874 +#endif + +#ifndef GL_UNSIGNED_SHORT_5_6_5 +# define GL_UNSIGNED_SHORT_5_6_5 33635 +#endif + +class QVideoSurfaceGLPainter : public QVideoSurfacePainter +{ +public: + QVideoSurfaceGLPainter(QGLContext *context); + ~QVideoSurfaceGLPainter(); + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const; + + bool isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const; + + QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame); + + void updateColors(int brightness, int contrast, int hue, int saturation); + +protected: + void initRgbTextureInfo(GLenum internalFormat, GLuint format, GLenum type, const QSize &size); + void initYuv420PTextureInfo(const QSize &size); + void initYv12TextureInfo(const QSize &size); + +#ifndef QT_OPENGL_ES + typedef void (APIENTRY *_glActiveTexture) (GLenum); + _glActiveTexture glActiveTexture; +#endif + + QList<QVideoFrame::PixelFormat> m_imagePixelFormats; + QList<QVideoFrame::PixelFormat> m_glPixelFormats; + QMatrix4x4 m_colorMatrix; + QVideoFrame m_frame; + + QGLContext *m_context; + QAbstractVideoBuffer::HandleType m_handleType; + QVideoSurfaceFormat::Direction m_scanLineDirection; + GLenum m_textureFormat; + GLuint m_textureInternalFormat; + GLenum m_textureType; + int m_textureCount; + GLuint m_textureIds[3]; + int m_textureWidths[3]; + int m_textureHeights[3]; + int m_textureOffsets[3]; + bool m_yuv; +}; + +QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QGLContext *context) + : m_context(context) + , m_handleType(QAbstractVideoBuffer::NoHandle) + , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom) + , m_textureFormat(0) + , m_textureInternalFormat(0) + , m_textureType(0) + , m_textureCount(0) + , m_yuv(false) +{ +#ifndef QT_OPENGL_ES + glActiveTexture = (_glActiveTexture)m_context->getProcAddress(QLatin1String("glActiveTexture")); +#endif +} + +QVideoSurfaceGLPainter::~QVideoSurfaceGLPainter() +{ +} + +QList<QVideoFrame::PixelFormat> QVideoSurfaceGLPainter::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + switch (handleType) { + case QAbstractVideoBuffer::NoHandle: + return m_imagePixelFormats; + case QAbstractVideoBuffer::GLTextureHandle: + return m_glPixelFormats; + default: + return QList<QVideoFrame::PixelFormat>(); + } +} + +bool QVideoSurfaceGLPainter::isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *) const +{ + if (format.frameSize().isEmpty()) { + return false; + } else { + switch (format.handleType()) { + case QAbstractVideoBuffer::NoHandle: + return m_imagePixelFormats.contains(format.pixelFormat()); + case QAbstractVideoBuffer::GLTextureHandle: + return m_glPixelFormats.contains(format.pixelFormat()); + default: + return false; + } + } +} + +QAbstractVideoSurface::Error QVideoSurfaceGLPainter::setCurrentFrame(const QVideoFrame &frame) +{ + m_frame = frame; + + if (m_handleType == QAbstractVideoBuffer::GLTextureHandle) { + m_textureIds[0] = frame.handle().toInt(); + } else if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) { + m_context->makeCurrent(); + + for (int i = 0; i < m_textureCount; ++i) { + glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); + glTexImage2D( + GL_TEXTURE_2D, + 0, + m_textureInternalFormat, + m_textureWidths[i], + m_textureHeights[i], + 0, + m_textureFormat, + m_textureType, + m_frame.bits() + m_textureOffsets[i]); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + m_frame.unmap(); + } else if (m_frame.isValid()) { + return QAbstractVideoSurface::IncorrectFormatError; + } + + return QAbstractVideoSurface::NoError; +} + +void QVideoSurfaceGLPainter::updateColors(int brightness, int contrast, int hue, int saturation) +{ + const qreal b = brightness / 200.0; + const qreal c = contrast / 100.0 + 1.0; + const qreal h = hue / 100.0; + const qreal s = saturation / 100.0 + 1.0; + + const qreal cosH = qCos(M_PI * h); + const qreal sinH = qSin(M_PI * h); + + const qreal h11 = 0.787 * cosH - 0.213 * sinH + 0.213; + const qreal h21 = -0.213 * cosH + 0.143 * sinH + 0.213; + const qreal h31 = -0.213 * cosH - 0.787 * sinH + 0.213; + + const qreal h12 = -0.715 * cosH - 0.715 * sinH + 0.715; + const qreal h22 = 0.285 * cosH + 0.140 * sinH + 0.715; + const qreal h32 = -0.715 * cosH + 0.715 * sinH + 0.715; + + const qreal h13 = -0.072 * cosH + 0.928 * sinH + 0.072; + const qreal h23 = -0.072 * cosH - 0.283 * sinH + 0.072; + const qreal h33 = 0.928 * cosH + 0.072 * sinH + 0.072; + + const qreal sr = (1.0 - s) * 0.3086; + const qreal sg = (1.0 - s) * 0.6094; + const qreal sb = (1.0 - s) * 0.0820; + + const qreal sr_s = sr + s; + const qreal sg_s = sg + s; + const qreal sb_s = sr + s; + + const float m4 = (s + sr + sg + sb) * (0.5 - 0.5 * c + b); + + m_colorMatrix(0, 0) = c * (sr_s * h11 + sg * h21 + sb * h31); + m_colorMatrix(0, 1) = c * (sr_s * h12 + sg * h22 + sb * h32); + m_colorMatrix(0, 2) = c * (sr_s * h13 + sg * h23 + sb * h33); + m_colorMatrix(0, 3) = m4; + + m_colorMatrix(1, 0) = c * (sr * h11 + sg_s * h21 + sb * h31); + m_colorMatrix(1, 1) = c * (sr * h12 + sg_s * h22 + sb * h32); + m_colorMatrix(1, 2) = c * (sr * h13 + sg_s * h23 + sb * h33); + m_colorMatrix(1, 3) = m4; + + m_colorMatrix(2, 0) = c * (sr * h11 + sg * h21 + sb_s * h31); + m_colorMatrix(2, 1) = c * (sr * h12 + sg * h22 + sb_s * h32); + m_colorMatrix(2, 2) = c * (sr * h13 + sg * h23 + sb_s * h33); + m_colorMatrix(2, 3) = m4; + + m_colorMatrix(3, 0) = 0.0; + m_colorMatrix(3, 1) = 0.0; + m_colorMatrix(3, 2) = 0.0; + m_colorMatrix(3, 3) = 1.0; + + if (m_yuv) { + m_colorMatrix = m_colorMatrix * QMatrix4x4( + 1.0, 0.000, 1.140, -0.5700, + 1.0, -0.394, -0.581, 0.4875, + 1.0, 2.028, 0.000, -1.0140, + 0.0, 0.000, 0.000, 1.0000); + } +} + +void QVideoSurfaceGLPainter::initRgbTextureInfo( + GLenum internalFormat, GLuint format, GLenum type, const QSize &size) +{ + m_yuv = false; + m_textureInternalFormat = internalFormat; + m_textureFormat = format; + m_textureType = type; + m_textureCount = 1; + m_textureWidths[0] = size.width(); + m_textureHeights[0] = size.height(); + m_textureOffsets[0] = 0; +} + +void QVideoSurfaceGLPainter::initYuv420PTextureInfo(const QSize &size) +{ + m_yuv = true; + m_textureInternalFormat = GL_LUMINANCE; + m_textureFormat = GL_LUMINANCE; + m_textureType = GL_UNSIGNED_BYTE; + m_textureCount = 3; + m_textureWidths[0] = size.width(); + m_textureHeights[0] = size.height(); + m_textureOffsets[0] = 0; + m_textureWidths[1] = size.width() / 2; + m_textureHeights[1] = size.height() / 2; + m_textureOffsets[1] = size.width() * size.height(); + m_textureWidths[2] = size.width() / 2; + m_textureHeights[2] = size.height() / 2; + m_textureOffsets[2] = size.width() * size.height() * 5 / 4; +} + +void QVideoSurfaceGLPainter::initYv12TextureInfo(const QSize &size) +{ + m_yuv = true; + m_textureInternalFormat = GL_LUMINANCE; + m_textureFormat = GL_LUMINANCE; + m_textureType = GL_UNSIGNED_BYTE; + m_textureCount = 3; + m_textureWidths[0] = size.width(); + m_textureHeights[0] = size.height(); + m_textureOffsets[0] = 0; + m_textureWidths[1] = size.width() / 2; + m_textureHeights[1] = size.height() / 2; + m_textureOffsets[1] = size.width() * size.height() * 5 / 4; + m_textureWidths[2] = size.width() / 2; + m_textureHeights[2] = size.height() / 2; + m_textureOffsets[2] = size.width() * size.height(); +} + +#ifndef QT_OPENGL_ES + +# ifndef GL_FRAGMENT_PROGRAM_ARB +# define GL_FRAGMENT_PROGRAM_ARB 0x8804 +# define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 +# endif + +// Paints an RGB32 frame +static const char *qt_arbfp_xrgbShaderProgram = + "!!ARBfp1.0\n" + "PARAM matrix[4] = { program.local[0..2]," + "{ 0.0, 0.0, 0.0, 1.0 } };\n" + "TEMP xrgb;\n" + "TEX xrgb.xyz, fragment.texcoord[0], texture[0], 2D;\n" + "MOV xrgb.w, matrix[3].w;\n" + "DP4 result.color.x, xrgb.zyxw, matrix[0];\n" + "DP4 result.color.y, xrgb.zyxw, matrix[1];\n" + "DP4 result.color.z, xrgb.zyxw, matrix[2];\n" + "END"; + +// Paints an ARGB frame. +static const char *qt_arbfp_argbShaderProgram = + "!!ARBfp1.0\n" + "PARAM matrix[4] = { program.local[0..2]," + "{ 0.0, 0.0, 0.0, 1.0 } };\n" + "TEMP argb;\n" + "TEX argb, fragment.texcoord[0], texture[0], 2D;\n" + "MOV argb.w, matrix[3].w;\n" + "DP4 result.color.x, argb.zyxw, matrix[0];\n" + "DP4 result.color.y, argb.zyxw, matrix[1];\n" + "DP4 result.color.z, argb.zyxw, matrix[2];\n" + "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n" + "END"; + +// Paints an RGB(A) frame. +static const char *qt_arbfp_rgbShaderProgram = + "!!ARBfp1.0\n" + "PARAM matrix[4] = { program.local[0..2]," + "{ 0.0, 0.0, 0.0, 1.0 } };\n" + "TEMP rgb;\n" + "TEX rgb, fragment.texcoord[0], texture[0], 2D;\n" + "MOV rgb.w, matrix[3].w;\n" + "DP4 result.color.x, rgb, matrix[0];\n" + "DP4 result.color.y, rgb, matrix[1];\n" + "DP4 result.color.z, rgb, matrix[2];\n" + "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n" + "END"; + +// Paints a YUV420P or YV12 frame. +static const char *qt_arbfp_yuvPlanarShaderProgram = + "!!ARBfp1.0\n" + "PARAM matrix[4] = { program.local[0..2]," + "{ 0.0, 0.0, 0.0, 1.0 } };\n" + "TEMP yuv;\n" + "TEX yuv.x, fragment.texcoord[0], texture[0], 2D;\n" + "TEX yuv.y, fragment.texcoord[0], texture[1], 2D;\n" + "TEX yuv.z, fragment.texcoord[0], texture[2], 2D;\n" + "MOV yuv.w, matrix[3].w;\n" + "DP4 result.color.x, yuv, matrix[0];\n" + "DP4 result.color.y, yuv, matrix[1];\n" + "DP4 result.color.z, yuv, matrix[2];\n" + "END"; + +// Paints a YUV444 frame. +static const char *qt_arbfp_xyuvShaderProgram = + "!!ARBfp1.0\n" + "PARAM matrix[4] = { program.local[0..2]," + "{ 0.0, 0.0, 0.0, 1.0 } };\n" + "TEMP ayuv;\n" + "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n" + "MOV ayuv.x, matrix[3].w;\n" + "DP4 result.color.x, ayuv.yzwx, matrix[0];\n" + "DP4 result.color.y, ayuv.yzwx, matrix[1];\n" + "DP4 result.color.z, ayuv.yzwx, matrix[2];\n" + "END"; + +// Paints a AYUV444 frame. +static const char *qt_arbfp_ayuvShaderProgram = + "!!ARBfp1.0\n" + "PARAM matrix[4] = { program.local[0..2]," + "{ 0.0, 0.0, 0.0, 1.0 } };\n" + "TEMP ayuv;\n" + "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n" + "MOV ayuv.x, matrix[3].w;\n" + "DP4 result.color.x, ayuv.yzwx, matrix[0];\n" + "DP4 result.color.y, ayuv.yzwx, matrix[1];\n" + "DP4 result.color.z, ayuv.yzwx, matrix[2];\n" + "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n" + "END"; + +class QVideoSurfaceArbFpPainter : public QVideoSurfaceGLPainter +{ +public: + QVideoSurfaceArbFpPainter(QGLContext *context); + + QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format); + void stop(); + + QAbstractVideoSurface::Error paint( + const QRectF &target, QPainter *painter, const QRectF &source); + +private: + typedef void (APIENTRY *_glProgramStringARB) (GLenum, GLenum, GLsizei, const GLvoid *); + typedef void (APIENTRY *_glBindProgramARB) (GLenum, GLuint); + typedef void (APIENTRY *_glDeleteProgramsARB) (GLsizei, const GLuint *); + typedef void (APIENTRY *_glGenProgramsARB) (GLsizei, GLuint *); + typedef void (APIENTRY *_glProgramLocalParameter4fARB) ( + GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); + typedef void (APIENTRY *_glActiveTexture) (GLenum); + + _glProgramStringARB glProgramStringARB; + _glBindProgramARB glBindProgramARB; + _glDeleteProgramsARB glDeleteProgramsARB; + _glGenProgramsARB glGenProgramsARB; + _glProgramLocalParameter4fARB glProgramLocalParameter4fARB; + + GLuint m_programId; + QSize m_frameSize; +}; + +QVideoSurfaceArbFpPainter::QVideoSurfaceArbFpPainter(QGLContext *context) + : QVideoSurfaceGLPainter(context) + , m_programId(0) +{ + glProgramStringARB = (_glProgramStringARB) m_context->getProcAddress( + QLatin1String("glProgramStringARB")); + glBindProgramARB = (_glBindProgramARB) m_context->getProcAddress( + QLatin1String("glBindProgramARB")); + glDeleteProgramsARB = (_glDeleteProgramsARB) m_context->getProcAddress( + QLatin1String("glDeleteProgramsARB")); + glGenProgramsARB = (_glGenProgramsARB) m_context->getProcAddress( + QLatin1String("glGenProgramsARB")); + glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) m_context->getProcAddress( + QLatin1String("glProgramLocalParameter4fARB")); + + m_imagePixelFormats + << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_BGR32 + << QVideoFrame::Format_ARGB32 + << QVideoFrame::Format_RGB24 + << QVideoFrame::Format_BGR24 + << QVideoFrame::Format_RGB565 + << QVideoFrame::Format_AYUV444 + << QVideoFrame::Format_YUV444 + << QVideoFrame::Format_YV12 + << QVideoFrame::Format_YUV420P; + m_glPixelFormats + << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_ARGB32; +} + +QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfaceFormat &format) +{ + Q_ASSERT(m_textureCount == 0); + + QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError; + + m_context->makeCurrent(); + + const char *program = 0; + + if (format.handleType() == QAbstractVideoBuffer::NoHandle) { + switch (format.pixelFormat()) { + case QVideoFrame::Format_RGB32: + initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + program = qt_arbfp_xrgbShaderProgram; + break; + case QVideoFrame::Format_BGR32: + initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + program = qt_arbfp_rgbShaderProgram; + break; + case QVideoFrame::Format_ARGB32: + initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + program = qt_arbfp_argbShaderProgram; + break; + case QVideoFrame::Format_RGB24: + initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + program = qt_arbfp_rgbShaderProgram; + break; + case QVideoFrame::Format_BGR24: + initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + program = qt_arbfp_xrgbShaderProgram; + break; + case QVideoFrame::Format_RGB565: + initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize()); + program = qt_arbfp_rgbShaderProgram; + break; + case QVideoFrame::Format_YUV444: + initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); + program = qt_arbfp_xyuvShaderProgram; + m_yuv = true; + break; + case QVideoFrame::Format_AYUV444: + initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + program = qt_arbfp_ayuvShaderProgram; + m_yuv = true; + break; + case QVideoFrame::Format_YV12: + initYv12TextureInfo(format.frameSize()); + program = qt_arbfp_yuvPlanarShaderProgram; + break; + case QVideoFrame::Format_YUV420P: + initYuv420PTextureInfo(format.frameSize()); + program = qt_arbfp_yuvPlanarShaderProgram; + break; + default: + break; + } + } else if (format.handleType() == QAbstractVideoBuffer::GLTextureHandle) { + switch (format.pixelFormat()) { + case QVideoFrame::Format_RGB32: + case QVideoFrame::Format_ARGB32: + m_yuv = false; + m_textureCount = 1; + program = qt_arbfp_rgbShaderProgram; + break; + default: + break; + } + } + + if (!program) { + error = QAbstractVideoSurface::UnsupportedFormatError; + } else { + glGenProgramsARB(1, &m_programId); + + GLenum glError = glGetError(); + if (glError != GL_NO_ERROR) { + qWarning("QPainterVideoSurface: ARBfb Shader allocation error %x", int(glError)); + m_textureCount = 0; + m_programId = 0; + + error = QAbstractVideoSurface::ResourceError; + } else { + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); + glProgramStringARB( + GL_FRAGMENT_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, + qstrlen(program), + reinterpret_cast<const GLvoid *>(program)); + + if ((glError = glGetError()) != GL_NO_ERROR) { + const GLubyte* errorString = glGetString(GL_PROGRAM_ERROR_STRING_ARB); + + qWarning("QPainterVideoSurface: ARBfp Shader compile error %x, %s", + int(glError), + reinterpret_cast<const char *>(errorString)); + glDeleteProgramsARB(1, &m_programId); + + m_textureCount = 0; + m_programId = 0; + + error = QAbstractVideoSurface::ResourceError; + } else { + m_handleType = format.handleType(); + m_scanLineDirection = format.scanLineDirection(); + m_frameSize = format.frameSize(); + + if (m_handleType == QAbstractVideoBuffer::NoHandle) + glGenTextures(m_textureCount, m_textureIds); + } + } + } + + return error; +} + +void QVideoSurfaceArbFpPainter::stop() +{ + m_context->makeCurrent(); + + if (m_handleType != QAbstractVideoBuffer::GLTextureHandle) + glDeleteTextures(m_textureCount, m_textureIds); + glDeleteProgramsARB(1, &m_programId); + + m_textureCount = 0; + m_programId = 0; + m_handleType = QAbstractVideoBuffer::NoHandle; +} + +QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint( + const QRectF &target, QPainter *painter, const QRectF &source) +{ + if (m_frame.isValid()) { + painter->beginNativePainting(); + + glEnable(GL_STENCIL_TEST); + glEnable(GL_SCISSOR_TEST); + + const float txLeft = source.left() / m_frameSize.width(); + const float txRight = source.right() / m_frameSize.width(); + const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom + ? source.top() / m_frameSize.height() + : source.bottom() / m_frameSize.height(); + const float txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom + ? source.bottom() / m_frameSize.height() + : source.top() / m_frameSize.height(); + + + const float tx_array[] = + { + txLeft , txBottom, + txRight, txBottom, + txLeft , txTop, + txRight, txTop + }; + const float v_array[] = + { + target.left() , target.bottom() + 1, + target.right() + 1, target.bottom() + 1, + target.left() , target.top(), + target.right() + 1, target.top() + }; + + glEnable(GL_FRAGMENT_PROGRAM_ARB); + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); + + glProgramLocalParameter4fARB( + GL_FRAGMENT_PROGRAM_ARB, + 0, + m_colorMatrix(0, 0), + m_colorMatrix(0, 1), + m_colorMatrix(0, 2), + m_colorMatrix(0, 3)); + glProgramLocalParameter4fARB( + GL_FRAGMENT_PROGRAM_ARB, + 1, + m_colorMatrix(1, 0), + m_colorMatrix(1, 1), + m_colorMatrix(1, 2), + m_colorMatrix(1, 3)); + glProgramLocalParameter4fARB( + GL_FRAGMENT_PROGRAM_ARB, + 2, + m_colorMatrix(2, 0), + m_colorMatrix(2, 1), + m_colorMatrix(2, 2), + m_colorMatrix(2, 3)); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + + if (m_textureCount == 3) { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + glActiveTexture(GL_TEXTURE0); + } + + glVertexPointer(2, GL_FLOAT, 0, v_array); + glTexCoordPointer(2, GL_FLOAT, 0, tx_array); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_FRAGMENT_PROGRAM_ARB); + + glDisable(GL_STENCIL_TEST); + glDisable(GL_SCISSOR_TEST); + + painter->endNativePainting(); + } + return QAbstractVideoSurface::NoError; +} + +#endif + +static const char *qt_glsl_vertexShaderProgram = + "attribute highp vec4 vertexCoordArray;\n" + "attribute highp vec2 textureCoordArray;\n" + "uniform highp mat4 positionMatrix;\n" + "varying highp vec2 textureCoord;\n" + "void main(void)\n" + "{\n" + " gl_Position = positionMatrix * vertexCoordArray;\n" + " textureCoord = textureCoordArray;\n" + "}\n"; + +// Paints an RGB32 frame +static const char *qt_glsl_xrgbShaderProgram = + "uniform sampler2D texRgb;\n" + "uniform mediump mat4 colorMatrix;\n" + "varying highp vec2 textureCoord;\n" + "void main(void)\n" + "{\n" + " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n" + " gl_FragColor = colorMatrix * color;\n" + "}\n"; + +// Paints an ARGB frame. +static const char *qt_glsl_argbShaderProgram = + "uniform sampler2D texRgb;\n" + "uniform mediump mat4 colorMatrix;\n" + "varying highp vec2 textureCoord;\n" + "void main(void)\n" + "{\n" + " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n" + " color = colorMatrix * color;\n" + " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n" + "}\n"; + +// Paints an RGB(A) frame. +static const char *qt_glsl_rgbShaderProgram = + "uniform sampler2D texRgb;\n" + "uniform mediump mat4 colorMatrix;\n" + "varying highp vec2 textureCoord;\n" + "void main(void)\n" + "{\n" + " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).rgb, 1.0);\n" + " color = colorMatrix * color;\n" + " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n" + "}\n"; + +// Paints a YUV420P or YV12 frame. +static const char *qt_glsl_yuvPlanarShaderProgram = + "uniform sampler2D texY;\n" + "uniform sampler2D texU;\n" + "uniform sampler2D texV;\n" + "uniform mediump mat4 colorMatrix;\n" + "varying highp vec2 textureCoord;\n" + "void main(void)\n" + "{\n" + " highp vec4 color = vec4(\n" + " texture2D(texY, textureCoord.st).r,\n" + " texture2D(texU, textureCoord.st).r,\n" + " texture2D(texV, textureCoord.st).r,\n" + " 1.0);\n" + " gl_FragColor = colorMatrix * color;\n" + "}\n"; + +// Paints a YUV444 frame. +static const char *qt_glsl_xyuvShaderProgram = + "uniform sampler2D texRgb;\n" + "uniform mediump mat4 colorMatrix;\n" + "varying highp vec2 textureCoord;\n" + "void main(void)\n" + "{\n" + " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n" + " gl_FragColor = colorMatrix * color;\n" + "}\n"; + +// Paints a AYUV444 frame. +static const char *qt_glsl_ayuvShaderProgram = + "uniform sampler2D texRgb;\n" + "uniform mediump mat4 colorMatrix;\n" + "varying highp vec2 textureCoord;\n" + "void main(void)\n" + "{\n" + " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n" + " color = colorMatrix * color;\n" + " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).r);\n" + "}\n"; + +class QVideoSurfaceGlslPainter : public QVideoSurfaceGLPainter +{ +public: + QVideoSurfaceGlslPainter(QGLContext *context); + + QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format); + void stop(); + + QAbstractVideoSurface::Error paint( + const QRectF &target, QPainter *painter, const QRectF &source); + +private: + QGLShaderProgram m_program; + QSize m_frameSize; +}; + +QVideoSurfaceGlslPainter::QVideoSurfaceGlslPainter(QGLContext *context) + : QVideoSurfaceGLPainter(context) + , m_program(context) +{ + m_imagePixelFormats + << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_BGR32 + << QVideoFrame::Format_ARGB32 +#ifndef QT_OPENGL_ES + << QVideoFrame::Format_RGB24 + << QVideoFrame::Format_BGR24 +#endif + << QVideoFrame::Format_RGB565 + << QVideoFrame::Format_YUV444 + << QVideoFrame::Format_AYUV444 + << QVideoFrame::Format_YV12 + << QVideoFrame::Format_YUV420P; + m_glPixelFormats + << QVideoFrame::Format_RGB32 + << QVideoFrame::Format_ARGB32; +} + +QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurfaceFormat &format) +{ + Q_ASSERT(m_textureCount == 0); + + QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError; + + m_context->makeCurrent(); + + const char *fragmentProgram = 0; + + if (format.handleType() == QAbstractVideoBuffer::NoHandle) { + switch (format.pixelFormat()) { + case QVideoFrame::Format_RGB32: + initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + fragmentProgram = qt_glsl_xrgbShaderProgram; + break; + case QVideoFrame::Format_BGR32: + initRgbTextureInfo(GL_RGB, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + fragmentProgram = qt_glsl_rgbShaderProgram; + break; + case QVideoFrame::Format_ARGB32: + initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + fragmentProgram = qt_glsl_argbShaderProgram; + break; +#ifndef QT_OPENGL_ES + case QVideoFrame::Format_RGB24: + initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); + fragmentProgram = qt_glsl_rgbShaderProgram; + break; + case QVideoFrame::Format_BGR24: + initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); + fragmentProgram = qt_glsl_argbShaderProgram; + break; +#endif + case QVideoFrame::Format_RGB565: + initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize()); + fragmentProgram = qt_glsl_rgbShaderProgram; + break; + case QVideoFrame::Format_YUV444: + initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); + fragmentProgram = qt_glsl_xyuvShaderProgram; + m_yuv = true; + break; + case QVideoFrame::Format_AYUV444: + initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); + fragmentProgram = qt_glsl_ayuvShaderProgram; + m_yuv = true; + break; + case QVideoFrame::Format_YV12: + initYv12TextureInfo(format.frameSize()); + fragmentProgram = qt_glsl_yuvPlanarShaderProgram; + break; + case QVideoFrame::Format_YUV420P: + initYuv420PTextureInfo(format.frameSize()); + fragmentProgram = qt_glsl_yuvPlanarShaderProgram; + break; + default: + break; + } + } else if (format.handleType() == QAbstractVideoBuffer::GLTextureHandle) { + switch (format.pixelFormat()) { + case QVideoFrame::Format_RGB32: + case QVideoFrame::Format_ARGB32: + m_yuv = false; + m_textureCount = 1; + fragmentProgram = qt_glsl_rgbShaderProgram; + break; + default: + break; + } + } + + if (!fragmentProgram) { + error = QAbstractVideoSurface::UnsupportedFormatError; + } else if (!m_program.addShaderFromSourceCode(QGLShader::Vertex, qt_glsl_vertexShaderProgram)) { + qWarning("QPainterVideoSurface: Vertex shader compile error %s", + qPrintable(m_program.log())); + error = QAbstractVideoSurface::ResourceError; + } else if (!m_program.addShaderFromSourceCode(QGLShader::Fragment, fragmentProgram)) { + qWarning("QPainterVideoSurface: Shader compile error %s", qPrintable(m_program.log())); + error = QAbstractVideoSurface::ResourceError; + m_program.removeAllShaders(); + } else if(!m_program.link()) { + qWarning("QPainterVideoSurface: Shader link error %s", qPrintable(m_program.log())); + m_program.removeAllShaders(); + error = QAbstractVideoSurface::ResourceError; + } else { + m_handleType = format.handleType(); + m_scanLineDirection = format.scanLineDirection(); + m_frameSize = format.frameSize(); + + if (m_handleType == QAbstractVideoBuffer::NoHandle) + glGenTextures(m_textureCount, m_textureIds); + } + + return error; +} + +void QVideoSurfaceGlslPainter::stop() +{ + m_context->makeCurrent(); + + if (m_handleType != QAbstractVideoBuffer::GLTextureHandle) + glDeleteTextures(m_textureCount, m_textureIds); + m_program.removeAllShaders(); + + m_textureCount = 0; + m_handleType = QAbstractVideoBuffer::NoHandle; +} + +QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint( + const QRectF &target, QPainter *painter, const QRectF &source) +{ + if (m_frame.isValid()) { + painter->beginNativePainting(); + + glEnable(GL_STENCIL_TEST); + glEnable(GL_SCISSOR_TEST); + + const int width = QGLContext::currentContext()->device()->width(); + const int height = QGLContext::currentContext()->device()->height(); + + const QTransform transform = painter->deviceTransform(); + + const GLfloat wfactor = 2.0 / width; + const GLfloat hfactor = -2.0 / height; + + const GLfloat positionMatrix[4][4] = + { + { + /*(0,0)*/ wfactor * transform.m11() - transform.m13(), + /*(0,1)*/ hfactor * transform.m12() + transform.m13(), + /*(0,2)*/ 0.0, + /*(0,3)*/ transform.m13() + }, { + /*(1,0)*/ wfactor * transform.m21() - transform.m23(), + /*(1,1)*/ hfactor * transform.m22() + transform.m23(), + /*(1,2)*/ 0.0, + /*(1,3)*/ transform.m23() + }, { + /*(2,0)*/ 0.0, + /*(2,1)*/ 0.0, + /*(2,2)*/ -1.0, + /*(2,3)*/ 0.0 + }, { + /*(3,0)*/ wfactor * transform.dx() - transform.m33(), + /*(3,1)*/ hfactor * transform.dy() + transform.m33(), + /*(3,2)*/ 0.0, + /*(3,3)*/ transform.m33() + } + }; + + const GLfloat vertexCoordArray[] = + { + target.left() , target.bottom() + 1, + target.right() + 1, target.bottom() + 1, + target.left() , target.top(), + target.right() + 1, target.top() + }; + + const GLfloat txLeft = source.left() / m_frameSize.width(); + const GLfloat txRight = source.right() / m_frameSize.width(); + const GLfloat txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom + ? source.top() / m_frameSize.height() + : source.bottom() / m_frameSize.height(); + const GLfloat txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom + ? source.bottom() / m_frameSize.height() + : source.top() / m_frameSize.height(); + + const GLfloat textureCoordArray[] = + { + txLeft , txBottom, + txRight, txBottom, + txLeft , txTop, + txRight, txTop + }; + + m_program.bind(); + + m_program.enableAttributeArray("vertexCoordArray"); + m_program.enableAttributeArray("textureCoordArray"); + m_program.setAttributeArray("vertexCoordArray", vertexCoordArray, 2); + m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2); + m_program.setUniformValue("positionMatrix", positionMatrix); + + if (m_textureCount == 3) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + glActiveTexture(GL_TEXTURE0); + + m_program.setUniformValue("texY", 0); + m_program.setUniformValue("texU", 1); + m_program.setUniformValue("texV", 2); + } else { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + + m_program.setUniformValue("texRgb", 0); + } + m_program.setUniformValue("colorMatrix", m_colorMatrix); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + m_program.release(); + + + glDisable(GL_SCISSOR_TEST); + glDisable(GL_STENCIL_TEST); + painter->endNativePainting(); + } + return QAbstractVideoSurface::NoError; +} + +#endif + +/*! + \class QPainterVideoSurface + \internal +*/ + +/*! +*/ +QPainterVideoSurface::QPainterVideoSurface(QObject *parent) + : QAbstractVideoSurface(parent) + , m_painter(0) +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + , m_glContext(0) + , m_shaderTypes(NoShaders) + , m_shaderType(NoShaders) +#endif + , m_brightness(0) + , m_contrast(0) + , m_hue(0) + , m_saturation(0) + , m_pixelFormat(QVideoFrame::Format_Invalid) + , m_colorsDirty(true) + , m_ready(false) +{ +} + +/*! +*/ +QPainterVideoSurface::~QPainterVideoSurface() +{ + if (isActive()) + m_painter->stop(); + + delete m_painter; +} + +/*! +*/ +QList<QVideoFrame::PixelFormat> QPainterVideoSurface::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + if (!m_painter) + const_cast<QPainterVideoSurface *>(this)->createPainter(); + + return m_painter->supportedPixelFormats(handleType); +} + +/*! +*/ +bool QPainterVideoSurface::isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const +{ + if (!m_painter) + const_cast<QPainterVideoSurface *>(this)->createPainter(); + + return m_painter->isFormatSupported(format, similar); +} + +/*! +*/ +bool QPainterVideoSurface::start(const QVideoSurfaceFormat &format) +{ + if (isActive()) + m_painter->stop(); + + if (!m_painter) + createPainter(); + + if (format.frameSize().isEmpty()) { + setError(UnsupportedFormatError); + } else { + QAbstractVideoSurface::Error error = m_painter->start(format); + + if (error != QAbstractVideoSurface::NoError) { + setError(error); + } else { + m_pixelFormat = format.pixelFormat(); + m_frameSize = format.frameSize(); + m_sourceRect = format.viewport(); + m_colorsDirty = true; + m_ready = true; + + return QAbstractVideoSurface::start(format); + } + } + + QAbstractVideoSurface::stop(); + + return false; +} + +/*! +*/ +void QPainterVideoSurface::stop() +{ + if (isActive()) { + m_painter->stop(); + m_ready = false; + + QAbstractVideoSurface::stop(); + } +} + +/*! +*/ +bool QPainterVideoSurface::present(const QVideoFrame &frame) +{ + if (!m_ready) { + if (!isActive()) + setError(StoppedError); + } else if (frame.isValid() + && (frame.pixelFormat() != m_pixelFormat || frame.size() != m_frameSize)) { + setError(IncorrectFormatError); + + stop(); + } else { + QAbstractVideoSurface::Error error = m_painter->setCurrentFrame(frame); + + if (error != QAbstractVideoSurface::NoError) { + setError(error); + + stop(); + } else { + m_ready = false; + + emit frameChanged(); + + return true; + } + } + return false; +} + +/*! +*/ +int QPainterVideoSurface::brightness() const +{ + return m_brightness; +} + +/*! +*/ +void QPainterVideoSurface::setBrightness(int brightness) +{ + m_brightness = brightness; + + m_colorsDirty = true; +} + +/*! +*/ +int QPainterVideoSurface::contrast() const +{ + return m_contrast; +} + +/*! +*/ +void QPainterVideoSurface::setContrast(int contrast) +{ + m_contrast = contrast; + + m_colorsDirty = true; +} + +/*! +*/ +int QPainterVideoSurface::hue() const +{ + return m_hue; +} + +/*! +*/ +void QPainterVideoSurface::setHue(int hue) +{ + m_hue = hue; + + m_colorsDirty = true; +} + +/*! +*/ +int QPainterVideoSurface::saturation() const +{ + return m_saturation; +} + +/*! +*/ +void QPainterVideoSurface::setSaturation(int saturation) +{ + m_saturation = saturation; + + m_colorsDirty = true; +} + +/*! +*/ +bool QPainterVideoSurface::isReady() const +{ + return m_ready; +} + +/*! +*/ +void QPainterVideoSurface::setReady(bool ready) +{ + m_ready = ready; +} + +/*! +*/ +void QPainterVideoSurface::paint(QPainter *painter, const QRectF &target, const QRectF &source) +{ + if (!isActive()) { + painter->fillRect(target, QBrush(Qt::black)); + } else { + if (m_colorsDirty) { + m_painter->updateColors(m_brightness, m_contrast, m_hue, m_saturation); + m_colorsDirty = false; + } + + const QRectF sourceRect( + m_sourceRect.x() + m_sourceRect.width() * source.x(), + m_sourceRect.y() + m_sourceRect.height() * source.y(), + m_sourceRect.width() * source.width(), + m_sourceRect.height() * source.height()); + + QAbstractVideoSurface::Error error = m_painter->paint(target, painter, sourceRect); + + if (error != QAbstractVideoSurface::NoError) { + setError(error); + + stop(); + } + } +} + +/*! + \fn QPainterVideoSurface::frameChanged() +*/ + +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + +/*! +*/ +const QGLContext *QPainterVideoSurface::glContext() const +{ + return m_glContext; +} + +/*! +*/ +void QPainterVideoSurface::setGLContext(QGLContext *context) +{ + if (m_glContext == context) + return; + + m_glContext = context; + + m_shaderTypes = NoShaders; + + if (m_glContext) { + m_glContext->makeCurrent(); + + const QByteArray extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); +#ifndef QT_OPENGL_ES + + if (extensions.contains("ARB_fragment_program")) + m_shaderTypes |= FragmentProgramShader; +#endif + + if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext) + && extensions.contains("ARB_shader_objects")) + m_shaderTypes |= GlslShader; + } + + ShaderType type = (m_shaderType & m_shaderTypes) + ? m_shaderType + : NoShaders; + + if (type != m_shaderType || type != NoShaders) { + m_shaderType = type; + + if (isActive()) { + m_painter->stop(); + delete m_painter; + m_painter = 0; + m_ready = false; + + setError(ResourceError); + QAbstractVideoSurface::stop(); + } + emit supportedFormatsChanged(); + } +} + +/*! + \enum QPainterVideoSurface::ShaderType + + \value NoShaders + \value FragmentProgramShader + \value HlslShader +*/ + +/*! + \typedef QPainterVideoSurface::ShaderTypes +*/ + +/*! +*/ +QPainterVideoSurface::ShaderTypes QPainterVideoSurface::supportedShaderTypes() const +{ + return m_shaderTypes; +} + +/*! +*/ +QPainterVideoSurface::ShaderType QPainterVideoSurface::shaderType() const +{ + return m_shaderType; +} + +/*! +*/ +void QPainterVideoSurface::setShaderType(ShaderType type) +{ + if (!(type & m_shaderTypes)) + type = NoShaders; + + if (type != m_shaderType) { + m_shaderType = type; + + if (isActive()) { + m_painter->stop(); + delete m_painter; + m_painter = 0; + m_ready = false; + + setError(ResourceError); + QAbstractVideoSurface::stop(); + } else { + delete m_painter; + m_painter = 0; + } + emit supportedFormatsChanged(); + } +} + +#endif + +void QPainterVideoSurface::createPainter() +{ + Q_ASSERT(!m_painter); + +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + switch (m_shaderType) { +#ifndef QT_OPENGL_ES + case FragmentProgramShader: + Q_ASSERT(m_glContext); + m_glContext->makeCurrent(); + m_painter = new QVideoSurfaceArbFpPainter(m_glContext); + break; +#endif + case GlslShader: + Q_ASSERT(m_glContext); + m_glContext->makeCurrent(); + m_painter = new QVideoSurfaceGlslPainter(m_glContext); + break; + default: + m_painter = new QVideoSurfaceRasterPainter; + break; + } +#else + m_painter = new QVideoSurfaceRasterPainter; +#endif +} + +QT_END_NAMESPACE + +#include "moc_qpaintervideosurface_p.cpp" + + diff --git a/src/multimedia/base/qpaintervideosurface_p.h b/src/multimedia/base/qpaintervideosurface_p.h new file mode 100644 index 0000000..d4b6740 --- /dev/null +++ b/src/multimedia/base/qpaintervideosurface_p.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPAINTERVIDEOSURFACE_P_H +#define QPAINTERVIDEOSURFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qsize.h> +#include <QtGui/qimage.h> +#include <QtGui/qmatrix4x4.h> +#include <QtGui/qpaintengine.h> +#include <QtMultimedia/qabstractvideosurface.h> +#include <QtMultimedia/qvideoframe.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGLContext; + + +class QVideoSurfacePainter; +class Q_MULTIMEDIA_EXPORT QPainterVideoSurface : public QAbstractVideoSurface +{ + Q_OBJECT +public: + explicit QPainterVideoSurface(QObject *parent = 0); + ~QPainterVideoSurface(); + + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; + + bool isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar = 0) const; + + bool start(const QVideoSurfaceFormat &format); + void stop(); + + bool present(const QVideoFrame &frame); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + + bool isReady() const; + void setReady(bool ready); + + void paint(QPainter *painter, const QRectF &target, const QRectF &source = QRectF(0, 0, 1, 1)); + +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + const QGLContext *glContext() const; + void setGLContext(QGLContext *context); + + enum ShaderType + { + NoShaders = 0x00, + FragmentProgramShader = 0x01, + GlslShader = 0x02 + }; + + Q_DECLARE_FLAGS(ShaderTypes, ShaderType) + + ShaderTypes supportedShaderTypes() const; + + ShaderType shaderType() const; + void setShaderType(ShaderType type); +#endif + +Q_SIGNALS: + void frameChanged(); + +private: + void createPainter(); + + QVideoSurfacePainter *m_painter; +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + QGLContext *m_glContext; + ShaderTypes m_shaderTypes; + ShaderType m_shaderType; +#endif + int m_brightness; + int m_contrast; + int m_hue; + int m_saturation; + + QVideoFrame::PixelFormat m_pixelFormat; + QSize m_frameSize; + QRect m_sourceRect; + bool m_colorsDirty; + bool m_ready; +}; + +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) +Q_DECLARE_OPERATORS_FOR_FLAGS(QPainterVideoSurface::ShaderTypes) +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qtmedianamespace.h b/src/multimedia/base/qtmedianamespace.h new file mode 100644 index 0000000..2a56fc3 --- /dev/null +++ b/src/multimedia/base/qtmedianamespace.h @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTMEDIANAMESPACE_H +#define QTMEDIANAMESPACE_H + +#include <QtCore/qpair.h> +#include <QtCore/qmetatype.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +namespace QtMultimedia +{ + enum MetaData + { + // Common + Title, + SubTitle, + Author, + Comment, + Description, + Category, + Genre, + Year, + Date, + UserRating, + Keywords, + Language, + Publisher, + Copyright, + ParentalRating, + RatingOrganisation, + + // Media + Size, + MediaType, + Duration, + + // Audio + AudioBitRate, + AudioCodec, + AverageLevel, + ChannelCount, + PeakValue, + SampleRate, + + // Music + AlbumTitle, + AlbumArtist, + ContributingArtist, + Composer, + Conductor, + Lyrics, + Mood, + TrackNumber, + TrackCount, + + CoverArtUrlSmall, + CoverArtUrlLarge, + + // Image/Video + Resolution, + PixelAspectRatio, + + // Video + VideoFrameRate, + VideoBitRate, + VideoCodec, + + PosterUrl, + + // Movie + ChapterNumber, + Director, + LeadPerformer, + Writer, + + // Photos + CameraManufacturer, + CameraModel, + Event, + Subject, + Orientation, + ExposureTime, + FNumber, + ExposureProgram, + ISOSpeedRatings, + ExposureBiasValue, + DateTimeOriginal, + DateTimeDigitized, + SubjectDistance, + MeteringMode, + LightSource, + Flash, + FocalLength, + ExposureMode, + WhiteBalance, + DigitalZoomRatio, + FocalLengthIn35mmFilm, + SceneCaptureType, + GainControl, + Contrast, + Saturation, + Sharpness, + DeviceSettingDescription + }; + + enum SupportEstimate + { + NotSupported, + MaybeSupported, + ProbablySupported, + PreferedService + }; + + enum EncodingQuality + { + VeryLowQuality, + LowQuality, + NormalQuality, + HighQuality, + VeryHighQuality + }; + + enum EncodingMode + { + ConstantQualityEncoding, + ConstantBitRateEncoding, + AverageBitRateEncoding, + TwoPassEncoding + }; + + enum AvailabilityError + { + NoError, + ServiceMissingError, + BusyError, + ResourceError + }; + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qtmedianamespace.qdoc b/src/multimedia/base/qtmedianamespace.qdoc new file mode 100644 index 0000000..0fb39f5 --- /dev/null +++ b/src/multimedia/base/qtmedianamespace.qdoc @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \namespace QtMedia + \ingroup multimedia + + \brief The QtMedia namespace contains miscellaneous identifiers used throughout the Qt Media + library. +*/ + +/*! + \enum QtMedia::MetaData + + This enum provides identifiers for meta-data attributes. + + Common attributes + \value Title The title of the media. QString. + \value SubTitle The sub-title of the media. QString. + \value Author The authors of the media. QStringList. + \value Comment A user comment about the media. QString. + \value Description A description of the media. QString + \value Category The category of the media. QStringList. + \value Genre The genre of the media. QStringList. + \value Year The year of release of the media. int. + \value Date The date of the media. QDate. + \value UserRating A user rating of the media. int [0..100]. + \value Keywords A list of keywords describing the media. QStringList. + \value Language The language of media, as an ISO 639-2 code. + + \value Publisher The publisher of the media. QString. + \value Copyright The media's copyright notice. QString. + \value ParentalRating The parental rating of the media. QString. + \value RatingOrganisation The organisation responsible for the parental rating of the media. + QString. + + Media attributes + \value Size The size in bytes of the media. qint64 + \value MediaType The type of the media (audio, video, etc). QString. + \value Duration The duration in millseconds of the media. qint64. + + Audio attributes + \value AudioBitRate The bit rate of the media's audio stream in bits per second. int. + \value AudioCodec The codec of the media's audio stream. QString. + \value AverageLevel The average volume level of the media. int. + \value ChannelCount The number of channels in the media's audio stream. int. + \value PeakValue The peak volume of the media's audio stream. int + \value SampleRate The sample rate of the media's audio stream in hertz. int + + Music attributes + \value AlbumTitle The title of the album the media belongs to. QString. + \value AlbumArtist The principal artist of the album the media belongs to. QString. + \value ContributingArtist The artists contributing to the media. QStringList. + \value Composer The composer of the media. QStringList. + \value Conductor The conductor of the media. QString. + \value Lyrics The lyrics to the media. QString. + \value Mood The mood of the media. QString. + \value TrackNumber The track number of the media. int. + \value TrackCount The number of tracks on the album containing the media. int. + + \value CoverArtUrlSmall The URL of a small cover art image. QUrl. + \value CoverArtUrlLarge The URL of a large cover art image. QUrl. + + Image and video attributes + \value Resolution The dimensions of an image or video. QSize. + \value PixelAspectRatio The pixel aspect ratio of an image or video. QSize. + + Video attributes + \value VideoFrameRate The frame rate of the media's video stream. qreal. + \value VideoBitRate The bit rate of the media's video stream in bits per second. int. + \value VideoCodec The codec of the media's video stream. QString. + + \value PosterUrl The URL of a poster image. QUrl. + + Movie attributes + \value ChapterNumber The chapter number of the media. int. + \value Director The director of the media. QString. + \value LeadPerformer The lead performer in the media. QStringList. + \value Writer The writer of the media. QStringList. + + Photo attributes. + \value CameraManufacturer The manufacturer of the camera used to capture the media. QString. + \value CameraModel The model of the camera used to capture the media. QString. + \value Event The event during which the media was captured. QString. + \value Subject The subject of the media. QString. + \value Orientation Orientation of image. + \value ExposureTime Exposure time, given in seconds. + \value FNumber The F Number. + \value ExposureProgram + The class of the program used by the camera to set exposure when the picture is taken. + \value ISOSpeedRatings + Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232. + \value ExposureBiasValue + The exposure bias. + The unit is the APEX (Additive System of Photographic Exposure) setting. + \value DateTimeOriginal The date and time when the original image data was generated. + \value DateTimeDigitized The date and time when the image was stored as digital data. + \value SubjectDistance The distance to the subject, given in meters. + \value MeteringMode The metering mode. + \value LightSource + The kind of light source. + \value Flash + Status of flash when the image was shot. + \value FocalLength + The actual focal length of the lens, in mm. + \value ExposureMode + Indicates the exposure mode set when the image was shot. + \value WhiteBalance + Indicates the white balance mode set when the image was shot. + \value DigitalZoomRatio + Indicates the digital zoom ratio when the image was shot. + \value FocalLengthIn35mmFilm + Indicates the equivalent focal length assuming a 35mm film camera, in mm. + \value SceneCaptureType + Indicates the type of scene that was shot. + It can also be used to record the mode in which the image was shot. + \value GainControl + Indicates the degree of overall image gain adjustment. + \value Contrast + Indicates the direction of contrast processing applied by the camera when the image was shot. + \value Saturation + Indicates the direction of saturation processing applied by the camera when the image was shot. + \value Sharpness + Indicates the direction of sharpness processing applied by the camera when the image was shot. + \value DeviceSettingDescription + Exif tag, indicates information on the picture-taking conditions of a particular camera model. QString +*/ + +/*! + \enum QtMedia::SupportEstimate + + Enumerates the levels of support a media service provider may have for a feature. + + \value NotSupported The feature is not supported. + \value MaybeSupported The feature may be supported. + \value ProbablySupported The feature is probably supported. + \value PreferedService The service is the preferred provider of a service. +*/ + +/*! + \enum QtMedia::EncodingQuality + + Enumerates quality encoding levels. + + \value VeryLowQuality + \value LowQuality + \value NormalQuality + \value HighQuality + \value VeryHighQuality +*/ + +/*! + \enum QtMedia::EncodingMode + + Enumerates encoding modes. + + \value ConstantQualityEncoding + \value ConstantBitRateEncoding + \value AverageBitRateEncoding + \value TwoPassEncoding +*/ + +/*! + \enum QtMedia::AvailabilityError + + Enumerates Service status errors. + + \value NoError + \value ServiceMissingError + \value ResourceError + \value BusyError +*/ diff --git a/src/multimedia/base/qvideodevicecontrol.cpp b/src/multimedia/base/qvideodevicecontrol.cpp new file mode 100644 index 0000000..21db500 --- /dev/null +++ b/src/multimedia/base/qvideodevicecontrol.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qvideodevicecontrol.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +/*! + \class QVideoDeviceControl + \preliminary + \brief The QVideoDeviceControl class provides an video device selector media control. + \ingroup multimedia-serv + + The QVideoDeviceControl class provides descriptions of the video devices + available on a system and allows one to be selected as the endpoint of + a media service. + + The interface name of QVideoDeviceControl is \c com.nokia.Qt.VideoDeviceControl as + defined in QVideoDeviceControl_iid. +*/ + +/*! + \macro QVideoDeviceControl_iid + + \c com.nokia.Qt.VideoDeviceControl + + Defines the interface name of the QVideoDeviceControl class. + + \relates QVideoDeviceControl +*/ + +/*! + Constructs a video device control with the given \a parent. +*/ +QVideoDeviceControl::QVideoDeviceControl(QObject *parent) + :QMediaControl(parent) +{ +} + +/*! + Destroys a video device control. +*/ +QVideoDeviceControl::~QVideoDeviceControl() +{ +} + +/*! + \fn QVideoDeviceControl::deviceCount() const + + Returns the number of available video devices; +*/ + +/*! + \fn QVideoDeviceControl::deviceName(int index) const + + Returns the name of the video device at \a index. +*/ + +/*! + \fn QVideoDeviceControl::deviceDescription(int index) const + + Returns a description of the video device at \a index. +*/ + +/*! + \fn QVideoDeviceControl::deviceIcon(int index) const + + Returns an icon for the video device at \a index. +*/ + +/*! + \fn QVideoDeviceControl::defaultDevice() const + + Returns the index of the default video device. +*/ + +/*! + \fn QVideoDeviceControl::selectedDevice() const + + Returns the index of the selected video device. +*/ + +/*! + \fn QVideoDeviceControl::setSelectedDevice(int index) + + Sets the selected video device \a index. +*/ + +/*! + \fn QVideoDeviceControl::devicesChanged() + + Signals that the list of available video devices has changed. +*/ + +/*! + \fn QVideoDeviceControl::selectedDeviceChanged(int index) + + Signals that the selected video device \a index has changed. +*/ + +/*! + \fn QVideoDeviceControl::selectedDeviceChanged(const QString &name) + + Signals that the selected video device \a name has changed. +*/ + +QT_END_NAMESPACE + +QT_END_HEADER + +#include "moc_qvideodevicecontrol.cpp" + + diff --git a/src/multimedia/base/qvideodevicecontrol.h b/src/multimedia/base/qvideodevicecontrol.h new file mode 100644 index 0000000..ce99fd1 --- /dev/null +++ b/src/multimedia/base/qvideodevicecontrol.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEODEVICECONTROL_H +#define QVIDEODEVICECONTROL_H + +#include <QtMultimedia/qmediacontrol.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class Q_MULTIMEDIA_EXPORT QVideoDeviceControl : public QMediaControl +{ + Q_OBJECT + +public: + virtual ~QVideoDeviceControl(); + + virtual int deviceCount() const = 0; + + virtual QString deviceName(int index) const = 0; + virtual QString deviceDescription(int index) const = 0; + virtual QIcon deviceIcon(int index) const = 0; + + virtual int defaultDevice() const = 0; + virtual int selectedDevice() const = 0; + +public Q_SLOTS: + virtual void setSelectedDevice(int index) = 0; + +Q_SIGNALS: + void selectedDeviceChanged(int index); + void selectedDeviceChanged(const QString &deviceName); + void devicesChanged(); + +protected: + QVideoDeviceControl(QObject *parent = 0); +}; + +#define QVideoDeviceControl_iid "com.nokia.Qt.QVideoDeviceControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QVideoDeviceControl, QVideoDeviceControl_iid) + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QVIDEODEVICECONTROL_H diff --git a/src/multimedia/base/qvideooutputcontrol.cpp b/src/multimedia/base/qvideooutputcontrol.cpp new file mode 100644 index 0000000..a904385 --- /dev/null +++ b/src/multimedia/base/qvideooutputcontrol.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qvideooutputcontrol.h> + + +QT_BEGIN_NAMESPACE + +/*! + \class QVideoOutputControl + \preliminary + + \brief The QVideoOutputControl class provides a means of selecting the + active video output control. + + \ingroup multimedia-serv + + There are multiple controls which a QMediaService may use to output + video ony one of which may be active at one time, QVideoOutputControl + is the means by which this active control is selected. + + The possible output controls are QVideoRendererControl, + QVideoWindowControl, and QVideoWidgetControl. + + The interface name of QVideoOutputControl is \c com.nokia.Qt.QVideoOutputControl/1.0 as + defined in QVideoOutputControl_iid. + + \sa QMediaService::control(), QVideoWidget, QVideoRendererControl, + QVideoWindowControl, QVideoWidgetControl +*/ + +/*! + \macro QVideoOutputControl_iid + + \c com.nokia.Qt.QVideoOutputControl/1.0 + + Defines the interface name of the QVideoOutputControl class. + + \relates QVideoOutputControl +*/ + +/*! + \enum QVideoOutputControl::Output + + Identifies the possible render targets of a video output. + + \value NoOutput Video is not rendered. + \value WindowOutput Video is rendered to the target of a QVideoWindowControl. + \value RendererOutput Video is rendered to the target of a QVideoRendererControl. + \value WidgetOutput Video is rendered to a QWidget provided by QVideoWidgetControl. + \value UserOutput Start value for user defined video targets. + \value MaxUserOutput End value for user defined video targets. +*/ + +/*! + Constructs a new video output control with the given \a parent. +*/ +QVideoOutputControl::QVideoOutputControl(QObject *parent) + : QMediaControl(parent) +{ +} + +/*! + Destroys a video output control. +*/ +QVideoOutputControl::~QVideoOutputControl() +{ +} + +/*! + \fn QList<QVideoOutputControl::Output> QVideoOutputControl::availableOutputs() const + + Returns a list of available video output targets. +*/ + +/*! + \fn QVideoOutputControl::output() const + + Returns the current video output target. +*/ + +/*! + \fn QVideoOutputControl::setOutput(Output output) + + Sets the current video \a output target. +*/ + +/*! + \fn QVideoOutputControl::availableOutputsChanged(const QList<QVideoOutputControl::Output> &outputs) + + Signals that available set of video \a outputs has changed. +*/ + +#include "moc_qvideooutputcontrol.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qvideooutputcontrol.h b/src/multimedia/base/qvideooutputcontrol.h new file mode 100644 index 0000000..805da58 --- /dev/null +++ b/src/multimedia/base/qvideooutputcontrol.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEOOUTPUTCONTROL_H +#define QVIDEOOUTPUTCONTROL_H + +#include <QtMultimedia/qmediacontrol.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class Q_MULTIMEDIA_EXPORT QVideoOutputControl : public QMediaControl +{ + Q_OBJECT + +public: + enum Output + { + NoOutput, + WindowOutput, + RendererOutput, + WidgetOutput, + UserOutput = 100, + MaxUserOutput = 1000 + }; + + ~QVideoOutputControl(); + + virtual QList<Output> availableOutputs() const = 0; + + virtual Output output() const = 0; + virtual void setOutput(Output output) = 0; + +Q_SIGNALS: + void availableOutputsChanged(const QList<QVideoOutputControl::Output> &outputs); + +protected: + QVideoOutputControl(QObject *parent = 0); +}; + +#define QVideoOutputControl_iid "com.nokia.Qt.QVideoOutputControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QVideoOutputControl, QVideoOutputControl_iid) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qvideorenderercontrol.cpp b/src/multimedia/base/qvideorenderercontrol.cpp new file mode 100644 index 0000000..4e7b3da --- /dev/null +++ b/src/multimedia/base/qvideorenderercontrol.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qvideorenderercontrol.h> + +#include "qmediacontrol_p.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QVideoRendererControl + \preliminary + + \brief The QVideoRendererControl class provides a control for rendering + to a video surface. + + \ingroup multimedia-serv + + Using the surface() property of QVideoRendererControl a QAbstractVideoSurface + may be set as the video render target of a QMediaService. + + \code + QVideoRendererControl *rendererControl = mediaService->control<QVideoRendererControl *>(); + rendererControl->setSurface(myVideoSurface); + \endcode + + QVideoRendererControl is one of number of possible video output controls, + in order to receive video it must be made the active video output + control by setting the output property of QVideoOutputControl to + \l {QVideoOutputControl::RendererOutput}{RendererOutput}. Consequently any + QMediaService that implements QVideoRendererControl must also implement + QVideoOutputControl. + + \code + QVideoOutputControl *outputControl = mediaService->control<QVideoOutputControl *>(); + outputControl->setOutput(QVideoOutputControl::RendererOutput); + \endcode + + The interface name of QVideoRendererControl is \c com.nokia.Qt.QVideoRendererControl/1.0 as + defined in QVideoRendererControl_iid. + + \sa QMediaService::control(), QVideoOutputControl, QVideoWidget +*/ + +/*! + \macro QVideoRendererControl_iid + + \c com.nokia.Qt.QVideoRendererControl/1.0 + + Defines the interface name of the QVideoRendererControl class. + + \relates QVideoRendererControl +*/ + +/*! + Constructs a new video renderer media end point with the given \a parent. +*/ +QVideoRendererControl::QVideoRendererControl(QObject *parent) + : QMediaControl(parent) +{ +} + +/*! + Destroys a video renderer media end point. +*/ +QVideoRendererControl::~QVideoRendererControl() +{ +} + +/*! + \fn QVideoRendererControl::surface() const + + Returns the surface a video producer renders to. +*/ + +/*! + \fn QVideoRendererControl::setSurface(QAbstractVideoSurface *surface) + + Sets the \a surface a video producer renders to. +*/ + +#include "moc_qvideorenderercontrol.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qvideorenderercontrol.h b/src/multimedia/base/qvideorenderercontrol.h new file mode 100644 index 0000000..f5ba83e --- /dev/null +++ b/src/multimedia/base/qvideorenderercontrol.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEORENDERERCONTROL_H +#define QVIDEORENDERERCONTROL_H + +#include <QtMultimedia/qmediacontrol.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QAbstractVideoSurface; + +class Q_MULTIMEDIA_EXPORT QVideoRendererControl : public QMediaControl +{ + Q_OBJECT + +public: + ~QVideoRendererControl(); + + virtual QAbstractVideoSurface *surface() const = 0; + virtual void setSurface(QAbstractVideoSurface *surface) = 0; + +protected: + QVideoRendererControl(QObject *parent = 0); +}; + +#define QVideoRendererControl_iid "com.nokia.Qt.QVideoRendererControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QVideoRendererControl, QVideoRendererControl_iid) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QVIDEORENDERERCONTROL_H diff --git a/src/multimedia/base/qvideowidget.cpp b/src/multimedia/base/qvideowidget.cpp new file mode 100644 index 0000000..5df245e --- /dev/null +++ b/src/multimedia/base/qvideowidget.cpp @@ -0,0 +1,913 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qvideowidget_p.h" + +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qvideooutputcontrol.h> +#include <QtMultimedia/qvideowindowcontrol.h> +#include <QtMultimedia/qvideowidgetcontrol.h> + +#include "qpaintervideosurface_p.h" +#include <QtMultimedia/qvideorenderercontrol.h> +#include <QtMultimedia/qvideosurfaceformat.h> +#include <qpainter.h> + +#include <qapplication.h> +#include <qevent.h> +#include <qdialog.h> +#include <qboxlayout.h> +#include <qnamespace.h> + + +QT_BEGIN_NAMESPACE + +QVideoWidgetControlBackend::QVideoWidgetControlBackend( + QVideoWidgetControl *control, QWidget *widget) + : m_widgetControl(control) +{ + connect(control, SIGNAL(brightnessChanged(int)), widget, SLOT(_q_brightnessChanged(int))); + connect(control, SIGNAL(contrastChanged(int)), widget, SLOT(_q_contrastChanged(int))); + connect(control, SIGNAL(hueChanged(int)), widget, SLOT(_q_hueChanged(int))); + connect(control, SIGNAL(saturationChanged(int)), widget, SLOT(_q_saturationChanged(int))); + connect(control, SIGNAL(fullScreenChanged(bool)), widget, SLOT(_q_fullScreenChanged(bool))); + + QBoxLayout *layout = new QVBoxLayout; + layout->setMargin(0); + layout->setSpacing(0); + layout->addWidget(control->videoWidget()); + + widget->setLayout(layout); +} + +void QVideoWidgetControlBackend::setBrightness(int brightness) +{ + m_widgetControl->setBrightness(brightness); +} + +void QVideoWidgetControlBackend::setContrast(int contrast) +{ + m_widgetControl->setContrast(contrast); +} + +void QVideoWidgetControlBackend::setHue(int hue) +{ + m_widgetControl->setHue(hue); +} + +void QVideoWidgetControlBackend::setSaturation(int saturation) +{ + m_widgetControl->setSaturation(saturation); +} + +void QVideoWidgetControlBackend::setFullScreen(bool fullScreen) +{ + m_widgetControl->setFullScreen(fullScreen); +} + + +QVideoWidget::AspectRatioMode QVideoWidgetControlBackend::aspectRatioMode() const +{ + return m_widgetControl->aspectRatioMode(); +} + +void QVideoWidgetControlBackend::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + m_widgetControl->setAspectRatioMode(mode); +} + +QRendererVideoWidgetBackend::QRendererVideoWidgetBackend( + QVideoRendererControl *control, QWidget *widget) + : m_rendererControl(control) + , m_widget(widget) + , m_surface(new QPainterVideoSurface) + , m_aspectRatioMode(QVideoWidget::KeepAspectRatio) + , m_updatePaintDevice(true) +{ + connect(this, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int))); + connect(this, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int))); + connect(this, SIGNAL(hueChanged(int)), m_widget, SLOT(_q_hueChanged(int))); + connect(this, SIGNAL(saturationChanged(int)), m_widget, SLOT(_q_saturationChanged(int))); + connect(m_surface, SIGNAL(frameChanged()), m_widget, SLOT(update())); + connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)), + m_widget, SLOT(_q_dimensionsChanged())); + + m_rendererControl->setSurface(m_surface); +} + +QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend() +{ + delete m_surface; +} + +void QRendererVideoWidgetBackend::clearSurface() +{ + m_rendererControl->setSurface(0); +} + +void QRendererVideoWidgetBackend::setBrightness(int brightness) +{ + m_surface->setBrightness(brightness); + + emit brightnessChanged(brightness); +} + +void QRendererVideoWidgetBackend::setContrast(int contrast) +{ + m_surface->setContrast(contrast); + + emit contrastChanged(contrast); +} + +void QRendererVideoWidgetBackend::setHue(int hue) +{ + m_surface->setHue(hue); + + emit hueChanged(hue); +} + +void QRendererVideoWidgetBackend::setSaturation(int saturation) +{ + m_surface->setSaturation(saturation); + + emit saturationChanged(saturation); +} + +QVideoWidget::AspectRatioMode QRendererVideoWidgetBackend::aspectRatioMode() const +{ + return m_aspectRatioMode; +} + +void QRendererVideoWidgetBackend::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + m_aspectRatioMode = mode; + + m_widget->updateGeometry(); +} + +void QRendererVideoWidgetBackend::setFullScreen(bool) +{ +} + +QSize QRendererVideoWidgetBackend::sizeHint() const +{ + return m_surface->surfaceFormat().sizeHint(); +} + +void QRendererVideoWidgetBackend::showEvent() +{ +} + +void QRendererVideoWidgetBackend::hideEvent(QHideEvent *) +{ +#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + m_updatePaintDevice = true; + m_surface->setGLContext(0); +#endif +} + +void QRendererVideoWidgetBackend::resizeEvent(QResizeEvent *) +{ +} + +void QRendererVideoWidgetBackend::moveEvent(QMoveEvent *) +{ +} + +void QRendererVideoWidgetBackend::paintEvent(QPaintEvent *event) +{ + QPainter painter(m_widget); + + if (m_surface->isActive()) { + m_surface->paint(&painter, displayRect()); + + m_surface->setReady(true); + } else { + painter.fillRect(event->rect(), m_widget->palette().background()); + + #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1) + if (m_updatePaintDevice && (painter.paintEngine()->type() == QPaintEngine::OpenGL + || painter.paintEngine()->type() == QPaintEngine::OpenGL2)) { + m_updatePaintDevice = false; + + m_surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext())); + if (m_surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) { + m_surface->setShaderType(QPainterVideoSurface::GlslShader); + } else { + m_surface->setShaderType(QPainterVideoSurface::FragmentProgramShader); + } + } +#endif + } +} + +QRect QRendererVideoWidgetBackend::displayRect() const +{ + QRect displayRect = m_widget->rect(); + + if (m_aspectRatioMode != QVideoWidget::IgnoreAspectRatio) { + QVideoSurfaceFormat format = m_surface->surfaceFormat(); + + QSize aspectRatio = format.pixelAspectRatio(); + + QSize size = format.viewport().size(); + size.rwidth() *= aspectRatio.width(); + size.rheight() *= aspectRatio.height(); + size.scale(displayRect.size(), Qt::KeepAspectRatio); + + QPoint center = displayRect.center(); + + displayRect = QRect(QPoint(0, 0), size); + displayRect.moveCenter(center); + } + + return displayRect; +} + +QWindowVideoWidgetBackend::QWindowVideoWidgetBackend(QVideoWindowControl *control, QWidget *widget) + : m_windowControl(control) + , m_widget(widget) + , m_aspectRatioMode(QVideoWidget::KeepAspectRatio) +{ + connect(control, SIGNAL(brightnessChanged(int)), m_widget, SLOT(_q_brightnessChanged(int))); + connect(control, SIGNAL(contrastChanged(int)), m_widget, SLOT(_q_contrastChanged(int))); + connect(control, SIGNAL(hueChanged(int)), m_widget, SLOT(_q_hueChanged(int))); + connect(control, SIGNAL(saturationChanged(int)), m_widget, SLOT(_q_saturationChanged(int))); + connect(control, SIGNAL(fullScreenChanged(bool)), m_widget, SLOT(_q_fullScreenChanged(bool))); + connect(control, SIGNAL(nativeSizeChanged()), m_widget, SLOT(_q_dimensionsChanged())); +} + +QWindowVideoWidgetBackend::~QWindowVideoWidgetBackend() +{ +} + +void QWindowVideoWidgetBackend::setBrightness(int brightness) +{ + m_windowControl->setBrightness(brightness); +} + +void QWindowVideoWidgetBackend::setContrast(int contrast) +{ + m_windowControl->setContrast(contrast); +} + +void QWindowVideoWidgetBackend::setHue(int hue) +{ + m_windowControl->setHue(hue); +} + +void QWindowVideoWidgetBackend::setSaturation(int saturation) +{ + m_windowControl->setSaturation(saturation); +} + +void QWindowVideoWidgetBackend::setFullScreen(bool fullScreen) +{ + m_windowControl->setFullScreen(fullScreen); +} + +QVideoWidget::AspectRatioMode QWindowVideoWidgetBackend::aspectRatioMode() const +{ + return m_windowControl->aspectRatioMode(); +} + +void QWindowVideoWidgetBackend::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + m_windowControl->setAspectRatioMode(mode); +} + +QSize QWindowVideoWidgetBackend::sizeHint() const +{ + return m_windowControl->nativeSize(); +} + +void QWindowVideoWidgetBackend::showEvent() +{ + m_windowControl->setWinId(m_widget->winId()); + + m_windowControl->setDisplayRect(m_widget->rect()); +} + +void QWindowVideoWidgetBackend::hideEvent(QHideEvent *) +{ +} + +void QWindowVideoWidgetBackend::moveEvent(QMoveEvent *) +{ + m_windowControl->setDisplayRect(m_widget->rect()); +} + +void QWindowVideoWidgetBackend::resizeEvent(QResizeEvent *) +{ + m_windowControl->setDisplayRect(m_widget->rect()); +} + +void QWindowVideoWidgetBackend::paintEvent(QPaintEvent *event) +{ + m_windowControl->repaint(); + + event->accept(); +} + +void QVideoWidgetPrivate::setCurrentControl(QVideoWidgetControlInterface *control) +{ + if (currentControl != control) { + currentControl = control; + + currentControl->setBrightness(brightness); + currentControl->setContrast(contrast); + currentControl->setHue(hue); + currentControl->setSaturation(saturation); + currentControl->setAspectRatioMode(aspectRatioMode); + } +} + +void QVideoWidgetPrivate::show() +{ + if (outputControl) { + if (widgetBackend != 0) { + setCurrentControl(widgetBackend); + outputControl->setOutput(QVideoOutputControl::WidgetOutput); + } else if (windowBackend != 0 && (q_func()->window() == 0 + || !q_func()->window()->testAttribute(Qt::WA_DontShowOnScreen))) { + windowBackend->showEvent(); + currentBackend = windowBackend; + setCurrentControl(windowBackend); + outputControl->setOutput(QVideoOutputControl::WindowOutput); + } else if (rendererBackend != 0) { + rendererBackend->showEvent(); + currentBackend = rendererBackend; + setCurrentControl(rendererBackend); + outputControl->setOutput(QVideoOutputControl::RendererOutput); + } else { + outputControl->setOutput(QVideoOutputControl::NoOutput); + } + } +} + +void QVideoWidgetPrivate::clearService() +{ + if (service) { + QObject::disconnect(service, SIGNAL(destroyed()), q_func(), SLOT(_q_serviceDestroyed())); + + if (outputControl) + outputControl->setOutput(QVideoOutputControl::NoOutput); + + if (widgetBackend) { + QLayout *layout = q_func()->layout(); + + for (QLayoutItem *item = layout->takeAt(0); item; item = layout->takeAt(0)) { + item->widget()->setParent(0); + delete item; + } + delete layout; + + delete widgetBackend; + widgetBackend = 0; + } + + delete windowBackend; + windowBackend = 0; + + if (rendererBackend) { + rendererBackend->clearSurface(); + + delete rendererBackend; + rendererBackend = 0; + } + + currentBackend = 0; + currentControl = 0; + outputControl = 0; + service = 0; + } +} + +void QVideoWidgetPrivate::_q_serviceDestroyed() +{ + if (widgetBackend) { + delete q_func()->layout(); + + delete widgetBackend; + widgetBackend = 0; + } + + delete windowBackend; + windowBackend = 0; + + delete rendererBackend; + rendererBackend = 0; + + currentControl = 0; + currentBackend = 0; + outputControl = 0; + service = 0; +} + +void QVideoWidgetPrivate::_q_mediaObjectDestroyed() +{ + mediaObject = 0; + clearService(); +} + +void QVideoWidgetPrivate::_q_brightnessChanged(int b) +{ + if (b != brightness) + emit q_func()->brightnessChanged(brightness = b); +} + +void QVideoWidgetPrivate::_q_contrastChanged(int c) +{ + if (c != contrast) + emit q_func()->contrastChanged(contrast = c); +} + +void QVideoWidgetPrivate::_q_hueChanged(int h) +{ + if (h != hue) + emit q_func()->hueChanged(hue = h); +} + +void QVideoWidgetPrivate::_q_saturationChanged(int s) +{ + if (s != saturation) + emit q_func()->saturationChanged(saturation = s); +} + + +void QVideoWidgetPrivate::_q_fullScreenChanged(bool fullScreen) +{ + if (!fullScreen && q_func()->isFullScreen()) + q_func()->showNormal(); +} + +void QVideoWidgetPrivate::_q_dimensionsChanged() +{ + q_func()->updateGeometry(); +} + +/*! + \class QVideoWidget + \preliminary + + \brief The QVideoWidget class provides a widget which presents video + produced by a media object. + \ingroup multimedia + + Attaching a QVideoWidget to a QMediaObject allows it to display the + video or image output of that media object. A QVideoWidget is attached + to media object by passing a pointer to the QMediaObject in its + constructor, and detached by destroying the QVideoWidget. + + \code + player = new QMediaPlayer; + + widget = new QVideoWidget(player); + widget->show(); + + player->setMedia(QUrl("http://example.com/movie.mp4")); + player->play(); + \endcode + + \bold {Note}: Only a single display output can be attached to a media + object at one time. + + \sa QMediaObject, QMediaPlayer, QGraphicsVideoItem +*/ + +/*! + \enum QVideoWidget::AspectRatioMode + + Specfies how video is scaled with respect to its aspect ratio. + + \value IgnoreAspectRatio The video is scaled to fill the widget ignoring its aspect ratio. + \value KeepAspectRatio The video is scaled to the largest rectangle that will fit within the + widget's dimensions while still retaining its original aspect ratio. +*/ + +/*! + Constructs a new video widget. + + The \a parent is passed to QWidget. +*/ +QVideoWidget::QVideoWidget(QWidget *parent) + : QWidget(parent, 0) + , d_ptr(new QVideoWidgetPrivate) +{ + d_ptr->q_ptr = this; + + QPalette palette = QWidget::palette(); + palette.setColor(QPalette::Background, Qt::black); + setPalette(palette); +} + +/*! + Destroys a video widget. +*/ +QVideoWidget::~QVideoWidget() +{ + setMediaObject(0); + delete d_ptr; +} + +/*! + \property QVideoWidget::mediaObject + \brief the media object which provides the video displayed by a widget. +*/ + +QMediaObject *QVideoWidget::mediaObject() const +{ + return d_func()->mediaObject; +} + +void QVideoWidget::setMediaObject(QMediaObject *object) +{ + Q_D(QVideoWidget); + + if (object == d->mediaObject) + return; + + if (d->mediaObject) { + disconnect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed())); + d->mediaObject->unbind(this); + } + + d->clearService(); + + d->mediaObject = object; + + if (d->mediaObject) { + d->service = d->mediaObject->service(); + + connect(d->mediaObject, SIGNAL(destroyed()), this, SLOT(_q_mediaObjectDestroyed())); + d->mediaObject->bind(this); + } + + if (d->service) { + connect(d->service, SIGNAL(destroyed()), SLOT(_q_serviceDestroyed())); + + d->outputControl = qobject_cast<QVideoOutputControl *>( + d->service->control(QVideoOutputControl_iid)); + + QVideoWidgetControl *widgetControl = qobject_cast<QVideoWidgetControl *>( + d->service->control(QVideoWidgetControl_iid)); + + if (widgetControl != 0) { + d->widgetBackend = new QVideoWidgetControlBackend(widgetControl, this); + } else { + QVideoWindowControl *windowControl = qobject_cast<QVideoWindowControl *>( + d->service->control(QVideoWindowControl_iid)); + + if (windowControl != 0) + d->windowBackend = new QWindowVideoWidgetBackend(windowControl, this); + + QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>( + d->service->control(QVideoRendererControl_iid)); + + if (rendererControl != 0) + d->rendererBackend = new QRendererVideoWidgetBackend(rendererControl, this); + } + + if (isVisible()) + d->show(); + } +} + +/*! + \property QVideoWidget::aspectRatioMode + \brief how video is scaled with respect to its aspect ratio. +*/ + +QVideoWidget::AspectRatioMode QVideoWidget::aspectRatioMode() const +{ + return d_func()->aspectRatioMode; +} + +void QVideoWidget::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + Q_D(QVideoWidget); + + if (d->currentControl) { + d->currentControl->setAspectRatioMode(mode); + d->aspectRatioMode = d->currentControl->aspectRatioMode(); + } else { + d->aspectRatioMode = mode; + } +} + +/*! + \property QVideoWidget::fullScreen + \brief whether video display is confined to a window or is fullScreen. +*/ + +void QVideoWidget::setFullScreen(bool fullScreen) +{ + Q_D(QVideoWidget); + + if (fullScreen) { + Qt::WindowFlags flags = windowFlags(); + + d->nonFullScreenFlags = flags & (Qt::Window | Qt::SubWindow); + flags |= Qt::Window; + flags &= ~Qt::SubWindow; + setWindowFlags(flags); + + showFullScreen(); + } else { + showNormal(); + } +} + +/*! + \fn QVideoWidget::fullScreenChanged(bool fullScreen) + + Signals that the \a fullScreen mode of a video widget has changed. + + \sa fullScreen +*/ + +/*! + \property QVideoWidget::brightness + \brief an adjustment to the brightness of displayed video. + + Valid brightness values range between -100 and 100, the default is 0. +*/ + +int QVideoWidget::brightness() const +{ + return d_func()->brightness; +} + +void QVideoWidget::setBrightness(int brightness) +{ + Q_D(QVideoWidget); + + int boundedBrightness = qBound(-100, brightness, 100); + + if (d->currentControl) + d->currentControl->setBrightness(boundedBrightness); + else if (d->brightness != boundedBrightness) + emit brightnessChanged(d->brightness = boundedBrightness); +} + +/*! + \fn QVideoWidget::brightnessChanged(int brightness) + + Signals that a video widgets's \a brightness adjustment has changed. + + \sa brightness +*/ + +/*! + \property QVideoWidget::contrast + \brief an adjustment to the contrast of displayed video. + + Valid contrast values range between -100 and 100, the default is 0. + +*/ + +int QVideoWidget::contrast() const +{ + return d_func()->contrast; +} + +void QVideoWidget::setContrast(int contrast) +{ + Q_D(QVideoWidget); + + int boundedContrast = qBound(-100, contrast, 100); + + if (d->currentControl) + d->currentControl->setContrast(boundedContrast); + else if (d->contrast != boundedContrast) + emit contrastChanged(d->contrast = boundedContrast); +} + +/*! + \fn QVideoWidget::contrastChanged(int contrast) + + Signals that a video widgets's \a contrast adjustment has changed. + + \sa contrast +*/ + +/*! + \property QVideoWidget::hue + \brief an adjustment to the hue of displayed video. + + Valid hue values range between -100 and 100, the default is 0. +*/ + +int QVideoWidget::hue() const +{ + return d_func()->hue; +} + +void QVideoWidget::setHue(int hue) +{ + Q_D(QVideoWidget); + + int boundedHue = qBound(-100, hue, 100); + + if (d->currentControl) + d->currentControl->setHue(boundedHue); + else if (d->hue != boundedHue) + emit hueChanged(d->hue = boundedHue); +} + +/*! + \fn QVideoWidget::hueChanged(int hue) + + Signals that a video widgets's \a hue has changed. + + \sa hue +*/ + +/*! + \property QVideoWidget::saturation + \brief an adjustment to the saturation of displayed video. + + Valid saturation values range between -100 and 100, the default is 0. +*/ + +int QVideoWidget::saturation() const +{ + return d_func()->saturation; +} + +void QVideoWidget::setSaturation(int saturation) +{ + Q_D(QVideoWidget); + + int boundedSaturation = qBound(-100, saturation, 100); + + if (d->currentControl) + d->currentControl->setSaturation(boundedSaturation); + else if (d->saturation != boundedSaturation) + emit saturationChanged(d->saturation = boundedSaturation); + +} + +/*! + \fn QVideoWidget::saturationChanged(int saturation) + + Signals that a video widgets's \a saturation has changed. + + \sa saturation +*/ + +/*! + Returns the size hint for the current back end, + if there is one, or else the size hint from QWidget. + */ +QSize QVideoWidget::sizeHint() const +{ + Q_D(const QVideoWidget); + + if (d->currentBackend) + return d->currentBackend->sizeHint(); + else + return QWidget::sizeHint(); + + +} + +/*! + \reimp + \internal + */ +bool QVideoWidget::event(QEvent *event) +{ + Q_D(QVideoWidget); + + if (event->type() == QEvent::WindowStateChange) { + Qt::WindowFlags flags = windowFlags(); + + if (windowState() & Qt::WindowFullScreen) { + if (d->currentControl) + d->currentControl->setFullScreen(true); + + if (!d->wasFullScreen) + emit fullScreenChanged(d->wasFullScreen = true); + } else { + if (d->currentControl) + d->currentControl->setFullScreen(false); + + if (d->wasFullScreen) { + flags &= ~(Qt::Window | Qt::SubWindow); //clear the flags... + flags |= d->nonFullScreenFlags; //then we reset the flags (window and subwindow) + setWindowFlags(flags); + + emit fullScreenChanged(d->wasFullScreen = false); + } + } + } + return QWidget::event(event); +} + +/*! + Handles the show \a event. + */ +void QVideoWidget::showEvent(QShowEvent *event) +{ + Q_D(QVideoWidget); + + QWidget::showEvent(event); + + d->show(); + +} + +/*! + + Handles the hide \a event. +*/ +void QVideoWidget::hideEvent(QHideEvent *event) +{ + Q_D(QVideoWidget); + + if (d->currentBackend) + d->currentBackend->hideEvent(event); + + QWidget::hideEvent(event); +} + +/*! + Handles the resize \a event. + */ +void QVideoWidget::resizeEvent(QResizeEvent *event) +{ + Q_D(QVideoWidget); + + QWidget::resizeEvent(event); + + if (d->currentBackend) + d->currentBackend->resizeEvent(event); +} + +/*! + Handles the move \a event. + */ +void QVideoWidget::moveEvent(QMoveEvent *event) +{ + Q_D(QVideoWidget); + + if (d->currentBackend) + d->currentBackend->moveEvent(event); +} + +/*! + Handles the paint \a event. + */ +void QVideoWidget::paintEvent(QPaintEvent *event) +{ + Q_D(QVideoWidget); + + if (d->currentBackend) + d->currentBackend->paintEvent(event); +} + +#include "moc_qvideowidget.cpp" +#include "moc_qvideowidget_p.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qvideowidget.h b/src/multimedia/base/qvideowidget.h new file mode 100644 index 0000000..4e6cf2e --- /dev/null +++ b/src/multimedia/base/qvideowidget.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEOWIDGET_H +#define QVIDEOWIDGET_H + +#include <QtGui/qwidget.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QMediaObject; + +class QVideoWidgetPrivate; +class Q_MULTIMEDIA_EXPORT QVideoWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QMediaObject* mediaObject READ mediaObject WRITE setMediaObject) + Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged) + Q_PROPERTY(AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode NOTIFY aspectRatioModeChanged) + Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged) + Q_PROPERTY(int contrast READ contrast WRITE setContrast NOTIFY contrastChanged) + Q_PROPERTY(int hue READ hue WRITE setHue NOTIFY hueChanged) + Q_PROPERTY(int saturation READ saturation WRITE setSaturation NOTIFY saturationChanged) + Q_ENUMS(AspectRatio) + +public: + enum AspectRatioMode { IgnoreAspectRatio, KeepAspectRatio }; + + QVideoWidget(QWidget *parent = 0); + ~QVideoWidget(); + + QMediaObject *mediaObject() const; + void setMediaObject(QMediaObject *object); + +#ifdef Q_QDOC + bool isFullScreen() const; +#endif + + AspectRatioMode aspectRatioMode() const; + + int brightness() const; + int contrast() const; + int hue() const; + int saturation() const; + + QSize sizeHint() const; + +public Q_SLOTS: + void setFullScreen(bool fullScreen); + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + void setBrightness(int brightness); + void setContrast(int contrast); + void setHue(int hue); + void setSaturation(int saturation); + +Q_SIGNALS: + void fullScreenChanged(bool fullScreen); + void brightnessChanged(int brightness); + void contrastChanged(int contrast); + void hueChanged(int hue); + void saturationChanged(int saturation); + +protected: + bool event(QEvent *event); + void showEvent(QShowEvent *event); + void hideEvent(QHideEvent *event); + void resizeEvent(QResizeEvent *event); + void moveEvent(QMoveEvent *event); + void paintEvent(QPaintEvent *event); + +protected: + QVideoWidgetPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QVideoWidget) + Q_PRIVATE_SLOT(d_func(), void _q_serviceDestroyed()) + Q_PRIVATE_SLOT(d_func(), void _q_mediaObjectDestroyed()) + Q_PRIVATE_SLOT(d_func(), void _q_brightnessChanged(int)) + Q_PRIVATE_SLOT(d_func(), void _q_contrastChanged(int)) + Q_PRIVATE_SLOT(d_func(), void _q_hueChanged(int)) + Q_PRIVATE_SLOT(d_func(), void _q_saturationChanged(int)) + Q_PRIVATE_SLOT(d_func(), void _q_fullScreenChanged(bool)) + Q_PRIVATE_SLOT(d_func(), void _q_dimensionsChanged()); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qvideowidget_p.h b/src/multimedia/base/qvideowidget_p.h new file mode 100644 index 0000000..4227afd --- /dev/null +++ b/src/multimedia/base/qvideowidget_p.h @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEOWIDGET_P_H +#define QVIDEOWIDGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtMultimedia/qvideowidget.h> + +#ifndef QT_NO_OPENGL +#include <QGLWidget> +#endif + +#include "qpaintervideosurface_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class QVideoWidgetControlInterface +{ +public: + virtual ~QVideoWidgetControlInterface() {} + + virtual void setBrightness(int brightness) = 0; + virtual void setContrast(int contrast) = 0; + virtual void setHue(int hue) = 0; + virtual void setSaturation(int saturation) = 0; + + virtual void setFullScreen(bool fullScreen) = 0; + + virtual QVideoWidget::AspectRatioMode aspectRatioMode() const = 0; + virtual void setAspectRatioMode(QVideoWidget::AspectRatioMode mode) = 0; +}; + +class QVideoWidgetBackend : public QObject, public QVideoWidgetControlInterface +{ + Q_OBJECT + +public: + virtual QSize sizeHint() const = 0; + + virtual void showEvent() = 0; + virtual void hideEvent(QHideEvent *event) = 0; + virtual void resizeEvent(QResizeEvent *event) = 0; + virtual void moveEvent(QMoveEvent *event) = 0; + virtual void paintEvent(QPaintEvent *event) = 0; +}; + +class QVideoWidgetControl; + +class QVideoWidgetControlBackend : public QObject, public QVideoWidgetControlInterface +{ + Q_OBJECT +public: + QVideoWidgetControlBackend(QVideoWidgetControl *control, QWidget *widget); + + void setBrightness(int brightness); + void setContrast(int contrast); + void setHue(int hue); + void setSaturation(int saturation); + + void setFullScreen(bool fullScreen); + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + +private: + QVideoWidgetControl *m_widgetControl; +}; + + +class QVideoRendererControl; + +class QRendererVideoWidgetBackend : public QVideoWidgetBackend +{ + Q_OBJECT +public: + QRendererVideoWidgetBackend(QVideoRendererControl *control, QWidget *widget); + ~QRendererVideoWidgetBackend(); + + void clearSurface(); + + void setBrightness(int brightness); + void setContrast(int contrast); + void setHue(int hue); + void setSaturation(int saturation); + + void setFullScreen(bool fullScreen); + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + + QSize sizeHint() const; + + void showEvent(); + void hideEvent(QHideEvent *event); + void resizeEvent(QResizeEvent *event); + void moveEvent(QMoveEvent *event); + void paintEvent(QPaintEvent *event); + +Q_SIGNALS: + void fullScreenChanged(bool fullScreen); + void brightnessChanged(int brightness); + void contrastChanged(int contrast); + void hueChanged(int hue); + void saturationChanged(int saturation); + +private: + QRect displayRect() const; + + QVideoRendererControl *m_rendererControl; + QWidget *m_widget; + QPainterVideoSurface *m_surface; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + QSize m_aspectRatio; + bool m_updatePaintDevice; +}; + +class QVideoWindowControl; + +class QWindowVideoWidgetBackend : public QVideoWidgetBackend +{ + Q_OBJECT +public: + QWindowVideoWidgetBackend(QVideoWindowControl *control, QWidget *widget); + ~QWindowVideoWidgetBackend(); + + void setBrightness(int brightness); + void setContrast(int contrast); + void setHue(int hue); + void setSaturation(int saturation); + + void setFullScreen(bool fullScreen); + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + + QSize sizeHint() const; + + void showEvent(); + void hideEvent(QHideEvent *event); + void resizeEvent(QResizeEvent *event); + void moveEvent(QMoveEvent *event); + void paintEvent(QPaintEvent *event); + +private: + QVideoWindowControl *m_windowControl; + QWidget *m_widget; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + QSize m_pixelAspectRatio; +}; + +class QMediaService; +class QVideoOutputControl; + +class QVideoWidgetPrivate +{ + Q_DECLARE_PUBLIC(QVideoWidget) +public: + QVideoWidgetPrivate() + : q_ptr(0) + , mediaObject(0) + , service(0) + , outputControl(0) + , widgetBackend(0) + , windowBackend(0) + , rendererBackend(0) + , currentControl(0) + , currentBackend(0) + , brightness(0) + , contrast(0) + , hue(0) + , saturation(0) + , aspectRatioMode(QVideoWidget::KeepAspectRatio) + , nonFullScreenFlags(0) + , wasFullScreen(false) + { + } + + QVideoWidget *q_ptr; + QMediaObject *mediaObject; + QMediaService *service; + QVideoOutputControl *outputControl; + QVideoWidgetControlBackend *widgetBackend; + QWindowVideoWidgetBackend *windowBackend; + QRendererVideoWidgetBackend *rendererBackend; + QVideoWidgetControlInterface *currentControl; + QVideoWidgetBackend *currentBackend; + int brightness; + int contrast; + int hue; + int saturation; + QVideoWidget::AspectRatioMode aspectRatioMode; + Qt::WindowFlags nonFullScreenFlags; + bool wasFullScreen; + + void setCurrentControl(QVideoWidgetControlInterface *control); + void show(); + void clearService(); + + void _q_serviceDestroyed(); + void _q_mediaObjectDestroyed(); + void _q_brightnessChanged(int brightness); + void _q_contrastChanged(int contrast); + void _q_hueChanged(int hue); + void _q_saturationChanged(int saturation); + void _q_fullScreenChanged(bool fullScreen); + void _q_dimensionsChanged(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qvideowidgetcontrol.cpp b/src/multimedia/base/qvideowidgetcontrol.cpp new file mode 100644 index 0000000..bd7ce4e --- /dev/null +++ b/src/multimedia/base/qvideowidgetcontrol.cpp @@ -0,0 +1,235 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qvideowidgetcontrol.h> +#include "qmediacontrol_p.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QVideoWidgetControl + \preliminary + + \brief The QVideoWidgetControl class provides a media control which + implements a video widget. + + \ingroup multimedia-serv + + The videoWidget() property of QVideoWidgetControl provides a pointer to + a video widget implemented by the control's media service. This widget + is owned by the media service and so care should be taken not to delete it. + + \code + QVideoWidgetControl *widgetControl = mediaService->control<QVideoWidgetControl *>(); + + layout->addWidget(widgetControl->widget()); + \endcode + + QVideoWidgetControl is one of number of possible video output controls, + in order to receive video it must be made the active video output + control by setting the output property of QVideoOutputControl to \l {QVideoOutputControl::WidgetOutput}{WidgetOutput}. Consequently any + QMediaService that implements QVideoWidgetControl must also implement + QVideoOutputControl. + + The interface name of QVideoWidgetControl is \c com.nokia.Qt.QVideoWidgetControl/1.0 as + defined in QVideoWidgetControl_iid. + + \sa QMediaService::control(), QVideoOutputControl, QVideoWidget +*/ + +/*! + \macro QVideoWidgetControl_iid + + \c com.nokia.Qt.QVideoWidgetControl/1.0 + + Defines the interface name of the QVideoWidgetControl class. + + \relates QVideoWidgetControl +*/ + +/*! + Constructs a new video widget control with the given \a parent. +*/ +QVideoWidgetControl::QVideoWidgetControl(QObject *parent) + :QMediaControl(parent) +{ +} + +/*! + Destroys a video widget control. +*/ +QVideoWidgetControl::~QVideoWidgetControl() +{ +} + +/*! + \fn QVideoWidgetControl::isFullScreen() const + + Returns true if the video is shown using the complete screen. +*/ + +/*! + \fn QVideoWidgetControl::setFullScreen(bool fullScreen) + + Sets whether a video widget is in \a fullScreen mode. +*/ + +/*! + \fn QVideoWidgetControl::fullScreenChanged(bool fullScreen) + + Signals that the \a fullScreen state of a video widget has changed. +*/ + +/*! + \fn QVideoWidgetControl::aspectRatioMode() const + + Returns how video is scaled to fit the widget with respect to its aspect ratio. +*/ + +/*! + \fn QVideoWidgetControl::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) + + Sets the aspect ratio \a mode which determines how video is scaled to the fit the widget with + respect to its aspect ratio. +*/ + +/*! + \fn QVideoWidgetControl::brightness() const + + Returns the brightness adjustment applied to a video. + + Valid brightness values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWidgetControl::setBrightness(int brightness) + + Sets a \a brightness adjustment for a video. + + Valid brightness values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWidgetControl::brightnessChanged(int brightness) + + Signals that a video widget's \a brightness adjustment has changed. +*/ + +/*! + \fn QVideoWidgetControl::contrast() const + + Returns the contrast adjustment applied to a video. + + Valid contrast values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWidgetControl::setContrast(int contrast) + + Sets the contrast adjustment for a video widget to \a contrast. + + Valid contrast values range between -100 and 100, the default is 0. +*/ + + +/*! + \fn QVideoWidgetControl::contrastChanged(int contrast) + + Signals that a video widget's \a contrast adjustment has changed. +*/ + +/*! + \fn QVideoWidgetControl::hue() const + + Returns the hue adjustment applied to a video widget. + + Value hue values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWidgetControl::setHue(int hue) + + Sets a \a hue adjustment for a video widget. + + Valid hue values range between -100 and 100, the default is 0. +*/ + + +/*! + \fn QVideoWidgetControl::hueChanged(int hue) + + Signals that a video widget's \a hue adjustment has changed. +*/ + +/*! + \fn QVideoWidgetControl::saturation() const + + Returns the saturation adjustment applied to a video widget. + + Value saturation values range between -100 and 100, the default is 0. +*/ + + +/*! + \fn QVideoWidgetControl::setSaturation(int saturation) + + Sets a \a saturation adjustment for a video widget. + + Valid saturation values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWidgetControl::saturationChanged(int saturation) + + Signals that a video widget's \a saturation adjustment has changed. +*/ + +/*! + \fn QVideoWidgetControl::videoWidget() + + Returns the QWidget. +*/ + +#include "moc_qvideowidgetcontrol.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qvideowidgetcontrol.h b/src/multimedia/base/qvideowidgetcontrol.h new file mode 100644 index 0000000..6981e89 --- /dev/null +++ b/src/multimedia/base/qvideowidgetcontrol.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEOWIDGETCONTROL_H +#define QVIDEOWIDGETCONTROL_H + +#include <QtGui/qwidget.h> + +#include <QtMultimedia/qvideowidget.h> +#include <QtMultimedia/qmediacontrol.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QVideoWidgetControlPrivate; + +class Q_MULTIMEDIA_EXPORT QVideoWidgetControl : public QMediaControl +{ + Q_OBJECT + +public: + virtual ~QVideoWidgetControl(); + + virtual QWidget *videoWidget() = 0; + + virtual QVideoWidget::AspectRatioMode aspectRatioMode() const = 0; + virtual void setAspectRatioMode(QVideoWidget::AspectRatioMode mode) = 0; + + virtual bool isFullScreen() const = 0; + virtual void setFullScreen(bool fullScreen) = 0; + + virtual int brightness() const = 0; + virtual void setBrightness(int brightness) = 0; + + virtual int contrast() const = 0; + virtual void setContrast(int contrast) = 0; + + virtual int hue() const = 0; + virtual void setHue(int hue) = 0; + + virtual int saturation() const = 0; + virtual void setSaturation(int saturation) = 0; + +Q_SIGNALS: + void fullScreenChanged(bool fullScreen); + void brightnessChanged(int brightness); + void contrastChanged(int contrast); + void hueChanged(int hue); + void saturationChanged(int saturation); + +protected: + QVideoWidgetControl(QObject *parent = 0); +}; + +#define QVideoWidgetControl_iid "com.nokia.Qt.QVideoWidgetControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QVideoWidgetControl, QVideoWidgetControl_iid) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/base/qvideowindowcontrol.cpp b/src/multimedia/base/qvideowindowcontrol.cpp new file mode 100644 index 0000000..a23cb4b --- /dev/null +++ b/src/multimedia/base/qvideowindowcontrol.cpp @@ -0,0 +1,274 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qvideowindowcontrol.h> + + +QT_BEGIN_NAMESPACE + +/*! + \class QVideoWindowControl + \preliminary + \ingroup multimedia-serv + \brief The QVideoWindowControl class provides a media control for rendering video to a window. + + + The winId() property QVideoWindowControl allows a platform specific + window ID to be set as the video render target of a QMediaService. The + displayRect() property is used to set the region of the window the + video should be rendered to, and the aspectRatioMode() property + indicates how the video should be scaled to fit the displayRect(). + + \code + QVideoWindowControl *windowControl = mediaService->control<QVideoWindowControl *>(); + windowControl->setWinId(widget->winId()); + windowControl->setDisplayRect(widget->rect()); + windowControl->setAspectRatioMode(QVideoWidget::KeepAspectRatio); + \endcode + + QVideoWindowControl is one of number of possible video output controls, + in order to receive video it must be made the active video output + control by setting the output property of QVideoOutputControl to \l {QVideoOutputControl::WindowOutput}{WindowOutput}. + Consequently any QMediaService that implements QVideoWindowControl must + also implement QVideoOutputControl. + + \code + QVideoOutputControl *outputControl = mediaService->control<QVideoOutputControl *>(); + outputControl->setOutput(QVideoOutputControl::WindowOutput); + \endcode + + The interface name of QVideoWindowControl is \c com.nokia.Qt.QVideoWindowControl/1.0 as + defined in QVideoWindowControl_iid. + + \sa QMediaService::control(), QVideoOutputControl, QVideoWidget +*/ + +/*! + \macro QVideoWindowControl_iid + + \c com.nokia.Qt.QVideoWindowControl/1.0 + + Defines the interface name of the QVideoWindowControl class. + + \relates QVideoWindowControl +*/ + +/*! + Constructs a new video window control with the given \a parent. +*/ +QVideoWindowControl::QVideoWindowControl(QObject *parent) + : QMediaControl(parent) +{ +} + +/*! + Destroys a video window control. +*/ +QVideoWindowControl::~QVideoWindowControl() +{ +} + +/*! + \fn QVideoWindowControl::winId() const + + Returns the ID of the window a video overlay end point renders to. +*/ + +/*! + \fn QVideoWindowControl::setWinId(WId id) + + Sets the \a id of the window a video overlay end point renders to. +*/ + +/*! + \fn QVideoWindowControl::displayRect() const + Returns the sub-rect of a window where video is displayed. +*/ + +/*! + \fn QVideoWindowControl::setDisplayRect(const QRect &rect) + Sets the sub-\a rect of a window where video is displayed. +*/ + +/*! + \fn QVideoWindowControl::isFullScreen() const + + Identifies if a video overlay is a fullScreen overlay. + + Returns true if the video overlay is fullScreen, and false otherwise. +*/ + +/*! + \fn QVideoWindowControl::setFullScreen(bool fullScreen) + + Sets whether a video overlay is a \a fullScreen overlay. +*/ + +/*! + \fn QVideoWindowControl::fullScreenChanged(bool fullScreen) + + Signals that the \a fullScreen state of a video overlay has changed. +*/ + +/*! + \fn QVideoWindowControl::repaint() + + Repaints the last frame. +*/ + +/*! + \fn QVideoWindowControl::nativeSize() const + + Returns a suggested size for the video display based on the resolution and aspect ratio of the + video. +*/ + +/*! + \fn QVideoWindowControl::nativeSizeChanged() + + Signals that the native dimensions of the video have changed. +*/ + + +/*! + \fn QVideoWindowControl::aspectRatioMode() const + + Returns how video is scaled to fit the display region with respect to its aspect ratio. +*/ + +/*! + \fn QVideoWindowControl::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) + + Sets the aspect ratio \a mode which determines how video is scaled to the fit the display region + with respect to its aspect ratio. +*/ + +/*! + \fn QVideoWindowControl::brightness() const + + Returns the brightness adjustment applied to a video overlay. + + Valid brightness values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::setBrightness(int brightness) + + Sets a \a brightness adjustment for a video overlay. + + Valid brightness values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::brightnessChanged(int brightness) + + Signals that a video overlay's \a brightness adjustment has changed. +*/ + +/*! + \fn QVideoWindowControl::contrast() const + + Returns the contrast adjustment applied to a video overlay. + + Valid contrast values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::setContrast(int contrast) + + Sets the \a contrast adjustment for a video overlay. + + Valid contrast values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::contrastChanged(int contrast) + + Signals that a video overlay's \a contrast adjustment has changed. +*/ + +/*! + \fn QVideoWindowControl::hue() const + + Returns the hue adjustment applied to a video overlay. + + Value hue values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::setHue(int hue) + + Sets a \a hue adjustment for a video overlay. + + Valid hue values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::hueChanged(int hue) + + Signals that a video overlay's \a hue adjustment has changed. +*/ + +/*! + \fn QVideoWindowControl::saturation() const + + Returns the saturation adjustment applied to a video overlay. + + Value saturation values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::setSaturation(int saturation) + Sets a \a saturation adjustment for a video overlay. + + Valid saturation values range between -100 and 100, the default is 0. +*/ + +/*! + \fn QVideoWindowControl::saturationChanged(int saturation) + + Signals that a video overlay's \a saturation adjustment has changed. +*/ + +#include "moc_qvideowindowcontrol.cpp" + +QT_END_NAMESPACE + diff --git a/src/multimedia/base/qvideowindowcontrol.h b/src/multimedia/base/qvideowindowcontrol.h new file mode 100644 index 0000000..9ee96ab --- /dev/null +++ b/src/multimedia/base/qvideowindowcontrol.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEOWINDOWCONTROL_H +#define QVIDEOWINDOWCONTROL_H + +#include <QtGui/qwidget.h> + +#include <QtMultimedia/qmediacontrol.h> +#include <QtMultimedia/qvideowidget.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class Q_MULTIMEDIA_EXPORT QVideoWindowControl : public QMediaControl +{ + Q_OBJECT + +public: + ~QVideoWindowControl(); + + virtual WId winId() const = 0; + virtual void setWinId(WId id) = 0; + + virtual QRect displayRect() const = 0; + virtual void setDisplayRect(const QRect &rect) = 0; + + virtual bool isFullScreen() const = 0; + virtual void setFullScreen(bool fullScreen) = 0; + + virtual void repaint() = 0; + + virtual QSize nativeSize() const = 0; + + virtual QVideoWidget::AspectRatioMode aspectRatioMode() const = 0; + virtual void setAspectRatioMode(QVideoWidget::AspectRatioMode mode) = 0; + + virtual int brightness() const = 0; + virtual void setBrightness(int brightness) = 0; + + virtual int contrast() const = 0; + virtual void setContrast(int contrast) = 0; + + virtual int hue() const = 0; + virtual void setHue(int hue) = 0; + + virtual int saturation() const = 0; + virtual void setSaturation(int saturation) = 0; + +Q_SIGNALS: + void fullScreenChanged(bool fullScreen); + void brightnessChanged(int brightness); + void contrastChanged(int contrast); + void hueChanged(int hue); + void saturationChanged(int saturation); + void nativeSizeChanged(); + +protected: + QVideoWindowControl(QObject *parent = 0); +}; + +#define QVideoWindowControl_iid "com.nokia.Qt.QVideoWindowControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QVideoWindowControl, QVideoWindowControl_iid) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index c729103..106d3ab 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -10,5 +10,8 @@ include(../qbase.pri) include(audio/audio.pri) include(video/video.pri) +include(base/base.pri) +include(playback/playback.pri) +include(qml/qml.pri) -symbian: TARGET.UID3 = 0x2001E627
\ No newline at end of file +symbian: TARGET.UID3 = 0x2001E627 diff --git a/src/multimedia/playback/playback.pri b/src/multimedia/playback/playback.pri new file mode 100644 index 0000000..09a81c9 --- /dev/null +++ b/src/multimedia/playback/playback.pri @@ -0,0 +1,11 @@ + +HEADERS += \ + $$PWD/qmediaplayer.h \ + $$PWD/qmediaplayercontrol.h + +SOURCES += \ + $$PWD/qmediaplayer.cpp \ + $$PWD/qmediaplayercontrol.cpp + + + diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp new file mode 100644 index 0000000..5f50fdb --- /dev/null +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -0,0 +1,955 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qcoreevent.h> +#include <QtCore/qmetaobject.h> +#include <QtCore/qtimer.h> +#include <QtCore/qpointer.h> + +#include <QtMultimedia/qmediaplayer.h> + +#include <QtMultimedia/private/qmediaobject_p.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaserviceprovider.h> +#include <QtMultimedia/qmediaplaylist.h> +#include <QtMultimedia/qmediaplaylistcontrol.h> +#include <QtMultimedia/qvideowidget.h> +#include <QtMultimedia/qgraphicsvideoitem.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +/*! + \class QMediaPlayer + \brief The QMediaPlayer class allows the playing of a media source. + \ingroup multimedia + + \preliminary + + The QMediaPlayer class is a high level media playback class. It can be used + to playback such content as songs, movies and internet radio. The content + to playback is specified as a QMediaContent, which can be thought of as a + main or canonical URL with addition information attached. When provided + with a QMediaContent playback may be able to commence. + + \code + player = new QMediaPlayer; + connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); + player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3")); + player->setVolume(50); + player->play(); + \endcode + + QVideoWidget can be used with QMediaPlayer for video rendering and QMediaPlaylist + for accessing playlist functionality. + + \code + player = new QMediaPlayer; + + playlist = new QMediaPlaylist; + playlist->setMediaObject(player); + playlist->append(QUrl("http://example.com/movie1.mp4")); + playlist->append(QUrl("http://example.com/movie2.mp4")); + + widget = new QVideoWidget; + widget->setMediaObject(player); + widget->show(); + + player->play(); + \endcode + + \sa QMediaObject, QMediaService, QVideoWidget, QMediaPlaylist +*/ + +namespace +{ +class MediaPlayerRegisterMetaTypes +{ +public: + MediaPlayerRegisterMetaTypes() + { + qRegisterMetaType<QMediaPlayer::State>(); + qRegisterMetaType<QMediaPlayer::MediaStatus>(); + qRegisterMetaType<QMediaPlayer::Error>(); + } +} _registerPlayerMetaTypes; +} + +class QMediaPlayerPrivate : public QMediaObjectPrivate +{ + Q_DECLARE_NON_CONST_PUBLIC(QMediaPlayer) + +public: + QMediaPlayerPrivate() + : provider(0) + , control(0) + , playlistControl(0) + , state(QMediaPlayer::StoppedState) + , error(QMediaPlayer::NoError) + , filterStates(false) + , playlist(0) + {} + + QMediaServiceProvider *provider; + QMediaPlayerControl* control; + QMediaPlaylistControl* playlistControl; + QMediaPlayer::State state; + QMediaPlayer::Error error; + QString errorString; + bool filterStates; + + QMediaPlaylist *playlist; + QPointer<QVideoWidget> videoWidget; + QPointer<QGraphicsVideoItem> videoItem; + + void _q_stateChanged(QMediaPlayer::State state); + void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status); + void _q_error(int error, const QString &errorString); + void _q_updateMedia(const QMediaContent&); + void _q_playlistDestroyed(); +}; + +void QMediaPlayerPrivate::_q_stateChanged(QMediaPlayer::State ps) +{ + Q_Q(QMediaPlayer); + + if (filterStates) + return; + + if (playlist + && !playlistControl //service should do this itself + && ps != state && ps == QMediaPlayer::StoppedState + && control->mediaStatus() == QMediaPlayer::EndOfMedia) { + playlist->next(); + ps = control->state(); + } + + if (ps != state) { + state = ps; + + if (ps == QMediaPlayer::PlayingState) + q->addPropertyWatch("position"); + else + q->removePropertyWatch("position"); + + emit q->stateChanged(ps); + } +} + +void QMediaPlayerPrivate::_q_mediaStatusChanged(QMediaPlayer::MediaStatus status) +{ + Q_Q(QMediaPlayer); + + switch (status) { + case QMediaPlayer::StalledMedia: + case QMediaPlayer::BufferingMedia: + q->addPropertyWatch("bufferStatus"); + emit q->mediaStatusChanged(status); + break; + default: + q->removePropertyWatch("bufferStatus"); + emit q->mediaStatusChanged(status); + break; + } + +} + +void QMediaPlayerPrivate::_q_error(int error, const QString &errorString) +{ + Q_Q(QMediaPlayer); + + this->error = QMediaPlayer::Error(error); + this->errorString = errorString; + + emit q->error(this->error); +} + +void QMediaPlayerPrivate::_q_updateMedia(const QMediaContent &media) +{ + const QMediaPlayer::State currentState = state; + + filterStates = true; + control->setMedia(media, 0); + + if (!media.isNull()) { + switch (currentState) { + case QMediaPlayer::PlayingState: + control->play(); + break; + case QMediaPlayer::PausedState: + control->pause(); + break; + default: + break; + } + } + filterStates = false; + + state = control->state(); + + if (state != currentState) + emit q_func()->stateChanged(state); +} + +void QMediaPlayerPrivate::_q_playlistDestroyed() +{ + playlist = 0; + + control->setMedia(QMediaContent(), 0); +} + +static QMediaService *playerService(QMediaPlayer::Flags flags, QMediaServiceProvider *provider) +{ + if (flags && QMediaPlayer::LowLatency) + return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER, + QMediaServiceProviderHint(QMediaServiceProviderHint::LowLatencyPlayback)); + else + return provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER); +} + + +/*! + Construct a QMediaPlayer that uses the playback service from \a provider, + parented to \a parent and with \a flags. + + If a playback service is not specified the system default will be used. +*/ + +QMediaPlayer::QMediaPlayer(QObject *parent, QMediaPlayer::Flags flags, QMediaServiceProvider *provider): + QMediaObject(*new QMediaPlayerPrivate, + parent, + playerService(flags,provider)) +{ + Q_D(QMediaPlayer); + + d->provider = provider; + + if (d->service == 0) { + d->error = ServiceMissingError; + } else { + d->control = qobject_cast<QMediaPlayerControl*>(d->service->control(QMediaPlayerControl_iid)); + d->playlistControl = qobject_cast<QMediaPlaylistControl*>(d->service->control(QMediaPlaylistControl_iid)); + if (d->control != 0) { + connect(d->control, SIGNAL(mediaChanged(QMediaContent)), SIGNAL(mediaChanged(QMediaContent))); + connect(d->control, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(_q_stateChanged(QMediaPlayer::State))); + connect(d->control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus))); + connect(d->control, SIGNAL(error(int,QString)), SLOT(_q_error(int,QString))); + + connect(d->control, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64))); + connect(d->control, SIGNAL(positionChanged(qint64)), SIGNAL(positionChanged(qint64))); + connect(d->control, SIGNAL(audioAvailableChanged(bool)), SIGNAL(audioAvailableChanged(bool))); + connect(d->control, SIGNAL(videoAvailableChanged(bool)), SIGNAL(videoAvailableChanged(bool))); + connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int))); + connect(d->control, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool))); + connect(d->control, SIGNAL(seekableChanged(bool)), SIGNAL(seekableChanged(bool))); + connect(d->control, SIGNAL(playbackRateChanged(qreal)), SIGNAL(playbackRateChanged(qreal))); + + if (d->control->state() == PlayingState) + addPropertyWatch("position"); + + if (d->control->mediaStatus() == StalledMedia || d->control->mediaStatus() == BufferingMedia) + addPropertyWatch("bufferStatus"); + } + } +} + + +/*! + Destroys the player object. +*/ + +QMediaPlayer::~QMediaPlayer() +{ + Q_D(QMediaPlayer); + + d->provider->releaseService(d->service); +} + +QMediaContent QMediaPlayer::media() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->media(); + + return QMediaContent(); +} + +/*! + Returns the stream source of media data. + + This is only valid if a stream was passed to setMedia(). + + \sa setMedia() +*/ + +const QIODevice *QMediaPlayer::mediaStream() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->mediaStream(); + + return 0; +} + +QMediaPlayer::State QMediaPlayer::state() const +{ + return d_func()->state; +} + +QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->mediaStatus(); + + return QMediaPlayer::UnknownMediaStatus; +} + +qint64 QMediaPlayer::duration() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->duration(); + + return -1; +} + +qint64 QMediaPlayer::position() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->position(); + + return 0; +} + +int QMediaPlayer::volume() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->volume(); + + return 0; +} + +bool QMediaPlayer::isMuted() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->isMuted(); + + return false; +} + +int QMediaPlayer::bufferStatus() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->bufferStatus(); + + return 0; +} + +bool QMediaPlayer::isAudioAvailable() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->isAudioAvailable(); + + return false; +} + +bool QMediaPlayer::isVideoAvailable() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->isVideoAvailable(); + + return false; +} + +bool QMediaPlayer::isSeekable() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->isSeekable(); + + return false; +} + +qreal QMediaPlayer::playbackRate() const +{ + Q_D(const QMediaPlayer); + + if (d->control != 0) + return d->control->playbackRate(); + + return 0.0; +} + +/*! + Returns the current error state. +*/ + +QMediaPlayer::Error QMediaPlayer::error() const +{ + return d_func()->error; +} + +QString QMediaPlayer::errorString() const +{ + return d_func()->errorString; +} + +//public Q_SLOTS: +/*! + Start or resume playing the current source. +*/ + +void QMediaPlayer::play() +{ + Q_D(QMediaPlayer); + + if (d->control == 0) { + QMetaObject::invokeMethod(this, "_q_error", Qt::QueuedConnection); + Q_ARG(int, QMediaPlayer::ServiceMissingError), + Q_ARG(QString, tr("The QMediaPlayer object does not have a valid service")); + return; + } + + //if playlist control is available, the service should advance itself + if (d->playlist && !d->playlistControl && d->playlist->currentIndex() == -1 && !d->playlist->isEmpty()) + d->playlist->setCurrentIndex(0); + + // Reset error conditions + d->error = NoError; + d->errorString = QString(); + + d->control->play(); +} + +/*! + Pause playing the current source. +*/ + +void QMediaPlayer::pause() +{ + Q_D(QMediaPlayer); + + if (d->control != 0) + d->control->pause(); +} + +/*! + Stop playing, and reset the play position to the beginning. +*/ + +void QMediaPlayer::stop() +{ + Q_D(QMediaPlayer); + + if (d->control != 0) + d->control->stop(); +} + +void QMediaPlayer::setPosition(qint64 position) +{ + Q_D(QMediaPlayer); + + if (d->control == 0 || !isSeekable()) + return; + + d->control->setPosition(qBound(qint64(0), duration(), position)); +} + +void QMediaPlayer::setVolume(int v) +{ + Q_D(QMediaPlayer); + + if (d->control == 0) + return; + + int clamped = qBound(0, v, 100); + if (clamped == volume()) + return; + + d->control->setVolume(clamped); +} + +void QMediaPlayer::setMuted(bool muted) +{ + Q_D(QMediaPlayer); + + if (d->control == 0 || muted == isMuted()) + return; + + d->control->setMuted(muted); +} + +void QMediaPlayer::setPlaybackRate(qreal rate) +{ + Q_D(QMediaPlayer); + + if (d->control != 0) + d->control->setPlaybackRate(rate); +} + +/*! + Sets the current \a media source. + + If a \a stream is supplied; media data will be read from it instead of resolving the media + source. In this case the media source may still be used to resolve additional information + about the media such as mime type. + + Setting the media to a null QMediaContent will cause the player to discard all + information relating to the current media source and to cease all I/O operations related + to that media. +*/ + +void QMediaPlayer::setMedia(const QMediaContent &media, QIODevice *stream) +{ + Q_D(QMediaPlayer); + + if (d->control != 0) + d_func()->control->setMedia(media, stream); +} + +/*! + \internal +*/ + +void QMediaPlayer::bind(QObject *obj) +{ + Q_D(QMediaPlayer); + + if (d->control != 0) { + QMediaPlaylist *playlist = qobject_cast<QMediaPlaylist*>(obj); + + if (playlist) { + if (d->playlist) + d->playlist->setMediaObject(0); + + d->playlist = playlist; + connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)), + this, SLOT(_q_updateMedia(QMediaContent))); + connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed())); + + setMedia(playlist->currentMedia()); + + return; + } + + QVideoWidget *videoWidget = qobject_cast<QVideoWidget*>(obj); + QGraphicsVideoItem *videoItem = qobject_cast<QGraphicsVideoItem*>(obj); + + if (videoWidget || videoItem) { + //detach the current video output + if (d->videoWidget) { + d->videoWidget->setMediaObject(0); + d->videoWidget = 0; + } + + if (d->videoItem) { + d->videoItem->setMediaObject(0); + d->videoItem = 0; + } + } + + if (videoWidget) + d->videoWidget = videoWidget; + + if (videoItem) + d->videoItem = videoItem; + } +} + +/*! + \internal +*/ + +void QMediaPlayer::unbind(QObject *obj) +{ + Q_D(QMediaPlayer); + + if (obj == d->videoWidget) { + d->videoWidget = 0; + } else if (obj == d->videoItem) { + d->videoItem = 0; + } else if (obj == d->playlist) { + disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)), + this, SLOT(_q_updateMedia(QMediaContent))); + disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed())); + d->playlist = 0; + setMedia(QMediaContent()); + } +} + +/*! + Returns the level of support a media player has for a \a mimeType and a set of \a codecs. + + The \a flags argument allows additional requirements such as performance indicators to be + specified. +*/ +QtMultimedia::SupportEstimate QMediaPlayer::hasSupport(const QString &mimeType, + const QStringList& codecs, + Flags flags) +{ + return QMediaServiceProvider::defaultServiceProvider()->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER), + mimeType, + codecs, + flags); +} + +/*! + Returns a list of MIME types supported by the media player. + + The \a flags argument causes the resultant list to be restricted to MIME types which can be supported + given additional requirements, such as performance indicators. +*/ +QStringList QMediaPlayer::supportedMimeTypes(Flags flags) +{ + return QMediaServiceProvider::defaultServiceProvider()->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER), + flags); +} + + +// Enums +/*! + \enum QMediaPlayer::State + + Defines the current state of a media player. + + \value PlayingState The media player is currently playing content. + \value PausedState The media player has paused playback, playback of the current track will + resume from the position the player was paused at. + \value StoppedState The media player is not playing content, playback will begin from the start + of the current track. +*/ + +/*! + \enum QMediaPlayer::MediaStatus + + Defines the status of a media player's current media. + + \value UnknownMediaStatus The status of the media cannot be determined. + \value NoMedia The is no current media. The player is in the StoppedState. + \value LoadingMedia The current media is being loaded. The player may be in any state. + \value LoadedMedia The current media has been loaded. The player is in the StoppedState. + \value StalledMedia Playback of the current media has stalled due to insufficient buffering or + some other temporary interruption. The player is in the PlayingState or PausedState. + \value BufferingMedia The player is buffering data but has enough data buffered for playback to + continue for the immediate future. The player is in the PlayingState or PausedState. + \value BufferedMedia The player has fully buffered the current media. The player is in the + PlayingState or PausedState. + \value EndOfMedia Playback has reached the end of the current media. The player is in the + StoppedState. + \value InvalidMedia The current media cannot be played. The player is in the StoppedState. +*/ + +/*! + \enum QMediaPlayer::Error + + Defines a media player error condition. + + \value NoError No error has occurred. + \value ResourceError A media resource couldn't be resolved. + \value FormatError The format of a media resource isn't (fully) supported. Playback may still + be possible, but without an audio or video component. + \value NetworkError A network error occurred. + \value AccessDeniedError There are not the appropriate permissions to play a media resource. + \value ServiceMissingError A valid playback service was not found, playback cannot proceed. +*/ + +// Signals +/*! + \fn QMediaPlayer::error(QMediaPlayer::Error error) + + Signals that an \a error condition has occurred. + + \sa errorString() +*/ + +/*! + \fn void QMediaPlayer::stateChanged(State state) + + Signal the \a state of the Player object has changed. +*/ + +/*! + \fn QMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status) + + Signals that the \a status of the current media has changed. + + \sa mediaStatus() +*/ + +/*! + \fn void QMediaPlayer::mediaChanged(const QMediaContent &media); + + Signals that the current playing content will be obtained from \a media. + + \sa media() +*/ + +/*! + \fn void QMediaPlayer::playbackRateChanged(qreal rate); + + Signals the playbackRate has changed to \a rate. +*/ + +/*! + \fn void QMediaPlayer::seekableChanged(bool seekable); + + Signals the \a seekable status of the player object has changed. +*/ + +// Properties +/*! + \property QMediaPlayer::state + \brief the media player's playback state. + + By default this property is QMediaPlayer::Stopped + + \sa mediaStatus(), play(), pause(), stop() +*/ + +/*! + \property QMediaPlayer::error + \brief a string describing the last error condition. + + \sa error() +*/ + +/*! + \property QMediaPlayer::media + \brief the active media source being used by the player object. + + The player object will use the QMediaContent for selection of the content to + be played. + + By default this property has a null QMediaContent. + + Setting this property to a null QMediaContent will cause the player to discard all + information relating to the current media source and to cease all I/O operations related + to that media. + + \sa QMediaContent +*/ + +/*! + \property QMediaPlayer::mediaStatus + \brief the status of the current media stream. + + The stream status describes how the playback of the current stream is + progressing. + + By default this property is QMediaPlayer::NoMedia + + \sa state +*/ + +/*! + \property QMediaPlayer::duration + \brief the duration of the current media. + + The value is the total playback time in milliseconds of the current media. + The value may change across the life time of the QMediaPlayer object and + may not be available when initial playback begins, connect to the + durationChanged() signal to receive status notifications. +*/ + +/*! + \property QMediaPlayer::position + \brief the playback position of the current media. + + The value is the current playback position, expressed in milliseconds since + the beginning of the media. Periodically changes in the position will be + indicated with the signal positionChanged(), the interval between updates + can be set with QMediaObject's method setNotifyInterval(). +*/ + +/*! + \property QMediaPlayer::volume + \brief the current playback volume. + + The playback volume is a linear in effect and the value can range from 0 - + 100, values outside this range will be clamped. +*/ + +/*! + \property QMediaPlayer::muted + \brief the muted state of the current media. + + The value will be true if the playback volume is muted; otherwise false. +*/ + +/*! + \property QMediaPlayer::bufferStatus + \brief the percentage of the temporary buffer filled before playback begins. + + When the player object is buffering; this property holds the percentage of + the temporary buffer that is filled. The buffer will need to reach 100% + filled before playback can resume, at which time the MediaStatus will be + BufferedMedia. + + \sa mediaStatus() +*/ + +/*! + \property QMediaPlayer::audioAvailable + \brief the audio availabilty status for the current media. + + As the life time of QMediaPlayer can be longer than the playback of one + QMediaContent, this property may change over time, the + audioAvailableChanged signal can be used to monitor it's status. +*/ + +/*! + \property QMediaPlayer::videoAvailable + \brief the video availability status for the current media. + + If available, the QVideoWidget class can be used to view the video. As the + life time of QMediaPlayer can be longer than the playback of one + QMediaContent, this property may change over time, the + videoAvailableChanged signal can be used to monitor it's status. + + \sa QVideoWidget, QMediaContent +*/ + +/*! + \property QMediaPlayer::seekable + \brief the seek-able status of the current media + + If seeking is supported this property will be true; false otherwise. The + status of this property may change across the life time of the QMediaPlayer + object, use the seekableChanged signal to monitor changes. +*/ + +/*! + \property QMediaPlayer::playbackRate + \brief the playback rate of the current media. + + This value is a multiplier applied to the media's standard play rate. By + default this value is 1.0, indicating that the media is playing at the + standard pace. Values higher than 1.0 will increase the rate of play. + Values less than zero can be set and indicate the media will rewind at the + multiplier of the standard pace. + + Not all playback services support change of the playback rate. It is + framework defined as to the status and quality of audio and video + while fast forwarding or rewinding. +*/ + +/*! + \fn void QMediaPlayer::durationChanged(qint64 duration) + + Signal the duration of the content has changed to \a duration, expressed in milliseconds. +*/ + +/*! + \fn void QMediaPlayer::positionChanged(qint64 position) + + Signal the position of the content has changed to \a position, expressed in + milliseconds. +*/ + +/*! + \fn void QMediaPlayer::volumeChanged(int volume) + + Signal the playback volume has changed to \a volume. +*/ + +/*! + \fn void QMediaPlayer::mutedChanged(bool muted) + + Signal the mute state has changed to \a muted. +*/ + +/*! + \fn void QMediaPlayer::audioAvailableChanged(bool available) + + Signals the availability of audio content has changed to \a available. +*/ + +/*! + \fn void QMediaPlayer::videoAvailableChanged(bool videoAvailable) + + Signal the availability of visual content has changed to \a videoAvailable. +*/ + +/*! + \fn void QMediaPlayer::bufferStatusChanged(int percentFilled) + + Signal the amount of the local buffer filled as a percentage by \a percentFilled. +*/ + +/*! + \enum QMediaPlayer::Flag + + \value LowLatency + The player is expected to be used with simple audio formats, + but playback should start without significant delay. + Such playback service can be used for beeps, ringtones, etc. +*/ + +#include "moc_qmediaplayer.cpp" + +QT_END_NAMESPACE + +QT_END_NAMESPACE + diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h new file mode 100644 index 0000000..1b761ce --- /dev/null +++ b/src/multimedia/playback/qmediaplayer.h @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYER_H +#define QMEDIAPLAYER_H + +#include <QtMultimedia/qmediaserviceprovider.h> +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediacontent.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QMediaPlaylist; + +class QMediaPlayerPrivate; +class Q_MULTIMEDIA_EXPORT QMediaPlayer : public QMediaObject +{ + Q_OBJECT + Q_PROPERTY(QMediaContent media READ media WRITE setMedia NOTIFY mediaChanged) + Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged) + Q_PROPERTY(qint64 position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) + Q_PROPERTY(int bufferStatus READ bufferStatus NOTIFY bufferStatusChanged) + Q_PROPERTY(bool audioAvailable READ isAudioAvailable NOTIFY audioAvailableChanged) + Q_PROPERTY(bool videoAvailable READ isVideoAvailable NOTIFY videoAvailableChanged) + Q_PROPERTY(bool seekable READ isSeekable NOTIFY seekableChanged) + Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged) + Q_PROPERTY(State state READ state NOTIFY stateChanged) + Q_PROPERTY(MediaStatus mediaStatus READ mediaStatus NOTIFY mediaStatusChanged) + Q_PROPERTY(QString error READ errorString) + Q_ENUMS(State) + Q_ENUMS(MediaStatus) + +public: + enum State + { + StoppedState, + PlayingState, + PausedState + }; + + enum MediaStatus + { + UnknownMediaStatus, + NoMedia, + LoadingMedia, + LoadedMedia, + StalledMedia, + BufferingMedia, + BufferedMedia, + EndOfMedia, + InvalidMedia + }; + + enum Flag + { + LowLatency = 0x01 + }; + Q_DECLARE_FLAGS(Flags, Flag) + + enum Error + { + NoError, + ResourceError, + FormatError, + NetworkError, + AccessDeniedError, + ServiceMissingError + }; + + QMediaPlayer(QObject *parent = 0, Flags flags = 0, QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider()); + ~QMediaPlayer(); + + static QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, + const QStringList& codecs = QStringList(), + Flags flags = 0); + static QStringList supportedMimeTypes(Flags flags = 0); + + QMediaContent media() const; + const QIODevice *mediaStream() const; + + State state() const; + MediaStatus mediaStatus() const; + + qint64 duration() const; + qint64 position() const; + + int volume() const; + bool isMuted() const; + bool isAudioAvailable() const; + bool isVideoAvailable() const; + + int bufferStatus() const; + + bool isSeekable() const; + qreal playbackRate() const; + + Error error() const; + QString errorString() const; + +public Q_SLOTS: + void play(); + void pause(); + void stop(); + + void setPosition(qint64 position); + void setVolume(int volume); + void setMuted(bool muted); + + void setPlaybackRate(qreal rate); + + void setMedia(const QMediaContent &media, QIODevice *stream = 0); + +Q_SIGNALS: + void mediaChanged(const QMediaContent &media); + + void stateChanged(QMediaPlayer::State newState); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + + void durationChanged(qint64 duration); + void positionChanged(qint64 position); + + void volumeChanged(int volume); + void mutedChanged(bool muted); + void audioAvailableChanged(bool audioAvailable); + void videoAvailableChanged(bool videoAvailable); + + void bufferStatusChanged(int percentFilled); + + void seekableChanged(bool seekable); + void playbackRateChanged(qreal rate); + + void error(QMediaPlayer::Error error); + +public: + virtual void bind(QObject*); + virtual void unbind(QObject*); + +private: + Q_DISABLE_COPY(QMediaPlayer) + Q_DECLARE_PRIVATE(QMediaPlayer) + Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaPlayer::State)) + Q_PRIVATE_SLOT(d_func(), void _q_mediaStatusChanged(QMediaPlayer::MediaStatus)) + Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &)) + Q_PRIVATE_SLOT(d_func(), void _q_updateMedia(const QMediaContent&)) + Q_PRIVATE_SLOT(d_func(), void _q_playlistDestroyed()) +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QMediaPlayer::State) +Q_DECLARE_METATYPE(QMediaPlayer::MediaStatus) +Q_DECLARE_METATYPE(QMediaPlayer::Error) + +QT_END_HEADER + +#endif // QMEDIAPLAYER_H diff --git a/src/multimedia/playback/qmediaplayercontrol.cpp b/src/multimedia/playback/qmediaplayercontrol.cpp new file mode 100644 index 0000000..95ffade --- /dev/null +++ b/src/multimedia/playback/qmediaplayercontrol.cpp @@ -0,0 +1,378 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/private/qmediacontrol_p.h> +#include <QtMultimedia/qmediaplayer.h> + + +QT_BEGIN_NAMESPACE + + +/*! + \class QMediaPlayerControl + \ingroup multimedia-serv + + \preliminary + \brief The QMediaPlayerControl class provides access to the media playing + functionality of a QMediaService. + + If a QMediaService can play media is will implement QMediaPlayerControl. + This control provides a means to set the \l {setMedia()}{media} to play, + \l {play()}{start}, \l {pause()} {pause} and \l {stop()}{stop} playback, + \l {setPosition()}{seek}, and control the \l {setVolume()}{volume}. + It also provides feedback on the \l {duration()}{duration} of the media, + the current \l {position()}{position}, and \l {bufferStatus()}{buffering} + progress. + + The functionality provided by this control is exposed to application + code through the QMediaPlayer class. + + The interface name of QMediaPlayerControl is \c com.nokia.Qt.QMediaPlayerControl/1.0 as + defined in QMediaPlayerControl_iid. + + \sa QMediaService::control(), QMediaPlayer +*/ + +/*! + \macro QMediaPlayerControl_iid + + \c com.nokia.Qt.QMediaPlayerControl/1.0 + + Defines the interface name of the QMediaPlayerControl class. + + \relates QMediaPlayerControl +*/ + +/*! + Destroys a media player control. +*/ +QMediaPlayerControl::~QMediaPlayerControl() +{ +} + +/*! + Constructs a new media player control with the given \a parent. +*/ +QMediaPlayerControl::QMediaPlayerControl(QObject *parent): + QMediaControl(*new QMediaControlPrivate, parent) +{ +} + +/*! + \fn QMediaPlayerControl::state() const + + Returns the state of a player control. +*/ + +/*! + \fn QMediaPlayerControl::stateChanged(QMediaPlayer::State state) + + Signals that the \a state of a player control has changed. + + \sa state() +*/ + +/*! + \fn QMediaPlayerControl::mediaStatus() const + + Returns the status of the current media. +*/ + +/*! + \fn QMediaPlayerControl::mediaStatusChanged(QMediaPlayer::MediaStatus status) + + Signals that the \a status of the current media has changed. + + \sa mediaStatus() +*/ + + +/*! + \fn QMediaPlayerControl::duration() const + + Returns the duration of the current media in milliseconds. +*/ + +/*! + \fn QMediaPlayerControl::durationChanged(qint64 duration) + + Signals that the \a duration of the current media has changed. + + \sa duration() +*/ + +/*! + \fn QMediaPlayerControl::position() const + + Returns the current playback position in milliseconds. +*/ + +/*! + \fn QMediaPlayerControl::setPosition(qint64 position) + + Sets the playback \a position of the current media. This will initiate a seek and it may take + some time for playback to reach the position set. +*/ + +/*! + \fn QMediaPlayerControl::positionChanged(qint64 position) + + Signals the playback \a position has changed. + + This is only emitted in when there has been a discontinous change in the playback postion, such + as a seek or the position being reset. + + \sa position() +*/ + +/*! + \fn QMediaPlayerControl::volume() const + + Returns the audio volume of a player control. +*/ + +/*! + \fn QMediaPlayerControl::setVolume(int volume) + + Sets the audio \a volume of a player control. +*/ + +/*! + \fn QMediaPlayerControl::volumeChanged(int volume) + + Signals the audio \a volume of a player control has changed. + + \sa volume() +*/ + +/*! + \fn QMediaPlayerControl::isMuted() const + + Returns the mute state of a player control. +*/ + +/*! + \fn QMediaPlayerControl::setMuted(bool mute) + + Sets the \a mute state of a player control. +*/ + +/*! + \fn QMediaPlayerControl::mutedChanged(bool mute) + + Signals a change in the \a mute status of a player control. + + \sa isMuted() +*/ + +/*! + \fn QMediaPlayerControl::bufferStatus() const + + Returns the buffering progress of the current media. Progress is measured in the percentage + of the buffer filled. +*/ + +/*! + \fn QMediaPlayerControl::bufferStatusChanged(int progress) + + Signals that buffering \a progress has changed. + + \sa bufferStatus() +*/ + +/*! + \fn QMediaPlayerControl::isAudioAvailable() const + + Identifies if there is audio output available for the current media. + + Returns true if audio output is available and false otherwise. +*/ + +/*! + \fn QMediaPlayerControl::audioAvailableChanged(bool audio) + + Signals that there has been a change in the availability of \a audio output. + + \sa isAudioAvailable() +*/ + +/*! + \fn QMediaPlayerControl::isVideoAvailable() const + + Identifies if there is video output available for the current media. + + Returns true if video output is available and false otherwise. +*/ + +/*! + \fn QMediaPlayerControl::videoAvailableChanged(bool video) + + Signals that there has been a change in the availability of \a video output. + + \sa isVideoAvailable() +*/ + +/*! + \fn QMediaPlayerControl::isSeekable() const + + Identifies if the current media is seekable. + + Returns true if it possible to seek within the current media, and false otherwise. +*/ + +/*! + \fn QMediaPlayerControl::seekableChanged(bool seekable) + + Signals that the \a seekable state of a player control has changed. + + \sa isSeekable() +*/ + +/*! + \fn QMediaPlayerControl::availablePlaybackRanges() const + + Returns a range of times in milliseconds that can be played back. + + Usually for local files this is a continuous interval equal to [0..duration()] + or an empty time range if seeking is not supported, but for network sources + it refers to the buffered parts of the media. +*/ + +/*! + \fn QMediaPlayerControl::availablePlaybackRangesChanged(const QMediaTimeRange &ranges) + + Signals that the available media playback \a ranges have changed. + + \sa QMediaPlayerControl::availablePlaybackRanges() +*/ + +/*! + \fn qreal QMediaPlayerControl::playbackRate() const + + Returns the rate of playback. +*/ + +/*! + \fn QMediaPlayerControl::setPlaybackRate(qreal rate) + + Sets the \a rate of playback. +*/ + +/*! + \fn QMediaPlayerControl::media() const + + Returns the current media source. +*/ + +/*! + \fn QMediaPlayerControl::mediaStream() const + + Returns the current media stream. This is only a valid if a stream was passed to setMedia(). + + \sa setMedia() +*/ + +/*! + \fn QMediaPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream) + + Sets the current \a media source. If a \a stream is supplied; data will be read from that + instead of attempting to resolve the media source. The media source may still be used to + supply media information such as mime type. + + Setting the media to a null QMediaContent will cause the control to discard all + information relating to the current media source and to cease all I/O operations related + to that media. +*/ + +/*! + \fn QMediaPlayerControl::mediaChanged(const QMediaContent& content) + + Signals that the current media \a content has changed. +*/ + +/*! + \fn QMediaPlayerControl::play() + + Starts playback of the current media. + + If successful the player control will immediately enter the \l {QMediaPlayer::PlayingState} + {playing} state. + + \sa state() +*/ + +/*! + \fn QMediaPlayerControl::pause() + + Pauses playback of the current media. + + If sucessful the player control will immediately enter the \l {QMediaPlayer::PausedState} + {paused} state. + + \sa state(), play(), stop() +*/ + +/*! + \fn QMediaPlayerControl::stop() + + Stops playback of the current media. + + If succesful the player control will immediately enter the \l {QMediaPlayer::StoppedState} + {stopped} state. +*/ + +/*! + \fn QMediaPlayerControl::error(int error, const QString &errorString) + + Signals that an \a error has occurred. The \a errorString provides a more detailed explanation. +*/ + +/*! + \fn QMediaPlayerControl::playbackRateChanged(qreal rate) + + Signal emitted when playback rate changes to \a rate. +*/ + +QT_END_NAMESPACE + +#include "moc_qmediaplayercontrol.cpp" + diff --git a/src/multimedia/playback/qmediaplayercontrol.h b/src/multimedia/playback/qmediaplayercontrol.h new file mode 100644 index 0000000..a7e418b --- /dev/null +++ b/src/multimedia/playback/qmediaplayercontrol.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEDIAPLAYERCONTROL_H +#define QMEDIAPLAYERCONTROL_H + +#include <QtCore/qpair.h> + +#include <QtMultimedia/qmediacontrol.h> +#include <QtMultimedia/qmediaplayer.h> +#include <QtMultimedia/qmediatimerange.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + + +class QMediaPlaylist; + +class Q_MULTIMEDIA_EXPORT QMediaPlayerControl : public QMediaControl +{ + Q_OBJECT + +public: + ~QMediaPlayerControl(); + + virtual QMediaPlayer::State state() const = 0; + + virtual QMediaPlayer::MediaStatus mediaStatus() const = 0; + + virtual qint64 duration() const = 0; + + virtual qint64 position() const = 0; + virtual void setPosition(qint64 position) = 0; + + virtual int volume() const = 0; + virtual void setVolume(int volume) = 0; + + virtual bool isMuted() const = 0; + virtual void setMuted(bool muted) = 0; + + virtual int bufferStatus() const = 0; + + virtual bool isAudioAvailable() const = 0; + virtual bool isVideoAvailable() const = 0; + + virtual bool isSeekable() const = 0; + + virtual QMediaTimeRange availablePlaybackRanges() const = 0; + + virtual qreal playbackRate() const = 0; + virtual void setPlaybackRate(qreal rate) = 0; + + virtual QMediaContent media() const = 0; + virtual const QIODevice *mediaStream() const = 0; + virtual void setMedia(const QMediaContent &media, QIODevice *stream) = 0; + + virtual void play() = 0; + virtual void pause() = 0; + virtual void stop() = 0; + +Q_SIGNALS: + void mediaChanged(const QMediaContent& content); + void durationChanged(qint64 duration); + void positionChanged(qint64 position); + void stateChanged(QMediaPlayer::State newState); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void volumeChanged(int volume); + void mutedChanged(bool muted); + void audioAvailableChanged(bool audioAvailable); + void videoAvailableChanged(bool videoAvailable); + void bufferStatusChanged(int percentFilled); + void seekableChanged(bool); + void availablePlaybackRangesChanged(const QMediaTimeRange&); + void playbackRateChanged(qreal rate); + void error(int error, const QString &errorString); + +protected: + QMediaPlayerControl(QObject* parent = 0); +}; + +#define QMediaPlayerControl_iid "com.nokia.Qt.QMediaPlayerControl/1.0" +Q_MEDIA_DECLARE_CONTROL(QMediaPlayerControl, QMediaPlayerControl_iid) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMEDIAPLAYERCONTROL_H + diff --git a/src/multimedia/qml/qmetadatacontrolmetaobject.cpp b/src/multimedia/qml/qmetadatacontrolmetaobject.cpp new file mode 100644 index 0000000..47b6382 --- /dev/null +++ b/src/multimedia/qml/qmetadatacontrolmetaobject.cpp @@ -0,0 +1,362 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/private/qmetadatacontrolmetaobject_p.h> +#include <QtMultimedia/qmetadatacontrol.h> + + +QT_BEGIN_NAMESPACE + +// copied from qmetaobject.cpp +// do not touch without touching the moc as well +enum PropertyFlags { + Invalid = 0x00000000, + Readable = 0x00000001, + Writable = 0x00000002, + Resettable = 0x00000004, + EnumOrFlag = 0x00000008, + StdCppSet = 0x00000100, +// Override = 0x00000200, + Designable = 0x00001000, + ResolveDesignable = 0x00002000, + Scriptable = 0x00004000, + ResolveScriptable = 0x00008000, + Stored = 0x00010000, + ResolveStored = 0x00020000, + Editable = 0x00040000, + ResolveEditable = 0x00080000, + User = 0x00100000, + ResolveUser = 0x00200000, + Notify = 0x00400000, + Dynamic = 0x00800000 +}; + +enum MethodFlags { + AccessPrivate = 0x00, + AccessProtected = 0x01, + AccessPublic = 0x02, + AccessMask = 0x03, //mask + + MethodMethod = 0x00, + MethodSignal = 0x04, + MethodSlot = 0x08, + MethodConstructor = 0x0c, + MethodTypeMask = 0x0c, + + MethodCompatibility = 0x10, + MethodCloned = 0x20, + MethodScriptable = 0x40 +}; + +struct QMetaObjectPrivate +{ + int revision; + int className; + int classInfoCount, classInfoData; + int methodCount, methodData; + int propertyCount, propertyData; + int enumeratorCount, enumeratorData; + int constructorCount, constructorData; + int flags; +}; + +static inline const QMetaObjectPrivate *priv(const uint* m_data) +{ return reinterpret_cast<const QMetaObjectPrivate*>(m_data); } +// end of copied lines from qmetaobject.cpp + +namespace +{ + struct MetaDataKey + { + QtMultimedia::MetaData key; + const char *name; + }; + + const MetaDataKey qt_metaDataKeys[] = + { + { QtMultimedia::Title, "title" }, + { QtMultimedia::SubTitle, "subTitle" }, + { QtMultimedia::Author, "author" }, + { QtMultimedia::Comment, "comment" }, + { QtMultimedia::Description, "description" }, + { QtMultimedia::Category, "category" }, + { QtMultimedia::Genre, "genre" }, + { QtMultimedia::Year, "year" }, + { QtMultimedia::Date, "date" }, + { QtMultimedia::UserRating, "userRating" }, + { QtMultimedia::Keywords, "keywords" }, + { QtMultimedia::Language, "language" }, + { QtMultimedia::Publisher, "publisher" }, + { QtMultimedia::Copyright, "copyright" }, + { QtMultimedia::ParentalRating, "parentalRating" }, + { QtMultimedia::RatingOrganisation, "ratingOrganisation" }, + + // Media + { QtMultimedia::Size, "size" }, + { QtMultimedia::MediaType, "mediaType" }, +// { QtMultimedia::Duration, "duration" }, + + // Audio + { QtMultimedia::AudioBitRate, "audioBitRate" }, + { QtMultimedia::AudioCodec, "audioCodec" }, + { QtMultimedia::AverageLevel, "averageLevel" }, + { QtMultimedia::ChannelCount, "channelCount" }, + { QtMultimedia::PeakValue, "peakValue" }, + { QtMultimedia::SampleRate, "sampleRate" }, + + // Music + { QtMultimedia::AlbumTitle, "albumTitle" }, + { QtMultimedia::AlbumArtist, "albumArtist" }, + { QtMultimedia::ContributingArtist, "contributingArtist" }, + { QtMultimedia::Composer, "composer" }, + { QtMultimedia::Conductor, "conductor" }, + { QtMultimedia::Lyrics, "lyrics" }, + { QtMultimedia::Mood, "mood" }, + { QtMultimedia::TrackNumber, "trackNumber" }, + { QtMultimedia::TrackCount, "trackCount" }, + + { QtMultimedia::CoverArtUrlSmall, "coverArtUrlSmall" }, + { QtMultimedia::CoverArtUrlLarge, "coverArtUrlLarge" }, + + // Image/Video + { QtMultimedia::Resolution, "resolution" }, + { QtMultimedia::PixelAspectRatio, "pixelAspectRatio" }, + + // Video + { QtMultimedia::VideoFrameRate, "videoFrameRate" }, + { QtMultimedia::VideoBitRate, "videoBitRate" }, + { QtMultimedia::VideoCodec, "videoCodec" }, + + { QtMultimedia::PosterUrl, "posterUrl" }, + + // Movie + { QtMultimedia::ChapterNumber, "chapterNumber" }, + { QtMultimedia::Director, "director" }, + { QtMultimedia::LeadPerformer, "leadPerformer" }, + { QtMultimedia::Writer, "writer" }, + + // Photos + { QtMultimedia::CameraManufacturer, "cameraManufacturer" }, + { QtMultimedia::CameraModel, "cameraModel" }, + { QtMultimedia::Event, "event" }, + { QtMultimedia::Subject, "subject" }, + { QtMultimedia::Orientation, "orientation" }, + { QtMultimedia::ExposureTime, "exposureTime" }, + { QtMultimedia::FNumber, "fNumber" }, + { QtMultimedia::ExposureProgram, "exposureProgram" }, + { QtMultimedia::ISOSpeedRatings, "isoSpeedRatings" }, + { QtMultimedia::ExposureBiasValue, "exposureBiasValue" }, + { QtMultimedia::DateTimeOriginal, "dateTimeOriginal" }, + { QtMultimedia::DateTimeDigitized, "dateTimeDigitized" }, + { QtMultimedia::SubjectDistance, "subjectDistance" }, + { QtMultimedia::MeteringMode, "meteringMode" }, + { QtMultimedia::LightSource, "lightSource" }, + { QtMultimedia::Flash, "flash" }, + { QtMultimedia::FocalLength, "focalLength" }, + { QtMultimedia::ExposureMode, "exposureMode" }, + { QtMultimedia::WhiteBalance, "whiteBalance" }, + { QtMultimedia::DigitalZoomRatio, "digitalZoomRatio" }, + { QtMultimedia::FocalLengthIn35mmFilm, "focalLengthIn35mmFilm" }, + { QtMultimedia::SceneCaptureType, "sceneCaptureType" }, + { QtMultimedia::GainControl, "gainControl" }, + { QtMultimedia::Contrast, "contrast" }, + { QtMultimedia::Saturation, "saturation" }, + { QtMultimedia::Sharpness, "sharpness" }, + { QtMultimedia::DeviceSettingDescription, "deviceSettingDescription" } + }; + + class QMetaDataControlObject : public QObject + { + public: + inline QObjectData *data() { return d_ptr.data(); } + }; +} + +QMetaDataControlMetaObject::QMetaDataControlMetaObject(QMetaDataControl *control, QObject *object) + : m_control(control) + , m_object(object) + , m_string(0) + , m_data(0) + , m_propertyOffset(0) + , m_signalOffset(0) +{ + const QMetaObject *superClass = m_object->metaObject(); + + const int propertyCount = sizeof(qt_metaDataKeys) / sizeof(MetaDataKey); + const int dataSize = sizeof(uint) + * (13 // QMetaObjectPrivate members. + + 5 // 5 members per signal. + + 4 * propertyCount // 3 members per property + 1 notify signal per property. + + 1); // Terminating value. + + m_data = reinterpret_cast<uint *>(qMalloc(dataSize)); + + QMetaObjectPrivate *pMeta = reinterpret_cast<QMetaObjectPrivate *>(m_data); + + pMeta->revision = 3; + pMeta->className = 0; + pMeta->classInfoCount = 0; + pMeta->classInfoData = 0; + pMeta->methodCount = 1; + pMeta->methodData = 13; + pMeta->propertyCount = propertyCount; + pMeta->propertyData = 18; + pMeta->enumeratorCount = 0; + pMeta->enumeratorData = 0; + pMeta->constructorCount = 0; + pMeta->constructorData = 0; + pMeta->flags = 0x01; // Dynamic meta object flag. + + const int classNameSize = qstrlen(superClass->className()) + 1; + + int stringIndex = classNameSize + 1; + + // __metaDataChanged() signal. + static const char *changeSignal = "__metaDataChanged()"; + const int changeSignalSize = qstrlen(changeSignal) + 1; + + m_data[13] = stringIndex; // Signature. + m_data[14] = classNameSize; // Parameters. + m_data[15] = classNameSize; // Type. + m_data[16] = classNameSize; // Tag. + m_data[17] = MethodSignal | AccessProtected; // Flags. + + stringIndex += changeSignalSize; + + const char *qvariantName = "QVariant"; + const int qvariantSize = qstrlen(qvariantName) + 1; + const int qvariantIndex = stringIndex; + + stringIndex += qvariantSize; + + // Properties. + for (int i = 0; i < propertyCount; ++i) { + m_data[18 + 3 * i] = stringIndex; // Name. + m_data[19 + 3 * i] = qvariantIndex; // Type. + m_data[20 + 3 * i] + = Readable | Writable | Notify | Dynamic | (0xffffffff << 24); // Flags. + m_data[18 + propertyCount * 3 + i] = 0; // Notify signal. + + stringIndex += qstrlen(qt_metaDataKeys[i].name) + 1; + } + + // Terminating value. + m_data[18 + propertyCount * 4] = 0; + + // Build string. + m_string = reinterpret_cast<char *>(qMalloc(stringIndex + 1)); + + // Class name. + qMemCopy(m_string, superClass->className(), classNameSize); + + stringIndex = classNameSize; + + // Null m_string. + m_string[stringIndex] = '\0'; + stringIndex += 1; + + // __metaDataChanged() signal. + qMemCopy(m_string + stringIndex, changeSignal, changeSignalSize); + stringIndex += changeSignalSize; + + qMemCopy(m_string + stringIndex, qvariantName, qvariantSize); + stringIndex += qvariantSize; + + // Properties. + for (int i = 0; i < propertyCount; ++i) { + const int propertyNameSize = qstrlen(qt_metaDataKeys[i].name) + 1; + + qMemCopy(m_string + stringIndex, qt_metaDataKeys[i].name, propertyNameSize); + stringIndex += propertyNameSize; + } + + // Terminating character. + m_string[stringIndex] = '\0'; + + d.superdata = superClass; + d.stringdata = m_string; + d.data = m_data; + d.extradata = 0; + + static_cast<QMetaDataControlObject *>(m_object)->data()->metaObject = this; + + m_propertyOffset = propertyOffset(); + m_signalOffset = methodOffset(); +} + +QMetaDataControlMetaObject::~QMetaDataControlMetaObject() +{ + static_cast<QMetaDataControlObject *>(m_object)->data()->metaObject = 0; + + qFree(m_data); + qFree(m_string); +} + +int QMetaDataControlMetaObject::metaCall(QMetaObject::Call c, int id, void **a) +{ + if (c == QMetaObject::ReadProperty && id >= m_propertyOffset) { + int propId = id - m_propertyOffset; + + *reinterpret_cast<QVariant *>(a[0]) = m_control->metaData(qt_metaDataKeys[propId].key); + + return -1; + } else if (c == QMetaObject::WriteProperty && id >= m_propertyOffset) { + int propId = id - m_propertyOffset; + + m_control->setMetaData(qt_metaDataKeys[propId].key, *reinterpret_cast<QVariant *>(a[0])); + + return -1; + } else { + return m_object->qt_metacall(c, id, a); + } +} + +int QMetaDataControlMetaObject::createProperty(const char *, const char *) +{ + return -1; +} + +void QMetaDataControlMetaObject::metaDataChanged() +{ + activate(m_object, m_signalOffset, 0); +} + +QT_END_NAMESPACE diff --git a/src/multimedia/qml/qmetadatacontrolmetaobject_p.h b/src/multimedia/qml/qmetadatacontrolmetaobject_p.h new file mode 100644 index 0000000..c0fd4e8 --- /dev/null +++ b/src/multimedia/qml/qmetadatacontrolmetaobject_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMETADATACONTROLMETAOBJECT_P_H +#define QMETADATACONTROLMETAOJBECT_P_H + +#include <QtCore/qmetaobject.h> +#include <QtMultimedia/qtmedianamespace.h> + +#include <QtCore/private/qobject_p.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMetaDataControl; + +class QMetaDataControlMetaObject : public QAbstractDynamicMetaObject +{ +public: + QMetaDataControlMetaObject(QMetaDataControl *control, QObject *object); + ~QMetaDataControlMetaObject(); + + int metaCall(QMetaObject::Call call, int _id, void **arguments); + int createProperty(const char *, const char *); + + void metaDataChanged(); + +private: + QMetaDataControl *m_control; + QObject *m_object; + char *m_string; + uint *m_data; + + int m_propertyOffset; + int m_signalOffset; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/qml/qml.pri b/src/multimedia/qml/qml.pri new file mode 100644 index 0000000..370232e --- /dev/null +++ b/src/multimedia/qml/qml.pri @@ -0,0 +1,35 @@ + +contains(QT_CONFIG, declarative) { + QT += declarative + + system(pkg-config --exists \'libpulse >= 0.9.10\') { + DEFINES += QT_MULTIMEDIA_PULSEAUDIO + HEADERS += $$PWD/qsoundeffect_pulse_p.h + SOURCES += $$PWD/qsoundeffect_pulse_p.cpp + LIBS += -lpulse + } else:x11 { + DEFINES += QT_MULTIMEDIA_QMEDIAPLAYER + HEADERS += $$PWD/qsoundeffect_qmedia_p.h + SOURCES += $$PWD/qsoundeffect_qmedia_p.cpp + } else { + HEADERS += $$PWD/qsoundeffect_qsound_p.h + SOURCES += $$PWD/qsoundeffect_qsound_p.cpp + } + + HEADERS += \ + $$PWD/qmetadatacontrolmetaobject_p.h \ + $$PWD/qmlaudio_p.h \ + $$PWD/qmlgraphicsvideo_p.h \ + $$PWD/qmlmediabase_p.h \ + $$PWD/qsoundeffect_p.h \ + $$PWD/wavedecoder_p.h + + SOURCES += \ + $$PWD/qmetadatacontrolmetaobject.cpp \ + $$PWD/qmlaudio.cpp \ + $$PWD/qmlgraphicsvideo.cpp \ + $$PWD/qmlmediabase.cpp \ + $$PWD/qsoundeffect.cpp \ + $$PWD/wavedecoder_p.cpp +} + diff --git a/src/multimedia/qml/qmlaudio.cpp b/src/multimedia/qml/qmlaudio.cpp new file mode 100644 index 0000000..5719050 --- /dev/null +++ b/src/multimedia/qml/qmlaudio.cpp @@ -0,0 +1,326 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmlaudio_p.h" + +#include <QtMultimedia/qmediaplayercontrol.h> + +QT_BEGIN_NAMESPACE + + +/*! + \qmlclass Audio QmlAudio + \brief The Audio element allows you to add audio playback to a scene. + + \qml + Audio { source: "audio/song.mp3" } + \endqml + + \sa Video +*/ + +/*! + \internal + \class QmlAudio + \brief The QmlAudio class provides an audio item that you can add to a QmlView. +*/ + +void QmlAudio::_q_error(int errorCode, const QString &errorString) +{ + m_error = QMediaPlayer::Error(errorCode); + m_errorString = errorString; + + emit error(Error(errorCode), errorString); + emit errorChanged(); +} + + +QmlAudio::QmlAudio(QObject *parent) + : QObject(parent) +{ + setObject(this); +} + +QmlAudio::~QmlAudio() +{ + shutdown(); +} + +/*! + \qmlmethod Audio::play() + + Starts playback of the media. + + Sets the \l playing property to true, and the \l paused property to false. +*/ + +void QmlAudio::play() +{ + m_playerControl->play(); + + if (m_paused) { + m_paused = false; + emit pausedChanged(); + } +} + +/*! + \qmlmethod Audio::pause() + + Pauses playback of the media. + + Sets the \l playing and \l paused properties to true. +*/ + +void QmlAudio::pause() +{ + m_playerControl->pause(); + + if (!m_paused && m_state == QMediaPlayer::PausedState) { + m_paused = true; + emit pausedChanged(); + } +} + +/*! + \qmlmethod Audio::stop() + + Stops playback of the media. + + Sets the \l playing and \l paused properties to false. +*/ + +void QmlAudio::stop() +{ + m_playerControl->stop(); + + if (m_paused) { + m_paused = false; + emit pausedChanged(); + } +} + +/*! + \qmlproperty url Audio::source + + This property holds the source URL of the media. +*/ + +/*! + \qmlproperty bool Audio::playing + + This property holds whether the media is playing. + + Defaults to false, and can be set to true to start playback. +*/ + +/*! + \qmlproperty bool Audio::paused + + This property holds whether the media is paused. + + Defaults to false, and can be set to true to pause playback. +*/ + +/*! + \qmlsignal Audio::onStarted() + + This handler is called when playback is started. +*/ + +/*! + \qmlsignal Audio::onResumed() + + This handler is called when playback is resumed from the paused state. +*/ + +/*! + \qmlsignal Audio::onPaused() + + This handler is called when playback is paused. +*/ + +/*! + \qmlsignal Audio::onStopped() + + This handler is called when playback is stopped. +*/ + +/*! + \qmlproperty enum Audio::status + + This property holds the status of media loading. It can be one of: + + \list + \o NoMedia - no media has been set. + \o Loading - the media is currently being loaded. + \o Loaded - the media has been loaded. + \o Buffering - the media is buffering data. + \o Stalled - playback has been interrupted while the media is buffering data. + \o Buffered - the media has buffered data. + \o EndOfMedia - the media has played to the end. + \o InvalidMedia - the media cannot be played. + \o UnknownStatus - the status of the media is unknown. + \endlist +*/ + +QmlAudio::Status QmlAudio::status() const +{ + return Status(m_status); +} + +/*! + \qmlsignal Audio::onLoaded() + + This handler is called when the media source has been loaded. +*/ + +/*! + \qmlsignal Audio::onBuffering() + + This handler is called when the media starts buffering. +*/ + +/*! + \qmlsignal Audio::onStalled() + + This handler is called when playback has stalled while the media buffers. +*/ + +/*! + \qmlsignal Audio::onBuffered() + + This handler is called when the media has finished buffering. +*/ + +/*! + \qmlsignal Audio::onEndOfMedia() + + This handler is called when playback stops because end of the media has been reached. +*/ +/*! + \qmlproperty int Audio::duration + + This property holds the duration of the media in milliseconds. + + If the media doesn't have a fixed duration (a live stream for example) this will be 0. +*/ + +/*! + \qmlproperty int Audio::position + + This property holds the current playback position in milliseconds. + + If the \l seekable property is true, this property can be set to seek to a new position. +*/ + +/*! + \qmlproperty qreal Audio::volume + + This property holds the volume of the audio output, from 0.0 (silent) to 1.0 (maximum volume). +*/ + +/*! + \qmlproperty bool Audio::muted + + This property holds whether the audio output is muted. +*/ + +/*! + \qmlproperty qreal Audio::bufferProgress + + This property holds how much of the data buffer is currently filled, from 0.0 (empty) to 1.0 + (full). +*/ + +/*! + \qmlproperty bool Audio::seekable + + This property holds whether position of the audio can be changed. + + If true; setting a \l position value will cause playback to seek to the new position. +*/ + +/*! + \qmlproperty qreal playbackRate + + This property holds the rate at which audio is played at as a multiple of the normal rate. +*/ + +/*! + \qmlproperty enum Audio::error + + This property holds the error state of the audio. It can be one of: + + \list + \o NoError - there is no current error. + \o ResourceError - the audio cannot be played due to a problem allocating resources. + \o FormatError - the audio format is not supported. + \o NetworkError - the audio cannot be played due to network issues. + \o AccessDenied - the audio cannot be played due to insufficient permissions. + \o ServiceMissing - the audio cannot be played because the media service could not be + instantiated. + \endlist +*/ + +QmlAudio::Error QmlAudio::error() const +{ + return Error(m_error); +} + +/*! + \qmlproperty string Audio::errorString + + This property holds a string describing the current error condition in more detail. +*/ + +/*! + \qmlproperty Audio::onError(error, errorString) + + This property is called when an \l {Error}{error} has occurred. The errorString parameter + may contain more detailed information about the error. +*/ + +QT_END_NAMESPACE + +#include "moc_qmlaudio_p.cpp" + + diff --git a/src/multimedia/qml/qmlaudio_p.h b/src/multimedia/qml/qmlaudio_p.h new file mode 100644 index 0000000..f6c5cbf --- /dev/null +++ b/src/multimedia/qml/qmlaudio_p.h @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLAUDIO_P_H +#define QMLAUDIO_P_H + +#include <QtMultimedia/private/qmlmediabase_p.h> + +#include <QtCore/qbasictimer.h> +#include <QtDeclarative/qmlgraphicsitem.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QTimerEvent; + +class Q_MULTIMEDIA_EXPORT QmlAudio : public QObject, public QmlMediaBase, public QmlParserStatus +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(bool playing READ isPlaying WRITE setPlaying NOTIFY playingChanged) + Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(int duration READ duration NOTIFY durationChanged) + Q_PROPERTY(int position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) + Q_PROPERTY(int bufferProgress READ bufferProgress NOTIFY bufferProgressChanged) + Q_PROPERTY(bool seekable READ isSeekable NOTIFY seekableChanged) + Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged) + Q_PROPERTY(Error error READ error NOTIFY errorChanged) + Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged) + Q_ENUMS(Status) + Q_ENUMS(Error) + Q_INTERFACES(QmlParserStatus) +public: + enum Status + { + UnknownStatus = QMediaPlayer::UnknownMediaStatus, + NoMedia = QMediaPlayer::NoMedia, + Loading = QMediaPlayer::LoadingMedia, + Loaded = QMediaPlayer::LoadedMedia, + Stalled = QMediaPlayer::StalledMedia, + Buffering = QMediaPlayer::BufferingMedia, + Buffered = QMediaPlayer::BufferedMedia, + EndOfMedia = QMediaPlayer::EndOfMedia, + InvalidMedia = QMediaPlayer::InvalidMedia + }; + + enum Error + { + NoError = QMediaPlayer::NoError, + ResourceError = QMediaPlayer::ResourceError, + FormatError = QMediaPlayer::FormatError, + NetworkError = QMediaPlayer::NetworkError, + AccessDenied = QMediaPlayer::AccessDeniedError, + ServiceMissing = QMediaPlayer::ServiceMissingError + }; + + QmlAudio(QObject *parent = 0); + ~QmlAudio(); + + Status status() const; + Error error() const; + +public Q_SLOTS: + void play(); + void pause(); + void stop(); + +Q_SIGNALS: + void sourceChanged(); + + void playingChanged(); + void pausedChanged(); + + void started(); + void resumed(); + void paused(); + void stopped(); + + void statusChanged(); + + void loaded(); + void buffering(); + void stalled(); + void buffered(); + void endOfMedia(); + + void durationChanged(); + void positionChanged(); + + void volumeChanged(); + void mutedChanged(); + + void bufferProgressChanged(); + + void seekableChanged(); + void playbackRateChanged(); + + void errorChanged(); + void error(QmlAudio::Error error, const QString &errorString); + +private Q_SLOTS: + void _q_error(int, const QString &); + +private: + Q_DISABLE_COPY(QmlAudio) + Q_PRIVATE_SLOT(mediaBase(), void _q_stateChanged(QMediaPlayer::State)) + Q_PRIVATE_SLOT(mediaBase(), void _q_mediaStatusChanged(QMediaPlayer::MediaStatus)) + Q_PRIVATE_SLOT(mediaBase(), void _q_metaDataChanged()) + + inline QmlMediaBase *mediaBase() { return this; } +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QmlAudio)) + +QT_END_HEADER + +#endif diff --git a/src/multimedia/qml/qmlgraphicsvideo.cpp b/src/multimedia/qml/qmlgraphicsvideo.cpp new file mode 100644 index 0000000..fde505d --- /dev/null +++ b/src/multimedia/qml/qmlgraphicsvideo.cpp @@ -0,0 +1,944 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmlgraphicsvideo_p.h" + +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/private/qpaintervideosurface_p.h> +#include <QtMultimedia/qvideooutputcontrol.h> +#include <QtMultimedia/qvideorenderercontrol.h> + + +QT_BEGIN_NAMESPACE + + +void QmlGraphicsVideo::_q_nativeSizeChanged(const QSizeF &size) +{ + setImplicitWidth(size.width()); + setImplicitHeight(size.height()); +} + +void QmlGraphicsVideo::_q_error(int errorCode, const QString &errorString) +{ + m_error = QMediaPlayer::Error(errorCode); + m_errorString = errorString; + + emit error(Error(errorCode), errorString); + emit errorChanged(); +} + + +/*! + \qmlclass Video QmlGraphicsVideo + \brief The Video element allows you to add videos to a scene. + \inherits Item + + \qml + Video { source: "video/movie.mpg" } + \endqml + + The video item supports untransformed, stretched, and uniformly scaled video presentation. + For a description of stretched uniformly scaled presentation, see the \l fillMode property + description. + + The video item is only visible when the \l hasVideo property is true and the video is playing. + + \sa Audio +*/ + +/*! + \internal + \class QmlGraphicsVideo + \brief The QmlGraphicsVideo class provides a video item that you can add to a QmlView. +*/ + +QmlGraphicsVideo::QmlGraphicsVideo(QmlGraphicsItem *parent) + : QmlGraphicsItem(parent) + , m_graphicsItem(0) + +{ + m_graphicsItem = new QGraphicsVideoItem(this); + connect(m_graphicsItem, SIGNAL(nativeSizeChanged(QSizeF)), + this, SLOT(_q_nativeSizeChanged(QSizeF))); + + setObject(this); + + if (m_mediaService) { + connect(m_playerControl, SIGNAL(audioAvailableChanged(bool)), + this, SIGNAL(hasAudioChanged())); + connect(m_playerControl, SIGNAL(videoAvailableChanged(bool)), + this, SIGNAL(hasVideoChanged())); + + m_graphicsItem->setMediaObject(m_mediaObject); + } +} + +QmlGraphicsVideo::~QmlGraphicsVideo() +{ + shutdown(); + + delete m_graphicsItem; +} + +/*! + \qmlproperty url Video::source + + This property holds the source URL of the media. +*/ + +/*! + \qmlproperty bool Video::playing + + This property holds whether the media is playing. + + Defaults to false, and can be set to true to start playback. +*/ + +/*! + \qmlproperty bool Video::paused + + This property holds whether the media is paused. + + Defaults to false, and can be set to true to pause playback. +*/ + +/*! + \qmlsignal Video::onStarted() + + This handler is called when playback is started. +*/ + +/*! + \qmlsignal Video::onResumed() + + This handler is called when playback is resumed from the paused state. +*/ + +/*! + \qmlsignal Video::onPaused() + + This handler is called when playback is paused. +*/ + +/*! + \qmlsignal Video::onStopped() + + This handler is called when playback is stopped. +*/ + +/*! + \qmlproperty enum Video::status + + This property holds the status of media loading. It can be one of: + + \list + \o NoMedia - no media has been set. + \o Loading - the media is currently being loaded. + \o Loaded - the media has been loaded. + \o Buffering - the media is buffering data. + \o Stalled - playback has been interrupted while the media is buffering data. + \o Buffered - the media has buffered data. + \o EndOfMedia - the media has played to the end. + \o InvalidMedia - the media cannot be played. + \o UnknownStatus - the status of the media is cannot be determined. + \endlist +*/ + +QmlGraphicsVideo::Status QmlGraphicsVideo::status() const +{ + return Status(m_status); +} + +/*! + \qmlsignal Video::onLoaded() + + This handler is called when the media source has been loaded. +*/ + +/*! + \qmlsignal Video::onBuffering() + + This handler is called when the media starts buffering. +*/ + +/*! + \qmlsignal Video::onStalled() + + This handler is called when playback has stalled while the media buffers. +*/ + +/*! + \qmlsignal Video::onBuffered() + + This handler is called when the media has finished buffering. +*/ + +/*! + \qmlsignal Video::onEndOfMedia() + + This handler is called when playback stops because end of the media has been reached. +*/ + +/*! + \qmlproperty int Video::duration + + This property holds the duration of the media in milliseconds. + + If the media doesn't have a fixed duration (a live stream for example) this will be 0. +*/ + +/*! + \qmlproperty int Video::position + + This property holds the current playback position in milliseconds. +*/ + +/*! + \qmlproperty qreal Video::volume + + This property holds the volume of the audio output, from 0.0 (silent) to 1.0 (maximum volume). +*/ + +/*! + \qmlproperty bool Video::muted + + This property holds whether the audio output is muted. +*/ + +/*! + \qmlproperty bool Video::hasAudio + + This property holds whether the media contains audio. +*/ + +bool QmlGraphicsVideo::hasAudio() const +{ + return m_playerControl->isAudioAvailable(); +} + +/*! + \qmlproperty bool Video::hasVideo + + This property holds whether the media contains video. +*/ + +bool QmlGraphicsVideo::hasVideo() const +{ + return m_playerControl->isVideoAvailable(); +} + +/*! + \qmlproperty qreal Video::bufferProgress + + This property holds how much of the data buffer is currently filled, from 0.0 (empty) to 1.0 + (full). +*/ + +/*! + \qmlproperty bool Video::seekable + + This property holds whether position of the video can be changed. +*/ + +/*! + \qmlproperty qreal playbackRate + + This property holds the rate at which video is played at as a multiple of the normal rate. +*/ + +/*! + \qmlproperty enum Video::error + + This property holds the error state of the video. It can be one of: + + \list + \o NoError - there is no current error. + \o ResourceError - the video cannot be played due to a problem allocating resources. + \o FormatError - the video format is not supported. + \o NetworkError - the video cannot be played due to network issues. + \o AccessDenied - the video cannot be played due to insufficient permissions. + \o ServiceMissing - the video cannot be played because the media service could not be + instantiated. + \endlist +*/ + + +QmlGraphicsVideo::Error QmlGraphicsVideo::error() const +{ + return Error(m_error); +} + +/*! + \qmlproperty string Video::errorString + + This property holds a string describing the current error condition in more detail. +*/ + +/*! + \qmlproperty Video::onError(error, errorString) + + This property is called when an \l {Error}{error} has occurred. The errorString parameter + may contain more detailed information about the error. +*/ + +/*! + \qmlproperty enum Video::fillMode + + Set this property to define how the video is scaled to fit the target area. + + \list + \o Stretch - the video is scaled to fit. + \o PreserveAspectFit - the video is scaled uniformly to fit without cropping + \o PreserveAspectCrop - the video is scaled uniformly to fill, cropping if necessary + \endlist + + The default fill mode is PreserveAspectFit. +*/ + +QmlGraphicsVideo::FillMode QmlGraphicsVideo::fillMode() const +{ + return FillMode(m_graphicsItem->aspectRatioMode()); +} + +void QmlGraphicsVideo::setFillMode(FillMode mode) +{ + m_graphicsItem->setAspectRatioMode(Qt::AspectRatioMode(mode)); +} + +/*! + \qmlmethod Video::play() + + Starts playback of the media. + + Sets the \l playing property to true, and the \l paused property to false. +*/ + +void QmlGraphicsVideo::play() +{ + m_playerControl->play(); + + if (m_paused) { + m_paused = false; + emit pausedChanged(); + } +} + +/*! + \qmlmethod Video::pause() + + Pauses playback of the media. + + Sets the \l playing and \l paused properties to true. +*/ + +void QmlGraphicsVideo::pause() +{ + m_playerControl->pause(); + + if (!m_paused && m_state == QMediaPlayer::PausedState) { + m_paused = true; + emit pausedChanged(); + } +} + +/*! + \qmlmethod Video::stop() + + Stops playback of the media. + + Sets the \l playing and \l paused properties to false. +*/ + +void QmlGraphicsVideo::stop() +{ + m_playerControl->stop(); + + if (m_paused) { + m_paused = false; + emit pausedChanged(); + } +} + +void QmlGraphicsVideo::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) +{ +} + +void QmlGraphicsVideo::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + m_graphicsItem->setSize(newGeometry.size()); + + QmlGraphicsItem::geometryChanged(newGeometry, oldGeometry); +} + +QT_END_NAMESPACE + +// *************************************** +// Documentation for meta-data properties. +// *************************************** + +/*! + \qmlproperty variant Video::title + + This property holds the tile of the media. + + \sa {QtMultimedia::Title} +*/ + +/*! + \qmlproperty variant Video::subTitle + + This property holds the sub-title of the media. + + \sa {QtMultimedia::SubTitle} +*/ + +/*! + \qmlproperty variant Video::author + + This property holds the author of the media. + + \sa {QtMultimedia::Author} +*/ + +/*! + \qmlproperty variant Video::comment + + This property holds a user comment about the media. + + \sa {QtMultimedia::Comment} +*/ + +/*! + \qmlproperty variant Video::description + + This property holds a description of the media. + + \sa {QtMultimedia::Description} +*/ + +/*! + \qmlproperty variant Video::category + + This property holds the category of the media + + \sa {QtMultimedia::Category} +*/ + +/*! + \qmlproperty variant Video::genre + + This property holds the genre of the media. + + \sa {QtMultimedia::Genre} +*/ + +/*! + \qmlproperty variant Video::year + + This property holds the year of release of the media. + + \sa {QtMultimedia::Year} +*/ + +/*! + \qmlproperty variant Video::date + + This property holds the date of the media. + + \sa {QtMultimedia::Date} +*/ + +/*! + \qmlproperty variant Video::userRating + + This property holds a user rating of the media in the range of 0 to 100. + + \sa {QtMultimedia::UserRating} +*/ + +/*! + \qmlproperty variant Video::keywords + + This property holds a list of keywords describing the media. + + \sa {QtMultimedia::Keywords} +*/ + +/*! + \qmlproperty variant Video::language + + This property holds the language of the media, as an ISO 639-2 code. + + \sa {QtMultimedia::Language} +*/ + +/*! + \qmlproperty variant Video::publisher + + This property holds the publisher of the media. + + \sa {QtMultimedia::Publisher} +*/ + +/*! + \qmlproperty variant Video::copyright + + This property holds the media's copyright notice. + + \sa {QtMultimedia::Copyright} +*/ + +/*! + \qmlproperty variant Video::parentalRating + + This property holds the parental rating of the media. + + \sa {QtMultimedia::ParentalRating} +*/ + +/*! + \qmlproperty variant Video::ratingOrganisation + + This property holds the name of the rating organisation responsible for the + parental rating of the media. + + \sa {QtMultimedia::RatingOrganisation} +*/ + +/*! + \qmlproperty variant Video::size + + This property property holds the size of the media in bytes. + + \sa {QtMultimedia::Size} +*/ + +/*! + \qmlproperty variant Video::mediaType + + This property holds the type of the media. + + \sa {QtMultimedia::MediaType} +*/ + +/*! + \qmlproperty variant Video::audioBitRate + + This property holds the bit rate of the media's audio stream ni bits per + second. + + \sa {QtMultimedia::AudioBitRate} +*/ + +/*! + \qmlproperty variant Video::audioCodec + + This property holds the encoding of the media audio stream. + + \sa {QtMultimedia::AudioCodec} +*/ + +/*! + \qmlproperty variant Video::averageLevel + + This property holds the average volume level of the media. + + \sa {QtMultimedia::AverageLevel} +*/ + +/*! + \qmlproperty variant Video::channelCount + + This property holds the number of channels in the media's audio stream. + + \sa {QtMultimedia::ChannelCount} +*/ + +/*! + \qmlproperty variant Video::peakValue + + This property holds the peak volume of media's audio stream. + + \sa {QtMultimedia::PeakValue} +*/ + +/*! + \qmlproperty variant Video::sampleRate + + This property holds the sample rate of the media's audio stream in hertz. + + \sa {QtMultimedia::SampleRate} +*/ + +/*! + \qmlproperty variant Video::albumTitle + + This property holds the title of the album the media belongs to. + + \sa {QtMultimedia::AlbumTitle} +*/ + +/*! + \qmlproperty variant Video::albumArtist + + This property holds the name of the principal artist of the album the media + belongs to. + + \sa {QtMultimedia::AlbumArtist} +*/ + +/*! + \qmlproperty variant Video::contributingArtist + + This property holds the names of artists contributing to the media. + + \sa {QtMultimedia::ContributingArtist} +*/ + +/*! + \qmlproperty variant Video::composer + + This property holds the composer of the media. + + \sa {QtMultimedia::Composer} +*/ + +/*! + \qmlproperty variant Video::conductor + + This property holds the conductor of the media. + + \sa {QtMultimedia::Conductor} +*/ + +/*! + \qmlproperty variant Video::lyrics + + This property holds the lyrics to the media. + + \sa {QtMultimedia::Lyrics} +*/ + +/*! + \qmlproperty variant Video::mood + + This property holds the mood of the media. + + \sa {QtMultimedia::Mood} +*/ + +/*! + \qmlproperty variant Video::trackNumber + + This property holds the track number of the media. + + \sa {QtMultimedia::TrackNumber} +*/ + +/*! + \qmlproperty variant Video::trackCount + + This property holds the number of track on the album containing the media. + + \sa {QtMultimedia::TrackNumber} +*/ + +/*! + \qmlproperty variant Video::coverArtUrlSmall + + This property holds the URL of a small cover art image. + + \sa {QtMultimedia::CoverArtUrlSmall} +*/ + +/*! + \qmlproperty variant Video::coverArtUrlLarge + + This property holds the URL of a large cover art image. + + \sa {QtMultimedia::CoverArtUrlLarge} +*/ + +/*! + \qmlproperty variant Video::resolution + + This property holds the dimension of an image or video. + + \sa {QtMultimedia::Resolution} +*/ + +/*! + \qmlproperty variant Video::pixelAspectRatio + + This property holds the pixel aspect ratio of an image or video. + + \sa {QtMultimedia::PixelAspectRatio} +*/ + +/*! + \qmlproperty variant Video::videoFrameRate + + This property holds the frame rate of the media's video stream. + + \sa {QtMultimedia::VideoFrameRate} +*/ + +/*! + \qmlproperty variant Video::videoBitRate + + This property holds the bit rate of the media's video stream in bits per + second. + + \sa {QtMultimedia::VideoBitRate} +*/ + +/*! + \qmlproperty variant Video::videoCodec + + This property holds the encoding of the media's video stream. + + \sa {QtMultimedia::VideoCodec} +*/ + +/*! + \qmlproperty variant Video::posterUrl + + This property holds the URL of a poster image. + + \sa {QtMultimedia::PosterUrl} +*/ + +/*! + \qmlproperty variant Video::chapterNumber + + This property holds the chapter number of the media. + + \sa {QtMultimedia::ChapterNumber} +*/ + +/*! + \qmlproperty variant Video::director + + This property holds the director of the media. + + \sa {QtMultimedia::Director} +*/ + +/*! + \qmlproperty variant Video::leadPerformer + + This property holds the lead performer in the media. + + \sa {QtMultimedia::LeadPerformer} +*/ + +/*! + \qmlproperty variant Video::writer + + This property holds the writer of the media. + + \sa {QtMultimedia::Writer} +*/ + +// The remaining properties are related to photos, and are technically +// available but will certainly never have values. +#ifndef Q_QDOC + +/*! + \qmlproperty variant Video::cameraManufacturer + + \sa {QtMultimedia::CameraManufacturer} +*/ + +/*! + \qmlproperty variant Video::cameraModel + + \sa {QtMultimedia::CameraModel} +*/ + +/*! + \qmlproperty variant Video::event + + \sa {QtMultimedia::Event} +*/ + +/*! + \qmlproperty variant Video::subject + + \sa {QtMultimedia::Subject} +*/ + +/*! + \qmlproperty variant Video::orientation + + \sa {QtMultimedia::Orientation} +*/ + +/*! + \qmlproperty variant Video::exposureTime + + \sa {QtMultimedia::ExposureTime} +*/ + +/*! + \qmlproperty variant Video::fNumber + + \sa {QtMultimedia::FNumber} +*/ + +/*! + \qmlproperty variant Video::exposureProgram + + \sa {QtMultimedia::ExposureProgram} +*/ + +/*! + \qmlproperty variant Video::isoSpeedRatings + + \sa {QtMultimedia::ISOSpeedRatings} +*/ + +/*! + \qmlproperty variant Video::exposureBiasValue + + \sa {QtMultimedia::ExposureBiasValue} +*/ + +/*! + \qmlproperty variant Video::dateTimeDigitized + + \sa {QtMultimedia::DateTimeDigitized} +*/ + +/*! + \qmlproperty variant Video::subjectDistance + + \sa {QtMultimedia::SubjectDistance} +*/ + +/*! + \qmlproperty variant Video::meteringMode + + \sa {QtMultimedia::MeteringMode} +*/ + +/*! + \qmlproperty variant Video::lightSource + + \sa {QtMultimedia::LightSource} +*/ + +/*! + \qmlproperty variant Video::flash + + \sa {QtMultimedia::Flash} +*/ + +/*! + \qmlproperty variant Video::focalLength + + \sa {QtMultimedia::FocalLength} +*/ + +/*! + \qmlproperty variant Video::exposureMode + + \sa {QtMultimedia::ExposureMode} +*/ + +/*! + \qmlproperty variant Video::whiteBalance + + \sa {QtMultimedia::WhiteBalance} +*/ + +/*! + \qmlproperty variant Video::DigitalZoomRatio + + \sa {QtMultimedia::DigitalZoomRatio} +*/ + +/*! + \qmlproperty variant Video::focalLengthIn35mmFilm + + \sa {QtMultimedia::FocalLengthIn35mmFile} +*/ + +/*! + \qmlproperty variant Video::sceneCaptureType + + \sa {QtMultimedia::SceneCaptureType} +*/ + +/*! + \qmlproperty variant Video::gainControl + + \sa {QtMultimedia::GainControl} +*/ + +/*! + \qmlproperty variant Video::contrast + + \sa {QtMultimedia::contrast} +*/ + +/*! + \qmlproperty variant Video::saturation + + \sa {QtMultimedia::Saturation} +*/ + +/*! + \qmlproperty variant Video::sharpness + + \sa {QtMultimedia::Sharpness} +*/ + +/*! + \qmlproperty variant Video::deviceSettingDescription + + \sa {QtMultimedia::DeviceSettingDescription} +*/ + +#endif + +#include "moc_qmlgraphicsvideo_p.cpp" diff --git a/src/multimedia/qml/qmlgraphicsvideo_p.h b/src/multimedia/qml/qmlgraphicsvideo_p.h new file mode 100644 index 0000000..bd15b7f --- /dev/null +++ b/src/multimedia/qml/qmlgraphicsvideo_p.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLGRAPHICSVIDEO_H +#define QMLGRAPHICSVIDEO_H + +#include <QtMultimedia/private/qmlmediabase_p.h> + +#include <QtMultimedia/qgraphicsvideoitem.h> + +#include <QtCore/qbasictimer.h> +#include <QtDeclarative/qmlgraphicsitem.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QTimerEvent; +class QVideoSurfaceFormat; + + +class Q_MULTIMEDIA_EXPORT QmlGraphicsVideo : public QmlGraphicsItem, public QmlMediaBase +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(bool playing READ isPlaying WRITE setPlaying NOTIFY playingChanged) + Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(int duration READ duration NOTIFY durationChanged) + Q_PROPERTY(int position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) + Q_PROPERTY(bool hasAudio READ hasAudio NOTIFY hasAudioChanged) + Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged) + Q_PROPERTY(int bufferProgress READ bufferProgress NOTIFY bufferProgressChanged) + Q_PROPERTY(bool seekable READ isSeekable NOTIFY seekableChanged) + Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged) + Q_PROPERTY(Error error READ error NOTIFY errorChanged) + Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged) + Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode) + Q_ENUMS(FillMode) + Q_ENUMS(Status) + Q_ENUMS(Error) +public: + enum FillMode + { + Stretch = Qt::IgnoreAspectRatio, + PreserveAspectFit = Qt::KeepAspectRatio, + PreserveAspectCrop = Qt::KeepAspectRatioByExpanding + }; + + enum Status + { + UnknownStatus = QMediaPlayer::UnknownMediaStatus, + NoMedia = QMediaPlayer::NoMedia, + Loading = QMediaPlayer::LoadingMedia, + Loaded = QMediaPlayer::LoadedMedia, + Stalled = QMediaPlayer::StalledMedia, + Buffering = QMediaPlayer::BufferingMedia, + Buffered = QMediaPlayer::BufferedMedia, + EndOfMedia = QMediaPlayer::EndOfMedia, + InvalidMedia = QMediaPlayer::InvalidMedia + }; + + enum Error + { + NoError = QMediaPlayer::NoError, + ResourceError = QMediaPlayer::ResourceError, + FormatError = QMediaPlayer::FormatError, + NetworkError = QMediaPlayer::NetworkError, + AccessDenied = QMediaPlayer::AccessDeniedError, + ServiceMissing = QMediaPlayer::ServiceMissingError + }; + + QmlGraphicsVideo(QmlGraphicsItem *parent = 0); + ~QmlGraphicsVideo(); + + bool hasAudio() const; + bool hasVideo() const; + + FillMode fillMode() const; + void setFillMode(FillMode mode); + + Status status() const; + Error error() const; + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); + +public Q_SLOTS: + void play(); + void pause(); + void stop(); + +Q_SIGNALS: + void sourceChanged(); + + void playingChanged(); + void pausedChanged(); + + void started(); + void resumed(); + void paused(); + void stopped(); + + void statusChanged(); + + void loaded(); + void buffering(); + void stalled(); + void buffered(); + void endOfMedia(); + + void durationChanged(); + void positionChanged(); + + void volumeChanged(); + void mutedChanged(); + void hasAudioChanged(); + void hasVideoChanged(); + + void bufferProgressChanged(); + + void seekableChanged(); + void playbackRateChanged(); + + void errorChanged(); + void error(QmlGraphicsVideo::Error error, const QString &errorString); + +protected: + void geometryChanged(const QRectF &geometry, const QRectF &); + +private Q_SLOTS: + void _q_nativeSizeChanged(const QSizeF &size); + void _q_error(int, const QString &); + +private: + Q_DISABLE_COPY(QmlGraphicsVideo) + + QGraphicsVideoItem *m_graphicsItem; + + Q_PRIVATE_SLOT(mediaBase(), void _q_stateChanged(QMediaPlayer::State)) + Q_PRIVATE_SLOT(mediaBase(), void _q_mediaStatusChanged(QMediaPlayer::MediaStatus)) + Q_PRIVATE_SLOT(mediaBase(), void _q_metaDataChanged()) + + inline QmlMediaBase *mediaBase() { return this; } +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QmlGraphicsVideo)) + +QT_END_HEADER + +#endif diff --git a/src/multimedia/qml/qmlmediabase.cpp b/src/multimedia/qml/qmlmediabase.cpp new file mode 100644 index 0000000..11b4337 --- /dev/null +++ b/src/multimedia/qml/qmlmediabase.cpp @@ -0,0 +1,413 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "QtMultimedia/private/qmlmediabase_p.h" + +#include <QtCore/qcoreevent.h> +#include <QtCore/qurl.h> + +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediaserviceprovider.h> +#include <QtMultimedia/qmetadatacontrol.h> +#include <QtMultimedia/private/qmetadatacontrolmetaobject_p.h> + + + +QT_BEGIN_NAMESPACE + + +class QmlMediaBaseObject : public QMediaObject +{ +public: + QmlMediaBaseObject(QMediaService *service) + : QMediaObject(0, service) + { + } +}; + +class QmlMediaBasePlayerControl : public QMediaPlayerControl +{ +public: + QmlMediaBasePlayerControl(QObject *parent) + : QMediaPlayerControl(parent) + { + } + + QMediaPlayer::State state() const { return QMediaPlayer::StoppedState; } + QMediaPlayer::MediaStatus mediaStatus() const { return QMediaPlayer::NoMedia; } + + qint64 duration() const { return 0; } + qint64 position() const { return 0; } + void setPosition(qint64) {} + int volume() const { return 0; } + void setVolume(int) {} + bool isMuted() const { return false; } + void setMuted(bool) {} + int bufferStatus() const { return 0; } + bool isAudioAvailable() const { return false; } + bool isVideoAvailable() const { return false; } + bool isSeekable() const { return false; } + QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(); } + qreal playbackRate() const { return 1; } + void setPlaybackRate(qreal) {} + QMediaContent media() const { return QMediaContent(); } + const QIODevice *mediaStream() const { return 0; } + void setMedia(const QMediaContent &, QIODevice *) {} + + void play() {} + void pause() {} + void stop() {} +}; + +class QmlMediaBaseAnimation : public QObject +{ +public: + QmlMediaBaseAnimation(QmlMediaBase *media) + : m_media(media) + { + } + + void start() { if (!m_timer.isActive()) m_timer.start(500, this); } + void stop() { m_timer.stop(); } + +protected: + void timerEvent(QTimerEvent *event) + { + if (event->timerId() == m_timer.timerId()) { + event->accept(); + + if (m_media->m_state == QMediaPlayer::PlayingState) + emit m_media->positionChanged(); + if (m_media->m_status == QMediaPlayer::BufferingMedia || QMediaPlayer::StalledMedia) + emit m_media->bufferProgressChanged(); + } else { + QObject::timerEvent(event); + } + } + +private: + QmlMediaBase *m_media; + QBasicTimer m_timer; +}; + +void QmlMediaBase::_q_stateChanged(QMediaPlayer::State state) +{ + if (state != m_state) { + QMediaPlayer::State oldState = m_state; + + m_state = state; + + if (state == QMediaPlayer::StoppedState) { + emit stopped(); + emit playingChanged(); + } else if (oldState == QMediaPlayer::StoppedState) { + emit started(); + emit playingChanged(); + } else if (oldState == QMediaPlayer::PausedState) { + m_paused = false; + + emit resumed(); + emit pausedChanged(); + } + + if (state == m_state && state == QMediaPlayer::PausedState) { + bool wasPaused = m_paused; + + m_paused = true; + + emit paused(); + + if (!wasPaused) + emit pausedChanged(); + } + + if (m_state == QMediaPlayer::PlayingState + || m_status == QMediaPlayer::BufferingMedia + || m_status == QMediaPlayer::StalledMedia) { + m_animation->start(); + } else { + m_animation->stop(); + } + } +} + +void QmlMediaBase::_q_mediaStatusChanged(QMediaPlayer::MediaStatus status) +{ + if (status != m_status) { + m_status = status; + + switch (status) { + case QMediaPlayer::LoadedMedia: + emit loaded(); + break; + case QMediaPlayer::BufferingMedia: + emit buffering(); + break; + case QMediaPlayer::BufferedMedia: + emit buffered(); + break; + case QMediaPlayer::StalledMedia: + emit stalled(); + break; + case QMediaPlayer::EndOfMedia: + emit endOfMedia(); + break; + default: + break; + } + + emit statusChanged(); + + if (m_state == QMediaPlayer::PlayingState + || m_status == QMediaPlayer::BufferingMedia + || m_status == QMediaPlayer::StalledMedia) { + m_animation->start(); + } else { + m_animation->stop(); + } + } +} + +void QmlMediaBase::_q_metaDataChanged() +{ + m_metaObject->metaDataChanged(); +} + +QmlMediaBase::QmlMediaBase() + : m_mediaService(0) + , m_playerControl(0) + , m_mediaObject(0) + , m_mediaProvider(0) + , m_metaDataControl(0) + , m_metaObject(0) + , m_animation(0) + , m_state(QMediaPlayer::StoppedState) + , m_status(QMediaPlayer::NoMedia) + , m_error(QMediaPlayer::NoError) + , m_paused(false) +{ +} + +QmlMediaBase::~QmlMediaBase() +{ +} + +void QmlMediaBase::shutdown() +{ + delete m_metaObject; + delete m_mediaObject; + + if (m_mediaProvider) + m_mediaProvider->releaseService(m_mediaService); + + delete m_animation; + +} + +void QmlMediaBase::setObject(QObject *object) +{ + if ((m_mediaProvider = QMediaServiceProvider::defaultServiceProvider())) { + if ((m_mediaService = m_mediaProvider->requestService(Q_MEDIASERVICE_MEDIAPLAYER))) { + m_playerControl = qobject_cast<QMediaPlayerControl *>( + m_mediaService->control(QMediaPlayerControl_iid)); + m_metaDataControl = qobject_cast<QMetaDataControl *>( + m_mediaService->control(QMetaDataControl_iid)); + m_mediaObject = new QmlMediaBaseObject(m_mediaService); + } + } + + if (m_playerControl) { + QObject::connect(m_playerControl, SIGNAL(stateChanged(QMediaPlayer::State)), + object, SLOT(_q_stateChanged(QMediaPlayer::State))); + QObject::connect(m_playerControl, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + object, SLOT(_q_mediaStatusChanged(QMediaPlayer::MediaStatus))); + QObject::connect(m_playerControl, SIGNAL(mediaChanged(QMediaContent)), + object, SIGNAL(sourceChanged())); + QObject::connect(m_playerControl, SIGNAL(durationChanged(qint64)), + object, SIGNAL(durationChanged())); + QObject::connect(m_playerControl, SIGNAL(positionChanged(qint64)), + object, SIGNAL(positionChanged())); + QObject::connect(m_playerControl, SIGNAL(volumeChanged(int)), + object, SIGNAL(volumeChanged())); + QObject::connect(m_playerControl, SIGNAL(mutedChanged(bool)), + object, SIGNAL(mutedChanged())); + QObject::connect(m_playerControl, SIGNAL(bufferStatusChanged(int)), + object, SIGNAL(bufferProgressChanged())); + QObject::connect(m_playerControl, SIGNAL(seekableChanged(bool)), + object, SIGNAL(seekableChanged())); + QObject::connect(m_playerControl, SIGNAL(playbackRateChanged(qreal)), + object, SIGNAL(playbackRateChanged())); + QObject::connect(m_playerControl, SIGNAL(error(int,QString)), + object, SLOT(_q_error(int,QString))); + + m_animation = new QmlMediaBaseAnimation(this); + } else { + m_error = QMediaPlayer::ServiceMissingError; + + m_playerControl = new QmlMediaBasePlayerControl(object); + } + + if (m_metaDataControl) { + m_metaObject = new QMetaDataControlMetaObject(m_metaDataControl, object); + + QObject::connect(m_metaDataControl, SIGNAL(metaDataChanged()), + object, SLOT(_q_metaDataChanged())); + } +} + +QUrl QmlMediaBase::source() const +{ + return m_playerControl->media().canonicalUrl(); +} + +void QmlMediaBase::setSource(const QUrl &url) +{ + if (m_error != QMediaPlayer::ServiceMissingError && m_error != QMediaPlayer::NoError) { + m_error = QMediaPlayer::NoError; + m_errorString = QString(); + + emit errorChanged(); + } + + m_playerControl->setMedia(QMediaContent(url), 0); +} + +bool QmlMediaBase::isPlaying() const +{ + return m_state != QMediaPlayer::StoppedState; +} + +void QmlMediaBase::setPlaying(bool playing) +{ + if (playing && m_state == QMediaPlayer::StoppedState) { + if (m_paused) + m_playerControl->pause(); + else + m_playerControl->play(); + } else if (!playing) { + m_playerControl->stop(); + } +} + +bool QmlMediaBase::isPaused() const +{ + return m_paused; +} + +void QmlMediaBase::setPaused(bool paused) +{ + if (m_paused != paused) { + if (paused && m_state == QMediaPlayer::PlayingState) { + m_playerControl->pause(); + } else if (!paused && m_state == QMediaPlayer::PausedState) { + m_playerControl->play(); + } else { + m_paused = paused; + + emit pausedChanged(); + } + } +} + +int QmlMediaBase::duration() const +{ + return m_playerControl->duration(); +} + +int QmlMediaBase::position() const +{ + return m_playerControl->position(); + +} + +void QmlMediaBase::setPosition(int position) +{ + m_playerControl->setPosition(position); +} + +qreal QmlMediaBase::volume() const +{ + return qreal(m_playerControl->volume()) / 100; +} + +void QmlMediaBase::setVolume(qreal volume) +{ + m_playerControl->setVolume(qRound(volume * 100)); +} + +bool QmlMediaBase::isMuted() const +{ + return m_playerControl->isMuted(); +} + +void QmlMediaBase::setMuted(bool muted) +{ + m_playerControl->setMuted(muted); +} + +qreal QmlMediaBase::bufferProgress() const +{ + return qreal(m_playerControl->bufferStatus()) / 100; +} + +bool QmlMediaBase::isSeekable() const +{ + return m_playerControl->isSeekable(); +} + +qreal QmlMediaBase::playbackRate() const +{ + return m_playerControl->playbackRate(); +} + +void QmlMediaBase::setPlaybackRate(qreal rate) +{ + m_playerControl->setPlaybackRate(rate); +} + +QString QmlMediaBase::errorString() const +{ + return m_errorString; +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/qml/qmlmediabase_p.h b/src/multimedia/qml/qmlmediabase_p.h new file mode 100644 index 0000000..948a0e8 --- /dev/null +++ b/src/multimedia/qml/qmlmediabase_p.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLMEDIABASE_P_H +#define QMLMEDIABASE_P_H + + +#include <QtCore/qbasictimer.h> +#include <QtMultimedia/qmediaplayer.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaPlayerControl; +class QMediaService; +class QMediaServiceProvider; +class QMetaDataControl; +class QMetaDataControlMetaObject; +class QmlMediaBaseAnimation; + +class Q_AUTOTEST_EXPORT QmlMediaBase +{ +public: + QmlMediaBase(); + virtual ~QmlMediaBase(); + + QUrl source() const; + void setSource(const QUrl &url); + + bool isPlaying() const; + void setPlaying(bool playing); + + bool isPaused() const; + void setPaused(bool paused); + + int duration() const; + + int position() const; + void setPosition(int position); + + qreal volume() const; + void setVolume(qreal volume); + + bool isMuted() const; + void setMuted(bool muted); + + qreal bufferProgress() const; + + bool isSeekable() const; + + qreal playbackRate() const; + void setPlaybackRate(qreal rate); + + QString errorString() const; + + void _q_stateChanged(QMediaPlayer::State state); + void _q_mediaStatusChanged(QMediaPlayer::MediaStatus status); + + void _q_metaDataChanged(); + +protected: + void shutdown(); + + void setObject(QObject *object); + + virtual void sourceChanged() = 0; + + virtual void playingChanged() = 0; + virtual void pausedChanged() = 0; + + virtual void started() = 0; + virtual void resumed() = 0; + virtual void paused() = 0; + virtual void stopped() = 0; + + virtual void statusChanged() = 0; + + virtual void loaded() = 0; + virtual void buffering() = 0; + virtual void stalled() = 0; + virtual void buffered() = 0; + virtual void endOfMedia() = 0; + + virtual void durationChanged() = 0; + virtual void positionChanged() = 0; + + virtual void volumeChanged() = 0; + virtual void mutedChanged() = 0; + + virtual void bufferProgressChanged() = 0; + + virtual void seekableChanged() = 0; + virtual void playbackRateChanged() = 0; + + virtual void errorChanged() = 0; + + QMediaService *m_mediaService; + QMediaPlayerControl *m_playerControl; + + QMediaObject *m_mediaObject; + QMediaServiceProvider *m_mediaProvider; + QMetaDataControl *m_metaDataControl; + QMetaDataControlMetaObject *m_metaObject; + QmlMediaBaseAnimation *m_animation; + + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_status; + QMediaPlayer::Error m_error; + bool m_paused; + QString m_errorString; + + friend class QmlMediaBaseAnimation; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/qml/qsoundeffect.cpp b/src/multimedia/qml/qsoundeffect.cpp new file mode 100644 index 0000000..1a67414 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmediacontent.h" +#include "qmediaplayer.h" + +#include "qsoundeffect_p.h" + +#if defined(QT_MULTIMEDIA_PULSEAUDIO) +#include "qsoundeffect_pulse_p.h" +#elif(QT_MULTIMEDIA_QMEDIAPLAYER) +#include "qsoundeffect_qmedia_p.h" +#else +#include "qsoundeffect_qsound_p.h" +#endif + + +/*! + \qmlclass QSoundEffect + \brief The SoundEffect element provides a way to play sound effects in qml. + + The following example plays a wav file on mouse click. + + \qml + SoundEffect { + id: playSound + source: "test.wav" + } + MouseRegion { + id: playArea + anchors.fill: parent + onPressed: { + playSound.play() + } + } + \endeml + + \sa SoundEffect +*/ + +/*! + \qmlproperty QUrl SoundEffect::source + + This property provides a way to control the sound to play. +*/ + +/*! + \qmlproperty int SoundEffect::loopCount + + This property provides a way to control the number of times to repeat the sound on each play(). +*/ + +/*! + \qmlproperty int SoundEffect::volume + + This property provides a way to control the volume for playback. +*/ + +/*! + \qmlproperty bool SoundEffect::muted + + This property provides a way to control muting. +*/ + +/*! + \qmlproperty int SoundEffect::duration + + This property holds the duration in milliseconds of the current source audio. +*/ + +/*! + \qmlsignal SoundEffect::sourceChanged() + + This handler is called when the source has changed. +*/ + +/*! + \qmlsignal SoundEffect::loopCountChanged() + + This handler is called when the number of loops has changes. +*/ + +/*! + \qmlsignal SoundEffect::volumeChanged() + + This handler is called when the volume has changed. +*/ + +/*! + \qmlsignal SoundEffect::mutedChanged() + + This handler is called when the mute state has changed. +*/ + +/*! + \qmlsignal SoundEffect::durationChanged() + + This handler is called when the duration has changed. +*/ + +QSoundEffect::QSoundEffect(QObject *parent) : + QObject(parent), + m_loopCount(1), + m_volume(100), + m_muted(false), + m_runningCount(0) +{ + d = new QSoundEffectPrivate(this); + connect(d, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged())); + connect(d, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged())); + connect(d, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged())); + connect(d, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(repeat())); +} + +QSoundEffect::~QSoundEffect() +{ + delete d; +} + +QUrl QSoundEffect::source() const +{ + return d != 0 ? d->media().canonicalUrl() : QUrl(); +} + +void QSoundEffect::setSource(const QUrl &url) +{ + if (d != 0 && d->media().canonicalUrl() == url) + return; + + d->setVolume(m_volume); + d->setMuted(m_muted); + d->setMedia(url); + + if (url.isEmpty()) + return; + + emit sourceChanged(); +} + +int QSoundEffect::loopCount() const +{ + return m_loopCount; +} + +void QSoundEffect::setLoopCount(int loopCount) +{ + if (m_loopCount == loopCount) + return; + + m_loopCount = loopCount; + emit loopCountChanged(); +} + +int QSoundEffect::volume() const +{ + return d != 0 ? d->volume() : m_volume; +} + +void QSoundEffect::setVolume(int volume) +{ + if (m_volume == volume) + return; + + m_volume = volume; + if (d != 0) + d->setVolume(volume); + else + emit volumeChanged(); +} + +bool QSoundEffect::isMuted() const +{ + return d != 0 ? d->isMuted() : m_muted; +} + +void QSoundEffect::setMuted(bool muted) +{ + if (m_muted == muted) + return; + + m_muted = muted; + if (d != 0) + d->setMuted(muted); + else + emit mutedChanged(); +} + +int QSoundEffect::duration() const +{ + return d != 0 ? d->duration() : 0; +} + +void QSoundEffect::play() +{ + m_runningCount = 0; + + if (d != 0) + d->play(); +} + +void QSoundEffect::stop() +{ + if (d != 0) + d->stop(); +} + +void QSoundEffect::repeat() +{ + if (d->state() == QMediaPlayer::StoppedState) { + if (++m_runningCount < m_loopCount) + d->play(); + } +} + diff --git a/src/multimedia/qml/qsoundeffect_p.h b/src/multimedia/qml/qsoundeffect_p.h new file mode 100644 index 0000000..2610a69 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_H +#define QSOUNDEFFECT_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> +#include <QtDeclarative/qml.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QSoundEffectPrivate; +class Q_MULTIMEDIA_EXPORT QSoundEffect : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount NOTIFY loopCountChanged) + Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) + Q_PROPERTY(int duration READ duration NOTIFY durationChanged) + +public: + explicit QSoundEffect(QObject *parent = 0); + ~QSoundEffect(); + + QUrl source() const; + void setSource(const QUrl &url); + + int loopCount() const; + void setLoopCount(int loopCount); + + int volume() const; + void setVolume(int volume); + + bool isMuted() const; + void setMuted(bool muted); + + int duration() const; + +signals: + void sourceChanged(); + void loopCountChanged(); + void volumeChanged(); + void mutedChanged(); + void durationChanged(); + +public slots: + void play(); + void stop(); + +private slots: + void repeat(); + +private: + Q_DISABLE_COPY(QSoundEffect) + + int m_loopCount; + int m_volume; + bool m_muted; + int m_runningCount; + + QSoundEffectPrivate* d; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QSoundEffect)) + +QT_END_HEADER + + +#endif // QSOUNDEFFECT_H diff --git a/src/multimedia/qml/qsoundeffect_pulse_p.cpp b/src/multimedia/qml/qsoundeffect_pulse_p.cpp new file mode 100644 index 0000000..b1e5982 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect_pulse_p.cpp @@ -0,0 +1,502 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qcoreapplication.h> +#include <QtMultimedia/qaudioformat.h> +#include <QtNetwork> +#include <QTime> + +#include "qmediacontent.h" +#include "qmediaplayer.h" +#include "qsoundeffect_p.h" + +#include "wavedecoder_p.h" + +#include "qsoundeffect_pulse_p.h" + +#if(Q_WS_MAEMO_5) +#include <pulse/ext-stream-restore.h> +#endif + +// Less than ideal +#define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*16) + +namespace +{ +inline pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format) +{ + pa_sample_spec spec; + + spec.rate = format.frequency(); + spec.channels = format.channels(); + + if (format.sampleSize() == 8) + spec.format = PA_SAMPLE_U8; + else if (format.sampleSize() == 16) { + switch (format.byteOrder()) { + case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S16BE; break; + case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S16LE; break; + } + } + else if (format.sampleSize() == 32) { + switch (format.byteOrder()) { + case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S32BE; break; + case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S32LE; break; + } + } + + return spec; +} + +class PulseDaemon +{ +public: + PulseDaemon():m_prepared(false) + { + prepare(); + } + + ~PulseDaemon() + { + if (m_prepared) + release(); + } + + inline void lock() + { + pa_threaded_mainloop_lock(m_mainLoop); + } + + inline void unlock() + { + pa_threaded_mainloop_unlock(m_mainLoop); + } + + inline pa_context *context() const + { + return m_context; + } + + int volume() + { + return m_volume; + } + +private: + void prepare() + { + m_volume = 100; + + m_mainLoop = pa_threaded_mainloop_new(); + if (m_mainLoop == 0) { + qWarning("PulseAudioService: unable to create pulseaudio mainloop"); + return; + } + + if (pa_threaded_mainloop_start(m_mainLoop) != 0) { + qWarning("PulseAudioService: unable to start pulseaudio mainloop"); + pa_threaded_mainloop_free(m_mainLoop); + return; + } + + m_mainLoopApi = pa_threaded_mainloop_get_api(m_mainLoop); + + lock(); + m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtPulseAudio:%1")).arg(::getpid()).toAscii().constData()); + +#if(Q_WS_MAEMO_5) + pa_context_set_state_callback(m_context, context_state_callback, this); +#endif + if (m_context == 0) { + qWarning("PulseAudioService: Unable to create new pulseaudio context"); + pa_threaded_mainloop_free(m_mainLoop); + return; + } + + if (pa_context_connect(m_context, NULL, (pa_context_flags_t)0, NULL) < 0) { + qWarning("PulseAudioService: pa_context_connect() failed"); + pa_context_unref(m_context); + pa_threaded_mainloop_free(m_mainLoop); + return; + } + unlock(); + + m_prepared = true; + } + + void release() + { + if (!m_prepared) return; + pa_threaded_mainloop_stop(m_mainLoop); + pa_threaded_mainloop_free(m_mainLoop); + m_prepared = false; + } + +#if(Q_WS_MAEMO_5) + static void context_state_callback(pa_context *c, void *userdata) + { + PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata); + switch (pa_context_get_state(c)) { + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + case PA_CONTEXT_READY: + pa_ext_stream_restore_set_subscribe_cb(c, &stream_restore_monitor_callback, self); + pa_ext_stream_restore_subscribe(c, 1, NULL, self); + break; + default: + break; + } + } + static void stream_restore_monitor_callback(pa_context *c, void *userdata) + { + PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata); + pa_ext_stream_restore2_read(c, &stream_restore_info_callback, self); + } + static void stream_restore_info_callback(pa_context *c, const pa_ext_stream_restore2_info *info, + int eol, void *userdata) + { + Q_UNUSED(c) + + PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata); + + if (!eol) { + if (QString(info->name).startsWith(QLatin1String("sink-input-by-media-role:x-maemo"))) { + const unsigned str_length = 256; + char str[str_length]; + pa_cvolume_snprint(str, str_length, &info->volume); + self->m_volume = QString(str).replace(" ","").replace("%","").mid(2).toInt(); + } + } + } +#endif + + int m_volume; + bool m_prepared; + pa_context *m_context; + pa_threaded_mainloop *m_mainLoop; + pa_mainloop_api *m_mainLoopApi; +}; +} + +Q_GLOBAL_STATIC(PulseDaemon, daemon) + + +QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): + QObject(parent), + m_muted(false), + m_playQueued(false), + m_volume(100), + m_duration(0), + m_dataUploaded(0), + m_state(QMediaPlayer::StoppedState), + m_status(QMediaPlayer::NoMedia), + m_reply(0), + m_stream(0), + m_networkAccessManager(0) +{ +} + +QSoundEffectPrivate::~QSoundEffectPrivate() +{ + delete m_reply; + unloadSample(); +} + +qint64 QSoundEffectPrivate::duration() const +{ + return m_duration; +} + +int QSoundEffectPrivate::volume() const +{ + return m_volume; +} + +bool QSoundEffectPrivate::isMuted() const +{ + return m_muted; +} + +QMediaContent QSoundEffectPrivate::media() const +{ + return m_media; +} + +QMediaPlayer::State QSoundEffectPrivate::state() const +{ + return m_state; +} + +QMediaPlayer::MediaStatus QSoundEffectPrivate::mediaStatus() const +{ + return m_status; +} + +void QSoundEffectPrivate::play() +{ + if (m_status == QMediaPlayer::LoadingMedia) { + m_playQueued = true; + return; + } + + if (m_status != QMediaPlayer::BufferedMedia || + m_state == QMediaPlayer::PlayingState) + return; + + pa_volume_t m_vol = PA_VOLUME_NORM; + + daemon()->lock(); +#if(Q_WS_MAEMO_5) + m_vol = PA_VOLUME_NORM/100*((daemon()->volume()+m_volume)/2); +#endif + pa_operation_unref( + pa_context_play_sample(daemon()->context(), + m_name.constData(), + 0, + m_vol, + play_callback, + this) + ); + daemon()->unlock(); + + m_playbackTime.start(); + + emit stateChanged(m_state = QMediaPlayer::PlayingState); +} + +void QSoundEffectPrivate::stop() +{ + emit stateChanged(m_state = QMediaPlayer::StoppedState); +} + +void QSoundEffectPrivate::setVolume(int volume) +{ + m_volume = volume; +} + +void QSoundEffectPrivate::setMuted(bool muted) +{ + m_muted = muted; +} + +void QSoundEffectPrivate::setMedia(const QMediaContent &media) +{ + if (media.isNull()) { + m_media = QMediaContent(); + unloadSample(); + return; + } + if (m_media == media) + return; + m_media = media; + + if (m_networkAccessManager == 0) + m_networkAccessManager = new QNetworkAccessManager(this); + + m_stream = m_networkAccessManager->get(QNetworkRequest(m_media.canonicalUrl())); + + unloadSample(); + loadSample(); + + emit mediaChanged(m_media); +} + +void QSoundEffectPrivate::decoderReady() +{ + if (m_waveDecoder->size() >= PA_SCACHE_ENTRY_SIZE_MAX) { + m_status = QMediaPlayer::InvalidMedia; + emit mediaStatusChanged(m_status); + qWarning("QtPulseAudio: attempting to load to large a sample"); + return; + } + + if (m_name.isNull()) + m_name = QString(QLatin1String("QtPulseSample-%1-%2")).arg(::getpid()).arg(int(this)).toUtf8(); + + pa_sample_spec spec = audioFormatToSampleSpec(m_waveDecoder->audioFormat()); + + daemon()->lock(); + pa_stream *stream = pa_stream_new(daemon()->context(), m_name.constData(), &spec, 0); + pa_stream_set_state_callback(stream, stream_state_callback, this); + pa_stream_set_write_callback(stream, stream_write_callback, this); + pa_stream_connect_upload(stream, (size_t)m_waveDecoder->size()); + daemon()->unlock(); +} + +void QSoundEffectPrivate::decoderError() +{ + emit mediaStatusChanged(m_status = QMediaPlayer::InvalidMedia); +} + +void QSoundEffectPrivate::checkPlayTime() +{ + int elapsed = m_playbackTime.elapsed(); + + if (elapsed >= m_duration) { + m_state = QMediaPlayer::StoppedState; + emit stateChanged(m_state); + } + else + startTimer(m_duration - elapsed); +} + +void QSoundEffectPrivate::loadSample() +{ + m_waveDecoder = new WaveDecoder(m_stream); + connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady())); + connect(m_waveDecoder, SIGNAL(invalidFormat()), SLOT(decoderError())); + + m_status = QMediaPlayer::LoadingMedia; + emit mediaStatusChanged(m_status); +} + +void QSoundEffectPrivate::unloadSample() +{ + if (m_status != QMediaPlayer::BufferedMedia) + return; + + m_status = QMediaPlayer::NoMedia; + + daemon()->lock(); + pa_context_remove_sample(daemon()->context(), m_name.constData(), NULL, NULL); + daemon()->unlock(); + + m_duration = 0; + m_dataUploaded = 0; +} + +void QSoundEffectPrivate::timerEvent(QTimerEvent *event) +{ + if (m_state == QMediaPlayer::PlayingState) { + m_state = QMediaPlayer::StoppedState; + emit stateChanged(m_state); + } + + killTimer(event->timerId()); +} + +void QSoundEffectPrivate::stream_write_callback(pa_stream *s, size_t length, void *userdata) +{ + Q_UNUSED(length); + + QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); + + size_t bufferSize = qMin(pa_stream_writable_size(s), + size_t(self->m_waveDecoder->bytesAvailable())); + char buffer[bufferSize]; + + size_t len = 0; + while (len < length) { + qint64 read = self->m_waveDecoder->read(buffer, qMin(bufferSize, length -len)); + if (read > 0) { + if (pa_stream_write(s, buffer, size_t(read), 0, 0, PA_SEEK_RELATIVE) == 0) + len += size_t(read); + else + break; + } + } + self->m_dataUploaded += len; + + if (self->m_waveDecoder->size() == self->m_dataUploaded) { + pa_stream_finish_upload(s); + + self->m_duration = self->m_waveDecoder->duration(); + emit self->durationChanged(self->m_duration); + + self->m_status = QMediaPlayer::BufferedMedia; + emit self->mediaStatusChanged(self->m_status); + + self->m_waveDecoder->deleteLater(); + if (!self->m_media.isNull()) + self->m_stream->deleteLater(); + + if (self->m_playQueued) { + self->m_playQueued = false; + QMetaObject::invokeMethod(self, "play"); + } + } +} + +void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata) +{ + QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); + + switch (pa_stream_get_state(s)) { + case PA_STREAM_CREATING: + case PA_STREAM_READY: + case PA_STREAM_TERMINATED: + break; + + case PA_STREAM_FAILED: + default: + self->m_status = QMediaPlayer::InvalidMedia; + emit self->mediaStatusChanged(self->m_status); + break; + } +} + +void QSoundEffectPrivate::play_callback(pa_context *c, int success, void *userdata) +{ + Q_UNUSED(c); + + QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); + + if (success == 1) + QMetaObject::invokeMethod(self, "checkPlayTime", Qt::QueuedConnection); + else { + self->m_state = QMediaPlayer::StoppedState; + emit self->stateChanged(self->m_state); + } +} + diff --git a/src/multimedia/qml/qsoundeffect_pulse_p.h b/src/multimedia/qml/qsoundeffect_pulse_p.h new file mode 100644 index 0000000..58a05d2 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect_pulse_p.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_PULSE_H +#define QSOUNDEFFECT_PULSE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include "qsoundeffect_p.h" + +#include <QtCore/qobject.h> +#include <QtCore/qdatetime.h> +#include <QtMultimedia/qmediaplayer.h> +#include <pulse/pulseaudio.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QNetworkReply; +class QNetworkAccessManager; +class WaveDecoder; + +class QSoundEffectPrivate : public QObject +{ + Q_OBJECT +public: + explicit QSoundEffectPrivate(QObject* parent); + ~QSoundEffectPrivate(); + + qint64 duration() const; + int volume() const; + bool isMuted() const; + QMediaContent media() const; + QMediaPlayer::State state() const; + QMediaPlayer::MediaStatus mediaStatus() const; + +public Q_SLOTS: + void play(); + void stop(); + void setVolume(int volume); + void setMuted(bool muted); + void setMedia(const QMediaContent &media); + +Q_SIGNALS: + void mediaChanged(const QMediaContent &media); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void stateChanged(QMediaPlayer::State newState); + void durationChanged(qint64 duration); + void volumeChanged(int volume); + void mutedChanged(bool muted); + void error(QMediaPlayer::Error error); + +private slots: + void decoderReady(); + void decoderError(); + void checkPlayTime(); + +private: + void loadSample(); + void unloadSample(); + + void timerEvent(QTimerEvent *event); + + static void stream_write_callback(pa_stream *s, size_t length, void *userdata); + static void stream_state_callback(pa_stream *s, void *userdata); + static void play_callback(pa_context *c, int success, void *userdata); + + bool m_muted; + bool m_playQueued; + int m_volume; + int m_duration; + int m_dataUploaded; + QTime m_playbackTime; + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_status; + QByteArray m_name; + QMediaContent m_media; + QNetworkReply *m_reply; + WaveDecoder *m_waveDecoder; + QIODevice *m_stream; + QNetworkAccessManager *m_networkAccessManager; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSOUNDEFFECT_PULSE_H diff --git a/src/multimedia/qml/qsoundeffect_qmedia_p.cpp b/src/multimedia/qml/qsoundeffect_qmedia_p.cpp new file mode 100644 index 0000000..e5ac0d3 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect_qmedia_p.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qcoreapplication.h> + +#include "qmediacontent.h" +#include "qmediaplayer.h" + +#include "qsoundeffect_p.h" +#include "qsoundeffect_qmedia_p.h" + + +QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): + QObject(parent), + m_muted(false), + m_volume(100), + m_player(0) +{ +} + +QSoundEffectPrivate::~QSoundEffectPrivate() +{ + if (m_player) delete m_player; +} + +qint64 QSoundEffectPrivate::duration() const +{ + if (m_player) return m_player->duration(); + + return 0; +} + +int QSoundEffectPrivate::volume() const +{ + if (m_player) return m_player->volume(); + + return m_volume; +} + +bool QSoundEffectPrivate::isMuted() const +{ + if (m_player) return m_player->isMuted(); + + return m_muted; +} + +QMediaContent QSoundEffectPrivate::media() const +{ + if (m_player) return m_player->media(); + + return QMediaContent(); +} + +QMediaPlayer::State QSoundEffectPrivate::state() const +{ + if (m_player) return m_player->state(); + + return QMediaPlayer::StoppedState; +} + +QMediaPlayer::MediaStatus QSoundEffectPrivate::mediaStatus() const +{ + if (m_player) return m_player->mediaStatus(); + + return QMediaPlayer::UnknownMediaStatus; +} + +void QSoundEffectPrivate::play() +{ + if (m_player && !m_player->isMuted()) + m_player->play(); +} + +void QSoundEffectPrivate::stop() +{ + if (m_player) + m_player->stop(); +} + +void QSoundEffectPrivate::setVolume(int volume) +{ + m_volume = volume; + + if (m_player) + m_player->setVolume(volume); +} + +void QSoundEffectPrivate::setMuted(bool muted) +{ + m_muted = muted; + + if (m_player) + m_player->setMuted(muted); +} + +void QSoundEffectPrivate::setMedia(const QMediaContent &media) +{ + if (media.isNull()) + return; + + if (m_player == 0) { + m_player = new QMediaPlayer(this, QMediaPlayer::LowLatency); + m_player->setVolume(m_volume); + m_player->setMuted(m_muted); + + connect(m_player, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int))); + connect(m_player, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool))); + connect(m_player, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64))); + connect(m_player, SIGNAL(stateChanged(QMediaPlayer::State)), SIGNAL(stateChanged(QMediaPlayer::State))); + } + + m_player->setMedia(media.canonicalUrl()); +} + diff --git a/src/multimedia/qml/qsoundeffect_qmedia_p.h b/src/multimedia/qml/qsoundeffect_qmedia_p.h new file mode 100644 index 0000000..e17d720 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect_qmedia_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_QMEDIA_H +#define QSOUNDEFFECT_QMEDIA_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> +#include <QtMultimedia/qmediaplayer.h> +#include "qsoundeffect_p.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class WaveDecoder; + +class QSoundEffectPrivate : public QObject +{ + Q_OBJECT +public: + explicit QSoundEffectPrivate(QObject* parent); + ~QSoundEffectPrivate(); + + qint64 duration() const; + int volume() const; + bool isMuted() const; + QMediaContent media() const; + QMediaPlayer::State state() const; + QMediaPlayer::MediaStatus mediaStatus() const; + +public Q_SLOTS: + void play(); + void stop(); + void setVolume(int volume); + void setMuted(bool muted); + void setMedia(const QMediaContent &media); + +Q_SIGNALS: + void mediaChanged(const QMediaContent &media); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void stateChanged(QMediaPlayer::State newState); + void durationChanged(qint64 duration); + void volumeChanged(int volume); + void mutedChanged(bool muted); + void error(QMediaPlayer::Error error); + +private: + bool m_muted; + int m_volume; + QMediaPlayer *m_player; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSOUNDEFFECT_QMEDIA_H diff --git a/src/multimedia/qml/qsoundeffect_qsound_p.cpp b/src/multimedia/qml/qsoundeffect_qsound_p.cpp new file mode 100644 index 0000000..33f5bd4 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect_qsound_p.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qtimer.h> +#include <QtCore/qfile.h> +#include <QtGui/qsound.h> +#include <QtMultimedia/qaudioformat.h> +#include <QDebug> + +#include "qmediacontent.h" +#include "qmediaplayer.h" +#include "qsoundeffect_p.h" + +#include "wavedecoder_p.h" + +#include "qsoundeffect_qsound_p.h" + + +QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): + QObject(parent), + m_queued(false), + m_muted(false), + m_state(QMediaPlayer::StoppedState), + m_status(QMediaPlayer::NoMedia), + m_file(0), + m_sound(0) +{ + m_timer = new QTimer(this); + connect(m_timer,SIGNAL(timeout()),SLOT(checkPlayTime())); + m_media = QMediaContent(); +} + +QSoundEffectPrivate::~QSoundEffectPrivate() +{ + if (m_sound) delete m_sound; + if (m_waveDecoder) delete m_waveDecoder; + m_file->close(); +} + +qint64 QSoundEffectPrivate::duration() const +{ + if (m_waveDecoder) + return m_waveDecoder->size(); + + return 0; +} + +int QSoundEffectPrivate::volume() const +{ + return 100; +} + +bool QSoundEffectPrivate::isMuted() const +{ + return m_muted; +} + +QMediaContent QSoundEffectPrivate::media() const +{ + return m_media; +} + +QMediaPlayer::State QSoundEffectPrivate::state() const +{ + return m_state; +} + +QMediaPlayer::MediaStatus QSoundEffectPrivate::mediaStatus() const +{ + return m_status; +} + +void QSoundEffectPrivate::play() +{ + if (m_sound && !m_muted) { + m_queued = false; + m_timer->start(20); + m_playbackTime.start(); + m_sound->play(); + emit stateChanged(m_state = QMediaPlayer::PlayingState); + } else if (m_status == QMediaPlayer::LoadingMedia) + m_queued = true; +} + +void QSoundEffectPrivate::stop() +{ + m_timer->stop(); + + if (m_sound) { + m_sound->stop(); + emit stateChanged(m_state = QMediaPlayer::StoppedState); + } +} + +void QSoundEffectPrivate::setVolume(int volume) +{ + Q_UNUSED(volume) +} + +void QSoundEffectPrivate::setMuted(bool muted) +{ + m_muted = muted; +} + +void QSoundEffectPrivate::setMedia(const QMediaContent &media) +{ + m_queued = false; + + if (media.isNull() || media.canonicalUrl().scheme() != "file") { + m_media = QMediaContent(); + return; + } + if (m_media == media) + return; + + m_media = media; + m_file = new QFile(m_media.canonicalUrl().toLocalFile()); + m_file->open(QIODevice::ReadOnly|QIODevice::Unbuffered); + + unloadSample(); + loadSample(); + + emit mediaChanged(m_media); +} + +void QSoundEffectPrivate::decoderReady() +{ + m_file->close(); + m_sound = new QSound(m_media.canonicalUrl().toLocalFile()); + emit mediaStatusChanged(m_status = QMediaPlayer::LoadedMedia); + + if (m_queued) + play(); +} + +void QSoundEffectPrivate::decoderError() +{ + m_file->close(); + emit mediaStatusChanged(m_status = QMediaPlayer::InvalidMedia); +} + +void QSoundEffectPrivate::checkPlayTime() +{ + if (m_sound->isFinished()) { + m_timer->stop(); + m_state = QMediaPlayer::StoppedState; + emit stateChanged(m_state); + } +} + +void QSoundEffectPrivate::loadSample() +{ + m_waveDecoder = new WaveDecoder(m_file); + connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady())); + connect(m_waveDecoder, SIGNAL(invalidFormat()), SLOT(decoderError())); + + m_status = QMediaPlayer::LoadingMedia; + emit mediaStatusChanged(m_status); +} + +void QSoundEffectPrivate::unloadSample() +{ + if (m_sound == 0) + return; + + m_status = QMediaPlayer::NoMedia; + + if (m_sound) + delete m_sound; + + m_sound = 0; +} + diff --git a/src/multimedia/qml/qsoundeffect_qsound_p.h b/src/multimedia/qml/qsoundeffect_qsound_p.h new file mode 100644 index 0000000..45c0888 --- /dev/null +++ b/src/multimedia/qml/qsoundeffect_qsound_p.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_QSOUND_H +#define QSOUNDEFFECT_QSOUND_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <QtCore/qobject.h> +#include <QtCore/qdatetime.h> +#include <QtMultimedia/qmediaplayer.h> + +#include "qsoundeffect_p.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QTimer; +class QSound; +class QFile; +class WaveDecoder; + +class QSoundEffectPrivate : public QObject +{ + Q_OBJECT +public: + explicit QSoundEffectPrivate(QObject* parent); + ~QSoundEffectPrivate(); + + qint64 duration() const; + int volume() const; + bool isMuted() const; + QMediaContent media() const; + QMediaPlayer::State state() const; + QMediaPlayer::MediaStatus mediaStatus() const; + +public Q_SLOTS: + void play(); + void stop(); + void setVolume(int volume); + void setMuted(bool muted); + void setMedia(const QMediaContent &media); + +Q_SIGNALS: + void mediaChanged(const QMediaContent &media); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void stateChanged(QMediaPlayer::State newState); + void durationChanged(qint64 duration); + void volumeChanged(int volume); + void mutedChanged(bool muted); + void error(QMediaPlayer::Error error); + +private slots: + void decoderReady(); + void decoderError(); + void checkPlayTime(); + +private: + void loadSample(); + void unloadSample(); + + bool m_queued; + bool m_muted; + QTime m_playbackTime; + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_status; + QFile *m_file; + QByteArray m_name; + QMediaContent m_media; + WaveDecoder *m_waveDecoder; + QSound *m_sound; + QTimer *m_timer; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSOUNDEFFECT_QSOUND_H diff --git a/src/multimedia/qml/wavedecoder_p.cpp b/src/multimedia/qml/wavedecoder_p.cpp new file mode 100644 index 0000000..5fc5a96 --- /dev/null +++ b/src/multimedia/qml/wavedecoder_p.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "wavedecoder_p.h" + +#include <QtCore/qtimer.h> +#include <QtCore/qendian.h> + +WaveDecoder::WaveDecoder(QIODevice *s, QObject *parent): + QIODevice(parent), + haveFormat(false), + dataSize(0), + remaining(0), + source(s) +{ + open(QIODevice::ReadOnly | QIODevice::Unbuffered); + + if (source->bytesAvailable() >= sizeof(CombinedHeader)) + QTimer::singleShot(0, this, SLOT(handleData())); + else + connect(source, SIGNAL(readyRead()), SLOT(handleData())); +} + +WaveDecoder::~WaveDecoder() +{ +} + +QAudioFormat WaveDecoder::audioFormat() const +{ + return format; +} + +int WaveDecoder::duration() const +{ + return size() * 1000 / (format.sampleSize() / 8) / format.channels() / format.frequency(); +} + +qint64 WaveDecoder::size() const +{ + return haveFormat ? dataSize : 0; +} + +bool WaveDecoder::isSequential() const +{ + return source->isSequential(); +} + +qint64 WaveDecoder::bytesAvailable() const +{ + return haveFormat ? source->bytesAvailable() : 0; +} + +qint64 WaveDecoder::readData(char *data, qint64 maxlen) +{ + return haveFormat ? source->read(data, maxlen) : 0; +} + +qint64 WaveDecoder::writeData(const char *data, qint64 len) +{ + Q_UNUSED(data); + Q_UNUSED(len); + + return -1; +} + +void WaveDecoder::handleData() +{ + if (source->bytesAvailable() < sizeof(CombinedHeader)) + return; + + source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData())); + source->read((char*)&header, sizeof(CombinedHeader)); + + if (qstrncmp(header.riff.descriptor.id, "RIFF", 4) != 0 || + qstrncmp(header.riff.type, "WAVE", 4) != 0 || + qstrncmp(header.wave.descriptor.id, "fmt ", 4) != 0 || + (header.wave.audioFormat != 0 && header.wave.audioFormat != 1) || + qstrncmp(header.data.descriptor.id, "data", 4) != 0) { + + emit invalidFormat(); + } + else { + int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample); + + format.setCodec("audio/pcm"); + format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setFrequency(qFromLittleEndian<quint32>(header.wave.sampleRate)); + format.setSampleSize(bps); + format.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels)); + + dataSize = qFromLittleEndian<quint32>(header.data.descriptor.size); + + haveFormat = true; + connect(source, SIGNAL(readyRead()), SIGNAL(readyRead())); + emit formatKnown(); + } +} diff --git a/src/multimedia/qml/wavedecoder_p.h b/src/multimedia/qml/wavedecoder_p.h new file mode 100644 index 0000000..3bcd90d --- /dev/null +++ b/src/multimedia/qml/wavedecoder_p.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WAVEDECODER_H +#define WAVEDECODER_H + +#include <QtCore/qiodevice.h> +#include <QtMultimedia/qaudioformat.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class WaveDecoder : public QIODevice +{ + Q_OBJECT + +public: + explicit WaveDecoder(QIODevice *source, QObject *parent = 0); + ~WaveDecoder(); + + QAudioFormat audioFormat() const; + int duration() const; + + qint64 size() const; + bool isSequential() const; + qint64 bytesAvailable() const; + +signals: + void formatKnown(); + void invalidFormat(); + +private slots: + void handleData(); + +private: + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + + struct chunk + { + char id[4]; + quint32 size; + }; + struct RIFFHeader + { + chunk descriptor; + char type[4]; + }; + struct WAVEHeader + { + chunk descriptor; + quint16 audioFormat; + quint16 numChannels; + quint32 sampleRate; + quint32 byteRate; + quint16 blockAlign; + quint16 bitsPerSample; + }; + struct DATAHeader + { + chunk descriptor; + }; + struct CombinedHeader + { + RIFFHeader riff; + WAVEHeader wave; + DATAHeader data; + }; + + bool haveFormat; + qint64 dataSize; + qint64 remaining; + QAudioFormat format; + QIODevice *source; + CombinedHeader header; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // WAVEDECODER_H diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp index 8cdfe6a..9eb2399 100644 --- a/src/network/access/qhttpnetworkrequest.cpp +++ b/src/network/access/qhttpnetworkrequest.cpp @@ -61,6 +61,7 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest uploadByteDevice = other.uploadByteDevice; autoDecompress = other.autoDecompress; pipeliningAllowed = other.pipeliningAllowed; + customVerb = other.customVerb; } QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate() @@ -76,36 +77,38 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot QByteArray QHttpNetworkRequestPrivate::methodName() const { - QByteArray ba; switch (operation) { - case QHttpNetworkRequest::Options: - ba += "OPTIONS"; - break; case QHttpNetworkRequest::Get: - ba += "GET"; + return "GET"; break; case QHttpNetworkRequest::Head: - ba += "HEAD"; + return "HEAD"; break; case QHttpNetworkRequest::Post: - ba += "POST"; + return "POST"; + break; + case QHttpNetworkRequest::Options: + return "OPTIONS"; break; case QHttpNetworkRequest::Put: - ba += "PUT"; + return "PUT"; break; case QHttpNetworkRequest::Delete: - ba += "DELETE"; + return "DELETE"; break; case QHttpNetworkRequest::Trace: - ba += "TRACE"; + return "TRACE"; break; case QHttpNetworkRequest::Connect: - ba += "CONNECT"; + return "CONNECT"; + break; + case QHttpNetworkRequest::Custom: + return customVerb; break; default: break; } - return ba; + return QByteArray(); } QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const @@ -128,26 +131,37 @@ QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy) { - QByteArray ba = request.d->methodName(); - QByteArray uri = request.d->uri(throughProxy); - ba += ' ' + uri; + QList<QPair<QByteArray, QByteArray> > fields = request.header(); + QByteArray ba; + ba.reserve(40 + fields.length()*25); // very rough lower bound estimation - QString majorVersion = QString::number(request.majorVersion()); - QString minorVersion = QString::number(request.minorVersion()); - ba += " HTTP/" + majorVersion.toLatin1() + '.' + minorVersion.toLatin1() + "\r\n"; + ba += request.d->methodName(); + ba += ' '; + ba += request.d->uri(throughProxy); + + ba += " HTTP/"; + ba += QByteArray::number(request.majorVersion()); + ba += '.'; + ba += QByteArray::number(request.minorVersion()); + ba += "\r\n"; - QList<QPair<QByteArray, QByteArray> > fields = request.header(); QList<QPair<QByteArray, QByteArray> >::const_iterator it = fields.constBegin(); - for (; it != fields.constEnd(); ++it) - ba += it->first + ": " + it->second + "\r\n"; + QList<QPair<QByteArray, QByteArray> >::const_iterator endIt = fields.constEnd(); + for (; it != endIt; ++it) { + ba += it->first; + ba += ": "; + ba += it->second; + ba += "\r\n"; + } if (request.d->operation == QHttpNetworkRequest::Post) { // add content type, if not set in the request if (request.headerField("content-type").isEmpty()) ba += "Content-Type: application/x-www-form-urlencoded\r\n"; if (!request.d->uploadByteDevice && request.d->url.hasQuery()) { QByteArray query = request.d->url.encodedQuery(); - ba += "Content-Length: "+ QByteArray::number(query.size()) + "\r\n"; - ba += "\r\n"; + ba += "Content-Length: "; + ba += QByteArray::number(query.size()); + ba += "\r\n\r\n"; ba += query; } else { ba += "\r\n"; @@ -230,6 +244,16 @@ void QHttpNetworkRequest::setOperation(Operation operation) d->operation = operation; } +QByteArray QHttpNetworkRequest::customVerb() const +{ + return d->customVerb; +} + +void QHttpNetworkRequest::setCustomVerb(const QByteArray &customVerb) +{ + d->customVerb = customVerb; +} + QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const { return d->priority; diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h index dad118e..1b35a84 100644 --- a/src/network/access/qhttpnetworkrequest_p.h +++ b/src/network/access/qhttpnetworkrequest_p.h @@ -72,7 +72,8 @@ public: Put, Delete, Trace, - Connect + Connect, + Custom }; enum Priority { @@ -103,6 +104,9 @@ public: Operation operation() const; void setOperation(Operation operation); + QByteArray customVerb() const; + void setCustomVerb(const QByteArray &customOperation); + Priority priority() const; void setPriority(Priority priority); @@ -133,6 +137,7 @@ public: static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy); QHttpNetworkRequest::Operation operation; + QByteArray customVerb; QHttpNetworkRequest::Priority priority; mutable QNonContiguousByteDevice* uploadByteDevice; bool autoDecompress; diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 8ac64d2..34d576a 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -120,8 +120,11 @@ QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice() if (reply->outgoingDataBuffer) device = QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer); - else + else if (reply->outgoingData) { device = QNonContiguousByteDeviceFactory::create(reply->outgoingData); + } else { + return 0; + } bool bufferDisallowed = reply->request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute, diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 8e02723..c8f4e5b 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -213,6 +213,7 @@ QNetworkAccessHttpBackendFactory::create(QNetworkAccessManager::Operation op, case QNetworkAccessManager::HeadOperation: case QNetworkAccessManager::PutOperation: case QNetworkAccessManager::DeleteOperation: + case QNetworkAccessManager::CustomOperation: break; default: @@ -526,6 +527,14 @@ void QNetworkAccessHttpBackend::postRequest() httpRequest.setOperation(QHttpNetworkRequest::Delete); break; + case QNetworkAccessManager::CustomOperation: + invalidateCache(); // for safety reasons, we don't know what the operation does + httpRequest.setOperation(QHttpNetworkRequest::Custom); + httpRequest.setUploadByteDevice(createUploadByteDevice()); + httpRequest.setCustomVerb(request().attribute( + QNetworkRequest::CustomVerbAttribute).toByteArray()); + break; + default: break; // can't happen } diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 0b32533..cc4c977 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -154,6 +154,9 @@ static void ensureInitialized() \value DeleteOperation delete contents operation (created with deleteResource()) + \value CustomOperation custom operation (created with + sendCustomRequest()) + \omitvalue UnknownOperation \sa QNetworkReply::operation() @@ -566,7 +569,7 @@ QNetworkReply *QNetworkAccessManager::head(const QNetworkRequest &request) The contents as well as associated headers will be downloaded. - \sa post(), put(), deleteResource() + \sa post(), put(), deleteResource(), sendCustomRequest() */ QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request) { @@ -585,7 +588,7 @@ QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request) \note Sending a POST request on protocols other than HTTP and HTTPS is undefined and will probably fail. - \sa get(), put(), deleteResource() + \sa get(), put(), deleteResource(), sendCustomRequest() */ QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QIODevice *data) { @@ -626,7 +629,7 @@ QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, const do not allow. Form upload mechanisms, including that of uploading files through HTML forms, use the POST mechanism. - \sa get(), post() + \sa get(), post(), deleteResource(), sendCustomRequest() */ QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QIODevice *data) { @@ -657,7 +660,7 @@ QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, const \note This feature is currently available for HTTP only, performing an HTTP DELETE request. - \sa get(), post(), put() + \sa get(), post(), put(), sendCustomRequest() */ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &request) { @@ -665,6 +668,32 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ } /*! + \since 4.7 + + Sends a custom request to the server identified by the URL of \a request. + + It is the user's responsibility to send a \a verb to the server that is valid + according to the HTTP specification. + + This method provides means to send verbs other than the common ones provided + via get() or post() etc., for instance sending an HTTP OPTIONS command. + + If \a data is not empty, the contents of the \a data + device will be uploaded to the server; in that case, data must be open for + reading and must remain valid until the finished() signal is emitted for this reply. + + \note This feature is currently available for HTTP only. + + \sa get(), post(), put(), deleteResource() +*/ +QNetworkReply *QNetworkAccessManager::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data) +{ + QNetworkRequest newRequest(request); + newRequest.setAttribute(QNetworkRequest::CustomVerbAttribute, verb); + return d_func()->postProcess(createRequest(QNetworkAccessManager::CustomOperation, newRequest, data)); +} + +/*! Returns a new QNetworkReply object to handle the operation \a op and request \a req. The device \a outgoingData is always 0 for Get and Head requests, but is the value passed to post() and put() in diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index d2fe527..3a8ba58 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -75,6 +75,7 @@ public: PutOperation, PostOperation, DeleteOperation, + CustomOperation, UnknownOperation = 0 }; @@ -102,6 +103,7 @@ public: QNetworkReply *put(const QNetworkRequest &request, QIODevice *data); QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data); QNetworkReply *deleteResource(const QNetworkRequest &request); + QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data = 0); Q_SIGNALS: #ifndef QT_NO_NETWORKPROXY diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index b8438a2..e563f4e 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -182,6 +182,12 @@ QT_BEGIN_NAMESPACE Indicates whether the HTTP pipelining was used for receiving this reply. + \value CustomVerbAttribute + Requests only, type: QVariant::ByteArray + Holds the value for the custom HTTP verb to send (destined for usage + of other verbs than GET, POST, PUT and DELETE). This verb is set + when calling QNetworkAccessManager::sendCustomRequest(). + \value User Special type. Additional information can be passed in QVariants with types ranging from User to UserMax. The default diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index bc2d9da..a0ef1a6 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -78,6 +78,7 @@ public: DoNotBufferUploadDataAttribute, HttpPipeliningAllowedAttribute, HttpPipeliningWasUsedAttribute, + CustomVerbAttribute, User = 1000, UserMax = 32767 diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp index 115f31b..ce917ff 100644 --- a/src/opengl/gl2paintengineex/qtriangulator.cpp +++ b/src/opengl/gl2paintengineex/qtriangulator.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/opengl/gl2paintengineex/qtriangulator_p.h b/src/opengl/gl2paintengineex/qtriangulator_p.h index da47666..e5eec39 100644 --- a/src/opengl/gl2paintengineex/qtriangulator_p.h +++ b/src/opengl/gl2paintengineex/qtriangulator_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index f1d2325..7bebd46 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -128,7 +128,7 @@ void QGLFramebufferObjectFormat::detach() attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. On OpenGL/ES systems, the default internal format is \c GL_RGBA. - \sa samples(), attachment(), target(), internalTextureFormat() + \sa samples(), attachment(), internalTextureFormat() */ QGLFramebufferObjectFormat::QGLFramebufferObjectFormat() diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index a0b332d..739983e 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -3082,20 +3082,18 @@ void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 * \since 4.7 - \sa setGeometryShaderOutputVertexCount + \sa setGeometryOutputVertexCount() */ int QGLShaderProgram::maxGeometryOutputVertices() const { - int n; + GLint n; glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); return n; } - - /*! Sets the maximum number of vertices the current geometry shader - program will produce, if active. + program will produce, if active, to \a count. \since 4.7 @@ -3129,7 +3127,7 @@ int QGLShaderProgram::geometryOutputVertexCount() const /*! - Sets the output type from the geometry shader, if active. + Sets the input type from \a inputType. This parameter takes effect the next time the program is linked. */ @@ -3154,7 +3152,8 @@ GLenum QGLShaderProgram::geometryInputType() const /*! - Sets the output type from the geometry shader, if active. + Sets the output type from the geometry shader, if active, to + \a outputType. This parameter takes effect the next time the program is linked. diff --git a/src/plugins/mediaservices/directshow/directshow.pro b/src/plugins/mediaservices/directshow/directshow.pro new file mode 100644 index 0000000..a3080d3 --- /dev/null +++ b/src/plugins/mediaservices/directshow/directshow.pro @@ -0,0 +1,14 @@ +TARGET = dsengine +include(../../qpluginbase.pri) + +QT += multimedia + +HEADERS += dsserviceplugin.h +SOURCES += dsserviceplugin.cpp + +include(mediaplayer/mediaplayer.pri) + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mediaservices +target.path = $$[QT_INSTALL_PLUGINS]/plugins/mediaservices +INSTALLS += target + diff --git a/src/plugins/mediaservices/directshow/dsserviceplugin.cpp b/src/plugins/mediaservices/directshow/dsserviceplugin.cpp new file mode 100644 index 0000000..f3ab889 --- /dev/null +++ b/src/plugins/mediaservices/directshow/dsserviceplugin.cpp @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qstring.h> +#include <QtCore/qdebug.h> +#include <QtCore/QFile> + +#include "dsserviceplugin.h" + +#ifdef QMEDIA_DIRECTSHOW_CAMERA +#include "dscameraservice.h" +#endif + +#ifdef QMEDIA_DIRECTSHOW_PLAYER +#include "directshowplayerservice.h" +#endif + +#include <qmediaserviceprovider.h> + + +#ifdef QMEDIA_DIRECTSHOW_CAMERA +#ifndef _STRSAFE_H_INCLUDED_ +#include <tchar.h> +#endif +#include <dshow.h> +#include <objbase.h> +#include <initguid.h> +#pragma comment(lib, "strmiids.lib") +#pragma comment(lib, "ole32.lib") +#include <windows.h> +#endif + + +QT_BEGIN_NAMESPACE + +QStringList DSServicePlugin::keys() const +{ + return QStringList() +#ifdef QMEDIA_DIRECTSHOW_CAMERA + << QLatin1String(Q_MEDIASERVICE_CAMERA) +#endif +#ifdef QMEDIA_DIRECTSHOW_PLAYER + << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER) +#endif + ; +} + +QMediaService* DSServicePlugin::create(QString const& key) +{ +#ifdef QMEDIA_DIRECTSHOW_CAMERA + if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) + return new DSCameraService; +#endif +#ifdef QMEDIA_DIRECTSHOW_PLAYER + if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) + return new DirectShowPlayerService; +#endif + + qDebug() << "unsupported key:" << key; + return 0; +} + +void DSServicePlugin::release(QMediaService *service) +{ + delete service; +} + +QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const +{ +#ifdef QMEDIA_DIRECTSHOW_CAMERA + if (service == Q_MEDIASERVICE_CAMERA) { + if (m_cameraDevices.isEmpty()) + updateDevices(); + + return m_cameraDevices; + } +#endif + + return QList<QByteArray>(); +} + +QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) +{ +#ifdef QMEDIA_DIRECTSHOW_CAMERA + if (service == Q_MEDIASERVICE_CAMERA) { + if (m_cameraDevices.isEmpty()) + updateDevices(); + + for (int i=0; i<m_cameraDevices.count(); i++) + if (m_cameraDevices[i] == device) + return m_cameraDescriptions[i]; + } +#endif + return QString(); +} + +#ifdef QMEDIA_DIRECTSHOW_CAMERA +void DSServicePlugin::updateDevices() const +{ + m_cameraDevices.clear(); + m_cameraDescriptions.clear(); + + CoInitialize(NULL); + ICreateDevEnum* pDevEnum = NULL; + IEnumMoniker* pEnum = NULL; + // Create the System device enumerator + HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, + CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, + reinterpret_cast<void**>(&pDevEnum)); + if(SUCCEEDED(hr)) { + // Create the enumerator for the video capture category + hr = pDevEnum->CreateClassEnumerator( + CLSID_VideoInputDeviceCategory, &pEnum, 0); + pEnum->Reset(); + // go through and find all video capture devices + IMoniker* pMoniker = NULL; + while(pEnum->Next(1, &pMoniker, NULL) == S_OK) { + IPropertyBag *pPropBag; + hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag, + (void**)(&pPropBag)); + if(FAILED(hr)) { + pMoniker->Release(); + continue; // skip this one + } + // Find the description + WCHAR str[120]; + VARIANT varName; + varName.vt = VT_BSTR; + hr = pPropBag->Read(L"FriendlyName", &varName, 0); + if(SUCCEEDED(hr)) { + StringCchCopyW(str,sizeof(str)/sizeof(str[0]),varName.bstrVal); + QString temp(QString::fromUtf16((unsigned short*)str)); + m_cameraDevices.append(QString("ds:%1").arg(temp).toLocal8Bit().constData()); + hr = pPropBag->Read(L"Description", &varName, 0); + StringCchCopyW(str,sizeof(str)/sizeof(str[0]),varName.bstrVal); + QString temp2(QString::fromUtf16((unsigned short*)str)); + m_cameraDescriptions.append(temp2); + } + pPropBag->Release(); + pMoniker->Release(); + } + } + CoUninitialize(); +} +#endif + +QT_END_NAMESPACE + +Q_EXPORT_PLUGIN2(dsengine, DSServicePlugin); + diff --git a/src/plugins/mediaservices/directshow/dsserviceplugin.h b/src/plugins/mediaservices/directshow/dsserviceplugin.h new file mode 100644 index 0000000..3c6f1b8 --- /dev/null +++ b/src/plugins/mediaservices/directshow/dsserviceplugin.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DSSERVICEPLUGIN_H +#define DSSERVICEPLUGIN_H + +#include <qmediaserviceproviderplugin.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class DSServicePlugin : public QMediaServiceProviderPlugin, public QMediaServiceSupportedDevicesInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceSupportedDevicesInterface) +public: + QStringList keys() const; + QMediaService* create(QString const& key); + void release(QMediaService *service); + + QList<QByteArray> devices(const QByteArray &service) const; + QString deviceDescription(const QByteArray &service, const QByteArray &device); + +private: +#ifdef QMEDIA_DIRECTSHOW_CAMERA + void updateDevices() const; + + mutable QList<QByteArray> m_cameraDevices; + mutable QStringList m_cameraDescriptions; +#endif +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // DSSERVICEPLUGIN_H diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowaudioendpointcontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowaudioendpointcontrol.cpp new file mode 100644 index 0000000..570b44a --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowaudioendpointcontrol.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowaudioendpointcontrol.h" + +#include "directshowglobal.h" +#include "directshowplayerservice.h" + + +QT_BEGIN_NAMESPACE + +DirectShowAudioEndpointControl::DirectShowAudioEndpointControl( + DirectShowPlayerService *service, QObject *parent) + : QMediaControl(parent) + , m_service(service) + , m_bindContext(0) + , m_deviceEnumerator(0) +{ + if (CreateBindCtx(0, &m_bindContext) == S_OK) { + m_deviceEnumerator = com_new<ICreateDevEnum>(CLSID_SystemDeviceEnum); + + updateEndpoints(); + + setActiveEndpoint(m_defaultEndpoint); + } +} + +DirectShowAudioEndpointControl::~DirectShowAudioEndpointControl() +{ + foreach (IMoniker *moniker, m_devices) + moniker->Release(); + + if (m_bindContext) + m_bindContext->Release(); + + if (m_deviceEnumerator) + m_deviceEnumerator->Release(); +} + +QList<QString> DirectShowAudioEndpointControl::availableEndpoints() const +{ + return m_devices.keys(); +} + +QString DirectShowAudioEndpointControl::endpointDescription(const QString &name) const +{ + QString description; + + if (IMoniker *moniker = m_devices.value(name, 0)) { + IPropertyBag *propertyBag = 0; + if (SUCCEEDED(moniker->BindToStorage( + 0, 0, IID_IPropertyBag, reinterpret_cast<void **>(&propertyBag)))) { + VARIANT name; + VariantInit(&name); + if (SUCCEEDED(propertyBag->Read(L"FriendlyName", &name, 0))) + description = QString::fromWCharArray(name.bstrVal); + VariantClear(&name); + propertyBag->Release(); + } + } + return description;; +} + +QString DirectShowAudioEndpointControl::defaultEndpoint() const +{ + return m_defaultEndpoint; +} + +QString DirectShowAudioEndpointControl::activeEndpoint() const +{ + return m_activeEndpoint; +} + +void DirectShowAudioEndpointControl::setActiveEndpoint(const QString &name) +{ + if (m_activeEndpoint == name) + return; + + if (IMoniker *moniker = m_devices.value(name, 0)) { + IBaseFilter *filter = 0; + + if (moniker->BindToObject( + m_bindContext, + 0, + __uuidof(IBaseFilter), + reinterpret_cast<void **>(&filter)) == S_OK) { + m_service->setAudioOutput(filter); + + filter->Release(); + } + } +} + +void DirectShowAudioEndpointControl::updateEndpoints() +{ + IMalloc *oleMalloc = 0; + if (m_deviceEnumerator && CoGetMalloc(1, &oleMalloc) == S_OK) { + IEnumMoniker *monikers = 0; + + if (m_deviceEnumerator->CreateClassEnumerator( + CLSID_AudioRendererCategory, &monikers, 0) == S_OK) { + for (IMoniker *moniker = 0; monikers->Next(1, &moniker, 0) == S_OK; moniker->Release()) { + OLECHAR *string = 0; + if (moniker->GetDisplayName(m_bindContext, 0, &string) == S_OK) { + QString deviceId = QString::fromWCharArray(string); + oleMalloc->Free(string); + + moniker->AddRef(); + m_devices.insert(deviceId, moniker); + + if (m_defaultEndpoint.isEmpty() + || deviceId.endsWith(QLatin1String("Default DirectSound Device"))) { + m_defaultEndpoint = deviceId; + } + } + } + monikers->Release(); + } + oleMalloc->Release(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowaudioendpointcontrol.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowaudioendpointcontrol.h new file mode 100644 index 0000000..2faac13 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowaudioendpointcontrol.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWAUDIOENDPOINTCONTROL_H +#define DIRECTSHOWAUDIOENDPOINTCONTROL_H + +#include <QtMultimedia/qmediacontrol.h> + +#include <dshow.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowPlayerService; + +class DirectShowAudioEndpointControl : public QMediaControl +{ + Q_OBJECT +public: + DirectShowAudioEndpointControl(DirectShowPlayerService *service, QObject *parent = 0); + ~DirectShowAudioEndpointControl(); + + QList<QString> availableEndpoints() const; + + QString endpointDescription(const QString &name) const; + + QString defaultEndpoint() const; + QString activeEndpoint() const; + + void setActiveEndpoint(const QString& name); + +private: + void updateEndpoints(); + + DirectShowPlayerService *m_service; + IBindCtx *m_bindContext; + ICreateDevEnum *m_deviceEnumerator; + + QMap<QString, IMoniker *> m_devices; + QString m_defaultEndpoint; + QString m_activeEndpoint; +}; + +#define QAudioEndpointSelector_iid "com.nokia.Qt.QAudioEndpointSelector/1.0" + +class Duck +{ + uint quack; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif + diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshoweventloop.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshoweventloop.cpp new file mode 100644 index 0000000..07541c2 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshoweventloop.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <directshoweventloop.h> + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qcoreevent.h> + + +QT_BEGIN_NAMESPACE + + +class DirectShowPostedEvent +{ +public: + DirectShowPostedEvent(QObject *receiver, QEvent *event) + : receiver(receiver) + , event(event) + , next(0) + { + } + + ~DirectShowPostedEvent() + { + delete event; + } + + QObject *receiver; + QEvent *event; + DirectShowPostedEvent *next; +}; + +DirectShowEventLoop::DirectShowEventLoop(QObject *parent) + : QWinEventNotifier(parent) + , m_postsHead(0) + , m_postsTail(0) + , m_eventHandle(::CreateEvent(0, 0, 0, 0)) + , m_waitHandle(::CreateEvent(0, 0, 0, 0)) +{ + setHandle(m_eventHandle); + setEnabled(true); +} + +DirectShowEventLoop::~DirectShowEventLoop() +{ + setEnabled(false); + + ::CloseHandle(m_eventHandle); + ::CloseHandle(m_waitHandle); + + for (DirectShowPostedEvent *post = m_postsHead; post; post = m_postsHead) { + m_postsHead = m_postsHead->next; + + delete post; + } +} + +void DirectShowEventLoop::wait(QMutex *mutex) +{ + ::ResetEvent(m_waitHandle); + + mutex->unlock(); + + HANDLE handles[] = { m_eventHandle, m_waitHandle }; + while (::WaitForMultipleObjects(2, handles, false, INFINITE) == WAIT_OBJECT_0) + processEvents(); + + mutex->lock(); +} + +void DirectShowEventLoop::wake() +{ + ::SetEvent(m_waitHandle); +} + +void DirectShowEventLoop::postEvent(QObject *receiver, QEvent *event) +{ + QMutexLocker locker(&m_mutex); + + DirectShowPostedEvent *post = new DirectShowPostedEvent(receiver, event); + + if (m_postsTail) + m_postsTail->next = post; + else + m_postsHead = post; + + m_postsTail = post; + + ::SetEvent(m_eventHandle); +} + +bool DirectShowEventLoop::event(QEvent *event) +{ + if (event->type() == QEvent::WinEventAct) { + processEvents(); + + return true; + } else { + return QWinEventNotifier::event(event); + } +} + +void DirectShowEventLoop::processEvents() +{ + QMutexLocker locker(&m_mutex); + + while(m_postsHead) { + ::ResetEvent(m_eventHandle); + + DirectShowPostedEvent *post = m_postsHead; + m_postsHead = m_postsHead->next; + + if (!m_postsHead) + m_postsTail = 0; + + locker.unlock(); + QCoreApplication::sendEvent(post->receiver, post->event); + delete post; + locker.relock(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshoweventloop.h b/src/plugins/mediaservices/directshow/mediaplayer/directshoweventloop.h new file mode 100644 index 0000000..f46e65a --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshoweventloop.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWEVENTLOOP_H +#define DIRECTSHOWEVENTLOOP_H + +#include <QtCore/qmutex.h> +#include <QtCore/private/qwineventnotifier_p.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowPostedEvent; + +class DirectShowEventLoop : public QWinEventNotifier +{ + Q_OBJECT +public: + DirectShowEventLoop(QObject *parent = 0); + ~DirectShowEventLoop(); + + void wait(QMutex *mutex); + void wake(); + + void postEvent(QObject *object, QEvent *event); + + bool event(QEvent *event); + +private: + void processEvents(); + + DirectShowPostedEvent *m_postsHead; + DirectShowPostedEvent *m_postsTail; + HANDLE m_eventHandle; + HANDLE m_waitHandle; + QMutex m_mutex; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowglobal.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowglobal.h new file mode 100644 index 0000000..1c9fe54 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowglobal.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWGLOBAL_H +#define DIRECTSHOWGLOBAL_H + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +template <typename T> T *com_cast(IUnknown *unknown) +{ + T *iface = 0; + return unknown && unknown->QueryInterface( + __uuidof(T), reinterpret_cast<void **>(&iface)) == S_OK + ? iface + : 0; +} + +template <typename T> T *com_new(const IID &clsid) +{ + T *object = 0; + return CoCreateInstance( + clsid, + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(T), + reinterpret_cast<void **>(&object)) == S_OK + ? object + : 0; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowioreader.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowioreader.cpp new file mode 100644 index 0000000..54446b8 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowioreader.cpp @@ -0,0 +1,501 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowioreader.h" + +#include "directshoweventloop.h" +#include "directshowglobal.h" +#include "directshowiosource.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qiodevice.h> +#include <QtCore/qthread.h> + + +QT_BEGIN_NAMESPACE + +class DirectShowSampleRequest +{ +public: + DirectShowSampleRequest( + IMediaSample *sample, DWORD_PTR userData, LONGLONG position, LONG length, BYTE *buffer) + : next(0) + , sample(sample) + , userData(userData) + , position(position) + , length(length) + , buffer(buffer) + , result(S_FALSE) + { + } + + DirectShowSampleRequest *remove() { DirectShowSampleRequest *n = next; delete this; return n; } + + DirectShowSampleRequest *next; + IMediaSample *sample; + DWORD_PTR userData; + LONGLONG position; + LONG length; + BYTE *buffer; + HRESULT result; +}; + +DirectShowIOReader::DirectShowIOReader( + QIODevice *device, DirectShowIOSource *source, DirectShowEventLoop *loop) + : m_source(source) + , m_device(device) + , m_loop(loop) + , m_pendingHead(0) + , m_pendingTail(0) + , m_readyHead(0) + , m_readyTail(0) + , m_synchronousPosition(0) + , m_synchronousLength(0) + , m_synchronousBytesRead(0) + , m_synchronousBuffer(0) + , m_synchronousResult(S_OK) + , m_totalLength(0) + , m_availableLength(0) + , m_flushing(false) +{ + moveToThread(device->thread()); + + connect(device, SIGNAL(readyRead()), this, SLOT(readyRead())); +} + +DirectShowIOReader::~DirectShowIOReader() +{ + flushRequests(); +} + +HRESULT DirectShowIOReader::QueryInterface(REFIID riid, void **ppvObject) +{ + return m_source->QueryInterface(riid, ppvObject); +} + +ULONG DirectShowIOReader::AddRef() +{ + return m_source->AddRef(); +} + +ULONG DirectShowIOReader::Release() +{ + return m_source->Release(); +} + +// IAsyncReader +HRESULT DirectShowIOReader::RequestAllocator( + IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual) +{ + if (!ppActual || !pProps) { + return E_POINTER; + } else { + ALLOCATOR_PROPERTIES actualProperties; + + if (pProps->cbAlign == 0) + pProps->cbAlign = 1; + + if (pPreferred && pPreferred->SetProperties(pProps, &actualProperties) == S_OK) { + pPreferred->AddRef(); + + *ppActual = pPreferred; + + m_source->setAllocator(*ppActual); + + return S_OK; + } else { + *ppActual = com_new<IMemAllocator>(CLSID_MemoryAllocator); + + if (*ppActual) { + if ((*ppActual)->SetProperties(pProps, &actualProperties) != S_OK) { + (*ppActual)->Release(); + } else { + m_source->setAllocator(*ppActual); + + return S_OK; + } + } + } + ppActual = 0; + + return E_FAIL; + } +} + +HRESULT DirectShowIOReader::Request(IMediaSample *pSample, DWORD_PTR dwUser) +{ + QMutexLocker locker(&m_mutex); + + if (!pSample) { + return E_POINTER; + } else if (m_flushing) { + return VFW_E_WRONG_STATE; + } else { + REFERENCE_TIME startTime = 0; + REFERENCE_TIME endTime = 0; + BYTE *buffer; + + if (pSample->GetTime(&startTime, &endTime) != S_OK + || pSample->GetPointer(&buffer) != S_OK) { + return VFW_E_SAMPLE_TIME_NOT_SET; + } else { + LONGLONG position = startTime / 10000000; + LONG length = (endTime - startTime) / 10000000; + + DirectShowSampleRequest *request = new DirectShowSampleRequest( + pSample, dwUser, position, length, buffer); + + if (m_pendingTail) { + m_pendingTail->next = request; + } else { + m_pendingHead = request; + + m_loop->postEvent(this, new QEvent(QEvent::User)); + } + m_pendingTail = request; + + return S_OK; + } + } +} + +HRESULT DirectShowIOReader::WaitForNext( + DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser) +{ + if (!ppSample || !pdwUser) + return E_POINTER; + + QMutexLocker locker(&m_mutex); + + do { + if (m_readyHead) { + DirectShowSampleRequest *request = m_readyHead; + + *ppSample = request->sample; + *pdwUser = request->userData; + + HRESULT hr = request->result; + + m_readyHead = request->next; + + if (!m_readyHead) + m_readyTail = 0; + + delete request; + + return hr; + } else if (m_flushing) { + *ppSample = 0; + *pdwUser = 0; + + return VFW_E_WRONG_STATE; + } + } while (m_wait.wait(&m_mutex, dwTimeout)); + + *ppSample = 0; + *pdwUser = 0; + + return VFW_E_TIMEOUT; +} + +HRESULT DirectShowIOReader::SyncReadAligned(IMediaSample *pSample) +{ + if (!pSample) { + return E_POINTER; + } else { + REFERENCE_TIME startTime = 0; + REFERENCE_TIME endTime = 0; + BYTE *buffer; + + if (pSample->GetTime(&startTime, &endTime) != S_OK + || pSample->GetPointer(&buffer) != S_OK) { + return VFW_E_SAMPLE_TIME_NOT_SET; + } else { + LONGLONG position = startTime / 10000000; + LONG length = (endTime - startTime) / 10000000; + + QMutexLocker locker(&m_mutex); + + if (thread() == QThread::currentThread()) { + qint64 bytesRead = 0; + + HRESULT hr = blockingRead(position, length, buffer, &bytesRead); + + if (SUCCEEDED(hr)) + pSample->SetActualDataLength(bytesRead); + + return hr; + } else { + m_synchronousPosition = position; + m_synchronousLength = length; + m_synchronousBuffer = buffer; + + m_loop->postEvent(this, new QEvent(QEvent::User)); + + m_wait.wait(&m_mutex); + + m_synchronousBuffer = 0; + + if (SUCCEEDED(m_synchronousResult)) + pSample->SetActualDataLength(m_synchronousBytesRead); + + return m_synchronousResult; + } + } + } +} + +HRESULT DirectShowIOReader::SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer) +{ + if (!pBuffer) { + return E_POINTER; + } else { + if (thread() == QThread::currentThread()) { + qint64 bytesRead; + + return blockingRead(llPosition, lLength, pBuffer, &bytesRead); + } else { + QMutexLocker locker(&m_mutex); + + m_synchronousPosition = llPosition; + m_synchronousLength = lLength; + m_synchronousBuffer = pBuffer; + + m_loop->postEvent(this, new QEvent(QEvent::User)); + + m_wait.wait(&m_mutex); + + m_synchronousBuffer = 0; + + return m_synchronousResult; + } + } +} + +HRESULT DirectShowIOReader::Length(LONGLONG *pTotal, LONGLONG *pAvailable) +{ + if (!pTotal || !pAvailable) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + *pTotal = m_totalLength; + *pAvailable = m_availableLength; + + return S_OK; + } +} + + +HRESULT DirectShowIOReader::BeginFlush() +{ + QMutexLocker locker(&m_mutex); + + if (m_flushing) + return S_FALSE; + + m_flushing = true; + + flushRequests(); + + m_wait.wakeAll(); + + return S_OK; +} + +HRESULT DirectShowIOReader::EndFlush() +{ + QMutexLocker locker(&m_mutex); + + if (!m_flushing) + return S_FALSE; + + m_flushing = false; + + return S_OK; +} + +void DirectShowIOReader::customEvent(QEvent *event) +{ + if (event->type() == QEvent::User) { + readyRead(); + } else { + QObject::customEvent(event); + } +} + +void DirectShowIOReader::readyRead() +{ + QMutexLocker locker(&m_mutex); + + m_availableLength = m_device->bytesAvailable() + m_device->pos(); + m_totalLength = m_device->size(); + + if (m_synchronousBuffer) { + if (nonBlockingRead( + m_synchronousPosition, + m_synchronousLength, + m_synchronousBuffer, + &m_synchronousBytesRead, + &m_synchronousResult)) { + m_wait.wakeAll(); + } + } else { + qint64 bytesRead = 0; + + while (m_pendingHead && nonBlockingRead( + m_pendingHead->position, + m_pendingHead->length, + m_pendingHead->buffer, + &bytesRead, + &m_pendingHead->result)) { + m_pendingHead->sample->SetActualDataLength(bytesRead); + + if (m_readyTail) + m_readyTail->next = m_pendingHead; + m_readyTail = m_pendingHead; + + m_pendingHead = m_pendingHead->next; + + m_readyTail->next = 0; + + if (!m_pendingHead) + m_pendingTail = 0; + + if (!m_readyHead) + m_readyHead = m_readyTail; + + m_wait.wakeAll(); + } + } +} + +HRESULT DirectShowIOReader::blockingRead( + LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead) +{ + *bytesRead = 0; + + if (qint64(position) > m_device->size()) + return S_FALSE; + + const qint64 maxSize = qMin<qint64>(m_device->size(), position + length); + + while (m_device->bytesAvailable() + m_device->pos() < maxSize) { + if (!m_device->waitForReadyRead(-1)) + return S_FALSE; + } + + if (m_device->pos() != position && !m_device->seek(position)) + return S_FALSE; + + const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable()); + + *bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes); + + if (*bytesRead != length) { + qMemSet(buffer + *bytesRead, 0, length - *bytesRead); + + return S_FALSE; + } else { + return S_OK; + } +} + +bool DirectShowIOReader::nonBlockingRead( + LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead, HRESULT *result) +{ + const qint64 maxSize = qMin<qint64>(m_device->size(), position + length); + + if (position > m_device->size()) { + *bytesRead = 0; + *result = S_FALSE; + + return true; + } else if (m_device->bytesAvailable() + m_device->pos() >= maxSize) { + if (m_device->pos() != position && !m_device->seek(position)) { + *bytesRead = 0; + *result = S_FALSE; + + return true; + } else { + const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable()); + + *bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes); + + if (*bytesRead != length) { + qMemSet(buffer + *bytesRead, 0, length - *bytesRead); + + *result = S_FALSE; + } else { + *result = S_OK; + } + + return true; + } + } else { + return false; + } +} + +void DirectShowIOReader::flushRequests() +{ + while (m_pendingHead) { + m_pendingHead->result = VFW_E_WRONG_STATE; + + if (m_readyTail) + m_readyTail->next = m_pendingHead; + + m_readyTail = m_pendingHead; + + m_pendingHead = m_pendingHead->next; + + m_readyTail->next = 0; + + if (!m_pendingHead) + m_pendingTail = 0; + + if (!m_readyHead) + m_readyHead = m_readyTail; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowioreader.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowioreader.h new file mode 100644 index 0000000..8cbc2f1 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowioreader.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWIOREADER_H +#define DIRECTSHOWIOREADER_H + +#include <QtCore/qmutex.h> +#include <QtCore/qobject.h> +#include <QtCore/qwaitcondition.h> + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QIODevice; + +class DirectShowEventLoop; +class DirectShowIOSource; +class DirectShowSampleRequest; + +class DirectShowIOReader : public QObject, public IAsyncReader +{ + Q_OBJECT +public: + DirectShowIOReader(QIODevice *device, DirectShowIOSource *source, DirectShowEventLoop *loop); + ~DirectShowIOReader(); + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + // IAsyncReader + HRESULT STDMETHODCALLTYPE RequestAllocator( + IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual); + + HRESULT STDMETHODCALLTYPE Request(IMediaSample *pSample, DWORD_PTR dwUser); + + HRESULT STDMETHODCALLTYPE WaitForNext( + DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser); + + HRESULT STDMETHODCALLTYPE SyncReadAligned(IMediaSample *pSample); + + HRESULT STDMETHODCALLTYPE SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer); + + HRESULT STDMETHODCALLTYPE Length(LONGLONG *pTotal, LONGLONG *pAvailable); + + HRESULT STDMETHODCALLTYPE BeginFlush(); + HRESULT STDMETHODCALLTYPE EndFlush(); + +protected: + void customEvent(QEvent *event); + +private Q_SLOTS: + void readyRead(); + +private: + HRESULT blockingRead(LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead); + bool nonBlockingRead( + LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead, HRESULT *result); + void flushRequests(); + + DirectShowIOSource *m_source; + QIODevice *m_device; + DirectShowEventLoop *m_loop; + DirectShowSampleRequest *m_pendingHead; + DirectShowSampleRequest *m_pendingTail; + DirectShowSampleRequest *m_readyHead; + DirectShowSampleRequest *m_readyTail; + LONGLONG m_synchronousPosition; + LONG m_synchronousLength; + qint64 m_synchronousBytesRead; + BYTE *m_synchronousBuffer; + HRESULT m_synchronousResult; + LONGLONG m_totalLength; + LONGLONG m_availableLength; + bool m_flushing; + QMutex m_mutex; + QWaitCondition m_wait; +}; + +QT_END_NAMESPACE + +QT_END_HEADER +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowiosource.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowiosource.cpp new file mode 100644 index 0000000..c2fb0d4 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowiosource.cpp @@ -0,0 +1,639 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowiosource.h" + +#include "directshowglobal.h" +#include "directshowmediatype.h" +#include "directshowpinenum.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qurl.h> + +QT_BEGIN_NAMESPACE + +static const GUID directshow_subtypes[] = +{ + MEDIASUBTYPE_Avi, + MEDIASUBTYPE_WAVE, + MEDIASUBTYPE_NULL +}; + +DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop) + : m_ref(1) + , m_state(State_Stopped) + , m_reader(0) + , m_loop(loop) + , m_graph(0) + , m_clock(0) + , m_allocator(0) + , m_peerPin(0) + , m_pinId(QLatin1String("Data")) +{ + QVector<AM_MEDIA_TYPE> mediaTypes; + + AM_MEDIA_TYPE type = + { + MEDIATYPE_Stream, // majortype + MEDIASUBTYPE_NULL, // subtype + TRUE, // bFixedSizeSamples + FALSE, // bTemporalCompression + 1, // lSampleSize + GUID_NULL, // formattype + 0, // pUnk + 0, // cbFormat + 0, // pbFormat + }; + + static const int count = sizeof(directshow_subtypes) / sizeof(GUID); + + for (int i = 0; i < count; ++i) { + type.subtype = directshow_subtypes[i]; + mediaTypes.append(type); + } + + setMediaTypes(mediaTypes); +} + +DirectShowIOSource::~DirectShowIOSource() +{ + Q_ASSERT(m_ref == 0); + + delete m_reader; +} + +void DirectShowIOSource::setDevice(QIODevice *device) +{ + Q_ASSERT(!m_reader); + + m_reader = new DirectShowIOReader(device, this, m_loop); +} + +void DirectShowIOSource::setAllocator(IMemAllocator *allocator) +{ + if (m_allocator) + m_allocator->Release(); + + m_allocator = allocator; + + if (m_allocator) + m_allocator->AddRef(); +} + +// IUnknown +HRESULT DirectShowIOSource::QueryInterface(REFIID riid, void **ppvObject) +{ + if (!ppvObject) { + return E_POINTER; + } else if (riid == IID_IUnknown + || riid == IID_IPersist + || riid == IID_IMediaFilter + || riid == IID_IBaseFilter) { + *ppvObject = static_cast<IBaseFilter *>(this); + } else if (riid == IID_IAMFilterMiscFlags) { + *ppvObject = static_cast<IAMFilterMiscFlags *>(this); + } else if (riid == IID_IPin) { + *ppvObject = static_cast<IPin *>(this); + } else if (riid == IID_IAsyncReader) { + *ppvObject = static_cast<IAsyncReader *>(m_reader); + } else { + *ppvObject = 0; + + return E_NOINTERFACE; + } + + AddRef(); + + return S_OK; +} + +ULONG DirectShowIOSource::AddRef() +{ + return InterlockedIncrement(&m_ref); +} + +ULONG DirectShowIOSource::Release() +{ + ULONG ref = InterlockedDecrement(&m_ref); + + if (ref == 0) { + delete this; + } + + return ref; +} + +// IPersist +HRESULT DirectShowIOSource::GetClassID(CLSID *pClassID) +{ + *pClassID = CLSID_NULL; + + return S_OK; +} + +// IMediaFilter +HRESULT DirectShowIOSource::Run(REFERENCE_TIME tStart) +{ + QMutexLocker locker(&m_mutex); + + m_state = State_Running; + + return S_OK; +} + +HRESULT DirectShowIOSource::Pause() +{ + QMutexLocker locker(&m_mutex); + + m_state = State_Paused; + + return S_OK; +} + +HRESULT DirectShowIOSource::Stop() +{ + QMutexLocker locker(&m_mutex); + + m_state = State_Stopped; + + return S_OK; +} + +HRESULT DirectShowIOSource::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) +{ + Q_UNUSED(dwMilliSecsTimeout); + + if (!pState) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + *pState = m_state; + + return S_OK; + } +} + +HRESULT DirectShowIOSource::SetSyncSource(IReferenceClock *pClock) +{ + QMutexLocker locker(&m_mutex); + + if (m_clock) + m_clock->Release(); + + m_clock = pClock; + + if (m_clock) + m_clock->AddRef(); + + return S_OK; +} + +HRESULT DirectShowIOSource::GetSyncSource(IReferenceClock **ppClock) +{ + if (!ppClock) { + return E_POINTER; + } else { + if (!m_clock) { + *ppClock = 0; + + return S_FALSE; + } else { + m_clock->AddRef(); + + *ppClock = m_clock; + + return S_OK; + } + } +} + +// IBaseFilter +HRESULT DirectShowIOSource::EnumPins(IEnumPins **ppEnum) +{ + if (!ppEnum) { + return E_POINTER; + } else { + *ppEnum = new DirectShowPinEnum(QList<IPin *>() << this); + + return S_OK; + } +} + +HRESULT DirectShowIOSource::FindPin(LPCWSTR Id, IPin **ppPin) +{ + if (!ppPin || !Id) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + if (QString::fromWCharArray(Id) == m_pinId) { + AddRef(); + + *ppPin = this; + + return S_OK; + } else { + *ppPin = 0; + + return VFW_E_NOT_FOUND; + } + } +} + +HRESULT DirectShowIOSource::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) +{ + QMutexLocker locker(&m_mutex); + + m_graph = pGraph; + m_filterName = QString::fromWCharArray(pName); + + return S_OK; +} + +HRESULT DirectShowIOSource::QueryFilterInfo(FILTER_INFO *pInfo) +{ + if (!pInfo) { + return E_POINTER; + } else { + QString name = m_filterName; + + if (name.length() >= MAX_FILTER_NAME) + name.truncate(MAX_FILTER_NAME - 1); + + int length = name.toWCharArray(pInfo->achName); + pInfo->achName[length] = '\0'; + + if (m_graph) + m_graph->AddRef(); + + pInfo->pGraph = m_graph; + + return S_OK; + } +} + +HRESULT DirectShowIOSource::QueryVendorInfo(LPWSTR *pVendorInfo) +{ + Q_UNUSED(pVendorInfo); + + return E_NOTIMPL; +} + +// IAMFilterMiscFlags +ULONG DirectShowIOSource::GetMiscFlags() +{ + return AM_FILTER_MISC_FLAGS_IS_SOURCE; +} + +// IPin +HRESULT DirectShowIOSource::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) +{ + QMutexLocker locker(&m_mutex); + if (!pReceivePin) { + return E_POINTER; + } else if (m_state != State_Stopped) { + return VFW_E_NOT_STOPPED; + } else if (m_peerPin) { + return VFW_E_ALREADY_CONNECTED; + } else { + HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED; + + m_peerPin = pReceivePin; + m_peerPin->AddRef(); + + if (!pmt) { + IEnumMediaTypes *mediaTypes = 0; + if (pReceivePin->EnumMediaTypes(&mediaTypes) == S_OK) { + for (AM_MEDIA_TYPE *type = 0; + mediaTypes->Next(1, &type, 0) == S_OK; + DirectShowMediaType::deleteType(type)) { + switch (tryConnect(pReceivePin, type)) { + case S_OK: + DirectShowMediaType::freeData(type); + mediaTypes->Release(); + return S_OK; + case VFW_E_NO_TRANSPORT: + hr = VFW_E_NO_TRANSPORT; + break; + default: + break; + } + } + mediaTypes->Release(); + } + AM_MEDIA_TYPE type = + { + MEDIATYPE_Stream, // majortype + MEDIASUBTYPE_NULL, // subtype + TRUE, // bFixedSizeSamples + FALSE, // bTemporalCompression + 1, // lSampleSize + GUID_NULL, // formattype + 0, // pUnk + 0, // cbFormat + 0, // pbFormat + }; + + static const int count = sizeof(directshow_subtypes) / sizeof(GUID); + + for (int i = 0; i < count; ++i) { + type.subtype = directshow_subtypes[i]; + + switch (tryConnect(pReceivePin, &type)) { + case S_OK: + return S_OK; + case VFW_E_NO_TRANSPORT: + hr = VFW_E_NO_TRANSPORT; + break; + default: + break; + } + } + } else if (pmt->majortype == MEDIATYPE_Stream && (hr = tryConnect(pReceivePin, pmt))) { + return S_OK; + } + + m_peerPin->Release(); + m_peerPin = 0; + + m_mediaType.clear(); + + return hr; + } +} + +HRESULT DirectShowIOSource::tryConnect(IPin *pin, const AM_MEDIA_TYPE *type) +{ + m_mediaType = *type; + + HRESULT hr = pin->ReceiveConnection(this, type); + + if (!SUCCEEDED(hr)) { + if (m_allocator) { + m_allocator->Release(); + m_allocator = 0; + } + } else if (!m_allocator) { + hr = VFW_E_NO_TRANSPORT; + + if (IMemInputPin *memPin = com_cast<IMemInputPin>(pin)) { + if ((m_allocator = com_new<IMemAllocator>(CLSID_MemoryAllocator))) { + ALLOCATOR_PROPERTIES properties; + if (memPin->GetAllocatorRequirements(&properties) == S_OK + || m_allocator->GetProperties(&properties) == S_OK) { + if (properties.cbAlign == 0) + properties.cbAlign = 1; + + ALLOCATOR_PROPERTIES actualProperties; + if (SUCCEEDED(hr = m_allocator->SetProperties(&properties, &actualProperties))) + hr = memPin->NotifyAllocator(m_allocator, TRUE); + } + if (!SUCCEEDED(hr)) { + m_allocator->Release(); + m_allocator = 0; + } + } + memPin->Release(); + } + if (!SUCCEEDED(hr)) + pin->Disconnect(); + } + return hr; +} + +HRESULT DirectShowIOSource::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) +{ + Q_UNUSED(pConnector); + Q_UNUSED(pmt); + // Output pin. + return E_NOTIMPL; +} + +HRESULT DirectShowIOSource::Disconnect() +{ + if (!m_peerPin) { + return S_FALSE; + } else if (m_state != State_Stopped) { + return VFW_E_NOT_STOPPED; + } else { + HRESULT hr = m_peerPin->Disconnect(); + + if (!SUCCEEDED(hr)) + return hr; + + if (m_allocator) { + m_allocator->Release(); + m_allocator = 0; + } + + m_peerPin->Release(); + m_peerPin = 0; + + m_mediaType.clear(); + + return S_OK; + } +} + +HRESULT DirectShowIOSource::ConnectedTo(IPin **ppPin) +{ + if (!ppPin) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + if (!m_peerPin) { + *ppPin = 0; + + return VFW_E_NOT_CONNECTED; + } else { + m_peerPin->AddRef(); + + *ppPin = m_peerPin; + + return S_OK; + } + } +} + +HRESULT DirectShowIOSource::ConnectionMediaType(AM_MEDIA_TYPE *pmt) +{ + if (!pmt) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + if (!m_peerPin) { + pmt = 0; + + return VFW_E_NOT_CONNECTED; + } else { + DirectShowMediaType::copy(pmt, m_mediaType); + + return S_OK; + } + } +} + +HRESULT DirectShowIOSource::QueryPinInfo(PIN_INFO *pInfo) +{ + if (!pInfo) { + return E_POINTER; + } else { + AddRef(); + + pInfo->pFilter = this; + pInfo->dir = PINDIR_OUTPUT; + + const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2); + + qMemCopy(pInfo->achName, m_pinId.utf16(), bytes); + + return S_OK; + } +} + +HRESULT DirectShowIOSource::QueryId(LPWSTR *Id) +{ + if (!Id) { + return E_POINTER; + } else { + const int bytes = (m_pinId.length() + 1) * 2; + + *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); + + qMemCopy(*Id, m_pinId.utf16(), bytes); + + return S_OK; + } +} + +HRESULT DirectShowIOSource::QueryAccept(const AM_MEDIA_TYPE *pmt) +{ + if (!pmt) { + return E_POINTER; + } else if (pmt->majortype == MEDIATYPE_Stream) { + return S_OK; + } else { + return S_FALSE; + } +} + +HRESULT DirectShowIOSource::EnumMediaTypes(IEnumMediaTypes **ppEnum) +{ + if (!ppEnum) { + return E_POINTER; + } else { + *ppEnum = createMediaTypeEnum(); + + return S_OK; + } +} + +HRESULT DirectShowIOSource::QueryInternalConnections(IPin **apPin, ULONG *nPin) +{ + Q_UNUSED(apPin); + Q_UNUSED(nPin); + + return E_NOTIMPL; +} + +HRESULT DirectShowIOSource::EndOfStream() +{ + return S_OK; +} + +HRESULT DirectShowIOSource::BeginFlush() +{ + return m_reader->BeginFlush(); +} + +HRESULT DirectShowIOSource::EndFlush() +{ + return m_reader->EndFlush(); +} + +HRESULT DirectShowIOSource::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ + Q_UNUSED(tStart); + Q_UNUSED(tStop); + Q_UNUSED(dRate); + + return S_OK; +} + +HRESULT DirectShowIOSource::QueryDirection(PIN_DIRECTION *pPinDir) +{ + if (!pPinDir) { + return E_POINTER; + } else { + *pPinDir = PINDIR_OUTPUT; + + return S_OK; + } +} + +QT_END_NAMESPACE + +DirectShowRcSource::DirectShowRcSource(DirectShowEventLoop *loop) + : DirectShowIOSource(loop) +{ +} + +bool DirectShowRcSource::open(const QUrl &url) +{ + m_file.moveToThread(QCoreApplication::instance()->thread()); + + m_file.setFileName(QLatin1Char(':') + url.path()); + + qDebug("qrc file %s", qPrintable(m_file.fileName())); + + if (m_file.open(QIODevice::ReadOnly)) { + qDebug("Size %d", m_file.size()); + qDebug("Sequential %d", int(m_file.isSequential())); + + setDevice(&m_file); + + return true; + } else { + return false; + } +} diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowiosource.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowiosource.h new file mode 100644 index 0000000..b626473 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowiosource.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWIOSOURCE_H +#define DIRECTSHOWIOSOURCE_H + +#include "directshowioreader.h" +#include "directshowmediatype.h" +#include "directshowmediatypelist.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +#include <QtCore/qfile.h> + +class DirectShowIOSource + : public DirectShowMediaTypeList + , public IBaseFilter + , public IAMFilterMiscFlags + , public IPin +{ +public: + DirectShowIOSource(DirectShowEventLoop *loop); + ~DirectShowIOSource(); + + void setDevice(QIODevice *device); + void setAllocator(IMemAllocator *allocator); + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + // IPersist + HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID); + + // IMediaFilter + HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart); + HRESULT STDMETHODCALLTYPE Pause(); + HRESULT STDMETHODCALLTYPE Stop(); + + HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState); + + HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock); + HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **ppClock); + + // IBaseFilter + HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum); + HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin); + + HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); + + HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo); + HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo); + + // IAMFilterMiscFlags + ULONG STDMETHODCALLTYPE GetMiscFlags(); + + // IPin + HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE Disconnect(); + HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **ppPin); + + HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt); + + HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo); + HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id); + + HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt); + + HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum); + + HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin); + + HRESULT STDMETHODCALLTYPE EndOfStream(); + + HRESULT STDMETHODCALLTYPE BeginFlush(); + HRESULT STDMETHODCALLTYPE EndFlush(); + + HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + + HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir); + +private: + HRESULT tryConnect(IPin *pin, const AM_MEDIA_TYPE *type); + + volatile LONG m_ref; + FILTER_STATE m_state; + DirectShowIOReader *m_reader; + DirectShowEventLoop *m_loop; + IFilterGraph *m_graph; + IReferenceClock *m_clock; + IMemAllocator *m_allocator; + IPin *m_peerPin; + DirectShowMediaType m_mediaType; + QString m_filterName; + const QString m_pinId; + QMutex m_mutex; +}; + +class DirectShowRcSource : public DirectShowIOSource +{ +public: + DirectShowRcSource(DirectShowEventLoop *loop); + + bool open(const QUrl &url); + +private: + QFile m_file; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatype.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatype.cpp new file mode 100644 index 0000000..f719b29 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatype.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowmediatype.h" + + +QT_BEGIN_NAMESPACE + +namespace +{ + struct TypeLookup + { + QVideoFrame::PixelFormat pixelFormat; + GUID mediaType; + }; + + static const TypeLookup qt_typeLookup[] = + { + { QVideoFrame::Format_RGB32, MEDIASUBTYPE_RGB32 }, + { QVideoFrame::Format_BGR24, MEDIASUBTYPE_RGB24 }, + { QVideoFrame::Format_RGB565, MEDIASUBTYPE_RGB565 }, + { QVideoFrame::Format_RGB555, MEDIASUBTYPE_RGB555 }, + { QVideoFrame::Format_AYUV444, MEDIASUBTYPE_AYUV }, + { QVideoFrame::Format_YUYV, MEDIASUBTYPE_YUY2 }, + { QVideoFrame::Format_UYVY, MEDIASUBTYPE_UYVY }, + { QVideoFrame::Format_IMC1, MEDIASUBTYPE_IMC1 }, + { QVideoFrame::Format_IMC2, MEDIASUBTYPE_IMC2 }, + { QVideoFrame::Format_IMC3, MEDIASUBTYPE_IMC3 }, + { QVideoFrame::Format_IMC4, MEDIASUBTYPE_IMC4 }, + { QVideoFrame::Format_YV12, MEDIASUBTYPE_YV12 }, + { QVideoFrame::Format_NV12, MEDIASUBTYPE_NV12 }, + { QVideoFrame::Format_YUV420P, MEDIASUBTYPE_IYUV } + }; +} + +void DirectShowMediaType::copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE &source) +{ + *target = source; + + if (source.cbFormat > 0) { + target->pbFormat = reinterpret_cast<PBYTE>(CoTaskMemAlloc(source.cbFormat)); + memcpy(target->pbFormat, source.pbFormat, source.cbFormat); + } + if (target->pUnk) + target->pUnk->AddRef(); +} + +void DirectShowMediaType::deleteType(AM_MEDIA_TYPE *type) +{ + freeData(type); + + CoTaskMemFree(type); +} + +void DirectShowMediaType::freeData(AM_MEDIA_TYPE *type) +{ + if (type->cbFormat > 0) + CoTaskMemFree(type->pbFormat); + + if (type->pUnk) + type->pUnk->Release(); +} + + +GUID DirectShowMediaType::convertPixelFormat(QVideoFrame::PixelFormat format) +{ + const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); + + for (int i = 0; i < count; ++i) + if (qt_typeLookup[i].pixelFormat == format) + return qt_typeLookup[i].mediaType; + return MEDIASUBTYPE_None; +} + +QVideoSurfaceFormat DirectShowMediaType::formatFromType(const AM_MEDIA_TYPE &type) +{ + const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); + + for (int i = 0; i < count; ++i) { + if (IsEqualGUID(qt_typeLookup[i].mediaType, type.subtype) && type.cbFormat > 0) { + if (IsEqualGUID(type.formattype, FORMAT_VideoInfo)) { + VIDEOINFOHEADER *header = reinterpret_cast<VIDEOINFOHEADER *>(type.pbFormat); + + QVideoSurfaceFormat format( + QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), + qt_typeLookup[i].pixelFormat); + + if (header->AvgTimePerFrame > 0) + format.setFrameRate(10000 /header->AvgTimePerFrame); + + format.setScanLineDirection(header->bmiHeader.biHeight < 0 + ? QVideoSurfaceFormat::TopToBottom + : QVideoSurfaceFormat::BottomToTop); + + return format; + } else if (IsEqualGUID(type.formattype, FORMAT_VideoInfo2)) { + VIDEOINFOHEADER2 *header = reinterpret_cast<VIDEOINFOHEADER2 *>(type.pbFormat); + + QVideoSurfaceFormat format( + QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), + qt_typeLookup[i].pixelFormat); + + if (header->AvgTimePerFrame > 0) + format.setFrameRate(10000 / header->AvgTimePerFrame); + + format.setScanLineDirection(header->bmiHeader.biHeight < 0 + ? QVideoSurfaceFormat::TopToBottom + : QVideoSurfaceFormat::BottomToTop); + + return format; + } + } + } + return QVideoSurfaceFormat(); +} + +int DirectShowMediaType::bytesPerLine(const QVideoSurfaceFormat &format) +{ + switch (format.pixelFormat()) { + // 32 bpp packed formats. + case QVideoFrame::Format_RGB32: + case QVideoFrame::Format_AYUV444: + return format.frameWidth() * 4; + // 24 bpp packed formats. + case QVideoFrame::Format_RGB24: + return format.frameWidth() * 3 + 3 - format.frameWidth() % 4; + // 16 bpp packed formats. + case QVideoFrame::Format_RGB565: + case QVideoFrame::Format_RGB555: + case QVideoFrame::Format_YUYV: + case QVideoFrame::Format_UYVY: + return format.frameWidth() * 2 + 3 - format.frameWidth() % 4; + // Planar formats. + case QVideoFrame::Format_IMC1: + case QVideoFrame::Format_IMC2: + case QVideoFrame::Format_IMC3: + case QVideoFrame::Format_IMC4: + case QVideoFrame::Format_YV12: + case QVideoFrame::Format_NV12: + case QVideoFrame::Format_YUV420P: + return format.frameWidth() + 3 - format.frameWidth() % 4; + default: + return 0; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatype.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatype.h new file mode 100644 index 0000000..3cc7307 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatype.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWMEDIATYPE_H +#define DIRECTSHOWMEDIATYPE_H + +#include <QtMultimedia/qvideosurfaceformat.h> + +#include <dshow.h> +#include <dvdmedia.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class DirectShowMediaType : public AM_MEDIA_TYPE +{ +public: + DirectShowMediaType() { memset(this, 0, sizeof(DirectShowMediaType)); } + DirectShowMediaType(const AM_MEDIA_TYPE &type) { copy(this, type); } + DirectShowMediaType(const DirectShowMediaType &other) { copy(this, other); } + DirectShowMediaType &operator =(const AM_MEDIA_TYPE &type) { + freeData(this); copy(this, type); return *this; } + DirectShowMediaType &operator =(const DirectShowMediaType &other) { + freeData(this); copy(this, other); return *this; } + ~DirectShowMediaType() { freeData(this); } + + void clear() { freeData(this); memset(this, 0, sizeof(DirectShowMediaType)); } + + static void copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE &source); + static void freeData(AM_MEDIA_TYPE *type); + static void deleteType(AM_MEDIA_TYPE *type); + + static GUID convertPixelFormat(QVideoFrame::PixelFormat format); + static QVideoSurfaceFormat formatFromType(const AM_MEDIA_TYPE &type); + + static int bytesPerLine(const QVideoSurfaceFormat &format); +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatypelist.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatypelist.cpp new file mode 100644 index 0000000..f67794a --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatypelist.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowmediatypelist.h" + +#include "directshowmediatype.h" +#include "videosurfacefilter.h" + + +QT_BEGIN_NAMESPACE + +class DirectShowMediaTypeEnum : public IEnumMediaTypes +{ +public: + DirectShowMediaTypeEnum(DirectShowMediaTypeList *list, int token, int index = 0); + ~DirectShowMediaTypeEnum(); + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + // IEnumMediaTypes + HRESULT STDMETHODCALLTYPE Next( + ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched); + HRESULT STDMETHODCALLTYPE Skip(ULONG cMediaTypes); + HRESULT STDMETHODCALLTYPE Reset(); + + HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes **ppEnum); + +private: + LONG m_ref; + DirectShowMediaTypeList *m_list; + int m_mediaTypeToken; + int m_index; +}; + + +DirectShowMediaTypeEnum::DirectShowMediaTypeEnum( + DirectShowMediaTypeList *list, int token, int index) + : m_ref(1) + , m_list(list) + , m_mediaTypeToken(token) + , m_index(index) +{ + m_list->AddRef(); +} + +DirectShowMediaTypeEnum::~DirectShowMediaTypeEnum() +{ + m_list->Release(); +} + +HRESULT DirectShowMediaTypeEnum::QueryInterface(REFIID riid, void **ppvObject) +{ + if (!ppvObject) { + return E_POINTER; + } else if (riid == IID_IUnknown + || riid == IID_IEnumMediaTypes) { + *ppvObject = static_cast<IEnumMediaTypes *>(this); + } else { + *ppvObject = 0; + + return E_NOINTERFACE; + } + + AddRef(); + + return S_OK; +} + +ULONG DirectShowMediaTypeEnum::AddRef() +{ + return InterlockedIncrement(&m_ref); +} + +ULONG DirectShowMediaTypeEnum::Release() +{ + ULONG ref = InterlockedDecrement(&m_ref); + + if (ref == 0) { + delete this; + } + + return ref; +} + +HRESULT DirectShowMediaTypeEnum::Next( + ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched) +{ + return m_list->nextMediaType(m_mediaTypeToken, &m_index, cMediaTypes, ppMediaTypes, pcFetched); +} + +HRESULT DirectShowMediaTypeEnum::Skip(ULONG cMediaTypes) +{ + return m_list->skipMediaType(m_mediaTypeToken, &m_index, cMediaTypes); +} + +HRESULT DirectShowMediaTypeEnum::Reset() +{ + m_mediaTypeToken = m_list->currentMediaTypeToken(); + m_index = 0; + + return S_OK; +} + +HRESULT DirectShowMediaTypeEnum::Clone(IEnumMediaTypes **ppEnum) +{ + return m_list->cloneMediaType(m_mediaTypeToken, m_index, ppEnum); +} + + +DirectShowMediaTypeList::DirectShowMediaTypeList() + : m_mediaTypeToken(0) +{ +} + +IEnumMediaTypes *DirectShowMediaTypeList::createMediaTypeEnum() +{ + return new DirectShowMediaTypeEnum(this, m_mediaTypeToken, 0); +} + + +void DirectShowMediaTypeList::setMediaTypes(const QVector<AM_MEDIA_TYPE> &types) +{ + ++m_mediaTypeToken; + + m_mediaTypes = types; +} + + +int DirectShowMediaTypeList::currentMediaTypeToken() +{ + return m_mediaTypeToken; +} + +HRESULT DirectShowMediaTypeList::nextMediaType( + int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount) +{ + if (!types || (count != 1 && !fetchedCount)) { + return E_POINTER; + } else if (m_mediaTypeToken != token) { + return VFW_E_ENUM_OUT_OF_SYNC; + } else { + int boundedCount = qBound<int>(0, count, m_mediaTypes.count() - *index); + + for (int i = 0; i < boundedCount; ++i, ++(*index)) { + types[i] = reinterpret_cast<AM_MEDIA_TYPE *>(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); + + if (types[i]) { + DirectShowMediaType::copy(types[i], m_mediaTypes.at(*index)); + } else { + for (--i; i >= 0; --i) + CoTaskMemFree(types[i]); + + if (fetchedCount) + *fetchedCount = 0; + + return E_OUTOFMEMORY; + } + } + if (fetchedCount) + *fetchedCount = boundedCount; + + return boundedCount == count ? S_OK : S_FALSE; + } +} + +HRESULT DirectShowMediaTypeList::skipMediaType(int token, int *index, ULONG count) +{ + if (m_mediaTypeToken != token) { + return VFW_E_ENUM_OUT_OF_SYNC; + } else { + *index = qMin<int>(*index + count, m_mediaTypes.size()); + + return *index < m_mediaTypes.size() ? S_OK : S_FALSE; + } +} + +HRESULT DirectShowMediaTypeList::cloneMediaType(int token, int index, IEnumMediaTypes **enumeration) +{ + if (m_mediaTypeToken != token) { + return VFW_E_ENUM_OUT_OF_SYNC; + } else { + *enumeration = new DirectShowMediaTypeEnum(this, token, index); + + return S_OK; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatypelist.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatypelist.h new file mode 100644 index 0000000..b49f24c --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowmediatypelist.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWMEDIATYPELIST_H +#define DIRECTSHOWMEDIATYPELIST_H + +#include <QtCore/qvector.h> + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowMediaTypeList : public IUnknown +{ +public: + DirectShowMediaTypeList(); + + IEnumMediaTypes *createMediaTypeEnum(); + + void setMediaTypes(const QVector<AM_MEDIA_TYPE> &types); + + virtual int currentMediaTypeToken(); + virtual HRESULT nextMediaType( + int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount); + virtual HRESULT skipMediaType(int token, int *index, ULONG count); + virtual HRESULT cloneMediaType(int token, int index, IEnumMediaTypes **enumeration); + +private: + int m_mediaTypeToken; + QVector<AM_MEDIA_TYPE> m_mediaTypes; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowmetadatacontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowmetadatacontrol.cpp new file mode 100644 index 0000000..7b2552f --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowmetadatacontrol.cpp @@ -0,0 +1,370 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <dshow.h> +#include <initguid.h> +#include <qnetwork.h> + +#include "directshowmetadatacontrol.h" + +#include "directshowplayerservice.h" + +#include <QtCore/qcoreapplication.h> + + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_WMSDK +namespace +{ + struct QWMMetaDataKeyLookup + { + QtMultimedia::MetaData key; + const wchar_t *token; + }; +} + +static const QWMMetaDataKeyLookup qt_wmMetaDataKeys[] = +{ + { QtMultimedia::Title, L"Title" }, + { QtMultimedia::SubTitle, L"WM/SubTitle" }, + { QtMultimedia::Author, L"Author" }, + { QtMultimedia::Comment, L"Comment" }, + { QtMultimedia::Description, L"Description" }, + { QtMultimedia::Category, L"WM/Category" }, + { QtMultimedia::Genre, L"WM/Genre" }, + //{ QtMultimedia::Date, 0 }, + { QtMultimedia::Year, L"WM/Year" }, + { QtMultimedia::UserRating, L"UserRating" }, + //{ QtMultimedia::MetaDatawords, 0 }, + { QtMultimedia::Language, L"Language" }, + { QtMultimedia::Publisher, L"WM/Publisher" }, + { QtMultimedia::Copyright, L"Copyright" }, + { QtMultimedia::ParentalRating, L"ParentalRating" }, + { QtMultimedia::RatingOrganisation, L"RatingOrganisation" }, + + // Media + { QtMultimedia::Size, L"FileSize" }, + { QtMultimedia::MediaType, L"MediaType" }, + { QtMultimedia::Duration, L"Duration" }, + + // Audio + { QtMultimedia::AudioBitRate, L"AudioBitRate" }, + { QtMultimedia::AudioCodec, L"AudioCodec" }, + { QtMultimedia::ChannelCount, L"ChannelCount" }, + { QtMultimedia::SampleRate, L"Frequency" }, + + // Music + { QtMultimedia::AlbumTitle, L"WM/AlbumTitle" }, + { QtMultimedia::AlbumArtist, L"WM/AlbumArtist" }, + { QtMultimedia::ContributingArtist, L"Author" }, + { QtMultimedia::Composer, L"WM/Composer" }, + { QtMultimedia::Conductor, L"WM/Conductor" }, + { QtMultimedia::Lyrics, L"WM/Lyrics" }, + { QtMultimedia::Mood, L"WM/Mood" }, + { QtMultimedia::TrackNumber, L"WM/TrackNumber" }, + //{ QtMultimedia::TrackCount, 0 }, + //{ QtMultimedia::CoverArtUriSmall, 0 }, + //{ QtMultimedia::CoverArtUriLarge, 0 }, + + // Image/Video + //{ QtMultimedia::Resolution, 0 }, + //{ QtMultimedia::PixelAspectRatio, 0 }, + + // Video + //{ QtMultimedia::FrameRate, 0 }, + { QtMultimedia::VideoBitRate, L"VideoBitRate" }, + { QtMultimedia::VideoCodec, L"VideoCodec" }, + + //{ QtMultimedia::PosterUri, 0 }, + + // Movie + { QtMultimedia::ChapterNumber, L"ChapterNumber" }, + { QtMultimedia::Director, L"WM/Director" }, + { QtMultimedia::LeadPerformer, L"LeadPerformer" }, + { QtMultimedia::Writer, L"WM/Writer" }, + + // Photos + { QtMultimedia::CameraManufacturer, L"CameraManufacturer" }, + { QtMultimedia::CameraModel, L"CameraModel" }, + { QtMultimedia::Event, L"Event" }, + { QtMultimedia::Subject, L"Subject" } +}; + +static QVariant getValue(IWMHeaderInfo *header, const wchar_t *key) +{ + WORD streamNumber = 0; + WMT_ATTR_DATATYPE type = WMT_TYPE_DWORD; + WORD size = 0; + + if (header->GetAttributeByName(&streamNumber, key, &type, 0, &size) == S_OK) { + switch (type) { + case WMT_TYPE_DWORD: + if (size == sizeof(DWORD)) { + DWORD word; + if (header->GetAttributeByName( + &streamNumber, + key, + &type, + reinterpret_cast<BYTE *>(&word), + &size) == S_OK) { + return int(word); + } + } + break; + case WMT_TYPE_STRING: + { + QString string; + string.resize(size / 2 - 1); + + if (header->GetAttributeByName( + &streamNumber, + key, + &type, + reinterpret_cast<BYTE *>(const_cast<ushort *>(string.utf16())), + &size) == S_OK) { + return string; + } + } + break; + case WMT_TYPE_BINARY: + { + QByteArray bytes; + bytes.resize(size); + if (header->GetAttributeByName( + &streamNumber, + key, + &type, + reinterpret_cast<BYTE *>(bytes.data()), + &size) == S_OK) { + return bytes; + } + } + break; + case WMT_TYPE_BOOL: + if (size == sizeof(DWORD)) { + DWORD word; + if (header->GetAttributeByName( + &streamNumber, + key, + &type, + reinterpret_cast<BYTE *>(&word), + &size) == S_OK) { + return bool(word); + } + } + break; + case WMT_TYPE_QWORD: + if (size == sizeof(QWORD)) { + QWORD word; + if (header->GetAttributeByName( + &streamNumber, + key, + &type, + reinterpret_cast<BYTE *>(&word), + &size) == S_OK) { + return qint64(word); + } + } + break; + case WMT_TYPE_WORD: + if (size == sizeof(WORD)){ + WORD word; + if (header->GetAttributeByName( + &streamNumber, + key, + &type, + reinterpret_cast<BYTE *>(&word), + &size) == S_OK) { + return short(word); + } + } + break; + case WMT_TYPE_GUID: + if (size == 16) { + } + break; + default: + break; + } + } + return QVariant(); +} +#endif + +DirectShowMetaDataControl::DirectShowMetaDataControl(QObject *parent) + : QMetaDataControl(parent) + , m_content(0) +#ifndef QT_NO_WMSDK + , m_headerInfo(0) +#endif +{ +} + +DirectShowMetaDataControl::~DirectShowMetaDataControl() +{ +} + +bool DirectShowMetaDataControl::isWritable() const +{ + return false; +} + +bool DirectShowMetaDataControl::isMetaDataAvailable() const +{ +#ifndef QT_NO_WMSDK + return m_content || m_headerInfo; +#else + return m_content; +#endif +} + +QVariant DirectShowMetaDataControl::metaData(QtMultimedia::MetaData key) const +{ + QVariant value; + +#ifndef QT_NO_WMSDK + if (m_headerInfo) { + static const int count = sizeof(qt_wmMetaDataKeys) / sizeof(QWMMetaDataKeyLookup); + for (int i = 0; i < count; ++i) { + if (qt_wmMetaDataKeys[i].key == key) { + value = getValue(m_headerInfo, qt_wmMetaDataKeys[i].token); + break; + } + } + } else if (m_content) { +#else + if (m_content) { +#endif + BSTR string = 0; + + switch (key) { + case QtMultimedia::Author: + m_content->get_AuthorName(&string); + break; + case QtMultimedia::Title: + m_content->get_Title(&string); + break; + case QtMultimedia::ParentalRating: + m_content->get_Rating(&string); + break; + case QtMultimedia::Description: + m_content->get_Description(&string); + break; + case QtMultimedia::Copyright: + m_content->get_Copyright(&string); + break; + default: + break; + } + + if (string) { + value = QString::fromUtf16(string, ::SysStringLen(string)); + + ::SysFreeString(string); + } + } + return value; +} + +void DirectShowMetaDataControl::setMetaData(QtMultimedia::MetaData, const QVariant &) +{ +} + +QList<QtMultimedia::MetaData> DirectShowMetaDataControl::availableMetaData() const +{ + return QList<QtMultimedia::MetaData>(); +} + +QVariant DirectShowMetaDataControl::extendedMetaData(const QString &) const +{ + return QVariant(); +} + +void DirectShowMetaDataControl::setExtendedMetaData(const QString &, const QVariant &) +{ +} + +QStringList DirectShowMetaDataControl::availableExtendedMetaData() const +{ + return QStringList(); +} + +void DirectShowMetaDataControl::updateGraph(IFilterGraph2 *graph, IBaseFilter *source) +{ + if (m_content) + m_content->Release(); + + if (!graph || graph->QueryInterface( + IID_IAMMediaContent, reinterpret_cast<void **>(&m_content)) != S_OK) { + m_content = 0; + } + +#ifdef QT_NO_WMSDK + Q_UNUSED(source); +#else + if (m_headerInfo) + m_headerInfo->Release(); + + m_headerInfo = com_cast<IWMHeaderInfo>(source); +#endif + // DirectShowMediaPlayerService holds a lock at this point so defer emitting signals to a later + // time. + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(MetaDataChanged))); +} + +void DirectShowMetaDataControl::customEvent(QEvent *event) +{ + if (event->type() == QEvent::Type(MetaDataChanged)) { + event->accept(); + + emit metaDataChanged(); +#ifndef QT_NO_WMSDK + emit metaDataAvailableChanged(m_content || m_headerInfo); +#else + emit metaDataAvailableChanged(m_content); +#endif + } else { + QMetaDataControl::customEvent(event); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowmetadatacontrol.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowmetadatacontrol.h new file mode 100644 index 0000000..966f9b8 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowmetadatacontrol.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWMETADATACONTROL_H +#define DIRECTSHOWMETADATACONTROL_H + +#include <QtMultimedia/qmetadatacontrol.h> + +#include <dshow.h> +#include <qnetwork.h> + +#ifndef QT_NO_WMSDK +#include <wmsdk.h> +#endif + +#include <QtCore/qcoreevent.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowPlayerService; + + +class DirectShowMetaDataControl : public QMetaDataControl +{ + Q_OBJECT +public: + DirectShowMetaDataControl(QObject *parent = 0); + ~DirectShowMetaDataControl(); + + bool isWritable() const; + bool isMetaDataAvailable() const; + + QVariant metaData(QtMultimedia::MetaData key) const; + void setMetaData(QtMultimedia::MetaData key, const QVariant &value); + QList<QtMultimedia::MetaData> availableMetaData() const; + + QVariant extendedMetaData(const QString &key) const; + void setExtendedMetaData(const QString &key, const QVariant &value); + QStringList availableExtendedMetaData() const; + + void updateGraph(IFilterGraph2 *graph, IBaseFilter *source); + +protected: + void customEvent(QEvent *event); + +private: + enum Event + { + MetaDataChanged = QEvent::User + }; + + IAMMediaContent *m_content; +#ifndef QT_NO_WMSDK + IWMHeaderInfo *m_headerInfo; +#endif +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowpinenum.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowpinenum.cpp new file mode 100644 index 0000000..19f65da --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowpinenum.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowpinenum.h" + +#include <QtMultimedia> + + +QT_BEGIN_NAMESPACE + +DirectShowPinEnum::DirectShowPinEnum(const QList<IPin *> &pins) + : m_ref(1) + , m_pins(pins) + , m_index(0) +{ + foreach (IPin *pin, m_pins) + pin->AddRef(); +} + +DirectShowPinEnum::~DirectShowPinEnum() +{ + foreach (IPin *pin, m_pins) + pin->Release(); +} + +HRESULT DirectShowPinEnum::QueryInterface(REFIID riid, void **ppvObject) +{ + if (riid == IID_IUnknown + || riid == IID_IEnumPins) { + AddRef(); + + *ppvObject = static_cast<IEnumPins *>(this); + + return S_OK; + } else { + *ppvObject = 0; + + return E_NOINTERFACE; + } +} + +ULONG DirectShowPinEnum::AddRef() +{ + return InterlockedIncrement(&m_ref); +} + +ULONG DirectShowPinEnum::Release() +{ + ULONG ref = InterlockedDecrement(&m_ref); + + if (ref == 0) { + delete this; + } + + return ref; +} + +HRESULT DirectShowPinEnum::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched) +{ + if (ppPins && (pcFetched || cPins == 1)) { + ULONG count = qBound<ULONG>(0, cPins, m_pins.count() - m_index); + + for (ULONG i = 0; i < count; ++i, ++m_index) { + ppPins[i] = m_pins.at(m_index); + ppPins[i]->AddRef(); + } + + if (pcFetched) + *pcFetched = count; + + return count == cPins ? S_OK : S_FALSE; + } else { + return E_POINTER; + } +} + +HRESULT DirectShowPinEnum::Skip(ULONG cPins) +{ + m_index = qMin(int(m_index + cPins), m_pins.count()); + + return m_index < m_pins.count() ? S_OK : S_FALSE; +} + +HRESULT DirectShowPinEnum::Reset() +{ + m_index = 0; + + return S_OK; +} + +HRESULT DirectShowPinEnum::Clone(IEnumPins **ppEnum) +{ + if (ppEnum) { + *ppEnum = new DirectShowPinEnum(m_pins); + + return S_OK; + } else { + return E_POINTER; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowpinenum.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowpinenum.h new file mode 100644 index 0000000..40d99ea --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowpinenum.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWPINENUM_H +#define DIRECTSHOWPINENUM_H + +#include <QtCore/qlist.h> + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowPinEnum : public IEnumPins +{ +public: + DirectShowPinEnum(const QList<IPin *> &pins); + ~DirectShowPinEnum(); + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + // IEnumPins + HRESULT STDMETHODCALLTYPE Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched); + HRESULT STDMETHODCALLTYPE Skip(ULONG cPins); + HRESULT STDMETHODCALLTYPE Reset(); + HRESULT STDMETHODCALLTYPE Clone(IEnumPins **ppEnum); + +private: + LONG m_ref; + QList<IPin *> m_pins; + int m_index; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp new file mode 100644 index 0000000..b024557 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.cpp @@ -0,0 +1,395 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowplayercontrol.h" + +#include "directshowplayerservice.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qmath.h> + + +QT_BEGIN_NAMESPACE + +static int volumeToDecibels(int volume) +{ + if (volume == 0) { + return -10000; + } else if (volume == 100) { + return 0; +#ifdef QT_USE_MATH_H_FLOATS + } else if (sizeof(qreal) == sizeof(float)) { + return qRound(::log10f(float(volume) / 100) * 5000); +#endif + } else { + return qRound(::log10(qreal(volume) / 100) * 5000); + } +} + +static int decibelsToVolume(int dB) +{ + if (dB == -10000) { + return 0; + } else if (dB == 0) { + return 100; + } else { + return qRound(100 * qPow(10, qreal(dB) / 5000)); + } +} + +DirectShowPlayerControl::DirectShowPlayerControl(DirectShowPlayerService *service, QObject *parent) + : QMediaPlayerControl(parent) + , m_service(service) + , m_audio(0) + , m_updateProperties(0) + , m_state(QMediaPlayer::StoppedState) + , m_status(QMediaPlayer::UnknownMediaStatus) + , m_error(QMediaPlayer::NoError) + , m_streamTypes(0) + , m_muteVolume(-1) + , m_position(0) + , m_duration(0) + , m_playbackRate(0) + , m_seekable(false) +{ +} + +DirectShowPlayerControl::~DirectShowPlayerControl() +{ + if (m_audio) + m_audio->Release(); +} + +QMediaPlayer::State DirectShowPlayerControl::state() const +{ + return m_state; +} + +QMediaPlayer::MediaStatus DirectShowPlayerControl::mediaStatus() const +{ + return m_status; +} + +qint64 DirectShowPlayerControl::duration() const +{ + return m_duration; +} + +qint64 DirectShowPlayerControl::position() const +{ + return const_cast<qint64 &>(m_position) = m_service->position(); +} + +void DirectShowPlayerControl::setPosition(qint64 position) +{ + m_service->seek(position); +} + +int DirectShowPlayerControl::volume() const +{ + if (m_muteVolume >= 0) { + return m_muteVolume; + } else if (m_audio) { + long dB = 0; + + m_audio->get_Volume(&dB); + + return decibelsToVolume(dB); + } else { + return 0; + } +} + +void DirectShowPlayerControl::setVolume(int volume) +{ + int boundedVolume = qBound(0, volume, 100); + + if (m_muteVolume >= 0) { + m_muteVolume = boundedVolume; + + emit volumeChanged(m_muteVolume); + } else if (m_audio) { + m_audio->put_Volume(volumeToDecibels(volume)); + + emit volumeChanged(boundedVolume); + } +} + +bool DirectShowPlayerControl::isMuted() const +{ + return m_muteVolume >= 0; +} + +void DirectShowPlayerControl::setMuted(bool muted) +{ + if (muted && m_muteVolume < 0) { + if (m_audio) { + long dB = 0; + + m_audio->get_Volume(&dB); + + m_muteVolume = decibelsToVolume(dB); + + m_audio->put_Volume(-10000); + } else { + m_muteVolume = 0; + } + + emit mutedChanged(muted); + } else if (!muted && m_muteVolume >= 0) { + if (m_audio) { + m_audio->put_Volume(volumeToDecibels(m_muteVolume)); + } + m_muteVolume = -1; + + emit mutedChanged(muted); + } +} + +int DirectShowPlayerControl::bufferStatus() const +{ + return m_service->bufferStatus(); +} + +bool DirectShowPlayerControl::isAudioAvailable() const +{ + return m_streamTypes & DirectShowPlayerService::AudioStream; +} + +bool DirectShowPlayerControl::isVideoAvailable() const +{ + return m_streamTypes & DirectShowPlayerService::VideoStream; +} + +bool DirectShowPlayerControl::isSeekable() const +{ + return m_seekable; +} + +QMediaTimeRange DirectShowPlayerControl::availablePlaybackRanges() const +{ + return m_service->availablePlaybackRanges(); +} + +qreal DirectShowPlayerControl::playbackRate() const +{ + return m_playbackRate; +} + +void DirectShowPlayerControl::setPlaybackRate(qreal rate) +{ + if (m_playbackRate != rate) { + m_service->setRate(rate); + + emit playbackRateChanged(m_playbackRate = rate); + } +} + +QMediaContent DirectShowPlayerControl::media() const +{ + return m_media; +} + +const QIODevice *DirectShowPlayerControl::mediaStream() const +{ + return m_stream; +} + +void DirectShowPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream) +{ + m_media = media; + m_stream = stream; + + m_updateProperties &= PlaybackRateProperty; + + m_service->load(media, stream); + + emitPropertyChanges(); +} + +void DirectShowPlayerControl::play() +{ + m_service->play(); + emit stateChanged(m_state = QMediaPlayer::PlayingState); +} + +void DirectShowPlayerControl::pause() +{ + m_service->pause(); + emit stateChanged(m_state = QMediaPlayer::PausedState); +} + +void DirectShowPlayerControl::stop() +{ + m_service->stop(); + emit stateChanged(m_state = QMediaPlayer::StoppedState); +} + +void DirectShowPlayerControl::customEvent(QEvent *event) +{ + if (event->type() == QEvent::Type(PropertiesChanged)) { + emitPropertyChanges(); + + event->accept(); + } else { + QMediaPlayerControl::customEvent(event); + } +} + +void DirectShowPlayerControl::emitPropertyChanges() +{ + int properties = m_updateProperties; + m_updateProperties = 0; + + if ((properties & ErrorProperty) && m_error != QMediaPlayer::NoError) + emit error(m_error, m_errorString); + + if (properties & PlaybackRateProperty) + emit playbackRateChanged(m_playbackRate); + + if (properties & StreamTypesProperty) { + emit audioAvailableChanged(m_streamTypes & DirectShowPlayerService::AudioStream); + emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream); + } + + if (properties & PositionProperty) + emit positionChanged(m_position); + + if (properties & DurationProperty) + emit durationChanged(m_duration); + + if (properties & SeekableProperty) + emit seekableChanged(m_seekable); + + if (properties & StatusProperty) + emit mediaStatusChanged(m_status); + + if (properties & StateProperty) + emit stateChanged(m_state); +} + +void DirectShowPlayerControl::scheduleUpdate(int properties) +{ + if (m_updateProperties == 0) + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PropertiesChanged))); + + m_updateProperties |= properties; +} + +void DirectShowPlayerControl::updateState(QMediaPlayer::State state) +{ + if (m_state != state) { + m_state = state; + + scheduleUpdate(StateProperty); + } +} + +void DirectShowPlayerControl::updateStatus(QMediaPlayer::MediaStatus status) +{ + if (m_status != status) { + m_status = status; + + scheduleUpdate(StatusProperty); + } +} + +void DirectShowPlayerControl::updateMediaInfo(qint64 duration, int streamTypes, bool seekable) +{ + int properties = 0; + + if (m_duration != duration) { + m_duration = duration; + + properties |= DurationProperty; + } + if (m_streamTypes != streamTypes) { + m_streamTypes = streamTypes; + + properties |= StreamTypesProperty; + } + + if (m_seekable != seekable) { + m_seekable = seekable; + + properties |= SeekableProperty; + } + + if (properties != 0) + scheduleUpdate(properties); +} + +void DirectShowPlayerControl::updatePlaybackRate(qreal rate) +{ + if (m_playbackRate != rate) { + m_playbackRate = rate; + + scheduleUpdate(PlaybackRateProperty); + } +} + +void DirectShowPlayerControl::updateAudioOutput(IBaseFilter *filter) +{ + if (m_audio) + m_audio->Release(); + + m_audio = com_cast<IBasicAudio>(filter); +} + +void DirectShowPlayerControl::updateError(QMediaPlayer::Error error, const QString &errorString) +{ + m_error = error; + m_errorString = errorString; + + if (m_error != QMediaPlayer::NoError) + scheduleUpdate(ErrorProperty); +} + +void DirectShowPlayerControl::updatePosition(qint64 position) +{ + if (m_position != position) { + m_position = position; + + scheduleUpdate(PositionProperty); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h new file mode 100644 index 0000000..dd25d30 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayercontrol.h @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWPLAYERCONTROL_H +#define DIRECTSHOWPLAYERCONTROL_H + +#include <QtMultimedia/qmediacontent.h> +#include <QtMultimedia/qmediaplayercontrol.h> + +#include <QtCore/qcoreevent.h> + +#include "directshowplayerservice.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowPlayerControl : public QMediaPlayerControl +{ + Q_OBJECT +public: + DirectShowPlayerControl(DirectShowPlayerService *service, QObject *parent = 0); + ~DirectShowPlayerControl(); + + QMediaPlayer::State state() const; + + QMediaPlayer::MediaStatus mediaStatus() const; + + qint64 duration() const; + + qint64 position() const; + void setPosition(qint64 position); + + int volume() const; + void setVolume(int volume); + + bool isMuted() const; + void setMuted(bool muted); + + int bufferStatus() const; + + bool isAudioAvailable() const; + bool isVideoAvailable() const; + + bool isSeekable() const; + + QMediaTimeRange availablePlaybackRanges() const; + + qreal playbackRate() const; + void setPlaybackRate(qreal rate); + + QMediaContent media() const; + const QIODevice *mediaStream() const; + void setMedia(const QMediaContent &media, QIODevice *stream); + + void play(); + void pause(); + void stop(); + + void updateState(QMediaPlayer::State state); + void updateStatus(QMediaPlayer::MediaStatus status); + void updateMediaInfo(qint64 duration, int streamTypes, bool seekable); + void updatePlaybackRate(qreal rate); + void updateAudioOutput(IBaseFilter *filter); + void updateError(QMediaPlayer::Error error, const QString &errorString); + void updatePosition(qint64 position); + +protected: + void customEvent(QEvent *event); + +private: + enum Properties + { + StateProperty = 0x01, + StatusProperty = 0x02, + StreamTypesProperty = 0x04, + DurationProperty = 0x08, + PlaybackRateProperty = 0x10, + SeekableProperty = 0x20, + ErrorProperty = 0x40, + PositionProperty = 0x80 + }; + + enum Event + { + PropertiesChanged = QEvent::User + }; + + void scheduleUpdate(int properties); + void emitPropertyChanges(); + + DirectShowPlayerService *m_service; + IBasicAudio *m_audio; + QIODevice *m_stream; + int m_updateProperties; + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_status; + QMediaPlayer::Error m_error; + int m_streamTypes; + int m_muteVolume; + qint64 m_position; + qint64 m_duration; + qreal m_playbackRate; + bool m_seekable; + QMediaContent m_media; + QString m_errorString; + +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp new file mode 100644 index 0000000..57f4bec --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.cpp @@ -0,0 +1,1352 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowplayerservice.h" + +#include "directshowaudioendpointcontrol.h" +#include "directshowiosource.h" +#include "directshowmetadatacontrol.h" +#include "directshowplayercontrol.h" +#include "directshowvideooutputcontrol.h" +#include "directshowvideorenderercontrol.h" +#include "vmr9videowindowcontrol.h" + +#include <QtMultimedia/qmediacontent.h> + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qdatetime.h> +#include <QtCore/qthread.h> +#include <QtCore/qvarlengtharray.h> + +#include <uuids.h> + +Q_GLOBAL_STATIC(DirectShowEventLoop, qt_directShowEventLoop) + +QT_BEGIN_NAMESPACE + +class DirectShowPlayerServiceThread : public QThread +{ +public: + DirectShowPlayerServiceThread(DirectShowPlayerService *service) + : m_service(service) + { + } + +protected: + void run() { m_service->run(); } + +private: + DirectShowPlayerService *m_service; +}; + +DirectShowPlayerService::DirectShowPlayerService(QObject *parent) + : QMediaService(parent) + , m_playerControl(0) + , m_audioEndpointControl(0) + , m_metaDataControl(0) + , m_videoOutputControl(0) + , m_videoRendererControl(0) + , m_videoWindowControl(0) + , m_taskThread(0) + , m_loop(qt_directShowEventLoop()) + , m_pendingTasks(0) + , m_executingTask(0) + , m_executedTasks(0) + , m_taskHandle(::CreateEvent(0, 0, 0, 0)) + , m_eventHandle(0) + , m_graphStatus(NoMedia) + , m_stream(0) + , m_graph(0) + , m_source(0) + , m_audioOutput(0) + , m_videoOutput(0) + , m_rate(1.0) + , m_position(0) + , m_duration(0) + , m_buffering(false) + , m_seekable(false) + , m_atEnd(false) +{ + m_playerControl = new DirectShowPlayerControl(this); + m_metaDataControl = new DirectShowMetaDataControl(this); + m_videoOutputControl = new DirectShowVideoOutputControl; + m_audioEndpointControl = new DirectShowAudioEndpointControl(this); + m_videoRendererControl = new DirectShowVideoRendererControl(m_loop); + m_videoWindowControl = new Vmr9VideoWindowControl; + + m_taskThread = new DirectShowPlayerServiceThread(this); + m_taskThread->start(); + + connect(m_videoOutputControl, SIGNAL(outputChanged()), this, SLOT(videoOutputChanged())); + connect(m_videoRendererControl, SIGNAL(filterChanged()), this, SLOT(videoOutputChanged())); +} + +DirectShowPlayerService::~DirectShowPlayerService() +{ + { + QMutexLocker locker(&m_mutex); + + releaseGraph(); + + m_pendingTasks = Shutdown; + ::SetEvent(m_taskHandle); + } + + m_taskThread->wait(); + delete m_taskThread; + + if (m_audioOutput) { + m_audioOutput->Release(); + m_audioOutput = 0; + } + + if (m_videoOutput) { + m_videoOutput->Release(); + m_videoOutput = 0; + } + + delete m_playerControl; + delete m_audioEndpointControl; + delete m_metaDataControl; + delete m_videoOutputControl; + delete m_videoRendererControl; + delete m_videoWindowControl; + + ::CloseHandle(m_taskHandle); +} + +QMediaControl *DirectShowPlayerService::control(const char *name) const +{ + if (qstrcmp(name, QMediaPlayerControl_iid) == 0) + return m_playerControl; + else if (qstrcmp(name, QAudioEndpointSelector_iid) == 0) + return m_audioEndpointControl; + else if (qstrcmp(name, QMetaDataControl_iid) == 0) + return m_metaDataControl; + else if (qstrcmp(name, QVideoOutputControl_iid) == 0) + return m_videoOutputControl; + else if (qstrcmp(name, QVideoRendererControl_iid) == 0) + return m_videoRendererControl; + else if (qstrcmp(name, QVideoWindowControl_iid) == 0) + return m_videoWindowControl; + else + return 0; +} + +void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream) +{ + QMutexLocker locker(&m_mutex); + + m_pendingTasks = 0; + + if (m_graph) + releaseGraph(); + + m_resources = media.resources(); + m_stream = stream; + m_error = QMediaPlayer::NoError; + m_errorString = QString(); + m_position = 0; + m_duration = 0; + m_streamTypes = 0; + m_executedTasks = 0; + m_buffering = false; + m_seekable = false; + m_atEnd = false; + m_metaDataControl->updateGraph(0, 0); + + if (m_resources.isEmpty() && !stream) { + m_pendingTasks = 0; + m_graphStatus = NoMedia; + + m_url.clear(); + } else if (stream && (!stream->isReadable() || stream->isSequential())) { + m_pendingTasks = 0; + m_graphStatus = InvalidMedia; + m_error = QMediaPlayer::ResourceError; + } else { + m_graphStatus = Loading; + + m_graph = com_new<IFilterGraph2>(CLSID_FilterGraph); + + if (stream) + m_pendingTasks = SetStreamSource; + else + m_pendingTasks = SetUrlSource; + + ::SetEvent(m_taskHandle); + } + + m_playerControl->updateError(m_error, m_errorString); + m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); + m_playerControl->updateState(QMediaPlayer::StoppedState); + m_playerControl->updatePosition(m_position); + updateStatus(); +} + +void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) +{ + IBaseFilter *source = 0; + + QMediaResource resource = m_resources.takeFirst(); + QUrl url = resource.url(); + + HRESULT hr = E_FAIL; + +#ifndef QT_NO_WMSDK + if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("https")) { + if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(CLSID_WMAsfReader)) { + locker->unlock(); + hr = fileSource->Load(url.toString().utf16(), 0); + locker->relock(); + + if (SUCCEEDED(hr)) { + source = com_cast<IBaseFilter>(fileSource); + + if (!SUCCEEDED(hr = m_graph->AddFilter(source, L"Source")) && source) { + source->Release(); + source = 0; + } + } + + fileSource->Release(); + } + } else if (url.scheme() == QLatin1String("qrc")) { + DirectShowRcSource *rcSource = new DirectShowRcSource(m_loop); + + if (rcSource->open(url) && SUCCEEDED(hr = m_graph->AddFilter(rcSource, L"Source"))) + source = rcSource; + else + rcSource->Release(); + } + + if (!SUCCEEDED(hr)) { +#endif + locker->unlock(); + hr = m_graph->AddSourceFilter(url.toString().utf16(), L"Source", &source); + locker->relock(); +#ifndef QT_NO_WMSDK + } +#endif + + if (SUCCEEDED(hr)) { + m_executedTasks = SetSource; + m_pendingTasks |= Render; + + if (m_audioOutput) + m_pendingTasks |= SetAudioOutput; + if (m_videoOutput) + m_pendingTasks |= SetVideoOutput; + + if (m_rate != 1.0) + m_pendingTasks |= SetRate; + + m_source = source; + } else if (!m_resources.isEmpty()) { + m_pendingTasks |= SetUrlSource; + } else { + m_pendingTasks = 0; + m_graphStatus = InvalidMedia; + + switch (hr) { + case VFW_E_UNKNOWN_FILE_TYPE: + m_error = QMediaPlayer::FormatError; + m_errorString = QString(); + break; + case E_OUTOFMEMORY: + case VFW_E_CANNOT_LOAD_SOURCE_FILTER: + case VFW_E_NOT_FOUND: + m_error = QMediaPlayer::ResourceError; + m_errorString = QString(); + default: + m_error = QMediaPlayer::ResourceError; + m_errorString = QString(); + qWarning("DirectShowPlayerService::doSetUrlSource: Unresolved error code %x", hr); + break; + } + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); + } +} + +void DirectShowPlayerService::doSetStreamSource(QMutexLocker *locker) +{ + DirectShowIOSource *source = new DirectShowIOSource(m_loop); + source->setDevice(m_stream); + + if (SUCCEEDED(m_graph->AddFilter(source, L"Source"))) { + m_executedTasks = SetSource; + m_pendingTasks |= Render; + + if (m_audioOutput) + m_pendingTasks |= SetAudioOutput; + if (m_videoOutput) + m_pendingTasks |= SetVideoOutput; + + if (m_rate != 1.0) + m_pendingTasks |= SetRate; + + m_source = source; + } else { + source->Release(); + + m_pendingTasks = 0; + m_graphStatus = InvalidMedia; + + m_error = QMediaPlayer::ResourceError; + m_errorString = QString(); + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); + } +} + +void DirectShowPlayerService::doRender(QMutexLocker *locker) +{ + m_pendingTasks |= m_executedTasks & (Play | Pause); + + if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) { + control->Stop(); + control->Release(); + } + + if (m_pendingTasks & SetAudioOutput) { + m_graph->AddFilter(m_audioOutput, L"AudioOutput"); + + m_pendingTasks ^= SetAudioOutput; + m_executedTasks |= SetAudioOutput; + } + if (m_pendingTasks & SetVideoOutput) { + m_graph->AddFilter(m_videoOutput, L"VideoOutput"); + + m_pendingTasks ^= SetVideoOutput; + m_executedTasks |= SetVideoOutput; + } + + IFilterGraph2 *graph = m_graph; + graph->AddRef(); + + QVarLengthArray<IBaseFilter *, 16> filters; + m_source->AddRef(); + filters.append(m_source); + + bool rendered = false; + + HRESULT renderHr = S_OK; + + while (!filters.isEmpty()) { + IEnumPins *pins = 0; + IBaseFilter *filter = filters[filters.size() - 1]; + filters.removeLast(); + + if (!(m_pendingTasks & ReleaseFilters) && SUCCEEDED(filter->EnumPins(&pins))) { + int outputs = 0; + for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + PIN_DIRECTION direction; + if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { + ++outputs; + + IPin *peer = 0; + if (pin->ConnectedTo(&peer) == S_OK) { + PIN_INFO peerInfo; + if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) + filters.append(peerInfo.pFilter); + peer->Release(); + } else { + locker->unlock(); + HRESULT hr; + if (SUCCEEDED(hr = graph->RenderEx( + pin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, 0))) { + rendered = true; + } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){ + renderHr = hr; + } + locker->relock(); + } + } + } + + pins->Release(); + + if (outputs == 0) + rendered = true; + } + filter->Release(); + } + + if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) { + graph->RemoveFilter(m_audioOutput); + + m_executedTasks &= ~SetAudioOutput; + } + + if (m_videoOutput && !isConnected(m_videoOutput, PINDIR_INPUT)) { + graph->RemoveFilter(m_videoOutput); + + m_executedTasks &= ~SetVideoOutput; + } + + graph->Release(); + + if (!(m_pendingTasks & ReleaseFilters)) { + if (rendered) { + if (!(m_executedTasks & FinalizeLoad)) + m_pendingTasks |= FinalizeLoad; + } else { + m_pendingTasks = 0; + + m_graphStatus = InvalidMedia; + + if (!m_audioOutput && !m_videoOutput) { + m_error = QMediaPlayer::ResourceError; + m_errorString = QString(); + } else { + switch (renderHr) { + case VFW_E_UNSUPPORTED_AUDIO: + case VFW_E_UNSUPPORTED_VIDEO: + case VFW_E_UNSUPPORTED_STREAM: + m_error = QMediaPlayer::FormatError; + m_errorString = QString(); + default: + m_error = QMediaPlayer::ResourceError; + m_errorString = QString(); + qWarning("DirectShowPlayerService::doRender: Unresolved error code %x", + renderHr); + } + } + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); + } + + m_executedTasks |= Render; + } +} + +void DirectShowPlayerService::doFinalizeLoad(QMutexLocker *locker) +{ + if (m_graphStatus != Loaded) { + if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph)) { + event->GetEventHandle(reinterpret_cast<OAEVENT *>(&m_eventHandle)); + event->Release(); + } + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG duration = 0; + seeking->GetDuration(&duration); + m_duration = duration / 10; + + DWORD capabilities = 0; + seeking->GetCapabilities(&capabilities); + m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute; + + seeking->Release(); + } + } + + if ((m_executedTasks & SetOutputs) == SetOutputs) { + m_streamTypes = AudioStream | VideoStream; + } else { + m_streamTypes = findStreamTypes(m_source); + } + + m_executedTasks |= FinalizeLoad; + + m_graphStatus = Loaded; + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(FinalizedLoad))); +} + +void DirectShowPlayerService::releaseGraph() +{ + if (m_graph) { + if (m_executingTask != 0) { + if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>(m_graph)) { + progress->AbortOperation(); + progress->Release(); + } + m_graph->Abort(); + } + + m_pendingTasks = ReleaseGraph; + + ::SetEvent(m_taskHandle); + + m_loop->wait(&m_mutex); + } +} + +void DirectShowPlayerService::doReleaseGraph(QMutexLocker *locker) +{ + Q_UNUSED(locker); + + if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) { + control->Stop(); + control->Release(); + } + + if (m_source) { + m_source->Release(); + m_source = 0; + } + + m_eventHandle = 0; + + m_graph->Release(); + m_graph = 0; + + m_loop->wake(); +} + +int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const +{ + QVarLengthArray<IBaseFilter *, 16> filters; + source->AddRef(); + filters.append(source); + + int streamTypes = 0; + + while (!filters.isEmpty()) { + IEnumPins *pins = 0; + IBaseFilter *filter = filters[filters.size() - 1]; + filters.removeLast(); + + if (SUCCEEDED(filter->EnumPins(&pins))) { + for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + PIN_DIRECTION direction; + if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { + AM_MEDIA_TYPE connectionType; + if (SUCCEEDED(pin->ConnectionMediaType(&connectionType))) { + IPin *peer = 0; + + if (connectionType.majortype == MEDIATYPE_Audio) { + streamTypes |= AudioStream; + } else if (connectionType.majortype == MEDIATYPE_Video) { + streamTypes |= VideoStream; + } else if (SUCCEEDED(pin->ConnectedTo(&peer))) { + PIN_INFO peerInfo; + if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) + filters.append(peerInfo.pFilter); + peer->Release(); + } + } else { + streamTypes |= findStreamType(pin); + } + } + } + } + filter->Release(); + } + return streamTypes; +} + +int DirectShowPlayerService::findStreamType(IPin *pin) const +{ + IEnumMediaTypes *types; + + if (SUCCEEDED(pin->EnumMediaTypes(&types))) { + bool video = false; + bool audio = false; + bool other = false; + + for (AM_MEDIA_TYPE *type = 0; + types->Next(1, &type, 0) == S_OK; + DirectShowMediaType::deleteType(type)) { + if (type->majortype == MEDIATYPE_Audio) + audio = true; + else if (type->majortype == MEDIATYPE_Video) + video = true; + else + other = true; + } + types->Release(); + + if (other) + return 0; + else if (audio && !video) + return AudioStream; + else if (!audio && video) + return VideoStream; + else + return 0; + } else { + return 0; + } +} + +void DirectShowPlayerService::play() +{ + QMutexLocker locker(&m_mutex); + + m_pendingTasks &= ~Pause; + m_pendingTasks |= Play; + + if (m_executedTasks & Render) { + if (m_executedTasks & Stop) { + m_atEnd = false; + m_position = 0; + m_pendingTasks |= Seek; + m_executedTasks ^= Stop; + } + + ::SetEvent(m_taskHandle); + } +} + +void DirectShowPlayerService::doPlay(QMutexLocker *locker) +{ + if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) { + locker->unlock(); + HRESULT hr = control->Run(); + locker->relock(); + + control->Release(); + + if (SUCCEEDED(hr)) { + m_executedTasks |= Play; + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); + } else { + m_error = QMediaPlayer::ResourceError; + m_errorString = QString(); + qWarning("DirectShowPlayerService::doPlay: Unresolved error code %x", hr); + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); + } + } +} + +void DirectShowPlayerService::pause() +{ + QMutexLocker locker(&m_mutex); + + m_pendingTasks &= ~Play; + m_pendingTasks |= Pause; + + if (m_executedTasks & Render) { + if (m_executedTasks & Stop) { + m_atEnd = false; + m_position = 0; + m_pendingTasks |= Seek; + m_executedTasks ^= Stop; + } + + ::SetEvent(m_taskHandle); + } +} + +void DirectShowPlayerService::doPause(QMutexLocker *locker) +{ + if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) { + locker->unlock(); + HRESULT hr = control->Pause(); + locker->relock(); + + control->Release(); + + if (SUCCEEDED(hr)) { + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG position = 0; + + seeking->GetCurrentPosition(&position); + seeking->Release(); + + m_position = position / 10; + } else { + m_position = 0; + } + + m_executedTasks |= Pause; + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); + } else { + m_error = QMediaPlayer::ResourceError; + m_errorString = QString(); + qWarning("DirectShowPlayerService::doPause: Unresolved error code %x", hr); + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); + } + } +} + +void DirectShowPlayerService::stop() +{ + QMutexLocker locker(&m_mutex); + + m_pendingTasks &= ~(Play | Pause | Seek); + + if ((m_executingTask | m_executedTasks) & (Play | Pause | Seek)) { + m_pendingTasks |= Stop; + + ::SetEvent(m_taskHandle); + + m_loop->wait(&m_mutex); + } + +} + +void DirectShowPlayerService::doStop(QMutexLocker *locker) +{ + if (m_executedTasks & (Play | Pause)) { + if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) { + control->Stop(); + control->Release(); + } + + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG position = 0; + + seeking->GetCurrentPosition(&position); + seeking->Release(); + + m_position = position / 10; + } else { + m_position = 0; + } + + m_executedTasks &= ~(Play | Pause); + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); + } + + m_executedTasks |= Stop; + + m_loop->wake(); +} + +void DirectShowPlayerService::setRate(qreal rate) +{ + QMutexLocker locker(&m_mutex); + + m_rate = rate; + + m_pendingTasks |= SetRate; + + if (m_executedTasks & FinalizeLoad) + ::SetEvent(m_taskHandle); +} + +void DirectShowPlayerService::doSetRate(QMutexLocker *locker) +{ + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + // Cache current values as we can't query IMediaSeeking during a seek due to the + // possibility of a deadlock when flushing the VideoSurfaceFilter. + LONGLONG currentPosition = 0; + seeking->GetCurrentPosition(¤tPosition); + m_position = currentPosition / 10; + + LONGLONG minimum = 0; + LONGLONG maximum = 0; + m_playbackRange = SUCCEEDED(seeking->GetAvailable(&minimum, &maximum)) + ? QMediaTimeRange(minimum / 10, maximum / 10) + : QMediaTimeRange(); + + locker->unlock(); + HRESULT hr = seeking->SetRate(m_rate); + locker->relock(); + + if (!SUCCEEDED(hr)) { + double rate = 0.0; + m_rate = seeking->GetRate(&rate) + ? rate + : 1.0; + } + + seeking->Release(); + } else if (m_rate != 1.0) { + m_rate = 1.0; + } + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(RateChange))); +} + +qint64 DirectShowPlayerService::position() const +{ + QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); + + if (m_graphStatus == Loaded) { + if (m_executingTask == Seek || m_executingTask == SetRate) { + return m_position; + } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG position = 0; + + seeking->GetCurrentPosition(&position); + seeking->Release(); + + const_cast<qint64 &>(m_position) = position / 10; + + return m_position; + } + } + return 0; +} + +QMediaTimeRange DirectShowPlayerService::availablePlaybackRanges() const +{ + QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); + + if (m_graphStatus == Loaded) { + if (m_executingTask == Seek || m_executingTask == SetRate) { + return m_playbackRange; + } else if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG minimum = 0; + LONGLONG maximum = 0; + + HRESULT hr = seeking->GetAvailable(&minimum, &maximum); + seeking->Release(); + + if (SUCCEEDED(hr)) + return QMediaTimeRange(minimum, maximum); + } + } + return QMediaTimeRange(); +} + +void DirectShowPlayerService::seek(qint64 position) +{ + QMutexLocker locker(&m_mutex); + + m_position = position; + + m_pendingTasks |= Seek; + + if (m_executedTasks & FinalizeLoad) + ::SetEvent(m_taskHandle); +} + +void DirectShowPlayerService::doSeek(QMutexLocker *locker) +{ + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG seekPosition = LONGLONG(m_position) * 10; + + // Cache current values as we can't query IMediaSeeking during a seek due to the + // possibility of a deadlock when flushing the VideoSurfaceFilter. + LONGLONG currentPosition = 0; + seeking->GetCurrentPosition(¤tPosition); + m_position = currentPosition / 10; + + LONGLONG minimum = 0; + LONGLONG maximum = 0; + m_playbackRange = SUCCEEDED(seeking->GetAvailable(&minimum, &maximum)) + ? QMediaTimeRange(minimum / 10, maximum / 10) + : QMediaTimeRange(); + + locker->unlock(); + seeking->SetPositions( + &seekPosition, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning); + locker->relock(); + + seeking->GetCurrentPosition(¤tPosition); + m_position = currentPosition / 10; + + seeking->Release(); + } else { + m_position = 0; + } + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PositionChange))); +} + +int DirectShowPlayerService::bufferStatus() const +{ +#ifndef QT_NO_WMSDK + QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); + + if (IWMReaderAdvanced2 *reader = com_cast<IWMReaderAdvanced2>(m_source)) { + DWORD percentage = 0; + + reader->GetBufferProgress(&percentage, 0); + reader->Release(); + + return percentage; + } else { + return 0; + } +#else + return 0; +#endif +} + +void DirectShowPlayerService::setAudioOutput(IBaseFilter *filter) +{ + QMutexLocker locker(&m_mutex); + + if (m_graph) { + if (m_audioOutput) { + if (m_executedTasks & SetAudioOutput) { + m_pendingTasks |= ReleaseAudioOutput; + + ::SetEvent(m_taskHandle); + + m_loop->wait(&m_mutex); + } + m_audioOutput->Release(); + } + + m_audioOutput = filter; + + if (m_audioOutput) { + m_audioOutput->AddRef(); + + m_pendingTasks |= SetAudioOutput; + + if (m_executedTasks & SetSource) { + m_pendingTasks |= Render; + + ::SetEvent(m_taskHandle); + } + } else { + m_pendingTasks &= ~ SetAudioOutput; + } + } else { + if (m_audioOutput) + m_audioOutput->Release(); + + m_audioOutput = filter; + + if (m_audioOutput) + m_audioOutput->AddRef(); + } + + m_playerControl->updateAudioOutput(m_audioOutput); +} + +void DirectShowPlayerService::doReleaseAudioOutput(QMutexLocker *locker) +{ + m_pendingTasks |= m_executedTasks & (Play | Pause); + + if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) { + control->Stop(); + control->Release(); + } + + IBaseFilter *decoder = getConnected(m_audioOutput, PINDIR_INPUT); + if (!decoder) { + decoder = m_audioOutput; + decoder->AddRef(); + } + + if (IFilterChain *chain = com_cast<IFilterChain>(m_graph)) { + chain->RemoveChain(decoder, m_audioOutput); + chain->Release(); + } else { + m_graph->RemoveFilter(m_audioOutput); + } + + decoder->Release(); + + m_executedTasks &= ~SetAudioOutput; + + m_loop->wake(); +} + +void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter) +{ + QMutexLocker locker(&m_mutex); + + if (m_graph) { + if (m_videoOutput) { + if (m_executedTasks & SetVideoOutput) { + m_pendingTasks |= ReleaseVideoOutput; + + ::SetEvent(m_taskHandle); + + m_loop->wait(&m_mutex); + } + m_videoOutput->Release(); + } + + m_videoOutput = filter; + + if (m_videoOutput) { + m_videoOutput->AddRef(); + + m_pendingTasks |= SetVideoOutput; + + if (m_executedTasks & SetSource) { + m_pendingTasks |= Render; + + ::SetEvent(m_taskHandle); + } + } + } else { + if (m_videoOutput) + m_videoOutput->Release(); + + m_videoOutput = filter; + + if (m_videoOutput) + m_videoOutput->AddRef(); + } +} + +void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker *locker) +{ + m_pendingTasks |= m_executedTasks & (Play | Pause); + + if (IMediaControl *control = com_cast<IMediaControl>(m_graph)) { + control->Stop(); + control->Release(); + } + + IBaseFilter *intermediate = 0; + if (!SUCCEEDED(m_graph->FindFilterByName(L"Color Space Converter", &intermediate))) { + intermediate = m_videoOutput; + intermediate->AddRef(); + } + + IBaseFilter *decoder = getConnected(intermediate, PINDIR_INPUT); + if (!decoder) { + decoder = intermediate; + decoder->AddRef(); + } + + if (IFilterChain *chain = com_cast<IFilterChain>(m_graph)) { + chain->RemoveChain(decoder, m_videoOutput); + chain->Release(); + } else { + m_graph->RemoveFilter(m_videoOutput); + } + + intermediate->Release(); + decoder->Release(); + + m_executedTasks &= ~SetVideoOutput; + + m_loop->wake(); +} + +void DirectShowPlayerService::customEvent(QEvent *event) +{ + if (event->type() == QEvent::Type(FinalizedLoad)) { + QMutexLocker locker(&m_mutex); + + m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); + m_metaDataControl->updateGraph(m_graph, m_source); + + updateStatus(); + } else if (event->type() == QEvent::Type(Error)) { + QMutexLocker locker(&m_mutex); + + if (m_error != QMediaPlayer::NoError) { + m_playerControl->updateError(m_error, m_errorString); + m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); + m_playerControl->updateState(QMediaPlayer::StoppedState); + updateStatus(); + } + } else if (event->type() == QEvent::Type(RateChange)) { + QMutexLocker locker(&m_mutex); + + m_playerControl->updatePlaybackRate(m_rate); + } else if (event->type() == QEvent::Type(StatusChange)) { + QMutexLocker locker(&m_mutex); + + updateStatus(); + m_playerControl->updatePosition(m_position); + } else if (event->type() == QEvent::Type(DurationChange)) { + QMutexLocker locker(&m_mutex); + + m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); + } else if (event->type() == QEvent::Type(EndOfMedia)) { + QMutexLocker locker(&m_mutex); + + if (m_atEnd) { + m_playerControl->updateState(QMediaPlayer::StoppedState); + m_playerControl->updateStatus(QMediaPlayer::EndOfMedia); + m_playerControl->updatePosition(m_position); + } + } else if (event->type() == QEvent::Type(PositionChange)) { + QMutexLocker locker(&m_mutex); + + m_playerControl->updatePosition(m_position); + } else { + QMediaService::customEvent(event); + } +} + +void DirectShowPlayerService::videoOutputChanged() +{ + IBaseFilter *videoOutput = 0; + + switch (m_videoOutputControl->output()) { + case QVideoOutputControl::RendererOutput: + videoOutput = m_videoRendererControl->filter(); + break; + case QVideoOutputControl::WindowOutput: + videoOutput = m_videoWindowControl->filter(); + break; + default: + break; + } + + setVideoOutput(videoOutput); +} + +void DirectShowPlayerService::graphEvent(QMutexLocker *locker) +{ + if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph)) { + long eventCode; + LONG_PTR param1; + LONG_PTR param2; + + while (event->GetEvent(&eventCode, ¶m1, ¶m2, 0) == S_OK) { + switch (eventCode) { + case EC_BUFFERING_DATA: + m_buffering = param1; + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); + break; + case EC_COMPLETE: + m_executedTasks &= ~(Play | Pause); + m_executedTasks |= Stop; + + m_buffering = false; + m_atEnd = true; + + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG position = 0; + + seeking->GetCurrentPosition(&position); + seeking->Release(); + + m_position = position / 10; + } + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EndOfMedia))); + break; + case EC_LENGTH_CHANGED: + if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph)) { + LONGLONG duration = 0; + seeking->GetDuration(&duration); + m_duration = duration / 10; + + DWORD capabilities = 0; + seeking->GetCapabilities(&capabilities); + m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute; + + seeking->Release(); + + QCoreApplication::postEvent(this, new QEvent(QEvent::Type(DurationChange))); + } + break; + default: + break; + } + + event->FreeEventParams(eventCode, param1, param2); + } + event->Release(); + } +} + +void DirectShowPlayerService::updateStatus() +{ + switch (m_graphStatus) { + case NoMedia: + m_playerControl->updateStatus(QMediaPlayer::NoMedia); + break; + case Loading: + m_playerControl->updateStatus(QMediaPlayer::LoadingMedia); + break; + case Loaded: + if ((m_pendingTasks | m_executingTask | m_executedTasks) & (Play | Pause)) { + if (m_buffering) + m_playerControl->updateStatus(QMediaPlayer::BufferingMedia); + else + m_playerControl->updateStatus(QMediaPlayer::BufferedMedia); + } else { + m_playerControl->updateStatus(QMediaPlayer::LoadedMedia); + } + break; + case InvalidMedia: + m_playerControl->updateStatus(QMediaPlayer::InvalidMedia); + break; + default: + m_playerControl->updateStatus(QMediaPlayer::UnknownMediaStatus); + } +} + +bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const +{ + bool connected = false; + + IEnumPins *pins = 0; + + if (SUCCEEDED(filter->EnumPins(&pins))) { + for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + PIN_DIRECTION dir; + if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { + IPin *peer = 0; + if (SUCCEEDED(pin->ConnectedTo(&peer))) { + connected = true; + + peer->Release(); + } + } + } + pins->Release(); + } + return connected; +} + +IBaseFilter *DirectShowPlayerService::getConnected( + IBaseFilter *filter, PIN_DIRECTION direction) const +{ + IBaseFilter *connected = 0; + + IEnumPins *pins = 0; + + if (SUCCEEDED(filter->EnumPins(&pins))) { + for (IPin *pin = 0; pins->Next(1, &pin, 0) == S_OK; pin->Release()) { + PIN_DIRECTION dir; + if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { + IPin *peer = 0; + if (SUCCEEDED(pin->ConnectedTo(&peer))) { + PIN_INFO info; + + if (SUCCEEDED(peer->QueryPinInfo(&info))) { + if (connected) { + qWarning("DirectShowPlayerService::getConnected: " + "Multiple connected filters"); + connected->Release(); + } + connected = info.pFilter; + } + peer->Release(); + } + } + } + pins->Release(); + } + return connected; +} + +void DirectShowPlayerService::run() +{ + QMutexLocker locker(&m_mutex); + + for (;;) { + ::ResetEvent(m_taskHandle); + + while (m_pendingTasks == 0) { + DWORD result = 0; + + locker.unlock(); + if (m_eventHandle) { + HANDLE handles[] = { m_taskHandle, m_eventHandle }; + + result = ::WaitForMultipleObjects(2, handles, false, INFINITE); + } else { + result = ::WaitForSingleObject(m_taskHandle, INFINITE); + } + locker.relock(); + + if (result == WAIT_OBJECT_0 + 1) { + graphEvent(&locker); + } + } + + if (m_pendingTasks & ReleaseGraph) { + m_pendingTasks ^= ReleaseGraph; + m_executingTask = ReleaseGraph; + + doReleaseGraph(&locker); + } else if (m_pendingTasks & Shutdown) { + return; + } else if (m_pendingTasks & ReleaseAudioOutput) { + m_pendingTasks ^= ReleaseAudioOutput; + m_executingTask = ReleaseAudioOutput; + + doReleaseAudioOutput(&locker); + } else if (m_pendingTasks & ReleaseVideoOutput) { + m_pendingTasks ^= ReleaseVideoOutput; + m_executingTask = ReleaseVideoOutput; + + doReleaseVideoOutput(&locker); + } else if (m_pendingTasks & SetUrlSource) { + m_pendingTasks ^= SetUrlSource; + m_executingTask = SetUrlSource; + + doSetUrlSource(&locker); + } else if (m_pendingTasks & SetStreamSource) { + m_pendingTasks ^= SetStreamSource; + m_executingTask = SetStreamSource; + + doSetStreamSource(&locker); + } else if (m_pendingTasks & Render) { + m_pendingTasks ^= Render; + m_executingTask = Render; + + doRender(&locker); + } else if (!(m_executedTasks & Render)) { + m_pendingTasks &= ~(FinalizeLoad | SetRate | Stop | Pause | Seek | Play); + } else if (m_pendingTasks & FinalizeLoad) { + m_pendingTasks ^= FinalizeLoad; + m_executingTask = FinalizeLoad; + + doFinalizeLoad(&locker); + } else if (m_pendingTasks & Stop) { + m_pendingTasks ^= Stop; + m_executingTask = Stop; + + doStop(&locker); + } else if (m_pendingTasks & SetRate) { + m_pendingTasks ^= SetRate; + m_executingTask = SetRate; + + doSetRate(&locker); + } else if (m_pendingTasks & Pause) { + m_pendingTasks ^= Pause; + m_executingTask = Pause; + + doPause(&locker); + } else if (m_pendingTasks & Seek) { + m_pendingTasks ^= Seek; + m_executingTask = Seek; + + doSeek(&locker); + } else if (m_pendingTasks & Play) { + m_pendingTasks ^= Play; + m_executingTask = Play; + + doPlay(&locker); + } + m_executingTask = 0; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h new file mode 100644 index 0000000..a5da9a4 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowplayerservice.h @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWPLAYERSERVICE_H +#define DIRECTSHOWPLAYERSERVICE_H + +#include <QtMultimedia/qmediaplayer.h> +#include <QtMultimedia/qmediaresource.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediatimerange.h> + +#include "directshoweventloop.h" +#include "directshowglobal.h" + +#include <QtCore/qcoreevent.h> +#include <QtCore/qmutex.h> +#include <QtCore/qurl.h> +#include <QtCore/qwaitcondition.h> + +#include <QtCore/private/qwineventnotifier_p.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowAudioEndpointControl; +class DirectShowMetaDataControl; +class DirectShowPlayerControl; +class DirectShowVideoOutputControl; +class DirectShowVideoRendererControl; +class Vmr9VideoWindowControl; + +class DirectShowPlayerService : public QMediaService +{ + Q_OBJECT +public: + enum StreamType + { + AudioStream = 0x01, + VideoStream = 0x02 + }; + + DirectShowPlayerService(QObject *parent = 0); + ~DirectShowPlayerService(); + + QMediaControl* control(const char *name) const; + + void load(const QMediaContent &media, QIODevice *stream); + void play(); + void pause(); + void stop(); + + qint64 position() const; + QMediaTimeRange availablePlaybackRanges() const; + + void seek(qint64 position); + void setRate(qreal rate); + + int bufferStatus() const; + + void setAudioOutput(IBaseFilter *filter); + void setVideoOutput(IBaseFilter *filter); + +protected: + void customEvent(QEvent *event); + +private Q_SLOTS: + void videoOutputChanged(); + +private: + void releaseGraph(); + void updateStatus(); + + int findStreamTypes(IBaseFilter *source) const; + int findStreamType(IPin *pin) const; + + bool isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const; + IBaseFilter *getConnected(IBaseFilter *filter, PIN_DIRECTION direction) const; + + void run(); + + void doSetUrlSource(QMutexLocker *locker); + void doSetStreamSource(QMutexLocker *locker); + void doRender(QMutexLocker *locker); + void doFinalizeLoad(QMutexLocker *locker); + void doSetRate(QMutexLocker *locker); + void doSeek(QMutexLocker *locker); + void doPlay(QMutexLocker *locker); + void doPause(QMutexLocker *locker); + void doStop(QMutexLocker *locker); + void doReleaseAudioOutput(QMutexLocker *locker); + void doReleaseVideoOutput(QMutexLocker *locker); + void doReleaseGraph(QMutexLocker *locker); + + void graphEvent(QMutexLocker *locker); + + enum Task + { + Shutdown = 0x0001, + SetUrlSource = 0x0002, + SetStreamSource = 0x0004, + SetSource = SetUrlSource | SetStreamSource, + SetAudioOutput = 0x0008, + SetVideoOutput = 0x0010, + SetOutputs = SetAudioOutput | SetVideoOutput, + Render = 0x0020, + FinalizeLoad = 0x0040, + SetRate = 0x0080, + Seek = 0x0100, + Play = 0x0200, + Pause = 0x0400, + Stop = 0x0800, + ReleaseGraph = 0x1000, + ReleaseAudioOutput = 0x2000, + ReleaseVideoOutput = 0x4000, + ReleaseFilters = ReleaseGraph | ReleaseAudioOutput | ReleaseVideoOutput + }; + + enum Event + { + FinalizedLoad = QEvent::User, + Error, + RateChange, + Started, + Paused, + DurationChange, + StatusChange, + EndOfMedia, + PositionChange + }; + + enum GraphStatus + { + NoMedia, + Loading, + Loaded, + InvalidMedia + }; + + DirectShowPlayerControl *m_playerControl; + DirectShowMetaDataControl *m_metaDataControl; + DirectShowVideoOutputControl *m_videoOutputControl; + DirectShowVideoRendererControl *m_videoRendererControl; + Vmr9VideoWindowControl *m_videoWindowControl; + DirectShowAudioEndpointControl *m_audioEndpointControl; + + QThread *m_taskThread; + DirectShowEventLoop *m_loop; + int m_pendingTasks; + int m_executingTask; + int m_executedTasks; + HANDLE m_taskHandle; + HANDLE m_eventHandle; + GraphStatus m_graphStatus; + QMediaPlayer::Error m_error; + QIODevice *m_stream; + IFilterGraph2 *m_graph; + IBaseFilter *m_source; + IBaseFilter *m_audioOutput; + IBaseFilter *m_videoOutput; + int m_streamTypes; + qreal m_rate; + qint64 m_position; + qint64 m_duration; + bool m_buffering; + bool m_seekable; + bool m_atEnd; + QMediaTimeRange m_playbackRange; + QUrl m_url; + QMediaResourceList m_resources; + QString m_errorString; + QMutex m_mutex; + + friend class DirectShowPlayerServiceThread; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp new file mode 100644 index 0000000..733080e --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.cpp @@ -0,0 +1,414 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowsamplescheduler.h" + +#include <QtCore/qcoreevent.h> + + +QT_BEGIN_NAMESPACE + +class DirectShowTimedSample +{ +public: + DirectShowTimedSample(IMediaSample *sample) + : m_next(0) + , m_sample(sample) + , m_cookie(0) + , m_lastSample(false) + { + m_sample->AddRef(); + } + + ~DirectShowTimedSample() + { + m_sample->Release(); + } + + IMediaSample *sample() const { return m_sample; } + + DirectShowTimedSample *nextSample() const { return m_next; } + void setNextSample(DirectShowTimedSample *sample) { Q_ASSERT(!m_next); m_next = sample; } + + DirectShowTimedSample *remove() { + DirectShowTimedSample *next = m_next; delete this; return next; } + + bool schedule(IReferenceClock *clock, REFERENCE_TIME startTime, HANDLE handle); + void unschedule(IReferenceClock *clock); + + bool isReady(IReferenceClock *clock) const; + + bool isLast() const { return m_lastSample; } + void setLast() { m_lastSample = true; } + +private: + DirectShowTimedSample *m_next; + IMediaSample *m_sample; + DWORD_PTR m_cookie; + bool m_lastSample; +}; + +bool DirectShowTimedSample::schedule( + IReferenceClock *clock, REFERENCE_TIME startTime, HANDLE handle) +{ + REFERENCE_TIME sampleStartTime; + REFERENCE_TIME sampleEndTime; + if (m_sample->GetTime(&sampleStartTime, &sampleEndTime) == S_OK) { + if (clock->AdviseTime( + startTime, sampleStartTime, reinterpret_cast<HEVENT>(handle), &m_cookie) == S_OK) { + return true; + } + } + return false; +} + +void DirectShowTimedSample::unschedule(IReferenceClock *clock) +{ + clock->Unadvise(m_cookie); +} + +bool DirectShowTimedSample::isReady(IReferenceClock *clock) const +{ + REFERENCE_TIME sampleStartTime; + REFERENCE_TIME sampleEndTime; + REFERENCE_TIME currentTime; + if (m_sample->GetTime(&sampleStartTime, &sampleEndTime) == S_OK) { + if (clock->GetTime(¤tTime) == S_OK) + return currentTime >= sampleStartTime; + } + return true; +} + +DirectShowSampleScheduler::DirectShowSampleScheduler(IUnknown *pin, QObject *parent) + : QWinEventNotifier(parent) + , m_pin(pin) + , m_clock(0) + , m_allocator(0) + , m_head(0) + , m_tail(0) + , m_maximumSamples(2) + , m_state(Stopped) + , m_startTime(0) + , m_timeoutEvent(::CreateEvent(0, 0, 0, 0)) +{ + m_semaphore.release(m_maximumSamples); + + setHandle(m_timeoutEvent); + setEnabled(true); +} + +DirectShowSampleScheduler::~DirectShowSampleScheduler() +{ + setEnabled(false); + + ::CloseHandle(m_timeoutEvent); + + Q_ASSERT(!m_clock); + Q_ASSERT(!m_allocator); +} + +HRESULT DirectShowSampleScheduler::QueryInterface(REFIID riid, void **ppvObject) +{ + return m_pin->QueryInterface(riid, ppvObject); +} + +ULONG DirectShowSampleScheduler::AddRef() +{ + return m_pin->AddRef(); +} + +ULONG DirectShowSampleScheduler::Release() +{ + return m_pin->Release(); +} + +// IMemInputPin +HRESULT DirectShowSampleScheduler::GetAllocator(IMemAllocator **ppAllocator) +{ + if (!ppAllocator) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + if (!m_allocator) { + return VFW_E_NO_ALLOCATOR; + } else { + *ppAllocator = m_allocator; + + return S_OK; + } + } +} + +HRESULT DirectShowSampleScheduler::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) +{ + Q_UNUSED(bReadOnly); + + HRESULT hr; + ALLOCATOR_PROPERTIES properties; + + if (!pAllocator) { + if (m_allocator) + m_allocator->Release(); + + m_allocator = 0; + + return S_OK; + } else if ((hr = pAllocator->GetProperties(&properties)) != S_OK) { + return hr; + } else { + if (properties.cBuffers == 1) { + ALLOCATOR_PROPERTIES actual; + + properties.cBuffers = 2; + if ((hr = pAllocator->SetProperties(&properties, &actual)) != S_OK) + return hr; + } + + QMutexLocker locker(&m_mutex); + + if (m_allocator) + m_allocator->Release(); + + m_allocator = pAllocator; + m_allocator->AddRef(); + + return S_OK; + } +} + +HRESULT DirectShowSampleScheduler::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) +{ + if (!pProps) + return E_POINTER; + + pProps->cBuffers = 2; + + return S_OK; +} + +HRESULT DirectShowSampleScheduler::Receive(IMediaSample *pSample) +{ + if (!pSample) + return E_POINTER; + + m_semaphore.acquire(1); + + QMutexLocker locker(&m_mutex); + + if (m_state & Flushing) { + m_semaphore.release(1); + + return S_FALSE; + } else if (m_state == Stopped) { + m_semaphore.release(); + + return VFW_E_WRONG_STATE; + } else { + DirectShowTimedSample *timedSample = new DirectShowTimedSample(pSample); + + if (m_tail) + m_tail->setNextSample(timedSample); + else + m_head = timedSample; + + m_tail = timedSample; + + if (m_state == Running) { + if (!timedSample->schedule(m_clock, m_startTime, m_timeoutEvent)) { + // Timing information is unavailable, so schedule frames immediately. + QMetaObject::invokeMethod(this, "timerActivated", Qt::QueuedConnection); + } + } else if (m_tail == m_head) { + // If this is the first frame make is available. + QMetaObject::invokeMethod(this, "timerActivated", Qt::QueuedConnection); + } + + return S_OK; + } +} + +HRESULT DirectShowSampleScheduler::ReceiveMultiple( + IMediaSample **pSamples, long nSamples, long *nSamplesProcessed) +{ + if (!pSamples || !nSamplesProcessed) + return E_POINTER; + + for (*nSamplesProcessed = 0; *nSamplesProcessed < nSamples; ++(*nSamplesProcessed)) { + HRESULT hr = Receive(pSamples[*nSamplesProcessed]); + + if (hr != S_OK) + return hr; + } + return S_OK; +} + +HRESULT DirectShowSampleScheduler::ReceiveCanBlock() +{ + return S_OK; +} + +void DirectShowSampleScheduler::run(REFERENCE_TIME startTime) +{ + QMutexLocker locker(&m_mutex); + + m_state = (m_state & Flushing) | Running; + m_startTime = startTime; + + for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample()) { + sample->schedule(m_clock, m_startTime, m_timeoutEvent); + } +} + +void DirectShowSampleScheduler::pause() +{ + QMutexLocker locker(&m_mutex); + + m_state = (m_state & Flushing) | Paused; + + for (DirectShowTimedSample *sample = m_head; sample; sample = sample->nextSample()) + sample->unschedule(m_clock); +} + +void DirectShowSampleScheduler::stop() +{ + QMutexLocker locker(&m_mutex); + + m_state = m_state & Flushing; + + for (DirectShowTimedSample *sample = m_head; sample; sample = sample->remove()) { + sample->unschedule(m_clock); + + m_semaphore.release(1); + } + + m_head = 0; + m_tail = 0; +} + +void DirectShowSampleScheduler::setFlushing(bool flushing) +{ + QMutexLocker locker(&m_mutex); + + const bool isFlushing = m_state & Flushing; + + if (isFlushing != flushing) { + if (flushing) { + m_state |= Flushing; + + for (DirectShowTimedSample *sample = m_head; sample; sample = sample->remove()) { + sample->unschedule(m_clock); + + m_semaphore.release(1); + } + m_head = 0; + m_tail = 0; + } else { + m_state &= ~Flushing; + } + } +} + +void DirectShowSampleScheduler::setClock(IReferenceClock *clock) +{ + QMutexLocker locker(&m_mutex); + + if (m_clock) + m_clock->Release(); + + m_clock = clock; + + if (m_clock) + m_clock->AddRef(); +} + +IMediaSample *DirectShowSampleScheduler::takeSample(bool *eos) +{ + QMutexLocker locker(&m_mutex); + + if (m_head && m_head->isReady(m_clock)) { + IMediaSample *sample = m_head->sample(); + sample->AddRef(); + + if (m_state == Running) { + *eos = m_head->isLast(); + + m_head = m_head->remove(); + + if (!m_head) + m_tail = 0; + + m_semaphore.release(1); + } + + return sample; + } else { + return 0; + } +} + +bool DirectShowSampleScheduler::scheduleEndOfStream() +{ + QMutexLocker locker(&m_mutex); + + if (m_tail) { + m_tail->setLast(); + + return true; + } else { + return false; + } +} + +bool DirectShowSampleScheduler::event(QEvent *event) +{ + if (event->type() == QEvent::WinEventAct) { + QObject::event(event); + + emit sampleReady(); + + return true; + } else { + return QWinEventNotifier::event(event); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h new file mode 100644 index 0000000..007fa99 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowsamplescheduler.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWSAMPLESCHEDULER_H +#define DIRECTSHOWSAMPLESCHEDULER_H + +#include <QtCore/qmutex.h> +#include <QtCore/qobject.h> +#include <QtCore/qsemaphore.h> + +#include <QtCore/private/qwineventnotifier_p.h> + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowTimedSample; + +class DirectShowSampleScheduler : public QWinEventNotifier, public IMemInputPin +{ + Q_OBJECT +public: + + enum State + { + Stopped = 0x00, + Running = 0x01, + Paused = 0x02, + RunMask = 0x03, + Flushing = 0x04 + }; + + DirectShowSampleScheduler(IUnknown *pin, QObject *parent = 0); + ~DirectShowSampleScheduler(); + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + // IMemInputPin + HRESULT STDMETHODCALLTYPE GetAllocator(IMemAllocator **ppAllocator); + HRESULT STDMETHODCALLTYPE NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly); + HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); + + HRESULT STDMETHODCALLTYPE Receive(IMediaSample *pSample); + HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed); + HRESULT STDMETHODCALLTYPE ReceiveCanBlock(); + + void run(REFERENCE_TIME startTime); + void pause(); + void stop(); + void setFlushing(bool flushing); + + IReferenceClock *clock() const { return m_clock; } + void setClock(IReferenceClock *clock); + + bool schedule(IMediaSample *sample); + bool scheduleEndOfStream(); + + IMediaSample *takeSample(bool *eos); + + bool event(QEvent *event); + +Q_SIGNALS: + void sampleReady(); + +private: + IUnknown *m_pin; + IReferenceClock *m_clock; + IMemAllocator *m_allocator; + DirectShowTimedSample *m_head; + DirectShowTimedSample *m_tail; + int m_maximumSamples; + int m_state; + REFERENCE_TIME m_startTime; + HANDLE m_timeoutEvent; + QSemaphore m_semaphore; + QMutex m_mutex; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowvideooutputcontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideooutputcontrol.cpp new file mode 100644 index 0000000..ee2bea8 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideooutputcontrol.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowvideooutputcontrol.h" + + +QT_BEGIN_NAMESPACE + +DirectShowVideoOutputControl::DirectShowVideoOutputControl(QObject *parent) + : QVideoOutputControl(parent) + , m_output(NoOutput) +{ + +} + +DirectShowVideoOutputControl::~DirectShowVideoOutputControl() +{ +} + +QList<QVideoOutputControl::Output> DirectShowVideoOutputControl::availableOutputs() const +{ + return QList<Output>() + << RendererOutput + << WindowOutput; +} + + +QVideoOutputControl::Output DirectShowVideoOutputControl::output() const +{ + return m_output; +} + +void DirectShowVideoOutputControl::setOutput(Output output) +{ + if (output != m_output) { + switch (output) { + case NoOutput: + case RendererOutput: + case WindowOutput: + m_output = output; + emit outputChanged(); + break; + default: + break; + } + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowvideooutputcontrol.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideooutputcontrol.h new file mode 100644 index 0000000..acb2937 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideooutputcontrol.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWVIDEOUTPUTCONTROL_H +#define DIRECTSHOWVIDEOOUPUTCONTROL_H + +#include <QtMultimedia/qvideooutputcontrol.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowVideoOutputControl : public QVideoOutputControl +{ + Q_OBJECT +public: + DirectShowVideoOutputControl(QObject *parent = 0); + ~DirectShowVideoOutputControl(); + + QList<Output> availableOutputs() const; + + Output output() const; + void setOutput(Output output); + +Q_SIGNALS: + void outputChanged(); + +private: + Output m_output; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowvideorenderercontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideorenderercontrol.cpp new file mode 100644 index 0000000..f27cb10 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideorenderercontrol.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowvideorenderercontrol.h" + +#include "videosurfacefilter.h" + + +QT_BEGIN_NAMESPACE + + +DirectShowVideoRendererControl::DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent) + : QVideoRendererControl(parent) + , m_loop(loop) + , m_surface(0) + , m_filter(0) +{ +} + +DirectShowVideoRendererControl::~DirectShowVideoRendererControl() +{ + delete m_filter; +} + +QAbstractVideoSurface *DirectShowVideoRendererControl::surface() const +{ + return m_surface; +} + +void DirectShowVideoRendererControl::setSurface(QAbstractVideoSurface *surface) +{ + if (surface != m_surface) { + m_surface = surface; + + VideoSurfaceFilter *existingFilter = m_filter; + + if (surface) { + m_filter = new VideoSurfaceFilter(surface, m_loop); + } else { + m_filter = 0; + } + + emit filterChanged(); + + delete existingFilter; + } +} + +IBaseFilter *DirectShowVideoRendererControl::filter() +{ + return m_filter; +} + + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/directshowvideorenderercontrol.h b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideorenderercontrol.h new file mode 100644 index 0000000..6b4f4a2 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/directshowvideorenderercontrol.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWVIDEORENDERERCONTROL_H +#define DIRECTSHOWVIDEORENDERERCONTROL_H + +#include <QtMultimedia/qvideorenderercontrol.h> + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class DirectShowEventLoop; +class VideoSurfaceFilter; + +class DirectShowVideoRendererControl : public QVideoRendererControl +{ + Q_OBJECT +public: + DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent = 0); + ~DirectShowVideoRendererControl(); + + QAbstractVideoSurface *surface() const; + void setSurface(QAbstractVideoSurface *surface); + + IBaseFilter *filter(); + +Q_SIGNALS: + void filterChanged(); + +private: + DirectShowEventLoop *m_loop; + QAbstractVideoSurface *m_surface; + VideoSurfaceFilter *m_filter; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/mediaplayer.pri b/src/plugins/mediaservices/directshow/mediaplayer/mediaplayer.pri new file mode 100644 index 0000000..a7adb38 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/mediaplayer.pri @@ -0,0 +1,45 @@ +INCLUDEPATH += $$PWD + +DEFINES += QMEDIA_DIRECTSHOW_PLAYER + +win32-g++: DEFINES += QT_NO_WMSDK + +HEADERS += \ + $$PWD/directshowaudioendpointcontrol.h \ + $$PWD/directshoweventloop.h \ + $$PWD/directshowglobal.h \ + $$PWD/directshowioreader.h \ + $$PWD/directshowiosource.h \ + $$PWD/directshowmediatype.h \ + $$PWD/directshowmediatypelist.h \ + $$PWD/directshowmetadatacontrol.h \ + $$PWD/directshowpinenum.h \ + $$PWD/directshowplayercontrol.h \ + $$PWD/directshowplayerservice.h \ + $$PWD/directshowsamplescheduler.h \ + $$PWD/directshowvideooutputcontrol.h \ + $$PWD/directshowvideorenderercontrol.h \ + $$PWD/mediasamplevideobuffer.h \ + $$PWD/videosurfacefilter.h \ + $$PWD/vmr9videowindowcontrol.h + +SOURCES += \ + $$PWD/directshowaudioendpointcontrol.cpp \ + $$PWD/directshoweventloop.cpp \ + $$PWD/directshowioreader.cpp \ + $$PWD/directshowiosource.cpp \ + $$PWD/directshowmediatype.cpp \ + $$PWD/directshowmediatypelist.cpp \ + $$PWD/directshowmetadatacontrol.cpp \ + $$PWD/directshowpinenum.cpp \ + $$PWD/directshowplayercontrol.cpp \ + $$PWD/directshowplayerservice.cpp \ + $$PWD/directshowsamplescheduler.cpp \ + $$PWD/directshowvideooutputcontrol.cpp \ + $$PWD/directshowvideorenderercontrol.cpp \ + $$PWD/mediasamplevideobuffer.cpp \ + $$PWD/videosurfacefilter.cpp \ + $$PWD/vmr9videowindowcontrol.cpp + +LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 + diff --git a/src/plugins/mediaservices/directshow/mediaplayer/mediasamplevideobuffer.cpp b/src/plugins/mediaservices/directshow/mediaplayer/mediasamplevideobuffer.cpp new file mode 100644 index 0000000..7eff226 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/mediasamplevideobuffer.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mediasamplevideobuffer.h" + + +QT_BEGIN_NAMESPACE + +MediaSampleVideoBuffer::MediaSampleVideoBuffer(IMediaSample *sample, int bytesPerLine) + : QAbstractVideoBuffer(NoHandle) + , m_sample(sample) + , m_bytesPerLine(m_bytesPerLine) + , m_mapMode(NotMapped) +{ + m_sample->AddRef(); +} + +MediaSampleVideoBuffer::~MediaSampleVideoBuffer() +{ + m_sample->Release(); +} + +uchar *MediaSampleVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) +{ + if (m_mapMode == NotMapped && mode != NotMapped) { + if (numBytes) + *numBytes = m_sample->GetActualDataLength(); + + if (bytesPerLine) + *bytesPerLine = m_bytesPerLine; + + BYTE *bytes = 0; + + if (m_sample->GetPointer(&bytes) == S_OK) { + m_mapMode = mode; + + return reinterpret_cast<uchar *>(bytes); + } + } + return 0; +} + +void MediaSampleVideoBuffer::unmap() +{ + m_mapMode = NotMapped; +} + +QAbstractVideoBuffer::MapMode MediaSampleVideoBuffer::mapMode() const +{ + return m_mapMode; +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/directshow/mediaplayer/mediasamplevideobuffer.h b/src/plugins/mediaservices/directshow/mediaplayer/mediasamplevideobuffer.h new file mode 100644 index 0000000..06dc31c --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/mediasamplevideobuffer.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MEDIASAMPLEVIDEOBUFFER_H +#define MEDIASAMPLEVIDEOBUFFER_H + +#include <QtMultimedia/qabstractvideobuffer.h> + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class MediaSampleVideoBuffer : public QAbstractVideoBuffer +{ +public: + MediaSampleVideoBuffer(IMediaSample *sample, int bytesPerLine); + ~MediaSampleVideoBuffer(); + + IMediaSample *sample() { return m_sample; } + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); + void unmap(); + + MapMode mapMode() const; + +private: + IMediaSample *m_sample; + int m_bytesPerLine; + MapMode m_mapMode; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp b/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp new file mode 100644 index 0000000..7b4aad5 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.cpp @@ -0,0 +1,625 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "videosurfacefilter.h" + +#include "directshoweventloop.h" +#include "directshowglobal.h" +#include "directshowpinenum.h" +#include "mediasamplevideobuffer.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qthread.h> +#include <QtMultimedia/qabstractvideosurface.h> + +#include <initguid.h> + + +QT_BEGIN_NAMESPACE + +// { e23cad72-153d-406c-bf3f-4c4b523d96f2 } +DEFINE_GUID(CLSID_VideoSurfaceFilter, +0xe23cad72, 0x153d, 0x406c, 0xbf, 0x3f, 0x4c, 0x4b, 0x52, 0x3d, 0x96, 0xf2); + +VideoSurfaceFilter::VideoSurfaceFilter( + QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent) + : QObject(parent) + , m_ref(1) + , m_state(State_Stopped) + , m_surface(surface) + , m_loop(loop) + , m_graph(0) + , m_peerPin(0) + , m_bytesPerLine(0) + , m_startResult(S_OK) + , m_pinId(QString::fromLatin1("reference")) + , m_sampleScheduler(static_cast<IPin *>(this)) +{ + connect(surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged())); + connect(&m_sampleScheduler, SIGNAL(sampleReady()), this, SLOT(sampleReady())); +} + +VideoSurfaceFilter::~VideoSurfaceFilter() +{ + Q_ASSERT(m_ref == 1); +} + +HRESULT VideoSurfaceFilter::QueryInterface(REFIID riid, void **ppvObject) +{ + if (!ppvObject) { + return E_POINTER; + } else if (riid == IID_IUnknown + || riid == IID_IPersist + || riid == IID_IMediaFilter + || riid == IID_IBaseFilter) { + *ppvObject = static_cast<IBaseFilter *>(this); + } else if (riid == IID_IAMFilterMiscFlags) { + *ppvObject = static_cast<IAMFilterMiscFlags *>(this); + } else if (riid == IID_IPin) { + *ppvObject = static_cast<IPin *>(this); + } else if (riid == IID_IMemInputPin) { + *ppvObject = static_cast<IMemInputPin *>(&m_sampleScheduler); + } else { + *ppvObject = 0; + + return E_NOINTERFACE; + } + + AddRef(); + + return S_OK; +} + +ULONG VideoSurfaceFilter::AddRef() +{ + return InterlockedIncrement(&m_ref); +} + +ULONG VideoSurfaceFilter::Release() +{ + ULONG ref = InterlockedDecrement(&m_ref); + + Q_ASSERT(ref != 0); + + return ref; +} + +HRESULT VideoSurfaceFilter::GetClassID(CLSID *pClassID) +{ + *pClassID = CLSID_VideoSurfaceFilter; + + return S_OK; +} + +HRESULT VideoSurfaceFilter::Run(REFERENCE_TIME tStart) +{ + m_state = State_Running; + + m_sampleScheduler.run(tStart); + + return S_OK; +} + +HRESULT VideoSurfaceFilter::Pause() +{ + m_state = State_Paused; + + m_sampleScheduler.pause(); + + return S_OK; +} + +HRESULT VideoSurfaceFilter::Stop() +{ + m_state = State_Stopped; + + m_sampleScheduler.stop(); + + return S_OK; +} + +HRESULT VideoSurfaceFilter::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) +{ + if (!pState) + return E_POINTER; + + *pState = m_state; + + return S_OK; +} + +HRESULT VideoSurfaceFilter::SetSyncSource(IReferenceClock *pClock) +{ + + m_sampleScheduler.setClock(pClock); + + return S_OK; +} + +HRESULT VideoSurfaceFilter::GetSyncSource(IReferenceClock **ppClock) +{ + if (!ppClock) { + return E_POINTER; + } else { + *ppClock = m_sampleScheduler.clock(); + + if (*ppClock) { + (*ppClock)->AddRef(); + + return S_OK; + } else { + return S_FALSE; + } + } +} + +HRESULT VideoSurfaceFilter::EnumPins(IEnumPins **ppEnum) +{ + if (ppEnum) { + *ppEnum = new DirectShowPinEnum(QList<IPin *>() << this); + + return S_OK; + } else { + return E_POINTER; + } +} + +HRESULT VideoSurfaceFilter::FindPin(LPCWSTR pId, IPin **ppPin) +{ + if (!ppPin || !pId) { + return E_POINTER; + } else if (QString::fromWCharArray(pId) == m_pinId) { + AddRef(); + + *ppPin = this; + + return S_OK; + } else { + return VFW_E_NOT_FOUND; + } +} + +HRESULT VideoSurfaceFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) +{ + m_graph = pGraph; + m_name = QString::fromWCharArray(pName); + + return S_OK; +} + +HRESULT VideoSurfaceFilter::QueryFilterInfo(FILTER_INFO *pInfo) +{ + if (pInfo) { + QString name = m_name; + + if (name.length() >= MAX_FILTER_NAME) + name.truncate(MAX_FILTER_NAME - 1); + + int length = name.toWCharArray(pInfo->achName); + pInfo->achName[length] = '\0'; + + if (m_graph) + m_graph->AddRef(); + + pInfo->pGraph = m_graph; + + return S_OK; + } else { + return E_POINTER; + } +} + +HRESULT VideoSurfaceFilter::QueryVendorInfo(LPWSTR *pVendorInfo) +{ + Q_UNUSED(pVendorInfo); + + return E_NOTIMPL; +} + +ULONG VideoSurfaceFilter::GetMiscFlags() +{ + return AM_FILTER_MISC_FLAGS_IS_RENDERER; +} + + +HRESULT VideoSurfaceFilter::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) +{ + // This is an input pin, you shouldn't be calling Connect on it. + return E_POINTER; +} + +HRESULT VideoSurfaceFilter::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) +{ + if (!pConnector) { + return E_POINTER; + } else if (!pmt) { + return E_POINTER; + } else { + HRESULT hr; + QMutexLocker locker(&m_mutex); + + if (m_peerPin) { + hr = VFW_E_ALREADY_CONNECTED; + } else if (pmt->majortype != MEDIATYPE_Video) { + hr = VFW_E_TYPE_NOT_ACCEPTED; + } else { + m_surfaceFormat = DirectShowMediaType::formatFromType(*pmt); + m_bytesPerLine = DirectShowMediaType::bytesPerLine(m_surfaceFormat); + + if (thread() == QThread::currentThread()) { + hr = start(); + } else { + m_loop->postEvent(this, new QEvent(QEvent::Type(StartSurface))); + + m_wait.wait(&m_mutex); + + hr = m_startResult; + } + } + if (hr == S_OK) { + m_peerPin = pConnector; + m_peerPin->AddRef(); + + DirectShowMediaType::copy(&m_mediaType, *pmt); + } + return hr; + } +} + +HRESULT VideoSurfaceFilter::start() +{ + if (!m_surface->start(m_surfaceFormat)) { + return VFW_E_TYPE_NOT_ACCEPTED; + } else { + return S_OK; + } +} + +HRESULT VideoSurfaceFilter::Disconnect() +{ + QMutexLocker locker(&m_mutex); + + if (!m_peerPin) + return S_FALSE; + + if (thread() == QThread::currentThread()) { + stop(); + } else { + m_loop->postEvent(this, new QEvent(QEvent::Type(StopSurface))); + + m_wait.wait(&m_mutex); + } + + m_mediaType.clear(); + + m_sampleScheduler.NotifyAllocator(0, FALSE); + + m_peerPin->Release(); + m_peerPin = 0; + + return S_OK; +} + +void VideoSurfaceFilter::stop() +{ + m_surface->stop(); +} + +HRESULT VideoSurfaceFilter::ConnectedTo(IPin **ppPin) +{ + if (!ppPin) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + if (!m_peerPin) { + return VFW_E_NOT_CONNECTED; + } else { + m_peerPin->AddRef(); + + *ppPin = m_peerPin; + + return S_OK; + } + } +} + +HRESULT VideoSurfaceFilter::ConnectionMediaType(AM_MEDIA_TYPE *pmt) +{ + if (!pmt) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + if (!m_peerPin) { + return VFW_E_NOT_CONNECTED; + } else { + DirectShowMediaType::copy(pmt, m_mediaType); + + return S_OK; + } + } +} + +HRESULT VideoSurfaceFilter::QueryPinInfo(PIN_INFO *pInfo) +{ + if (!pInfo) { + return E_POINTER; + } else { + AddRef(); + + pInfo->pFilter = this; + pInfo->dir = PINDIR_INPUT; + + const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2); + + qMemCopy(pInfo->achName, m_pinId.utf16(), bytes); + + return S_OK; + } +} + +HRESULT VideoSurfaceFilter::QueryId(LPWSTR *Id) +{ + if (!Id) { + return E_POINTER; + } else { + const int bytes = (m_pinId.length() + 1) * 2; + + *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); + + qMemCopy(*Id, m_pinId.utf16(), bytes); + + return S_OK; + } +} + +HRESULT VideoSurfaceFilter::QueryAccept(const AM_MEDIA_TYPE *pmt) +{ + return !m_surface->isFormatSupported(DirectShowMediaType::formatFromType(*pmt)) + ? S_OK + : S_FALSE; +} + +HRESULT VideoSurfaceFilter::EnumMediaTypes(IEnumMediaTypes **ppEnum) +{ + if (!ppEnum) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + *ppEnum = createMediaTypeEnum(); + + return S_OK; + } +} + +HRESULT VideoSurfaceFilter::QueryInternalConnections(IPin **apPin, ULONG *nPin) +{ + Q_UNUSED(apPin); + Q_UNUSED(nPin); + + return E_NOTIMPL; +} + +HRESULT VideoSurfaceFilter::EndOfStream() +{ + QMutexLocker locker(&m_mutex); + + if (!m_sampleScheduler.scheduleEndOfStream()) { + if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph)) { + sink->Notify( + EC_COMPLETE, + S_OK, + reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this))); + sink->Release(); + } + } + + return S_OK; +} + +HRESULT VideoSurfaceFilter::BeginFlush() +{ + QMutexLocker locker(&m_mutex); + + m_sampleScheduler.setFlushing(true); + + if (thread() == QThread::currentThread()) { + flush(); + } else { + m_loop->postEvent(this, new QEvent(QEvent::Type(FlushSurface))); + + m_wait.wait(&m_mutex); + } + + return S_OK; +} + +HRESULT VideoSurfaceFilter::EndFlush() +{ + QMutexLocker locker(&m_mutex); + + m_sampleScheduler.setFlushing(false); + + return S_OK; +} + +void VideoSurfaceFilter::flush() +{ + m_surface->present(QVideoFrame()); + + m_wait.wakeAll(); +} + +HRESULT VideoSurfaceFilter::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ + Q_UNUSED(tStart); + Q_UNUSED(tStop); + Q_UNUSED(dRate); + + return S_OK; +} + +HRESULT VideoSurfaceFilter::QueryDirection(PIN_DIRECTION *pPinDir) +{ + if (!pPinDir) { + return E_POINTER; + } else { + *pPinDir = PINDIR_INPUT; + + return S_OK; + } +} + +int VideoSurfaceFilter::currentMediaTypeToken() +{ + QMutexLocker locker(&m_mutex); + + return DirectShowMediaTypeList::currentMediaTypeToken(); +} + +HRESULT VideoSurfaceFilter::nextMediaType( + int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount) +{ + QMutexLocker locker(&m_mutex); + + return DirectShowMediaTypeList::nextMediaType(token, index, count, types, fetchedCount); + +} + +HRESULT VideoSurfaceFilter::skipMediaType(int token, int *index, ULONG count) +{ + QMutexLocker locker(&m_mutex); + + return DirectShowMediaTypeList::skipMediaType(token, index, count); +} + +HRESULT VideoSurfaceFilter::cloneMediaType(int token, int index, IEnumMediaTypes **enumeration) +{ + QMutexLocker locker(&m_mutex); + + return DirectShowMediaTypeList::cloneMediaType(token, index, enumeration); +} + +void VideoSurfaceFilter::customEvent(QEvent *event) +{ + if (event->type() == StartSurface) { + QMutexLocker locker(&m_mutex); + + m_startResult = start(); + + m_wait.wakeAll(); + } else if (event->type() == StopSurface) { + QMutexLocker locker(&m_mutex); + + stop(); + + m_wait.wakeAll(); + } else if (event->type() == FlushSurface) { + QMutexLocker locker(&m_mutex); + + flush(); + + m_wait.wakeAll(); + } else { + QObject::customEvent(event); + } +} + +void VideoSurfaceFilter::supportedFormatsChanged() +{ + QMutexLocker locker(&m_mutex); + + QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(); + + QVector<AM_MEDIA_TYPE> mediaTypes; + mediaTypes.reserve(formats.count()); + + AM_MEDIA_TYPE type; + type.majortype = MEDIATYPE_Video; + type.bFixedSizeSamples = TRUE; + type.bTemporalCompression = FALSE; + type.lSampleSize = 0; + type.formattype = GUID_NULL; + type.pUnk = 0; + type.cbFormat = 0; + type.pbFormat = 0; + + foreach (QVideoFrame::PixelFormat format, formats) { + type.subtype = DirectShowMediaType::convertPixelFormat(format); + + if (type.subtype != MEDIASUBTYPE_None) + mediaTypes.append(type); + } + + setMediaTypes(mediaTypes); +} + +void VideoSurfaceFilter::sampleReady() +{ + bool eos = false; + + IMediaSample *sample = m_sampleScheduler.takeSample(&eos); + + if (sample) { + m_surface->present(QVideoFrame( + new MediaSampleVideoBuffer(sample, m_bytesPerLine), + m_surfaceFormat.frameSize(), + m_surfaceFormat.pixelFormat())); + + sample->Release(); + + if (eos) { + if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph)) { + sink->Notify( + EC_COMPLETE, + S_OK, + reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this))); + sink->Release(); + } + } + } +} + +QT_END_NAMESPACE + diff --git a/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.h b/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.h new file mode 100644 index 0000000..8f3a101 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/videosurfacefilter.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef VIDEOSURFACEFILTER_H +#define VIDEOSURFACEFILTER_H + +#include "directshowmediatypelist.h" +#include "directshowsamplescheduler.h" +#include "directshowmediatype.h" + +#include <QtCore/qbasictimer.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qmutex.h> +#include <QtCore/qsemaphore.h> +#include <QtCore/qstring.h> +#include <QtCore/qwaitcondition.h> + +#include <dshow.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class QAbstractVideoSurface; + +class DirectShowEventLoop; + +class VideoSurfaceFilter + : public QObject + , public DirectShowMediaTypeList + , public IBaseFilter + , public IAMFilterMiscFlags + , public IPin +{ + Q_OBJECT +public: + VideoSurfaceFilter( + QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent = 0); + ~VideoSurfaceFilter(); + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + // IPersist + HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID); + + // IMediaFilter + HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart); + HRESULT STDMETHODCALLTYPE Pause(); + HRESULT STDMETHODCALLTYPE Stop(); + + HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState); + + HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock); + HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **ppClock); + + // IBaseFilter + HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum); + HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin); + + HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); + + HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo); + HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo); + + // IAMFilterMiscFlags + ULONG STDMETHODCALLTYPE GetMiscFlags(); + + // IPin + HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); + HRESULT STDMETHODCALLTYPE Disconnect(); + HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **ppPin); + + HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt); + + HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo); + HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id); + + HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt); + + HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum); + + HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin); + + HRESULT STDMETHODCALLTYPE EndOfStream(); + + HRESULT STDMETHODCALLTYPE BeginFlush(); + HRESULT STDMETHODCALLTYPE EndFlush(); + + HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + + HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir); + + int currentMediaTypeToken(); + HRESULT nextMediaType( + int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount); + HRESULT skipMediaType(int token, int *index, ULONG count); + HRESULT cloneMediaType(int token, int index, IEnumMediaTypes **enumeration); + +protected: + void customEvent(QEvent *event); + +private Q_SLOTS: + void supportedFormatsChanged(); + void sampleReady(); + +private: + HRESULT start(); + void stop(); + void flush(); + + enum + { + StartSurface = QEvent::User, + StopSurface, + FlushSurface + }; + + LONG m_ref; + FILTER_STATE m_state; + QAbstractVideoSurface *m_surface; + DirectShowEventLoop *m_loop; + IFilterGraph *m_graph; + IPin *m_peerPin; + int m_bytesPerLine; + HRESULT m_startResult; + QString m_name; + QString m_pinId; + DirectShowMediaType m_mediaType; + QVideoSurfaceFormat m_surfaceFormat; + QMutex m_mutex; + QWaitCondition m_wait; + DirectShowSampleScheduler m_sampleScheduler; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.cpp b/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.cpp new file mode 100644 index 0000000..a564e14 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.cpp @@ -0,0 +1,308 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "vmr9videowindowcontrol.h" + +#include "directshowglobal.h" + + +QT_BEGIN_NAMESPACE + +Vmr9VideoWindowControl::Vmr9VideoWindowControl(QObject *parent) + : QVideoWindowControl(parent) + , m_filter(com_new<IBaseFilter>(CLSID_VideoMixingRenderer9)) + , m_windowId(0) + , m_dirtyValues(0) + , m_brightness(0) + , m_contrast(0) + , m_hue(0) + , m_saturation(0) + , m_fullScreen(false) +{ + if (IVMRFilterConfig9 *config = com_cast<IVMRFilterConfig9>(m_filter)) { + config->SetRenderingMode(VMR9Mode_Windowless); + config->SetNumberOfStreams(1); + config->Release(); + } +} + +Vmr9VideoWindowControl::~Vmr9VideoWindowControl() +{ + if (m_filter) + m_filter->Release(); +} + + +WId Vmr9VideoWindowControl::winId() const +{ + return m_windowId; + +} + +void Vmr9VideoWindowControl::setWinId(WId id) +{ + m_windowId = id; + + if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(m_filter)) { + control->SetVideoClippingWindow(m_windowId); + control->Release(); + } +} + +QRect Vmr9VideoWindowControl::displayRect() const +{ + QRect rect; + + if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(m_filter)) { + RECT sourceRect; + RECT displayRect; + + if (control->GetVideoPosition(&sourceRect, &displayRect) == S_OK) { + rect = QRect( + displayRect.left, + displayRect.bottom, + displayRect.right - displayRect.left, + displayRect.bottom - displayRect.top); + } + control->Release(); + } + return rect; +} + +void Vmr9VideoWindowControl::setDisplayRect(const QRect &rect) +{ + if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(m_filter)) { + RECT sourceRect = { 0, 0, 0, 0 }; + RECT displayRect = { rect.left(), rect.top(), rect.right(), rect.bottom() }; + + control->GetNativeVideoSize(&sourceRect.right, &sourceRect.bottom, 0, 0); + control->SetVideoPosition(&sourceRect, &displayRect); + control->Release(); + } +} + +bool Vmr9VideoWindowControl::isFullScreen() const +{ + return m_fullScreen; +} + +void Vmr9VideoWindowControl::setFullScreen(bool fullScreen) +{ + emit fullScreenChanged(m_fullScreen = fullScreen); +} + +void Vmr9VideoWindowControl::repaint() +{ + + if (QWidget *widget = QWidget::find(m_windowId)) { + HDC dc = widget->getDC(); + if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(m_filter)) { + control->RepaintVideo(m_windowId, dc); + control->Release(); + } + widget->releaseDC(dc); + } +} + +QSize Vmr9VideoWindowControl::nativeSize() const +{ + QSize size; + + if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(m_filter)) { + LONG width; + LONG height; + + if (control->GetNativeVideoSize(&width, &height, 0, 0) == S_OK) + size = QSize(width, height); + control->Release(); + } + return size; +} + +QVideoWidget::AspectRatioMode Vmr9VideoWindowControl::aspectRatioMode() const +{ + QVideoWidget::AspectRatioMode mode = QVideoWidget::KeepAspectRatio; + + if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(m_filter)) { + DWORD arMode; + + if (control->GetAspectRatioMode(&arMode) == S_OK && arMode == VMR9ARMode_None) + mode = QVideoWidget::IgnoreAspectRatio; + control->Release(); + } + return mode; +} + +void Vmr9VideoWindowControl::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(m_filter)) { + switch (mode) { + case QVideoWidget::IgnoreAspectRatio: + control->SetAspectRatioMode(VMR9ARMode_None); + break; + case QVideoWidget::KeepAspectRatio: + control->SetAspectRatioMode(VMR9ARMode_LetterBox); + break; + default: + break; + } + control->Release(); + } +} + +int Vmr9VideoWindowControl::brightness() const +{ + return m_brightness; +} + +void Vmr9VideoWindowControl::setBrightness(int brightness) +{ + m_brightness = brightness; + + m_dirtyValues |= ProcAmpControl9_Brightness; + + setProcAmpValues(); + + emit brightnessChanged(brightness); +} + +int Vmr9VideoWindowControl::contrast() const +{ + return m_contrast; +} + +void Vmr9VideoWindowControl::setContrast(int contrast) +{ + m_contrast = contrast; + + m_dirtyValues |= ProcAmpControl9_Contrast; + + setProcAmpValues(); + + emit contrastChanged(contrast); +} + +int Vmr9VideoWindowControl::hue() const +{ + return m_hue; +} + +void Vmr9VideoWindowControl::setHue(int hue) +{ + m_hue = hue; + + m_dirtyValues |= ProcAmpControl9_Hue; + + setProcAmpValues(); + + emit hueChanged(hue); +} + +int Vmr9VideoWindowControl::saturation() const +{ + return m_saturation; +} + +void Vmr9VideoWindowControl::setSaturation(int saturation) +{ + m_saturation = saturation; + + m_dirtyValues |= ProcAmpControl9_Saturation; + + setProcAmpValues(); + + emit saturationChanged(saturation); +} + +void Vmr9VideoWindowControl::setProcAmpValues() +{ + if (IVMRMixerControl9 *control = com_cast<IVMRMixerControl9>(m_filter)) { + VMR9ProcAmpControl procAmp; + procAmp.dwSize = sizeof(VMR9ProcAmpControl); + procAmp.dwFlags = m_dirtyValues; + + if (m_dirtyValues & ProcAmpControl9_Brightness) { + procAmp.Brightness = scaleProcAmpValue( + control, ProcAmpControl9_Brightness, m_brightness); + } + if (m_dirtyValues & ProcAmpControl9_Contrast) { + procAmp.Contrast = scaleProcAmpValue( + control, ProcAmpControl9_Contrast, m_contrast); + } + if (m_dirtyValues & ProcAmpControl9_Hue) { + procAmp.Hue = scaleProcAmpValue( + control, ProcAmpControl9_Hue, m_hue); + } + if (m_dirtyValues & ProcAmpControl9_Saturation) { + procAmp.Saturation = scaleProcAmpValue( + control, ProcAmpControl9_Saturation, m_saturation); + } + + if (SUCCEEDED(control->SetProcAmpControl(0, &procAmp))) { + m_dirtyValues = 0; + } + + control->Release(); + } +} + +float Vmr9VideoWindowControl::scaleProcAmpValue( + IVMRMixerControl9 *control, VMR9ProcAmpControlFlags property, int value) const +{ + float scaledValue = 0.0; + + VMR9ProcAmpControlRange range; + range.dwSize = sizeof(VMR9ProcAmpControlRange); + range.dwProperty = property; + + if (SUCCEEDED(control->GetProcAmpControlRange(0, &range))) { + scaledValue = range.DefaultValue; + if (value > 0) + scaledValue += float(value) * (range.MaxValue - range.DefaultValue) / 100; + else if (value < 0) + scaledValue -= float(value) * (range.MinValue - range.DefaultValue) / 100; + } + + return scaledValue; +} + +QT_END_NAMESPACE + diff --git a/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.h b/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.h new file mode 100644 index 0000000..a0aca95 --- /dev/null +++ b/src/plugins/mediaservices/directshow/mediaplayer/vmr9videowindowcontrol.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VMR9VIDEOWINDOWCONTROL_H +#define VMR9VIDEOWINDOWCONTROL_H + +#include <QtMultimedia/qvideowindowcontrol.h> + +#include <dshow.h> +#include <d3d9.h> +#include <vmr9.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class Vmr9VideoWindowControl : public QVideoWindowControl +{ + Q_OBJECT +public: + Vmr9VideoWindowControl(QObject *parent = 0); + ~Vmr9VideoWindowControl(); + + IBaseFilter *filter() const { return m_filter; } + + WId winId() const; + void setWinId(WId id); + + QRect displayRect() const; + void setDisplayRect(const QRect &rect); + + bool isFullScreen() const; + void setFullScreen(bool fullScreen); + + void repaint(); + + QSize nativeSize() const; + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + +private: + void setProcAmpValues(); + float scaleProcAmpValue( + IVMRMixerControl9 *control, VMR9ProcAmpControlFlags property, int value) const; + + IBaseFilter *m_filter; + WId m_windowId; + DWORD m_dirtyValues; + int m_brightness; + int m_contrast; + int m_hue; + int m_saturation; + bool m_fullScreen; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/gstreamer.pro b/src/plugins/mediaservices/gstreamer/gstreamer.pro new file mode 100644 index 0000000..db0ee4e --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/gstreamer.pro @@ -0,0 +1,58 @@ +TARGET = gstengine +include(../../qpluginbase.pri) + +QT += multimedia + +unix:contains(QT_CONFIG, alsa) { + DEFINES += HAVE_ALSA + LIBS += -lasound +} + +LIBS += -lXv + +CONFIG += link_pkgconfig + +PKGCONFIG += \ + gstreamer-0.10 \ + gstreamer-base-0.10 \ + gstreamer-interfaces-0.10 \ + gstreamer-audio-0.10 \ + gstreamer-video-0.10 + +# Input +HEADERS += \ + qgstreamermessage.h \ + qgstreamerbushelper.h \ + qgstreamervideooutputcontrol.h \ + qgstreamervideorendererinterface.h \ + qgstreamervideowidget.h \ + qgstreamerserviceplugin.h \ + qgstreamervideoinputdevicecontrol.h \ + qgstreamervideooverlay.h \ + qgstreamervideorenderer.h \ + qgstvideobuffer.h \ + qvideosurfacegstsink.h \ + qx11videosurface.h \ + qgstxvimagebuffer.h + + +SOURCES += \ + qgstreamermessage.cpp \ + qgstreamerbushelper.cpp \ + qgstreamervideooutputcontrol.cpp \ + qgstreamervideorendererinterface.cpp \ + qgstreamervideowidget.cpp \ + qgstreamerserviceplugin.cpp \ + qgstreamervideoinputdevicecontrol.cpp \ + qgstreamervideooverlay.cpp \ + qgstreamervideorenderer.cpp \ + qgstvideobuffer.cpp \ + qvideosurfacegstsink.cpp \ + qx11videosurface.cpp \ + qgstxvimagebuffer.cpp + +include(mediaplayer/mediaplayer.pri) + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mediaservices +target.path = $$[QT_INSTALL_PLUGINS]/plugins/mediaservices +INSTALLS += target diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/mediaplayer.pri b/src/plugins/mediaservices/gstreamer/mediaplayer/mediaplayer.pri new file mode 100644 index 0000000..19ff034 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/mediaplayer.pri @@ -0,0 +1,17 @@ +INCLUDEPATH += $$PWD + +DEFINES += QMEDIA_GSTREAMER_PLAYER + +HEADERS += \ + $$PWD/qgstreamerplayercontrol.h \ + $$PWD/qgstreamerplayerservice.h \ + $$PWD/qgstreamerplayersession.h \ + $$PWD/qgstreamermetadataprovider.h + +SOURCES += \ + $$PWD/qgstreamerplayercontrol.cpp \ + $$PWD/qgstreamerplayerservice.cpp \ + $$PWD/qgstreamerplayersession.cpp \ + $$PWD/qgstreamermetadataprovider.cpp + + diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp new file mode 100644 index 0000000..49eeb23 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamermetadataprovider.h" +#include "qgstreamerplayersession.h" +#include <QDebug> + +#include <gst/gstversion.h> + +struct QGstreamerMetaDataKeyLookup +{ + QtMultimedia::MetaData key; + const char *token; +}; + +static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = +{ + { QtMultimedia::Title, GST_TAG_TITLE }, + //{ QtMultimedia::SubTitle, 0 }, + //{ QtMultimedia::Author, 0 }, + { QtMultimedia::Comment, GST_TAG_COMMENT }, + { QtMultimedia::Description, GST_TAG_DESCRIPTION }, + //{ QtMultimedia::Category, 0 }, + { QtMultimedia::Genre, GST_TAG_GENRE }, + { QtMultimedia::Year, "year" }, + //{ QtMultimedia::UserRating, 0 }, + + { QtMultimedia::Language, GST_TAG_LANGUAGE_CODE }, + + { QtMultimedia::Publisher, GST_TAG_ORGANIZATION }, + { QtMultimedia::Copyright, GST_TAG_COPYRIGHT }, + //{ QtMultimedia::ParentalRating, 0 }, + //{ QtMultimedia::RatingOrganisation, 0 }, + + // Media + //{ QtMultimedia::Size, 0 }, + //{ QtMultimedia::MediaType, 0 }, + { QtMultimedia::Duration, GST_TAG_DURATION }, + + // Audio + { QtMultimedia::AudioBitRate, GST_TAG_BITRATE }, + { QtMultimedia::AudioCodec, GST_TAG_AUDIO_CODEC }, + //{ QtMultimedia::ChannelCount, 0 }, + //{ QtMultimedia::Frequency, 0 }, + + // Music + { QtMultimedia::AlbumTitle, GST_TAG_ALBUM }, + { QtMultimedia::AlbumArtist, GST_TAG_ARTIST}, + { QtMultimedia::ContributingArtist, GST_TAG_PERFORMER }, +#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19) + { QtMultimedia::Composer, GST_TAG_COMPOSER }, +#endif + //{ QtMultimedia::Conductor, 0 }, + //{ QtMultimedia::Lyrics, 0 }, + //{ QtMultimedia::Mood, 0 }, + { QtMultimedia::TrackNumber, GST_TAG_TRACK_NUMBER }, + + //{ QtMultimedia::CoverArtUrlSmall, 0 }, + //{ QtMultimedia::CoverArtUrlLarge, 0 }, + + // Image/Video + //{ QtMultimedia::Resolution, 0 }, + //{ QtMultimedia::PixelAspectRatio, 0 }, + + // Video + //{ QtMultimedia::VideoFrameRate, 0 }, + //{ QtMultimedia::VideoBitRate, 0 }, + { QtMultimedia::VideoCodec, GST_TAG_VIDEO_CODEC }, + + //{ QtMultimedia::PosterUrl, 0 }, + + // Movie + //{ QtMultimedia::ChapterNumber, 0 }, + //{ QtMultimedia::Director, 0 }, + { QtMultimedia::LeadPerformer, GST_TAG_PERFORMER }, + //{ QtMultimedia::Writer, 0 }, + + // Photos + //{ QtMultimedia::CameraManufacturer, 0 }, + //{ QtMultimedia::CameraModel, 0 }, + //{ QtMultimedia::Event, 0 }, + //{ QtMultimedia::Subject, 0 } +}; + +QGstreamerMetaDataProvider::QGstreamerMetaDataProvider(QGstreamerPlayerSession *session, QObject *parent) + :QMetaDataControl(parent), m_session(session) +{ + connect(m_session, SIGNAL(tagsChanged()), SLOT(updateTags())); +} + +QGstreamerMetaDataProvider::~QGstreamerMetaDataProvider() +{ +} + +bool QGstreamerMetaDataProvider::isMetaDataAvailable() const +{ + return !m_session->tags().isEmpty(); +} + +bool QGstreamerMetaDataProvider::isWritable() const +{ + return false; +} + +QVariant QGstreamerMetaDataProvider::metaData(QtMultimedia::MetaData key) const +{ + static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); + + for (int i = 0; i < count; ++i) { + if (qt_gstreamerMetaDataKeys[i].key == key) { + return m_session->tags().value(QByteArray(qt_gstreamerMetaDataKeys[i].token)); + } + } + return QVariant(); +} + +void QGstreamerMetaDataProvider::setMetaData(QtMultimedia::MetaData key, QVariant const &value) +{ + Q_UNUSED(key); + Q_UNUSED(value); +} + +QList<QtMultimedia::MetaData> QGstreamerMetaDataProvider::availableMetaData() const +{ + static QMap<QByteArray, QtMultimedia::MetaData> keysMap; + if (keysMap.isEmpty()) { + const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); + for (int i = 0; i < count; ++i) { + keysMap[QByteArray(qt_gstreamerMetaDataKeys[i].token)] = qt_gstreamerMetaDataKeys[i].key; + } + } + + QList<QtMultimedia::MetaData> res; + foreach (const QByteArray &key, m_session->tags().keys()) { + QtMultimedia::MetaData tag = keysMap.value(key, QtMultimedia::MetaData(-1)); + if (tag != -1) + res.append(tag); + } + + return res; +} + +QVariant QGstreamerMetaDataProvider::extendedMetaData(const QString &key) const +{ + return m_session->tags().value(key.toLatin1()); +} + +void QGstreamerMetaDataProvider::setExtendedMetaData(const QString &key, QVariant const &value) +{ + Q_UNUSED(key); + Q_UNUSED(value); +} + +QStringList QGstreamerMetaDataProvider::availableExtendedMetaData() const +{ + QStringList res; + foreach (const QByteArray &key, m_session->tags().keys()) + res.append(QString(key)); + + return res; +} + +void QGstreamerMetaDataProvider::updateTags() +{ + emit metaDataChanged(); +} diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamermetadataprovider.h b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamermetadataprovider.h new file mode 100644 index 0000000..267c2d7 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamermetadataprovider.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERMETADATAPROVIDER_H +#define QGSTREAMERMETADATAPROVIDER_H + +#include <QtMultimedia/qmetadatacontrol.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerPlayerSession; + +class QGstreamerMetaDataProvider : public QMetaDataControl +{ + Q_OBJECT +public: + QGstreamerMetaDataProvider( QGstreamerPlayerSession *session, QObject *parent ); + virtual ~QGstreamerMetaDataProvider(); + + bool isMetaDataAvailable() const; + bool isWritable() const; + + QVariant metaData(QtMultimedia::MetaData key) const; + void setMetaData(QtMultimedia::MetaData key, const QVariant &value); + QList<QtMultimedia::MetaData> availableMetaData() const; + + QVariant extendedMetaData(const QString &key) const ; + void setExtendedMetaData(const QString &key, const QVariant &value); + QStringList availableExtendedMetaData() const; + +private slots: + void updateTags(); + +private: + QGstreamerPlayerSession *m_session; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGSTREAMERMETADATAPROVIDER_H diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp new file mode 100644 index 0000000..d417266 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp @@ -0,0 +1,343 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamerplayercontrol.h" +#include "qgstreamerplayersession.h" + +#include <qmediaplaylistnavigator.h> + +#include <QtCore/qdir.h> +#include <QtCore/qsocketnotifier.h> +#include <QtCore/qurl.h> +#include <QtCore/qdebug.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent) + : QMediaPlayerControl(parent) + , m_session(session) + , m_stream(0) + , m_fifoNotifier(0) + , m_fifoCanWrite(false) + , m_bufferSize(0) + , m_bufferOffset(0) +{ + m_fifoFd[0] = -1; + m_fifoFd[1] = -1; + + connect(m_session, SIGNAL(positionChanged(qint64)), + this, SIGNAL(positionChanged(qint64))); + connect(m_session, SIGNAL(durationChanged(qint64)), + this, SIGNAL(durationChanged(qint64))); + connect(m_session, SIGNAL(mutedStateChanged(bool)), + this, SIGNAL(mutedChanged(bool))); + connect(m_session, SIGNAL(volumeChanged(int)), + this, SIGNAL(volumeChanged(int))); + connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)), + this, SIGNAL(stateChanged(QMediaPlayer::State))); + connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + connect(m_session,SIGNAL(bufferingProgressChanged(int)), + this, SIGNAL(bufferStatusChanged(int))); + connect(m_session, SIGNAL(audioAvailableChanged(bool)), + this, SIGNAL(audioAvailableChanged(bool))); + connect(m_session, SIGNAL(videoAvailableChanged(bool)), + this, SIGNAL(videoAvailableChanged(bool))); + connect(m_session, SIGNAL(seekableChanged(bool)), + this, SIGNAL(seekableChanged(bool))); + connect(m_session, SIGNAL(error(int,QString)), + this, SIGNAL(error(int,QString))); +} + +QGstreamerPlayerControl::~QGstreamerPlayerControl() +{ + if (m_fifoFd[0] >= 0) { + ::close(m_fifoFd[0]); + ::close(m_fifoFd[1]); + m_fifoFd[0] = -1; + m_fifoFd[1] = -1; + } +} + +qint64 QGstreamerPlayerControl::position() const +{ + return m_session->position(); +} + +qint64 QGstreamerPlayerControl::duration() const +{ + return m_session->duration(); +} + +QMediaPlayer::State QGstreamerPlayerControl::state() const +{ + return m_session->state(); +} + +QMediaPlayer::MediaStatus QGstreamerPlayerControl::mediaStatus() const +{ + return m_session->mediaStatus(); +} + +int QGstreamerPlayerControl::bufferStatus() const +{ + return 100; +} + +int QGstreamerPlayerControl::volume() const +{ + return m_session->volume(); +} + +bool QGstreamerPlayerControl::isMuted() const +{ + return m_session->isMuted(); +} + +bool QGstreamerPlayerControl::isSeekable() const +{ + return m_session->isSeekable(); +} + +QMediaTimeRange QGstreamerPlayerControl::availablePlaybackRanges() const +{ + QMediaTimeRange ranges; + + if (m_session->isSeekable()) + ranges.addInterval(0, m_session->duration()); + + return ranges; +} + +qreal QGstreamerPlayerControl::playbackRate() const +{ + return m_session->playbackRate(); +} + +void QGstreamerPlayerControl::setPlaybackRate(qreal rate) +{ + m_session->setPlaybackRate(rate); +} + +void QGstreamerPlayerControl::setPosition(qint64 pos) +{ + m_session->seek(pos); +} + +void QGstreamerPlayerControl::play() +{ + m_session->play(); + + if (m_fifoFd[1] >= 0) { + m_fifoCanWrite = true; + + writeFifo(); + } +} + +void QGstreamerPlayerControl::pause() +{ + m_session->pause(); +} + +void QGstreamerPlayerControl::stop() +{ + m_session->stop(); +} + +void QGstreamerPlayerControl::setVolume(int volume) +{ + m_session->setVolume(volume); +} + +void QGstreamerPlayerControl::setMuted(bool muted) +{ + m_session->setMuted(muted); +} + +QMediaContent QGstreamerPlayerControl::media() const +{ + return m_currentResource; +} + +const QIODevice *QGstreamerPlayerControl::mediaStream() const +{ + return m_stream; +} + +void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream) +{ + m_session->stop(); + + if (m_stream) { + closeFifo(); + + disconnect(m_stream, SIGNAL(readyRead()), this, SLOT(writeFifo())); + m_stream = 0; + } + + m_currentResource = content; + m_stream = stream; + + QUrl url; + + if (m_stream) { + if (m_stream->isReadable() && openFifo()) { + url = QUrl(QString(QLatin1String("fd://%1")).arg(m_fifoFd[0])); + } + } else if (!content.isNull()) { + url = content.canonicalUrl(); + } + + m_session->load(url); + + emit mediaChanged(m_currentResource); +} + +void QGstreamerPlayerControl::setVideoOutput(QObject *output) +{ + m_session->setVideoRenderer(output); +} + +bool QGstreamerPlayerControl::isAudioAvailable() const +{ + return m_session->isAudioAvailable(); +} + +bool QGstreamerPlayerControl::isVideoAvailable() const +{ + return m_session->isVideoAvailable(); +} + +void QGstreamerPlayerControl::writeFifo() +{ + if (m_fifoCanWrite) { + qint64 bytesToRead = qMin<qint64>( + m_stream->bytesAvailable(), PIPE_BUF - m_bufferSize); + + if (bytesToRead > 0) { + int bytesRead = m_stream->read(&m_buffer[m_bufferOffset + m_bufferSize], bytesToRead); + + if (bytesRead > 0) + m_bufferSize += bytesRead; + } + + if (m_bufferSize > 0) { + int bytesWritten = ::write(m_fifoFd[1], &m_buffer[m_bufferOffset], size_t(m_bufferSize)); + + if (bytesWritten > 0) { + m_bufferOffset += bytesWritten; + m_bufferSize -= bytesWritten; + + if (m_bufferSize == 0) + m_bufferOffset = 0; + } else if (errno == EAGAIN) { + m_fifoCanWrite = false; + } else { + closeFifo(); + } + } + } + + m_fifoNotifier->setEnabled(m_stream->bytesAvailable() > 0); +} + +void QGstreamerPlayerControl::fifoReadyWrite(int socket) +{ + if (socket == m_fifoFd[1]) { + m_fifoCanWrite = true; + + writeFifo(); + } +} + +bool QGstreamerPlayerControl::openFifo() +{ + Q_ASSERT(m_fifoFd[0] < 0); + Q_ASSERT(m_fifoFd[1] < 0); + + if (::pipe(m_fifoFd) == 0) { + int flags = ::fcntl(m_fifoFd[1], F_GETFD); + + if (::fcntl(m_fifoFd[1], F_SETFD, flags | O_NONBLOCK) >= 0) { + m_fifoNotifier = new QSocketNotifier(m_fifoFd[1], QSocketNotifier::Write); + + connect(m_fifoNotifier, SIGNAL(activated(int)), this, SLOT(fifoReadyWrite(int))); + + return true; + } else { + qWarning("Failed to make pipe non blocking %d", errno); + + ::close(m_fifoFd[0]); + ::close(m_fifoFd[1]); + + m_fifoFd[0] = -1; + m_fifoFd[1] = -1; + + return false; + } + } else { + qWarning("Failed to create pipe %d", errno); + + return false; + } +} + +void QGstreamerPlayerControl::closeFifo() +{ + if (m_fifoFd[0] >= 0) { + delete m_fifoNotifier; + m_fifoNotifier = 0; + + ::close(m_fifoFd[0]); + ::close(m_fifoFd[1]); + m_fifoFd[0] = -1; + m_fifoFd[1] = -1; + + m_fifoCanWrite = false; + + m_bufferSize = 0; + m_bufferOffset = 0; + } +} diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.h b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.h new file mode 100644 index 0000000..ae0f8b6 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERPLAYERCONTROL_H +#define QGSTREAMERPLAYERCONTROL_H + +#include <QtCore/qobject.h> + +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaplayer.h> + +#include <limits.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaPlaylist; +class QGstreamerPlayerSession; +class QGstreamerPlayerService; +class QMediaPlaylistNavigator; +class QSocketNotifier; + +class QGstreamerPlayerControl : public QMediaPlayerControl +{ + Q_OBJECT + +public: + QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent = 0); + ~QGstreamerPlayerControl(); + + QMediaPlayer::State state() const; + QMediaPlayer::MediaStatus mediaStatus() const; + + qint64 position() const; + qint64 duration() const; + + int bufferStatus() const; + + int volume() const; + bool isMuted() const; + + bool isAudioAvailable() const; + bool isVideoAvailable() const; + void setVideoOutput(QObject *output); + + bool isSeekable() const; + QMediaTimeRange availablePlaybackRanges() const; + + qreal playbackRate() const; + void setPlaybackRate(qreal rate); + + QMediaContent media() const; + const QIODevice *mediaStream() const; + void setMedia(const QMediaContent&, QIODevice *); + +public Q_SLOTS: + void setPosition(qint64 pos); + + void play(); + void pause(); + void stop(); + + void setVolume(int volume); + void setMuted(bool muted); + +private Q_SLOTS: + void writeFifo(); + void fifoReadyWrite(int socket); + +private: + bool openFifo(); + void closeFifo(); + + QGstreamerPlayerSession *m_session; + QMediaContent m_currentResource; + QIODevice *m_stream; + QSocketNotifier *m_fifoNotifier; + int m_fifoFd[2]; + bool m_fifoCanWrite; + int m_bufferSize; + int m_bufferOffset; + char m_buffer[PIPE_BUF]; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayerservice.cpp new file mode 100644 index 0000000..d5d7bd0 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayerservice.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qvariant.h> +#include <QtCore/qdebug.h> +#include <QtGui/qwidget.h> + +#include "qgstreamerplayerservice.h" +#include "qgstreamerplayercontrol.h" +#include "qgstreamerplayersession.h" +#include "qgstreamermetadataprovider.h" +#include "qgstreamervideooutputcontrol.h" + +#include "qgstreamervideooverlay.h" +#include "qgstreamervideorenderer.h" + +#include "qgstreamervideowidget.h" +//#include "qgstreamerstreamscontrol.h" + +#include <qmediaplaylistnavigator.h> +#include <qmediaplaylist.h> + + +QT_BEGIN_NAMESPACE + + +QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent): + QMediaService(parent) +{ + m_session = new QGstreamerPlayerSession(this); + m_control = new QGstreamerPlayerControl(m_session, this); + m_metaData = new QGstreamerMetaDataProvider(m_session, this); + m_videoOutput = new QGstreamerVideoOutputControl(this); +// m_streamsControl = new QGstreamerStreamsControl(m_session,this); + + connect(m_videoOutput, SIGNAL(outputChanged(QVideoOutputControl::Output)), + this, SLOT(videoOutputChanged(QVideoOutputControl::Output))); + m_videoRenderer = new QGstreamerVideoRenderer(this); + m_videoWindow = new QGstreamerVideoOverlay(this); + m_videoWidget = new QGstreamerVideoWidgetControl(this); + + m_videoOutput->setAvailableOutputs(QList<QVideoOutputControl::Output>() + << QVideoOutputControl::RendererOutput + << QVideoOutputControl::WindowOutput + << QVideoOutputControl::WidgetOutput); +} + +QGstreamerPlayerService::~QGstreamerPlayerService() +{ +} + +QMediaControl *QGstreamerPlayerService::control(const char *name) const +{ + if (qstrcmp(name,QMediaPlayerControl_iid) == 0) + return m_control; + + if (qstrcmp(name,QMetaDataControl_iid) == 0) + return m_metaData; + +// if (qstrcmp(name,QMediaStreamsControl_iid) == 0) +// return m_streamsControl; + + if (qstrcmp(name, QVideoOutputControl_iid) == 0) + return m_videoOutput; + + if (qstrcmp(name, QVideoWidgetControl_iid) == 0) + return m_videoWidget; + + if (qstrcmp(name, QVideoRendererControl_iid) == 0) + return m_videoRenderer; + + if (qstrcmp(name, QVideoWindowControl_iid) == 0) + return m_videoWindow; + + return 0; +} + +void QGstreamerPlayerService::videoOutputChanged(QVideoOutputControl::Output output) +{ + switch (output) { + case QVideoOutputControl::NoOutput: + m_control->setVideoOutput(0); + break; + case QVideoOutputControl::RendererOutput: + m_control->setVideoOutput(m_videoRenderer); + break; + case QVideoOutputControl::WindowOutput: + m_control->setVideoOutput(m_videoWindow); + break; + case QVideoOutputControl::WidgetOutput: + m_control->setVideoOutput(m_videoWidget); + break; + default: + qWarning("Invalid video output selection"); + break; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayerservice.h b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayerservice.h new file mode 100644 index 0000000..f60c72e --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayerservice.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERPLAYERSERVICE_H +#define QGSTREAMERPLAYERSERVICE_H + +#include <QtCore/qobject.h> +#include <QtCore/qiodevice.h> + +#include <QtMultimedia/qmediaservice.h> + +#include "qgstreamervideooutputcontrol.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaMetaData; +class QMediaPlayerControl; +class QMediaPlaylist; +class QMediaPlaylistNavigator; +class QGstreamerMetaData; +class QGstreamerPlayerControl; +class QGstreamerPlayerSession; +class QGstreamerMetaDataProvider; +class QGstreamerStreamsControl; +class QGstreamerVideoRenderer; +class QGstreamerVideoOverlay; +class QGstreamerVideoWidgetControl; + + +class QGstreamerPlayerService : public QMediaService +{ + Q_OBJECT +public: + QGstreamerPlayerService(QObject *parent = 0); + ~QGstreamerPlayerService(); + + //void setVideoOutput(QObject *output); + + QMediaControl *control(const char *name) const; + +private slots: + void videoOutputChanged(QVideoOutputControl::Output output); + +private: + QGstreamerPlayerControl *m_control; + QGstreamerPlayerSession *m_session; + QGstreamerMetaDataProvider *m_metaData; + QGstreamerVideoOutputControl *m_videoOutput; + QGstreamerStreamsControl *m_streamsControl; + + QGstreamerVideoRenderer *m_videoRenderer; + QGstreamerVideoOverlay *m_videoWindow; + QGstreamerVideoWidgetControl *m_videoWidget; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.cpp new file mode 100644 index 0000000..2e5d10f --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -0,0 +1,712 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamerplayersession.h" +#include "qgstreamerbushelper.h" + +#include "qgstreamervideorendererinterface.h" + +#include <gst/gstvalue.h> + +#include <QtCore/qdatetime.h> +#include <QtCore/qdebug.h> + +//#define USE_PLAYBIN2 + +QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) + :QObject(parent), + m_state(QMediaPlayer::StoppedState), + m_mediaStatus(QMediaPlayer::UnknownMediaStatus), + m_busHelper(0), + m_playbin(0), + m_nullVideoOutput(0), + m_bus(0), + m_renderer(0), + m_volume(100), + m_playbackRate(1.0), + m_muted(false), + m_audioAvailable(false), + m_videoAvailable(false), + m_seekable(false), + m_lastPosition(0), + m_duration(-1) +{ + static bool initialized = false; + if (!initialized) { + initialized = true; + gst_init(NULL, NULL); + } + +#ifdef USE_PLAYBIN2 + m_playbin = gst_element_factory_make("playbin2", NULL); +#else + m_playbin = gst_element_factory_make("playbin", NULL); +#endif + + if (m_playbin != 0) { + // Sort out messages + m_bus = gst_element_get_bus(m_playbin); + m_busHelper = new QGstreamerBusHelper(m_bus, this); + connect(m_busHelper, SIGNAL(message(QGstreamerMessage)), SLOT(busMessage(QGstreamerMessage))); + m_busHelper->installSyncEventFilter(this); + + m_nullVideoOutput = gst_element_factory_make("fakesink", NULL); + g_object_set(G_OBJECT(m_playbin), "video-sink", m_nullVideoOutput, NULL); + + // Initial volume + double volume = 1.0; + g_object_get(G_OBJECT(m_playbin), "volume", &volume, NULL); + m_volume = int(volume*100); + } +} + +QGstreamerPlayerSession::~QGstreamerPlayerSession() +{ + if (m_playbin) { + stop(); + + delete m_busHelper; + gst_object_unref(GST_OBJECT(m_bus)); + gst_object_unref(GST_OBJECT(m_playbin)); + } +} + +void QGstreamerPlayerSession::load(const QUrl &url) +{ + m_url = url; + if (m_playbin) { + m_tags.clear(); + emit tagsChanged(); + + g_object_set(G_OBJECT(m_playbin), "uri", m_url.toEncoded().constData(), NULL); + +// if (!m_streamTypes.isEmpty()) { +// m_streamProperties.clear(); +// m_streamTypes.clear(); +// +// emit streamsChanged(); +// } + } +} + +qint64 QGstreamerPlayerSession::duration() const +{ + return m_duration; +} + +qint64 QGstreamerPlayerSession::position() const +{ + GstFormat format = GST_FORMAT_TIME; + gint64 position = 0; + + if ( m_playbin && gst_element_query_position(m_playbin, &format, &position)) + return position / 1000000; + else + return 0; +} + +qreal QGstreamerPlayerSession::playbackRate() const +{ + return m_playbackRate; +} + +void QGstreamerPlayerSession::setPlaybackRate(qreal rate) +{ + if (!qFuzzyCompare(m_playbackRate, rate)) { + m_playbackRate = rate; + if (m_playbin) { + gst_element_seek(m_playbin, rate, GST_FORMAT_TIME, + GstSeekFlags(GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT), + GST_SEEK_TYPE_NONE,0, + GST_SEEK_TYPE_NONE,0 ); + } + } +} + + +//int QGstreamerPlayerSession::activeStream(QMediaStreamsControl::StreamType streamType) const +//{ +// int streamNumber = -1; +// if (m_playbin) { +// switch (streamType) { +// case QMediaStreamsControl::AudioStream: +// g_object_set(G_OBJECT(m_playbin), "current-audio", streamNumber, NULL); +// break; +// case QMediaStreamsControl::VideoStream: +// g_object_set(G_OBJECT(m_playbin), "current-video", streamNumber, NULL); +// break; +// case QMediaStreamsControl::SubPictureStream: +// g_object_set(G_OBJECT(m_playbin), "current-text", streamNumber, NULL); +// break; +// default: +// break; +// } +// } +// +//#ifdef USE_PLAYBIN2 +// streamNumber += m_playbin2StreamOffset.value(streamType,0); +//#endif +// +// return streamNumber; +//} + +//void QGstreamerPlayerSession::setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber) +//{ +//#ifdef USE_PLAYBIN2 +// streamNumber -= m_playbin2StreamOffset.value(streamType,0); +//#endif +// +// if (m_playbin) { +// switch (streamType) { +// case QMediaStreamsControl::AudioStream: +// g_object_get(G_OBJECT(m_playbin), "current-audio", &streamNumber, NULL); +// break; +// case QMediaStreamsControl::VideoStream: +// g_object_get(G_OBJECT(m_playbin), "current-video", &streamNumber, NULL); +// break; +// case QMediaStreamsControl::SubPictureStream: +// g_object_get(G_OBJECT(m_playbin), "current-text", &streamNumber, NULL); +// break; +// default: +// break; +// } +// } +//} + + +bool QGstreamerPlayerSession::isBuffering() const +{ + return false; +} + +int QGstreamerPlayerSession::bufferingProgress() const +{ + return 0; +} + +int QGstreamerPlayerSession::volume() const +{ + return m_volume; +} + +bool QGstreamerPlayerSession::isMuted() const +{ + return m_muted; +} + +bool QGstreamerPlayerSession::isAudioAvailable() const +{ + return m_audioAvailable; +} + +void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) +{ + m_renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput); + if (m_renderer) + g_object_set(G_OBJECT(m_playbin), "video-sink", m_renderer->videoSink(), NULL); + else + g_object_set(G_OBJECT(m_playbin), "video-sink", m_nullVideoOutput, NULL); +} + +bool QGstreamerPlayerSession::isVideoAvailable() const +{ + return m_videoAvailable; +} + +bool QGstreamerPlayerSession::isSeekable() const +{ + return m_seekable; +} + +void QGstreamerPlayerSession::play() +{ + if (m_playbin) { + if (gst_element_set_state(m_playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { + qWarning() << "GStreamer; Unable to play -" << m_url.toString(); + m_state = QMediaPlayer::StoppedState; + m_mediaStatus = QMediaPlayer::InvalidMedia; + + emit stateChanged(m_state); + emit mediaStatusChanged(m_mediaStatus); + + emit error(int(QMediaPlayer::ResourceError), tr("Unable to play %1").arg(m_url.path())); + } + } +} + +void QGstreamerPlayerSession::pause() +{ + if (m_playbin) + gst_element_set_state(m_playbin, GST_STATE_PAUSED); +} + +void QGstreamerPlayerSession::stop() +{ + if (m_playbin) { + gst_element_set_state(m_playbin, GST_STATE_NULL); + + //we have to do it here, since gstreamer will not emit bus messages any more + if (m_state != QMediaPlayer::StoppedState) + emit stateChanged(m_state = QMediaPlayer::StoppedState); + } +} + +void QGstreamerPlayerSession::seek(qint64 ms) +{ + if (m_playbin && m_state != QMediaPlayer::StoppedState) { + gint64 position = (gint64)ms * 1000000; + gst_element_seek_simple(m_playbin, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, position); + } +} + +void QGstreamerPlayerSession::setVolume(int volume) +{ + m_volume = volume; + emit volumeChanged(m_volume); + + if (!m_muted && m_playbin) + g_object_set(G_OBJECT(m_playbin), "volume", m_volume/100.0, NULL); + +} + +void QGstreamerPlayerSession::setMuted(bool muted) +{ + m_muted = muted; + + g_object_set(G_OBJECT(m_playbin), "volume", (m_muted ? 0 : m_volume/100.0), NULL); + + emit mutedStateChanged(m_muted); +} + +static void addTagToMap(const GstTagList *list, + const gchar *tag, + gpointer user_data) +{ + QMap<QByteArray, QVariant> *map = reinterpret_cast<QMap<QByteArray, QVariant>* >(user_data); + + GValue val; + val.g_type = 0; + gst_tag_list_copy_value(&val,list,tag); + + switch( G_VALUE_TYPE(&val) ) { + case G_TYPE_STRING: + { + const gchar *str_value = g_value_get_string(&val); + map->insert(QByteArray(tag), QString::fromUtf8(str_value)); + break; + } + case G_TYPE_INT: + map->insert(QByteArray(tag), g_value_get_int(&val)); + break; + case G_TYPE_UINT: + map->insert(QByteArray(tag), g_value_get_uint(&val)); + break; + case G_TYPE_LONG: + map->insert(QByteArray(tag), qint64(g_value_get_long(&val))); + break; + case G_TYPE_BOOLEAN: + map->insert(QByteArray(tag), g_value_get_boolean(&val)); + break; + case G_TYPE_CHAR: + map->insert(QByteArray(tag), g_value_get_char(&val)); + break; + case G_TYPE_DOUBLE: + map->insert(QByteArray(tag), g_value_get_double(&val)); + break; + default: + // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch + if (G_VALUE_TYPE(&val) == GST_TYPE_DATE) { + const GDate *date = gst_value_get_date(&val); + if (g_date_valid(date)) { + int year = g_date_get_year(date); + int month = g_date_get_month(date); + int day = g_date_get_day(date); + map->insert(QByteArray(tag), QDate(year,month,day)); + if (!map->contains("year")) + map->insert("year", year); + } + } else if (G_VALUE_TYPE(&val) == GST_TYPE_FRACTION) { + int nom = gst_value_get_fraction_numerator(&val); + int denom = gst_value_get_fraction_denominator(&val); + + if (denom > 0) { + map->insert(QByteArray(tag), double(nom)/denom); + } + } + break; + } + + g_value_unset(&val); +} + +void QGstreamerPlayerSession::setSeekable(bool seekable) +{ + if (seekable != m_seekable) { + m_seekable = seekable; + emit seekableChanged(m_seekable); + } +} + +void QGstreamerPlayerSession::setMediaStatus(QMediaPlayer::MediaStatus status) +{ + if (m_mediaStatus != status) { + m_mediaStatus = status; + emit mediaStatusChanged(status); + } +} + +bool QGstreamerPlayerSession::processSyncMessage(const QGstreamerMessage &message) +{ + GstMessage* gm = message.rawMessage(); + + if (gm && + GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT && + gst_structure_has_name(gm->structure, "prepare-xwindow-id")) + { + if (m_renderer) + m_renderer->precessNewStream(); + return true; + } + + return false; +} + +void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message) +{ + GstMessage* gm = message.rawMessage(); + + if (gm == 0) { + // Null message, query current position + quint32 newPos = position(); + + if (newPos/1000 != m_lastPosition) { + m_lastPosition = newPos/1000; + emit positionChanged(newPos); + } + + } else { + //tag message comes from elements inside playbin, not from playbin itself + if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) { + //qDebug() << "tag message"; + GstTagList *tag_list; + gst_message_parse_tag(gm, &tag_list); + gst_tag_list_foreach(tag_list, addTagToMap, &m_tags); + + //qDebug() << m_tags; + + emit tagsChanged(); + } + + if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) { + switch (GST_MESSAGE_TYPE(gm)) { + case GST_MESSAGE_DURATION: + break; + + case GST_MESSAGE_STATE_CHANGED: + { + GstState oldState; + GstState newState; + GstState pending; + + gst_message_parse_state_changed(gm, &oldState, &newState, &pending); + + /*QStringList states; + states << "GST_STATE_VOID_PENDING" << "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING"; + + qDebug() << QString("state changed: old: %1 new: %2 pending: %3") \ + .arg(states[oldState]) \ + .arg(states[newState]) \ + .arg(states[pending]);*/ + + switch (newState) { + case GST_STATE_VOID_PENDING: + case GST_STATE_NULL: + setMediaStatus(QMediaPlayer::UnknownMediaStatus); + setSeekable(false); + if (m_state != QMediaPlayer::StoppedState) + emit stateChanged(m_state = QMediaPlayer::StoppedState); + break; + case GST_STATE_READY: + setMediaStatus(QMediaPlayer::LoadedMedia); + setSeekable(false); + if (m_state != QMediaPlayer::StoppedState) + emit stateChanged(m_state = QMediaPlayer::StoppedState); + break; + case GST_STATE_PAUSED: + //don't emit state changes for intermediate states + if (m_state != QMediaPlayer::PausedState && pending == GST_STATE_VOID_PENDING) + emit stateChanged(m_state = QMediaPlayer::PausedState); + + setMediaStatus(QMediaPlayer::LoadedMedia); + + //check for seekable + if (oldState == GST_STATE_READY) { + /* + //gst_element_seek_simple doesn't work reliably here, have to find a better solution + + GstFormat format = GST_FORMAT_TIME; + gint64 position = 0; + bool seekable = false; + if (gst_element_query_position(m_playbin, &format, &position)) { + seekable = gst_element_seek_simple(m_playbin, format, GST_SEEK_FLAG_NONE, position); + } + + setSeekable(seekable); + */ + + setSeekable(true); + + if (!qFuzzyCompare(m_playbackRate, qreal(1.0))) + setPlaybackRate(m_playbackRate); + + if (m_renderer) + m_renderer->precessNewStream(); + + } + + + break; + case GST_STATE_PLAYING: + if (oldState == GST_STATE_PAUSED) + getStreamsInfo(); + + if (m_state != QMediaPlayer::PlayingState) + emit stateChanged(m_state = QMediaPlayer::PlayingState); + break; + } + } + break; + + case GST_MESSAGE_EOS: + if (m_state != QMediaPlayer::StoppedState) + emit stateChanged(m_state = QMediaPlayer::StoppedState); + + setMediaStatus(QMediaPlayer::EndOfMedia); + + emit playbackFinished(); + break; + + case GST_MESSAGE_TAG: + case GST_MESSAGE_STREAM_STATUS: + case GST_MESSAGE_UNKNOWN: + break; + case GST_MESSAGE_ERROR: + { + GError *err; + gchar *debug; + gst_message_parse_error (gm, &err, &debug); + emit error(int(QMediaPlayer::ResourceError), QString::fromUtf8(err->message)); + qWarning() << "Error:" << QString::fromUtf8(err->message); + g_error_free (err); + g_free (debug); + } + break; + case GST_MESSAGE_WARNING: + case GST_MESSAGE_INFO: + break; + case GST_MESSAGE_BUFFERING: + setMediaStatus(QMediaPlayer::BufferingMedia); + break; + case GST_MESSAGE_STATE_DIRTY: + case GST_MESSAGE_STEP_DONE: + case GST_MESSAGE_CLOCK_PROVIDE: + case GST_MESSAGE_CLOCK_LOST: + case GST_MESSAGE_NEW_CLOCK: + case GST_MESSAGE_STRUCTURE_CHANGE: + case GST_MESSAGE_APPLICATION: + case GST_MESSAGE_ELEMENT: + case GST_MESSAGE_SEGMENT_START: + case GST_MESSAGE_SEGMENT_DONE: + case GST_MESSAGE_LATENCY: +#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13) + case GST_MESSAGE_ASYNC_START: + case GST_MESSAGE_ASYNC_DONE: +#if GST_VERSION_MICRO >= 23 + case GST_MESSAGE_REQUEST_STATE: +#endif +#endif + case GST_MESSAGE_ANY: + break; + } + } + } +} + +void QGstreamerPlayerSession::getStreamsInfo() +{ + GstFormat format = GST_FORMAT_TIME; + gint64 duration = 0; + + if (gst_element_query_duration(m_playbin, &format, &duration)) { + int newDuration = duration / 1000000; + if (m_duration != newDuration) { + m_duration = newDuration; + emit durationChanged(m_duration); + } + } + + //check if video is available: + bool haveAudio = false; + bool haveVideo = false; +// m_streamProperties.clear(); +// m_streamTypes.clear(); + +#ifdef USE_PLAYBIN2 + gint audioStreamsCount = 0; + gint videoStreamsCount = 0; + gint textStreamsCount = 0; + + g_object_get(G_OBJECT(m_playbin), "n-audio", &audioStreamsCount, NULL); + g_object_get(G_OBJECT(m_playbin), "n-video", &videoStreamsCount, NULL); + g_object_get(G_OBJECT(m_playbin), "n-text", &textStreamsCount, NULL); + + haveAudio = audioStreamsCount > 0; + haveVideo = videoStreamsCount > 0; + + m_playbin2StreamOffset[QMediaStreamsControl::AudioStream] = 0; + m_playbin2StreamOffset[QMediaStreamsControl::VideoStream] = audioStreamsCount; + m_playbin2StreamOffset[QMediaStreamsControl::SubPictureStream] = audioStreamsCount+videoStreamsCount; + + for (int i=0; i<audioStreamsCount; i++) + m_streamTypes.append(QMediaStreamsControl::AudioStream); + + for (int i=0; i<videoStreamsCount; i++) + m_streamTypes.append(QMediaStreamsControl::VideoStream); + + for (int i=0; i<textStreamsCount; i++) + m_streamTypes.append(QMediaStreamsControl::SubPictureStream); + + for (int i=0; i<m_streamTypes.count(); i++) { + QMediaStreamsControl::StreamType streamType = m_streamTypes[i]; + QMap<QtMultimedia::MetaData, QVariant> streamProperties; + + int streamIndex = i - m_playbin2StreamOffset[streamType]; + + GstTagList *tags = 0; + switch (streamType) { + case QMediaStreamsControl::AudioStream: + g_signal_emit_by_name(G_OBJECT(m_playbin), "get-audio-tags", streamIndex, &tags); + break; + case QMediaStreamsControl::VideoStream: + g_signal_emit_by_name(G_OBJECT(m_playbin), "get-video-tags", streamIndex, &tags); + break; + case QMediaStreamsControl::SubPictureStream: + g_signal_emit_by_name(G_OBJECT(m_playbin), "get-text-tags", streamIndex, &tags); + break; + default: + break; + } + + if (tags && gst_is_tag_list(tags)) { + gchar *languageCode = 0; + if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &languageCode)) + streamProperties[QtMultimedia::Language] = QString::fromUtf8(languageCode); + + //qDebug() << "language for setream" << i << QString::fromUtf8(languageCode); + g_free (languageCode); + } + + m_streamProperties.append(streamProperties); + } + +#else + enum { + GST_STREAM_TYPE_UNKNOWN, + GST_STREAM_TYPE_AUDIO, + GST_STREAM_TYPE_VIDEO, + GST_STREAM_TYPE_TEXT, + GST_STREAM_TYPE_SUBPICTURE, + GST_STREAM_TYPE_ELEMENT + }; + + GList* streamInfo; + g_object_get(G_OBJECT(m_playbin), "stream-info", &streamInfo, NULL); + + for (; streamInfo != 0; streamInfo = g_list_next(streamInfo)) { + gint type; + gchar *languageCode = 0; + + GObject* obj = G_OBJECT(streamInfo->data); + + g_object_get(obj, "type", &type, NULL); + g_object_get(obj, "language-code", &languageCode, NULL); + + if (type == GST_STREAM_TYPE_VIDEO) + haveVideo = true; + else if (type == GST_STREAM_TYPE_AUDIO) + haveAudio = true; + +// QMediaStreamsControl::StreamType streamType = QMediaStreamsControl::UnknownStream; +// +// switch (type) { +// case GST_STREAM_TYPE_VIDEO: +// streamType = QMediaStreamsControl::VideoStream; +// break; +// case GST_STREAM_TYPE_AUDIO: +// streamType = QMediaStreamsControl::AudioStream; +// break; +// case GST_STREAM_TYPE_SUBPICTURE: +// streamType = QMediaStreamsControl::SubPictureStream; +// break; +// default: +// streamType = QMediaStreamsControl::UnknownStream; +// break; +// } +// +// QMap<QtMultimedia::MetaData, QVariant> streamProperties; +// streamProperties[QtMultimedia::Language] = QString::fromUtf8(languageCode); +// +// m_streamProperties.append(streamProperties); +// m_streamTypes.append(streamType); + } +#endif + + if (haveAudio != m_audioAvailable) { + m_audioAvailable = haveAudio; + emit audioAvailableChanged(m_audioAvailable); + } + if (haveVideo != m_videoAvailable) { + m_videoAvailable = haveVideo; + emit videoAvailableChanged(m_videoAvailable); + } + + emit streamsChanged(); +} diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.h new file mode 100644 index 0000000..d650ec7 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERPLAYERSESSION_H +#define QGSTREAMERPLAYERSESSION_H + +#include <QObject> +#include <QUrl> +#include "qgstreamerplayercontrol.h" +#include "qgstreamerbushelper.h" +#include <QtMultimedia/qmediaplayer.h> +//#include <qmediastreamscontrol.h> + +#include <gst/gst.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerBusHelper; +class QGstreamerMessage; +class QGstreamerVideoRendererInterface; + +class QGstreamerPlayerSession : public QObject, public QGstreamerSyncEventFilter +{ +Q_OBJECT + +public: + QGstreamerPlayerSession(QObject *parent); + virtual ~QGstreamerPlayerSession(); + + QUrl url() const; + + QMediaPlayer::State state() const { return m_state; } + QMediaPlayer::MediaStatus mediaStatus() const { return m_mediaStatus; } + + qint64 duration() const; + qint64 position() const; + + bool isBuffering() const; + + int bufferingProgress() const; + + int volume() const; + bool isMuted() const; + + void setVideoRenderer(QObject *renderer); + bool isAudioAvailable() const; + bool isVideoAvailable() const; + + bool isSeekable() const; + + qreal playbackRate() const; + void setPlaybackRate(qreal rate); + + QMap<QByteArray ,QVariant> tags() const { return m_tags; } + QMap<QtMultimedia::MetaData,QVariant> streamProperties(int streamNumber) const { return m_streamProperties[streamNumber]; } +// int streamCount() const { return m_streamProperties.count(); } +// QMediaStreamsControl::StreamType streamType(int streamNumber) { return m_streamTypes.value(streamNumber, QMediaStreamsControl::UnknownStream); } +// +// int activeStream(QMediaStreamsControl::StreamType streamType) const; +// void setActiveStream(QMediaStreamsControl::StreamType streamType, int streamNumber); + + bool processSyncMessage(const QGstreamerMessage &message); + +public slots: + void load(const QUrl &url); + + void play(); + void pause(); + void stop(); + + void seek(qint64 pos); + + void setVolume(int volume); + void setMuted(bool muted); + +signals: + void durationChanged(qint64 duration); + void positionChanged(qint64 position); + void stateChanged(QMediaPlayer::State state); + void mediaStatusChanged(QMediaPlayer::MediaStatus mediaStatus); + void volumeChanged(int volume); + void mutedStateChanged(bool muted); + void audioAvailableChanged(bool audioAvailable); + void videoAvailableChanged(bool videoAvailable); + void bufferingChanged(bool buffering); + void bufferingProgressChanged(int percentFilled); + void playbackFinished(); + void tagsChanged(); + void streamsChanged(); + void seekableChanged(bool); + void error(int error, const QString &errorString); + +private slots: + void busMessage(const QGstreamerMessage &message); + void getStreamsInfo(); + void setSeekable(bool); + +private: + void setMediaStatus(QMediaPlayer::MediaStatus); + + QUrl m_url; + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_mediaStatus; + QGstreamerBusHelper* m_busHelper; + GstElement* m_playbin; + GstElement* m_nullVideoOutput; + GstBus* m_bus; + QGstreamerVideoRendererInterface *m_renderer; + + QMap<QByteArray, QVariant> m_tags; + QList< QMap<QtMultimedia::MetaData,QVariant> > m_streamProperties; +// QList<QMediaStreamsControl::StreamType> m_streamTypes; +// QMap<QMediaStreamsControl::StreamType, int> m_playbin2StreamOffset; + + + int m_volume; + qreal m_playbackRate; + bool m_muted; + bool m_audioAvailable; + bool m_videoAvailable; + bool m_seekable; + + qint64 m_lastPosition; + qint64 m_duration; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGSTREAMERPLAYERSESSION_H diff --git a/src/plugins/mediaservices/gstreamer/qgstreamerbushelper.cpp b/src/plugins/mediaservices/gstreamer/qgstreamerbushelper.cpp new file mode 100644 index 0000000..4649c21 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamerbushelper.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QMap> +#include <QTimer> +#include <QMutex> + +#include "qgstreamerbushelper.h" + + +#ifndef QT_NO_GLIB +class QGstreamerBusHelperPrivate : public QObject +{ + Q_OBJECT + +public: + void addWatch(GstBus* bus, QGstreamerBusHelper* helper) + { + setParent(helper); + m_tag = gst_bus_add_watch_full(bus, 0, busCallback, this, NULL); + m_helper = helper; + filter = 0; + } + + void removeWatch(QGstreamerBusHelper* helper) + { + Q_UNUSED(helper); + g_source_remove(m_tag); + } + + static QGstreamerBusHelperPrivate* instance() + { + return new QGstreamerBusHelperPrivate; + } + +private: + void processMessage(GstBus* bus, GstMessage* message) + { + Q_UNUSED(bus); + emit m_helper->message(message); + } + + static gboolean busCallback(GstBus *bus, GstMessage *message, gpointer data) + { + reinterpret_cast<QGstreamerBusHelperPrivate*>(data)->processMessage(bus, message); + return TRUE; + } + + guint m_tag; + QGstreamerBusHelper* m_helper; + +public: + GstBus* bus; + QGstreamerSyncEventFilter *filter; + QMutex filterMutex; +}; + +#else + +class QGstreamerBusHelperPrivate : public QObject +{ + Q_OBJECT + typedef QMap<QGstreamerBusHelper*, GstBus*> HelperMap; + +public: + void addWatch(GstBus* bus, QGstreamerBusHelper* helper) + { + m_helperMap.insert(helper, bus); + + if (m_helperMap.size() == 1) + m_intervalTimer->start(); + } + + void removeWatch(QGstreamerBusHelper* helper) + { + m_helperMap.remove(helper); + + if (m_helperMap.size() == 0) + m_intervalTimer->stop(); + } + + static QGstreamerBusHelperPrivate* instance() + { + static QGstreamerBusHelperPrivate self; + + return &self; + } + +private slots: + void interval() + { + for (HelperMap::iterator it = m_helperMap.begin(); it != m_helperMap.end(); ++it) { + GstMessage* message; + + while ((message = gst_bus_poll(it.value(), GST_MESSAGE_ANY, 0)) != 0) { + emit it.key()->message(message); + gst_message_unref(message); + } + + emit it.key()->message(QGstreamerMessage()); + } + } + +private: + QGstreamerBusHelperPrivate() + { + m_intervalTimer = new QTimer(this); + m_intervalTimer->setInterval(250); + + connect(m_intervalTimer, SIGNAL(timeout()), SLOT(interval())); + } + + HelperMap m_helperMap; + QTimer* m_intervalTimer; + +public: + GstBus* bus; + QGstreamerSyncEventFilter *filter; + QMutex filterMutex; +}; +#endif + + +static GstBusSyncReply syncGstBusFilter(GstBus* bus, GstMessage* message, QGstreamerBusHelperPrivate *d) +{ + Q_UNUSED(bus); + QMutexLocker lock(&d->filterMutex); + + bool res = false; + + if (d->filter) + res = d->filter->processSyncMessage(QGstreamerMessage(message)); + + return res ? GST_BUS_DROP : GST_BUS_PASS; +} + + +/*! + \class gstreamer::QGstreamerBusHelper + \internal +*/ + +QGstreamerBusHelper::QGstreamerBusHelper(GstBus* bus, QObject* parent): + QObject(parent), + d(QGstreamerBusHelperPrivate::instance()) +{ + d->bus = bus; + d->addWatch(bus, this); + + gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d); +} + +QGstreamerBusHelper::~QGstreamerBusHelper() +{ + d->removeWatch(this); + gst_bus_set_sync_handler(d->bus,0,0); +} + +void QGstreamerBusHelper::installSyncEventFilter(QGstreamerSyncEventFilter *filter) +{ + QMutexLocker lock(&d->filterMutex); + d->filter = filter; +} + +#include "qgstreamerbushelper.moc" diff --git a/src/plugins/mediaservices/gstreamer/qgstreamerbushelper.h b/src/plugins/mediaservices/gstreamer/qgstreamerbushelper.h new file mode 100644 index 0000000..8600015 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamerbushelper.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERBUSHELPER_H +#define QGSTREAMERBUSHELPER_H + +#include <QObject> + +#include <qgstreamermessage.h> +#include <gst/gst.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerSyncEventFilter { +public: + //returns true if message was processed and should be dropped, false otherwise + virtual bool processSyncMessage(const QGstreamerMessage &message) = 0; +}; + +class QGstreamerBusHelperPrivate; + +class QGstreamerBusHelper : public QObject +{ + Q_OBJECT + friend class QGstreamerBusHelperPrivate; + +public: + QGstreamerBusHelper(GstBus* bus, QObject* parent = 0); + ~QGstreamerBusHelper(); + + void installSyncEventFilter(QGstreamerSyncEventFilter *filter); + +signals: + void message(QGstreamerMessage const& message); + + +private: + QGstreamerBusHelperPrivate* d; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qgstreamermessage.cpp b/src/plugins/mediaservices/gstreamer/qgstreamermessage.cpp new file mode 100644 index 0000000..13a2454 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamermessage.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <gst/gst.h> + +#include "qgstreamermessage.h" + + +static int wuchi = qRegisterMetaType<QGstreamerMessage>(); + + +/*! + \class gstreamer::QGstreamerMessage + \internal +*/ + +QGstreamerMessage::QGstreamerMessage(): + m_message(0) +{ +} + +QGstreamerMessage::QGstreamerMessage(GstMessage* message): + m_message(message) +{ + gst_message_ref(m_message); +} + +QGstreamerMessage::QGstreamerMessage(QGstreamerMessage const& m): + m_message(m.m_message) +{ + gst_message_ref(m_message); +} + + +QGstreamerMessage::~QGstreamerMessage() +{ + if (m_message != 0) + gst_message_unref(m_message); +} + +GstMessage* QGstreamerMessage::rawMessage() const +{ + return m_message; +} + +QGstreamerMessage& QGstreamerMessage::operator=(QGstreamerMessage const& rhs) +{ + if (m_message != 0) + gst_message_unref(m_message); + + if ((m_message = rhs.m_message) != 0) + gst_message_ref(m_message); + + return *this; +} diff --git a/src/plugins/mediaservices/gstreamer/qgstreamermessage.h b/src/plugins/mediaservices/gstreamer/qgstreamermessage.h new file mode 100644 index 0000000..4680903 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamermessage.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERMESSAGE_H +#define QGSTREAMERMESSAGE_H + +#include <QMetaType> + +#include <gst/gst.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerMessage +{ +public: + QGstreamerMessage(); + QGstreamerMessage(GstMessage* message); + QGstreamerMessage(QGstreamerMessage const& m); + ~QGstreamerMessage(); + + GstMessage* rawMessage() const; + + QGstreamerMessage& operator=(QGstreamerMessage const& rhs); + +private: + GstMessage* m_message; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QGstreamerMessage); + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp b/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp new file mode 100644 index 0000000..9e5f425 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qstring.h> +#include <QtCore/qdebug.h> +#include <QtGui/QIcon> +#include <QtCore/QDir> +#include <QtCore/QDebug> + +#include "qgstreamerserviceplugin.h" + +#ifdef QMEDIA_GSTREAMER_PLAYER +#include "qgstreamerplayerservice.h" +#endif +#ifdef QMEDIA_GSTREAMER_CAPTURE +#include "qgstreamercaptureservice.h" +#endif + +#include <QtMultimedia/qmediaserviceprovider.h> + +#include <linux/types.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <sys/poll.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <linux/videodev2.h> + + +QT_BEGIN_NAMESPACE + + +QStringList QGstreamerServicePlugin::keys() const +{ + return QStringList() +#ifdef QMEDIA_GSTREAMER_PLAYER + << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER) +#endif +#ifdef QMEDIA_GSTREAMER_CAPTURE + << QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE) + << QLatin1String(Q_MEDIASERVICE_CAMERA) +#endif + ; +} + +QMediaService* QGstreamerServicePlugin::create(const QString &key) +{ +#ifdef QMEDIA_GSTREAMER_PLAYER + if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) + return new QGstreamerPlayerService; +#endif +#ifdef QMEDIA_GSTREAMER_CAPTURE + if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) + return new QGstreamerCaptureService(key); + + if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) + return new QGstreamerCaptureService(key); +#endif + + qDebug() << "unsupported key:" << key; + return 0; +} + +void QGstreamerServicePlugin::release(QMediaService *service) +{ + delete service; +} + +QList<QByteArray> QGstreamerServicePlugin::devices(const QByteArray &service) const +{ + if (service == Q_MEDIASERVICE_CAMERA) { + if (m_cameraDevices.isEmpty()) + updateDevices(); + + return m_cameraDevices; + } + + return QList<QByteArray>(); +} + +QString QGstreamerServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) +{ + if (service == Q_MEDIASERVICE_CAMERA) { + if (m_cameraDevices.isEmpty()) + updateDevices(); + + for (int i=0; i<m_cameraDevices.count(); i++) + if (m_cameraDevices[i] == device) + return m_cameraDescriptions[i]; + } + + return QString(); +} + +void QGstreamerServicePlugin::updateDevices() const +{ + m_cameraDevices.clear(); + m_cameraDescriptions.clear(); + + QDir devDir("/dev"); + devDir.setFilter(QDir::System); + + QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*"); + + foreach( const QFileInfo &entryInfo, entries ) { + qDebug() << "Try" << entryInfo.filePath(); + + int fd = ::open(entryInfo.filePath().toLatin1().constData(), O_RDWR ); + if (fd == -1) + continue; + + bool isCamera = false; + + v4l2_input input; + memset(&input, 0, sizeof(input)); + for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) { + if(input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) { + isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0; + break; + } + } + + if (isCamera) { + // find out its driver "name" + QString name; + struct v4l2_capability vcap; + memset(&vcap, 0, sizeof(struct v4l2_capability)); + + if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) + name = entryInfo.fileName(); + else + name = QString((const char*)vcap.card); + qDebug() << "found camera: " << name; + + m_cameraDevices.append(entryInfo.filePath().toLocal8Bit()); + m_cameraDescriptions.append(name); + } + ::close(fd); + } +} + +Q_EXPORT_PLUGIN2(gstengine, QGstreamerServicePlugin); + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.h b/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.h new file mode 100644 index 0000000..d6d6899 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamerserviceplugin.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QGSTREAMERSERVICEPLUGIN_H +#define QGSTREAMERSERVICEPLUGIN_H + +#include <QtMultimedia/qmediaserviceproviderplugin.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerServicePlugin : public QMediaServiceProviderPlugin, public QMediaServiceSupportedDevicesInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceSupportedDevicesInterface) +public: + QStringList keys() const; + QMediaService* create(QString const& key); + void release(QMediaService *service); + + QList<QByteArray> devices(const QByteArray &service) const; + QString deviceDescription(const QByteArray &service, const QByteArray &device); + +private: + void updateDevices() const; + + mutable QList<QByteArray> m_cameraDevices; + mutable QStringList m_cameraDescriptions; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGSTREAMERSERVICEPLUGIN_H diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.cpp new file mode 100644 index 0000000..ac9a1e3 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamervideoinputdevicecontrol.h" + +#include <QtGui/QIcon> +#include <QtCore/QDir> +#include <QtCore/QDebug> + +#include <linux/types.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <sys/poll.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <linux/videodev2.h> + +QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(QObject *parent) + :QVideoDeviceControl(parent), m_selectedDevice(0) +{ + update(); +} + +QGstreamerVideoInputDeviceControl::~QGstreamerVideoInputDeviceControl() +{ +} + +int QGstreamerVideoInputDeviceControl::deviceCount() const +{ + return m_names.size(); +} + +QString QGstreamerVideoInputDeviceControl::deviceName(int index) const +{ + return m_names[index]; +} + +QString QGstreamerVideoInputDeviceControl::deviceDescription(int index) const +{ + return m_descriptions[index]; +} + +QIcon QGstreamerVideoInputDeviceControl::deviceIcon(int index) const +{ + Q_UNUSED(index); + return QIcon(); +} + +int QGstreamerVideoInputDeviceControl::defaultDevice() const +{ + return 0; +} + +int QGstreamerVideoInputDeviceControl::selectedDevice() const +{ + return m_selectedDevice; +} + + +void QGstreamerVideoInputDeviceControl::setSelectedDevice(int index) +{ + if (index != m_selectedDevice) { + m_selectedDevice = index; + emit selectedDeviceChanged(index); + emit selectedDeviceChanged(deviceName(index)); + } +} + + +void QGstreamerVideoInputDeviceControl::update() +{ + m_names.clear(); + m_descriptions.clear(); + + QDir devDir("/dev"); + devDir.setFilter(QDir::System); + + QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*"); + + foreach( const QFileInfo &entryInfo, entries ) { + qDebug() << "Try" << entryInfo.filePath(); + + int fd = ::open(entryInfo.filePath().toLatin1().constData(), O_RDWR ); + if (fd == -1) + continue; + + bool isCamera = false; + + v4l2_input input; + memset(&input, 0, sizeof(input)); + for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) { + if(input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) { + isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0; + break; + } + } + + if (isCamera) { + // find out its driver "name" + QString name; + struct v4l2_capability vcap; + memset(&vcap, 0, sizeof(struct v4l2_capability)); + + if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) + name = entryInfo.fileName(); + else + name = QString((const char*)vcap.card); + qDebug() << "found camera: " << name; + + m_names.append(entryInfo.filePath()); + m_descriptions.append(name); + } + ::close(fd); + } +} diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.h b/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.h new file mode 100644 index 0000000..6762bab --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideoinputdevicecontrol.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERVIDEOINPUTDEVICECONTROL_H +#define QGSTREAMERVIDEOINPUTDEVICECONTROL_H + +#include <QtMultimedia/qvideodevicecontrol.h> +#include <QtCore/qstringlist.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class QGstreamerVideoInputDeviceControl : public QVideoDeviceControl +{ +Q_OBJECT +public: + QGstreamerVideoInputDeviceControl(QObject *parent); + ~QGstreamerVideoInputDeviceControl(); + + int deviceCount() const; + + QString deviceName(int index) const; + QString deviceDescription(int index) const; + QIcon deviceIcon(int index) const; + + int defaultDevice() const; + int selectedDevice() const; + +public Q_SLOTS: + void setSelectedDevice(int index); + +private: + void update(); + + int m_selectedDevice; + QStringList m_names; + QStringList m_descriptions; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGSTREAMERAUDIOINPUTDEVICECONTROL_H diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideooutputcontrol.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideooutputcontrol.cpp new file mode 100644 index 0000000..decf524 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideooutputcontrol.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamervideooutputcontrol.h" + +QGstreamerVideoOutputControl::QGstreamerVideoOutputControl(QObject *parent) + : QVideoOutputControl(parent) + , m_output(NoOutput) +{ +} + +QList<QVideoOutputControl::Output> QGstreamerVideoOutputControl::availableOutputs() const +{ + return m_outputs; +} + +void QGstreamerVideoOutputControl::setAvailableOutputs(const QList<Output> &outputs) +{ + emit availableOutputsChanged(m_outputs = outputs); +} + +QVideoOutputControl::Output QGstreamerVideoOutputControl::output() const +{ + return m_output; +} + +void QGstreamerVideoOutputControl::setOutput(Output output) +{ + if (!m_outputs.contains(output)) + output = NoOutput; + + if (m_output != output) + emit outputChanged(m_output = output); +} diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideooutputcontrol.h b/src/plugins/mediaservices/gstreamer/qgstreamervideooutputcontrol.h new file mode 100644 index 0000000..7685239 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideooutputcontrol.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERVIDEOOUTPUTCONTROL_H +#define QGSTREAMERVIDEOOUTPUTCONTROL_H + +#include <QtMultimedia/qvideooutputcontrol.h> + +#include <gst/gst.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerVideoRendererInterface +{ +public: + virtual ~QGstreamerVideoRendererInterface(); + virtual GstElement *videoSink() = 0; + virtual void precessNewStream() {} +}; + +class QGstreamerVideoOutputControl : public QVideoOutputControl +{ + Q_OBJECT +public: + QGstreamerVideoOutputControl(QObject *parent = 0); + + QList<Output> availableOutputs() const; + void setAvailableOutputs(const QList<Output> &outputs); + + Output output() const; + void setOutput(Output output); + +Q_SIGNALS: + void outputChanged(QVideoOutputControl::Output output); + +private: + QList<Output> m_outputs; + Output m_output; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideooverlay.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideooverlay.cpp new file mode 100644 index 0000000..6c6c802 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideooverlay.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamervideooverlay.h" +#include "qvideosurfacegstsink.h" + +#include <QtMultimedia/qvideosurfaceformat.h> + +#include "qx11videosurface.h" + +QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent) + : QVideoWindowControl(parent) + , m_surface(new QX11VideoSurface) + , m_videoSink(reinterpret_cast<GstElement*>(QVideoSurfaceGstSink::createSink(m_surface))) + , m_aspectRatioMode(QVideoWidget::KeepAspectRatio) + , m_fullScreen(false) +{ + if (m_videoSink) { + gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership + gst_object_sink(GST_OBJECT(m_videoSink)); + } + + connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)), + this, SLOT(surfaceFormatChanged())); +} + +QGstreamerVideoOverlay::~QGstreamerVideoOverlay() +{ + if (m_videoSink) + gst_object_unref(GST_OBJECT(m_videoSink)); + + delete m_surface; +} + +WId QGstreamerVideoOverlay::winId() const +{ + return m_surface->winId(); +} + +void QGstreamerVideoOverlay::setWinId(WId id) +{ + m_surface->setWinId(id); +} + +QRect QGstreamerVideoOverlay::displayRect() const +{ + return m_displayRect; +} + +void QGstreamerVideoOverlay::setDisplayRect(const QRect &rect) +{ + m_displayRect = rect; + + setScaledDisplayRect(); +} + +QVideoWidget::AspectRatioMode QGstreamerVideoOverlay::aspectRatioMode() const +{ + return m_aspectRatioMode; +} + +void QGstreamerVideoOverlay::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + m_aspectRatioMode = mode; + + setScaledDisplayRect(); +} + +void QGstreamerVideoOverlay::repaint() +{ +} + +int QGstreamerVideoOverlay::brightness() const +{ + return m_surface->brightness(); +} + +void QGstreamerVideoOverlay::setBrightness(int brightness) +{ + m_surface->setBrightness(brightness); + + emit brightnessChanged(m_surface->brightness()); +} + +int QGstreamerVideoOverlay::contrast() const +{ + return m_surface->contrast(); +} + +void QGstreamerVideoOverlay::setContrast(int contrast) +{ + m_surface->setContrast(contrast); + + emit contrastChanged(m_surface->contrast()); +} + +int QGstreamerVideoOverlay::hue() const +{ + return m_surface->hue(); +} + +void QGstreamerVideoOverlay::setHue(int hue) +{ + m_surface->setHue(hue); + + emit hueChanged(m_surface->hue()); +} + +int QGstreamerVideoOverlay::saturation() const +{ + return m_surface->saturation(); +} + +void QGstreamerVideoOverlay::setSaturation(int saturation) +{ + m_surface->setSaturation(saturation); + + emit saturationChanged(m_surface->saturation()); +} + +bool QGstreamerVideoOverlay::isFullScreen() const +{ + return m_fullScreen; +} + +void QGstreamerVideoOverlay::setFullScreen(bool fullScreen) +{ + emit fullScreenChanged(m_fullScreen = fullScreen); +} + +QSize QGstreamerVideoOverlay::nativeSize() const +{ + return m_surface->surfaceFormat().sizeHint(); +} + +QAbstractVideoSurface *QGstreamerVideoOverlay::surface() const +{ + return m_surface; +} + +GstElement *QGstreamerVideoOverlay::videoSink() +{ + return m_videoSink; +} + +void QGstreamerVideoOverlay::surfaceFormatChanged() +{ + setScaledDisplayRect(); + + emit nativeSizeChanged(); +} + +void QGstreamerVideoOverlay::setScaledDisplayRect() +{ + switch (m_aspectRatioMode) { + case QVideoWidget::KeepAspectRatio: + { + QSize size = m_surface->surfaceFormat().viewport().size(); + + size.scale(m_displayRect.size(), Qt::KeepAspectRatio); + + QRect rect(QPoint(0, 0), size); + rect.moveCenter(m_displayRect.center()); + + m_surface->setDisplayRect(rect); + } + break; + case QVideoWidget::IgnoreAspectRatio: + m_surface->setDisplayRect(m_displayRect); + break; + }; +} diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideooverlay.h b/src/plugins/mediaservices/gstreamer/qgstreamervideooverlay.h new file mode 100644 index 0000000..9566949 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideooverlay.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERVIDEOOVERLAY_H +#define QGSTREAMERVIDEOOVERLAY_H + +#include <QtMultimedia/qvideowindowcontrol.h> + +#include "qgstreamervideorendererinterface.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractVideoSurface; +class QX11VideoSurface; + +class QGstreamerVideoOverlay : public QVideoWindowControl, public QGstreamerVideoRendererInterface +{ + Q_OBJECT + Q_INTERFACES(QGstreamerVideoRendererInterface) +public: + QGstreamerVideoOverlay(QObject *parent = 0); + ~QGstreamerVideoOverlay(); + + WId winId() const; + void setWinId(WId id); + + QRect displayRect() const; + void setDisplayRect(const QRect &rect); + + bool isFullScreen() const; + void setFullScreen(bool fullScreen); + + QSize nativeSize() const; + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + + void repaint(); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + + QAbstractVideoSurface *surface() const; + + GstElement *videoSink(); + +private slots: + void surfaceFormatChanged(); + +private: + void setScaledDisplayRect(); + + QX11VideoSurface *m_surface; + GstElement *m_videoSink; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + QRect m_displayRect; + bool m_fullScreen; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideorenderer.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideorenderer.cpp new file mode 100644 index 0000000..25a53cf --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideorenderer.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamervideorenderer.h" +#include "qvideosurfacegstsink.h" + +#include <QEvent> +#include <QApplication> + +#include <gst/gst.h> + +QGstreamerVideoRenderer::QGstreamerVideoRenderer(QObject *parent) + :QVideoRendererControl(parent),m_videoSink(0) +{ +} + +QGstreamerVideoRenderer::~QGstreamerVideoRenderer() +{ + if (m_videoSink) + gst_object_unref(GST_OBJECT(m_videoSink)); +} + +GstElement *QGstreamerVideoRenderer::videoSink() +{ + if (!m_videoSink) { + m_videoSink = reinterpret_cast<GstElement*>(QVideoSurfaceGstSink::createSink(m_surface)); + gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership + gst_object_sink(GST_OBJECT(m_videoSink)); + } + + return m_videoSink; +} + + +QAbstractVideoSurface *QGstreamerVideoRenderer::surface() const +{ + return m_surface; +} + +void QGstreamerVideoRenderer::setSurface(QAbstractVideoSurface *surface) +{ + m_surface = surface; +} + diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideorenderer.h b/src/plugins/mediaservices/gstreamer/qgstreamervideorenderer.h new file mode 100644 index 0000000..ba3f806 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideorenderer.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERVIDEORENDERER_H +#define QGSTREAMERVIDEORENDERER_H + +#include <QtMultimedia/qvideorenderercontrol.h> +#include "qvideosurfacegstsink.h" + +#include "qgstreamervideorendererinterface.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerVideoRenderer : public QVideoRendererControl, public QGstreamerVideoRendererInterface +{ + Q_OBJECT + Q_INTERFACES(QGstreamerVideoRendererInterface) +public: + QGstreamerVideoRenderer(QObject *parent = 0); + virtual ~QGstreamerVideoRenderer(); + + QAbstractVideoSurface *surface() const; + void setSurface(QAbstractVideoSurface *surface); + + GstElement *videoSink(); + void precessNewStream() {} + +private: + GstElement *m_videoSink; + QAbstractVideoSurface *m_surface; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGSTREAMERVIDEORENDRER_H diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideorendererinterface.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideorendererinterface.cpp new file mode 100644 index 0000000..0a1c20d --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideorendererinterface.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamervideorendererinterface.h" + +QGstreamerVideoRendererInterface::~QGstreamerVideoRendererInterface() +{ +} diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideorendererinterface.h b/src/plugins/mediaservices/gstreamer/qgstreamervideorendererinterface.h new file mode 100644 index 0000000..39deee8 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideorendererinterface.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERVIDEOOUTPUTCONTROL_H +#define QGSTREAMERVIDEOOUTPUTCONTROL_H + +#include <gst/gst.h> + +#include <QtCore/qobject.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerVideoRendererInterface +{ +public: + virtual ~QGstreamerVideoRendererInterface(); + virtual GstElement *videoSink() = 0; + virtual void precessNewStream() {} +}; + +QT_END_NAMESPACE + +#define QGstreamerVideoRendererInterface_iid "com.nokia.Qt.QGstreamerVideoRendererInterface/1.0" +Q_DECLARE_INTERFACE(QGstreamerVideoRendererInterface, QGstreamerVideoRendererInterface_iid) + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.cpp b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.cpp new file mode 100644 index 0000000..1d8d43d --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.cpp @@ -0,0 +1,322 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamervideowidget.h" + +#include <QtCore/qcoreevent.h> +#include <QtCore/qdebug.h> +#include <QtGui/qapplication.h> +#include <QtGui/qpainter.h> + +#include <X11/Xlib.h> +#include <gst/gst.h> +#include <gst/interfaces/xoverlay.h> +#include <gst/interfaces/propertyprobe.h> + +class QGstreamerVideoWidget : public QWidget +{ +public: + QGstreamerVideoWidget(QWidget *parent = 0) + :QWidget(parent) + { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + QPalette palette; + palette.setColor(QPalette::Background, Qt::black); + setPalette(palette); + } + + virtual ~QGstreamerVideoWidget() {} + + QSize sizeHint() const + { + return m_nativeSize; + } + + void setNativeSize( const QSize &size) + { + if (size != m_nativeSize) { + m_nativeSize = size; + if (size.isEmpty()) + setMinimumSize(0,0); + else + setMinimumSize(160,120); + + updateGeometry(); + } + } + +protected: + void paintEvent(QPaintEvent *) + { + QPainter painter(this); + painter.fillRect(rect(), palette().background()); + } + + QSize m_nativeSize; +}; + +QGstreamerVideoWidgetControl::QGstreamerVideoWidgetControl(QObject *parent) + : QVideoWidgetControl(parent) + , m_videoSink(0) + , m_widget(new QGstreamerVideoWidget) + , m_fullScreen(false) +{ + m_widget->installEventFilter(this); + m_windowId = m_widget->winId(); + + m_videoSink = gst_element_factory_make ("xvimagesink", NULL); + if (m_videoSink) { + // Check if the xv sink is usable + if (gst_element_set_state(m_videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) { + gst_object_unref(GST_OBJECT(m_videoSink)); + m_videoSink = 0; + } else { + gst_element_set_state(m_videoSink, GST_STATE_NULL); + + g_object_set(G_OBJECT(m_videoSink), "force-aspect-ratio", 1, (const char*)NULL); + } + } + + if (!m_videoSink) + m_videoSink = gst_element_factory_make ("ximagesink", NULL); + + gst_object_ref (GST_OBJECT (m_videoSink)); //Take ownership + gst_object_sink (GST_OBJECT (m_videoSink)); +} + +QGstreamerVideoWidgetControl::~QGstreamerVideoWidgetControl() +{ + if (m_videoSink) + gst_object_unref(GST_OBJECT(m_videoSink)); + + delete m_widget; +} + +GstElement *QGstreamerVideoWidgetControl::videoSink() +{ + return m_videoSink; +} + +bool QGstreamerVideoWidgetControl::eventFilter(QObject *object, QEvent *e) +{ + if (object == m_widget) { + if (e->type() == QEvent::ParentChange || e->type() == QEvent::Show) { + WId newWId = m_widget->winId(); + if (newWId != m_windowId) { + m_windowId = newWId; + // Even if we have created a winId at this point, other X applications + // need to be aware of it. + QApplication::syncX(); + setOverlay(); + } + } + + if (e->type() == QEvent::Show) { + // Setting these values ensures smooth resizing since it + // will prevent the system from clearing the background + m_widget->setAttribute(Qt::WA_NoSystemBackground, true); + m_widget->setAttribute(Qt::WA_PaintOnScreen, true); + } else if (e->type() == QEvent::Resize) { + // This is a workaround for missing background repaints + // when reducing window size + windowExposed(); + } + } + + return false; +} + +void QGstreamerVideoWidgetControl::precessNewStream() +{ + setOverlay(); + QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection); +} + +void QGstreamerVideoWidgetControl::setOverlay() +{ + if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) { + gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId); + } +} + +void QGstreamerVideoWidgetControl::updateNativeVideoSize() +{ + if (m_videoSink) { + //find video native size to update video widget size hint + GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink"); + GstCaps *caps = gst_pad_get_negotiated_caps(pad); + + if (caps) { + GstStructure *str; + gint width, height; + + if ((str = gst_caps_get_structure (caps, 0))) { + if (gst_structure_get_int (str, "width", &width) && gst_structure_get_int (str, "height", &height)) { + gint aspectNum = 0; + gint aspectDenum = 0; + if (gst_structure_get_fraction(str, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) { + if (aspectDenum > 0) + width = width*aspectNum/aspectDenum; + } + m_widget->setNativeSize(QSize(width, height)); + } + } + gst_caps_unref(caps); + } + } else { + m_widget->setNativeSize(QSize()); + } +} + + +void QGstreamerVideoWidgetControl::windowExposed() +{ + if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) + gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink)); +} + +QWidget *QGstreamerVideoWidgetControl::videoWidget() +{ + return m_widget; +} + +QVideoWidget::AspectRatioMode QGstreamerVideoWidgetControl::aspectRatioMode() const +{ + return m_aspectRatioMode; +} + +void QGstreamerVideoWidgetControl::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + if (m_videoSink) { + g_object_set(G_OBJECT(m_videoSink), + "force-aspect-ratio", + (mode == QVideoWidget::KeepAspectRatio), + (const char*)NULL); + } + + m_aspectRatioMode = mode; +} + +bool QGstreamerVideoWidgetControl::isFullScreen() const +{ + return m_fullScreen; +} + +void QGstreamerVideoWidgetControl::setFullScreen(bool fullScreen) +{ + emit fullScreenChanged(m_fullScreen = fullScreen); +} + +int QGstreamerVideoWidgetControl::brightness() const +{ + int brightness = 0; + + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) + g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL); + + return brightness / 10; +} + +void QGstreamerVideoWidgetControl::setBrightness(int brightness) +{ + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness")) { + g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, NULL); + + emit brightnessChanged(brightness); + } +} + +int QGstreamerVideoWidgetControl::contrast() const +{ + int contrast = 0; + + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) + g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); + + return contrast / 10; +} + +void QGstreamerVideoWidgetControl::setContrast(int contrast) +{ + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast")) { + g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, NULL); + + emit contrastChanged(contrast); + } +} + +int QGstreamerVideoWidgetControl::hue() const +{ + int hue = 0; + + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) + g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL); + + return hue / 10; +} + +void QGstreamerVideoWidgetControl::setHue(int hue) +{ + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue")) { + g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, NULL); + + emit hueChanged(hue); + } +} + +int QGstreamerVideoWidgetControl::saturation() const +{ + int saturation = 0; + + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) + g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL); + + return saturation / 10; +} + +void QGstreamerVideoWidgetControl::setSaturation(int saturation) +{ + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation")) { + g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, NULL); + + emit saturationChanged(saturation); + } +} diff --git a/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.h b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.h new file mode 100644 index 0000000..7b966b7 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstreamervideowidget.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTREAMERVIDEOWIDGET_H +#define QGSTREAMERVIDEOWIDGET_H + +#include <QtMultimedia/qvideowidgetcontrol.h> + +#include "qgstreamervideorendererinterface.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstreamerVideoWidget; + +class QGstreamerVideoWidgetControl + : public QVideoWidgetControl + , public QGstreamerVideoRendererInterface +{ + Q_OBJECT + Q_INTERFACES(QGstreamerVideoRendererInterface) +public: + QGstreamerVideoWidgetControl(QObject *parent = 0); + virtual ~QGstreamerVideoWidgetControl(); + + GstElement *videoSink(); + void precessNewStream(); + + QWidget *videoWidget(); + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + + bool isFullScreen() const; + void setFullScreen(bool fullScreen); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + + void setOverlay(); + + bool eventFilter(QObject *object, QEvent *event); + +public slots: + void updateNativeVideoSize(); + +private: + void windowExposed(); + + GstElement *m_videoSink; + QGstreamerVideoWidget *m_widget; + WId m_windowId; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + bool m_fullScreen; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGSTREAMERVIDEOWIDGET_H diff --git a/src/plugins/mediaservices/gstreamer/qgstvideobuffer.cpp b/src/plugins/mediaservices/gstreamer/qgstvideobuffer.cpp new file mode 100644 index 0000000..9519db6 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstvideobuffer.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstvideobuffer.h" + + +QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine) + : QAbstractVideoBuffer(NoHandle) + , m_buffer(buffer) + , m_bytesPerLine(bytesPerLine) + , m_mode(NotMapped) +{ + gst_buffer_ref(m_buffer); +} + +QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine, + QGstVideoBuffer::HandleType handleType, + const QVariant &handle) + : QAbstractVideoBuffer(handleType) + , m_buffer(buffer) + , m_bytesPerLine(bytesPerLine) + , m_mode(NotMapped) + , m_handle(handle) +{ + gst_buffer_ref(m_buffer); +} + +QGstVideoBuffer::~QGstVideoBuffer() +{ + gst_buffer_unref(m_buffer); +} + + +QAbstractVideoBuffer::MapMode QGstVideoBuffer::mapMode() const +{ + return m_mode; +} + +uchar *QGstVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) +{ + if (mode != NotMapped && m_mode == NotMapped) { + if (numBytes) + *numBytes = m_buffer->size; + + if (bytesPerLine) + *bytesPerLine = m_bytesPerLine; + + m_mode = mode; + + return m_buffer->data; + } else { + return 0; + } +} +void QGstVideoBuffer::unmap() +{ + m_mode = NotMapped; +} + diff --git a/src/plugins/mediaservices/gstreamer/qgstvideobuffer.h b/src/plugins/mediaservices/gstreamer/qgstvideobuffer.h new file mode 100644 index 0000000..5133e2e --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstvideobuffer.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTVIDEOBUFFER_H +#define QGSTVIDEOBUFFER_H + +#include <QtMultimedia/QAbstractVideoBuffer> +#include <QtCore/qvariant.h> + +#include <gst/gst.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QGstVideoBuffer : public QAbstractVideoBuffer +{ +public: + QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine); + QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine, + HandleType handleType, const QVariant &handle); + ~QGstVideoBuffer(); + + MapMode mapMode() const; + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); + void unmap(); + + QVariant handle() const { return m_handle; } +private: + GstBuffer *m_buffer; + int m_bytesPerLine; + MapMode m_mode; + QVariant m_handle; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qgstxvimagebuffer.cpp b/src/plugins/mediaservices/gstreamer/qgstxvimagebuffer.cpp new file mode 100644 index 0000000..0e47c98 --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstxvimagebuffer.cpp @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> +#include <QtCore/qvariant.h> +#include <QtGui/qx11info_x11.h> + +#include "qgstxvimagebuffer.h" +#include "qvideosurfacegstsink.h" + +GstBufferClass *QGstXvImageBuffer::parent_class = NULL; + +GType QGstXvImageBuffer::get_type(void) +{ + static GType buffer_type = 0; + + if (buffer_type == 0) { + static const GTypeInfo buffer_info = { + sizeof (GstBufferClass), + NULL, + NULL, + QGstXvImageBuffer::class_init, + NULL, + NULL, + sizeof(QGstXvImageBuffer), + 0, + (GInstanceInitFunc)QGstXvImageBuffer::buffer_init, + NULL + }; + buffer_type = g_type_register_static(GST_TYPE_BUFFER, + "QGstXvImageBuffer", &buffer_info, GTypeFlags(0)); + } + return buffer_type; +} + +void QGstXvImageBuffer::class_init(gpointer g_class, gpointer class_data) +{ + Q_UNUSED(class_data); + GST_MINI_OBJECT_CLASS(g_class)->finalize = + (GstMiniObjectFinalizeFunction)buffer_finalize; + parent_class = (GstBufferClass*)g_type_class_peek_parent(g_class); +} + +void QGstXvImageBuffer::buffer_init(QGstXvImageBuffer *xvImage, gpointer g_class) +{ + Q_UNUSED(g_class); + xvImage->pool = 0; + xvImage->shmInfo.shmaddr = ((char *) -1); + xvImage->shmInfo.shmid = -1; + xvImage->markedForDeletion = false; +} + +void QGstXvImageBuffer::buffer_finalize(QGstXvImageBuffer * xvImage) +{ + if (xvImage->pool) { + if (xvImage->markedForDeletion) + xvImage->pool->destroyBuffer(xvImage); + else + xvImage->pool->recycleBuffer(xvImage); + } +} + + +QGstXvImageBufferPool::QGstXvImageBufferPool(QObject *parent) + :QObject(parent) +{ +} + +QGstXvImageBufferPool::~QGstXvImageBufferPool() +{ +} + +bool QGstXvImageBufferPool::isFormatSupported(const QVideoSurfaceFormat &surfaceFormat) +{ + bool ok = true; + surfaceFormat.property("portId").toULongLong(&ok); + if (!ok) + return false; + + int xvFormatId = surfaceFormat.property("xvFormatId").toInt(&ok); + if (!ok || xvFormatId < 0) + return false; + + int dataSize = surfaceFormat.property("dataSize").toInt(&ok); + if (!ok || dataSize<=0) + return false; + + return true; +} + +QGstXvImageBuffer *QGstXvImageBufferPool::takeBuffer(const QVideoSurfaceFormat &format, GstCaps *caps) +{ + m_poolMutex.lock(); + + m_caps = caps; + if (format != m_format) { + doClear(); + m_format = format; + } + + + if (m_pool.isEmpty()) { + //qDebug() << "QGstXvImageBufferPool::takeBuffer: no buffer available, allocate the new one"; + if (QThread::currentThread() == thread()) { + m_poolMutex.unlock(); + queuedAlloc(); + m_poolMutex.lock(); + } else { + QMetaObject::invokeMethod(this, "queuedAlloc", Qt::QueuedConnection); + m_allocWaitCondition.wait(&m_poolMutex, 300); + } + } + QGstXvImageBuffer *res = 0; + + if (!m_pool.isEmpty()) { + res = m_pool.takeLast(); + } + + m_poolMutex.unlock(); + + return res; +} + +void QGstXvImageBufferPool::queuedAlloc() +{ + QMutexLocker lock(&m_poolMutex); + + Q_ASSERT(QThread::currentThread() == thread()); + + QGstXvImageBuffer *xvBuffer = (QGstXvImageBuffer *)gst_mini_object_new(QGstXvImageBuffer::get_type()); + + quint64 portId = m_format.property("portId").toULongLong(); + int xvFormatId = m_format.property("xvFormatId").toInt(); + + xvBuffer->xvImage = XvShmCreateImage( + QX11Info::display(), + portId, + xvFormatId, + 0, + m_format.frameWidth(), + m_format.frameHeight(), + &xvBuffer->shmInfo + ); + + if (!xvBuffer->xvImage) { + qDebug() << "QGstXvImageBufferPool: XvShmCreateImage failed"; + m_allocWaitCondition.wakeOne(); + return; + } + + xvBuffer->shmInfo.shmid = shmget(IPC_PRIVATE, xvBuffer->xvImage->data_size, IPC_CREAT | 0777); + xvBuffer->shmInfo.shmaddr = xvBuffer->xvImage->data = (char*)shmat(xvBuffer->shmInfo.shmid, 0, 0); + xvBuffer->shmInfo.readOnly = False; + + if (!XShmAttach(QX11Info::display(), &xvBuffer->shmInfo)) { + qDebug() << "QGstXvImageBufferPool: XShmAttach failed"; + m_allocWaitCondition.wakeOne(); + return; + } + + shmctl (xvBuffer->shmInfo.shmid, IPC_RMID, NULL); + + xvBuffer->pool = this; + GST_MINI_OBJECT_CAST(xvBuffer)->flags = 0; + gst_buffer_set_caps(GST_BUFFER_CAST(xvBuffer), m_caps); + GST_BUFFER_DATA(xvBuffer) = (uchar*)xvBuffer->xvImage->data; + GST_BUFFER_SIZE(xvBuffer) = xvBuffer->xvImage->data_size; + + m_allBuffers.append(xvBuffer); + m_pool.append(xvBuffer); + + m_allocWaitCondition.wakeOne(); +} + + +void QGstXvImageBufferPool::clear() +{ + QMutexLocker lock(&m_poolMutex); + doClear(); +} + +void QGstXvImageBufferPool::doClear() +{ + foreach (QGstXvImageBuffer *xvBuffer, m_allBuffers) { + xvBuffer->markedForDeletion = true; + } + m_allBuffers.clear(); + + foreach (QGstXvImageBuffer *xvBuffer, m_pool) { + gst_buffer_unref(GST_BUFFER(xvBuffer)); + } + m_pool.clear(); + + m_format = QVideoSurfaceFormat(); +} + +void QGstXvImageBufferPool::queuedDestroy() +{ + QMutexLocker lock(&m_destroyMutex); + + foreach(XvShmImage xvImage, m_imagesToDestroy) { + if (xvImage.shmInfo.shmaddr != ((void *) -1)) { + XShmDetach(QX11Info::display(), &xvImage.shmInfo); + XSync(QX11Info::display(), false); + + shmdt(xvImage.shmInfo.shmaddr); + } + + if (xvImage.xvImage) + XFree(xvImage.xvImage); + } + + m_imagesToDestroy.clear(); + + XSync(QX11Info::display(), false); +} + +void QGstXvImageBufferPool::recycleBuffer(QGstXvImageBuffer *xvBuffer) +{ + QMutexLocker lock(&m_poolMutex); + gst_buffer_ref(GST_BUFFER_CAST(xvBuffer)); + m_pool.append(xvBuffer); +} + +void QGstXvImageBufferPool::destroyBuffer(QGstXvImageBuffer *xvBuffer) +{ + XvShmImage imageToDestroy; + imageToDestroy.xvImage = xvBuffer->xvImage; + imageToDestroy.shmInfo = xvBuffer->shmInfo; + + m_destroyMutex.lock(); + m_imagesToDestroy.append(imageToDestroy); + m_destroyMutex.unlock(); + + if (m_imagesToDestroy.size() == 1) + QMetaObject::invokeMethod(this, "queuedDestroy", Qt::QueuedConnection); +} diff --git a/src/plugins/mediaservices/gstreamer/qgstxvimagebuffer.h b/src/plugins/mediaservices/gstreamer/qgstxvimagebuffer.h new file mode 100644 index 0000000..beeb01f --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qgstxvimagebuffer.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGSTXVIMAGEBUFFER_H +#define QGSTXVIMAGEBUFFER_H + +#include <QtMultimedia/qabstractvideobuffer.h> +#include <QtMultimedia/qvideosurfaceformat.h> +#include <QtCore/qmutex.h> +#include <QtCore/qwaitcondition.h> +#include <QtCore/qqueue.h> + +#include <X11/Xlib.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvlib.h> + + +#include <gst/gst.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class QGstXvImageBufferPool; + +struct QGstXvImageBuffer { + GstBuffer buffer; + QGstXvImageBufferPool *pool; + XvImage *xvImage; + XShmSegmentInfo shmInfo; + bool markedForDeletion; + + static GType get_type(void); + static void class_init(gpointer g_class, gpointer class_data); + static void buffer_init(QGstXvImageBuffer *xvimage, gpointer g_class); + static void buffer_finalize(QGstXvImageBuffer * xvimage); + static GstBufferClass *parent_class; +}; + +const QAbstractVideoBuffer::HandleType XvHandleType = QAbstractVideoBuffer::HandleType(4); + +Q_DECLARE_METATYPE(XvImage*) + + +class QGstXvImageBufferPool : public QObject { +Q_OBJECT +friend class QGstXvImageBuffer; +public: + QGstXvImageBufferPool(QObject *parent = 0); + virtual ~QGstXvImageBufferPool(); + + bool isFormatSupported(const QVideoSurfaceFormat &format); + + QGstXvImageBuffer *takeBuffer(const QVideoSurfaceFormat &format, GstCaps *caps); + void clear(); + +private slots: + void queuedAlloc(); + void queuedDestroy(); + + void doClear(); + + void recycleBuffer(QGstXvImageBuffer *); + void destroyBuffer(QGstXvImageBuffer *); + +private: + struct XvShmImage { + XvImage *xvImage; + XShmSegmentInfo shmInfo; + }; + + QMutex m_poolMutex; + QMutex m_allocMutex; + QWaitCondition m_allocWaitCondition; + QMutex m_destroyMutex; + QVideoSurfaceFormat m_format; + GstCaps *m_caps; + QList<QGstXvImageBuffer*> m_pool; + QList<QGstXvImageBuffer*> m_allBuffers; + QList<XvShmImage> m_imagesToDestroy; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qvideosurfacegstsink.cpp b/src/plugins/mediaservices/gstreamer/qvideosurfacegstsink.cpp new file mode 100644 index 0000000..9e3807b --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qvideosurfacegstsink.cpp @@ -0,0 +1,694 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtMultimedia/QAbstractVideoSurface> +#include <QtMultimedia/QVideoFrame> +#include <QDebug> +#include <QMap> +#include <QDebug> +#include <QThread> +#include <QtGui/qx11info_x11.h> + +#include "qvideosurfacegstsink.h" + +#include "qgstvideobuffer.h" +#include "qgstxvimagebuffer.h" + + +Q_DECLARE_METATYPE(QVideoSurfaceFormat) + +QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface) + : m_surface(surface) + , m_renderReturn(GST_FLOW_ERROR) + , m_bytesPerLine(0) +{ + m_supportedPixelFormats = m_surface->supportedPixelFormats(); + + connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged())); +} + +QList<QVideoFrame::PixelFormat> QVideoSurfaceGstDelegate::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const +{ + QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); + + if (handleType == QAbstractVideoBuffer::NoHandle) + return m_supportedPixelFormats; + else + return m_surface->supportedPixelFormats(handleType); +} + +QVideoSurfaceFormat QVideoSurfaceGstDelegate::surfaceFormat() const +{ + QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); + return m_format; +} + +bool QVideoSurfaceGstDelegate::start(const QVideoSurfaceFormat &format, int bytesPerLine) +{ + QMutexLocker locker(&m_mutex); + + m_format = format; + m_bytesPerLine = bytesPerLine; + + if (QThread::currentThread() == thread()) { + m_started = !m_surface.isNull() ? m_surface->start(m_format) : false; + } else { + QMetaObject::invokeMethod(this, "queuedStart", Qt::QueuedConnection); + + m_setupCondition.wait(&m_mutex); + } + + m_format = m_surface->surfaceFormat(); + + return m_started; +} + +void QVideoSurfaceGstDelegate::stop() +{ + QMutexLocker locker(&m_mutex); + + if (QThread::currentThread() == thread()) { + if (!m_surface.isNull()) + m_surface->stop(); + } else { + QMetaObject::invokeMethod(this, "queuedStop", Qt::QueuedConnection); + + m_setupCondition.wait(&m_mutex); + } + + m_started = false; +} + +bool QVideoSurfaceGstDelegate::isActive() +{ + QMutexLocker locker(&m_mutex); + return m_surface->isActive(); +} + +GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer) +{ + QMutexLocker locker(&m_mutex); + + QGstVideoBuffer *videoBuffer = 0; + + if (G_TYPE_CHECK_INSTANCE_TYPE(buffer, QGstXvImageBuffer::get_type())) { + QGstXvImageBuffer *xvBuffer = reinterpret_cast<QGstXvImageBuffer *>(buffer); + QVariant handle = QVariant::fromValue(xvBuffer->xvImage); + videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine, XvHandleType, handle); + } else + videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine); + + m_frame = QVideoFrame( + videoBuffer, + m_format.frameSize(), + m_format.pixelFormat()); + + qint64 startTime = GST_BUFFER_TIMESTAMP(buffer); + + if (startTime >= 0) { + m_frame.setStartTime(startTime/G_GINT64_CONSTANT (1000000)); + + qint64 duration = GST_BUFFER_DURATION(buffer); + + if (duration >= 0) + m_frame.setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000000)); + } + + QMetaObject::invokeMethod(this, "queuedRender", Qt::QueuedConnection); + + if (!m_renderCondition.wait(&m_mutex, 300)) { + m_frame = QVideoFrame(); + + return GST_FLOW_OK; + } else { + return m_renderReturn; + } +} + +void QVideoSurfaceGstDelegate::queuedStart() +{ + QMutexLocker locker(&m_mutex); + + m_started = m_surface->start(m_format); + + m_setupCondition.wakeAll(); +} + +void QVideoSurfaceGstDelegate::queuedStop() +{ + QMutexLocker locker(&m_mutex); + + m_surface->stop(); + + m_setupCondition.wakeAll(); +} + +void QVideoSurfaceGstDelegate::queuedRender() +{ + QMutexLocker locker(&m_mutex); + + if (m_surface.isNull()) { + m_renderReturn = GST_FLOW_ERROR; + } else if (m_surface->present(m_frame)) { + m_renderReturn = GST_FLOW_OK; + } else { + switch (m_surface->error()) { + case QAbstractVideoSurface::NoError: + m_renderReturn = GST_FLOW_OK; + break; + case QAbstractVideoSurface::StoppedError: + m_renderReturn = GST_FLOW_NOT_NEGOTIATED; + break; + default: + m_renderReturn = GST_FLOW_ERROR; + break; + } + } + + m_renderCondition.wakeAll(); +} + +void QVideoSurfaceGstDelegate::supportedFormatsChanged() +{ + QMutexLocker locker(&m_mutex); + + m_supportedPixelFormats = m_surface->supportedPixelFormats(); +} + +struct YuvFormat +{ + QVideoFrame::PixelFormat pixelFormat; + guint32 fourcc; + int bitsPerPixel; +}; + +static const YuvFormat qt_yuvColorLookup[] = +{ + { QVideoFrame::Format_YUV420P, GST_MAKE_FOURCC('I','4','2','0'), 8 }, + { QVideoFrame::Format_YV12, GST_MAKE_FOURCC('Y','V','1','2'), 8 }, + { QVideoFrame::Format_UYVY, GST_MAKE_FOURCC('U','Y','V','Y'), 16 }, + { QVideoFrame::Format_YUYV, GST_MAKE_FOURCC('Y','U','Y','2'), 16 }, + { QVideoFrame::Format_NV12, GST_MAKE_FOURCC('N','V','1','2'), 8 }, + { QVideoFrame::Format_NV21, GST_MAKE_FOURCC('N','V','2','1'), 8 }, + { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 } +}; + +static int indexOfYuvColor(QVideoFrame::PixelFormat format) +{ + const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat); + + for (int i = 0; i < count; ++i) + if (qt_yuvColorLookup[i].pixelFormat == format) + return i; + + return -1; +} + +static int indexOfYuvColor(guint32 fourcc) +{ + const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat); + + for (int i = 0; i < count; ++i) + if (qt_yuvColorLookup[i].fourcc == fourcc) + return i; + + return -1; +} + +struct RgbFormat +{ + QVideoFrame::PixelFormat pixelFormat; + int bitsPerPixel; + int depth; + int endianness; + int red; + int green; + int blue; + int alpha; +}; + +static const RgbFormat qt_rgbColorLookup[] = +{ + { QVideoFrame::Format_RGB32 , 32, 24, 4321, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, + { QVideoFrame::Format_RGB32 , 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, + { QVideoFrame::Format_BGR32 , 32, 24, 4321, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, + { QVideoFrame::Format_BGR32 , 32, 24, 1234, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }, + { QVideoFrame::Format_ARGB32, 32, 24, 4321, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, + { QVideoFrame::Format_ARGB32, 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, + { QVideoFrame::Format_RGB24 , 24, 24, 4321, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, + { QVideoFrame::Format_BGR24 , 24, 24, 4321, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }, + { QVideoFrame::Format_RGB565, 16, 16, 1234, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 } +}; + +static int indexOfRgbColor( + int bits, int depth, int endianness, int red, int green, int blue, int alpha) +{ + const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat); + + for (int i = 0; i < count; ++i) { + if (qt_rgbColorLookup[i].bitsPerPixel == bits + && qt_rgbColorLookup[i].depth == depth + && qt_rgbColorLookup[i].endianness == endianness + && qt_rgbColorLookup[i].red == red + && qt_rgbColorLookup[i].green == green + && qt_rgbColorLookup[i].blue == blue + && qt_rgbColorLookup[i].alpha == alpha) { + return i; + } + } + return -1; +} + +static GstVideoSinkClass *sink_parent_class; + +#define VO_SINK(s) QVideoSurfaceGstSink *sink(reinterpret_cast<QVideoSurfaceGstSink *>(s)) + +QVideoSurfaceGstSink *QVideoSurfaceGstSink::createSink(QAbstractVideoSurface *surface) +{ + QVideoSurfaceGstSink *sink = reinterpret_cast<QVideoSurfaceGstSink *>( + g_object_new(QVideoSurfaceGstSink::get_type(), 0)); + + sink->delegate = new QVideoSurfaceGstDelegate(surface); + + return sink; +} + +GType QVideoSurfaceGstSink::get_type() +{ + static GType type = 0; + + if (type == 0) { + static const GTypeInfo info = + { + sizeof(QVideoSurfaceGstSinkClass), // class_size + base_init, // base_init + NULL, // base_finalize + class_init, // class_init + NULL, // class_finalize + NULL, // class_data + sizeof(QVideoSurfaceGstSink), // instance_size + 0, // n_preallocs + instance_init, // instance_init + 0 // value_table + }; + + type = g_type_register_static( + GST_TYPE_VIDEO_SINK, "QVideoSurfaceGstSink", &info, GTypeFlags(0)); + } + + return type; +} + +void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data) +{ + Q_UNUSED(class_data); + + sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class)); + + GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class); + base_sink_class->get_caps = QVideoSurfaceGstSink::get_caps; + base_sink_class->set_caps = QVideoSurfaceGstSink::set_caps; + base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc; + base_sink_class->start = QVideoSurfaceGstSink::start; + base_sink_class->stop = QVideoSurfaceGstSink::stop; + // base_sink_class->unlock = QVideoSurfaceGstSink::unlock; // Not implemented. + // base_sink_class->event = QVideoSurfaceGstSink::event; // Not implemented. + base_sink_class->preroll = QVideoSurfaceGstSink::preroll; + base_sink_class->render = QVideoSurfaceGstSink::render; + + GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class); + element_class->change_state = QVideoSurfaceGstSink::change_state; + + GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class); + object_class->finalize = QVideoSurfaceGstSink::finalize; +} + +void QVideoSurfaceGstSink::base_init(gpointer g_class) +{ + static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE( + "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS( + "video/x-raw-rgb, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]; " + "video/x-raw-yuv, " + "framerate = (fraction) [ 0, MAX ], " + "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ]")); + + gst_element_class_add_pad_template( + GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template)); +} + +void QVideoSurfaceGstSink::instance_init(GTypeInstance *instance, gpointer g_class) +{ + VO_SINK(instance); + + Q_UNUSED(g_class); + + sink->delegate = 0; + sink->pool = new QGstXvImageBufferPool(); + sink->lastRequestedCaps = 0; + sink->lastBufferCaps = 0; + sink->lastSurfaceFormat = new QVideoSurfaceFormat; +} + +void QVideoSurfaceGstSink::finalize(GObject *object) +{ + VO_SINK(object); + delete sink->pool; + sink->pool = 0; + delete sink->lastSurfaceFormat; + sink->lastSurfaceFormat = 0; + + if (sink->lastBufferCaps) + gst_caps_unref(sink->lastBufferCaps); + sink->lastBufferCaps = 0; + + if (sink->lastRequestedCaps) + gst_caps_unref(sink->lastRequestedCaps); + sink->lastRequestedCaps = 0; +} + +GstStateChangeReturn QVideoSurfaceGstSink::change_state( + GstElement *element, GstStateChange transition) +{ + Q_UNUSED(element); + + return GST_ELEMENT_CLASS(sink_parent_class)->change_state( + element, transition); +} + +GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base) +{ + VO_SINK(base); + + GstCaps *caps = gst_caps_new_empty(); + + foreach (QVideoFrame::PixelFormat format, sink->delegate->supportedPixelFormats()) { + int index = indexOfYuvColor(format); + + if (index != -1) { + gst_caps_append_structure(caps, gst_structure_new( + "video/x-raw-yuv", + "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1, + "width" , GST_TYPE_INT_RANGE, 1, INT_MAX, + "height" , GST_TYPE_INT_RANGE, 1, INT_MAX, + "format" , GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc, + NULL)); + continue; + } + + const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat); + + for (int i = 0; i < count; ++i) { + if (qt_rgbColorLookup[i].pixelFormat == format) { + GstStructure *structure = gst_structure_new( + "video/x-raw-rgb", + "framerate" , GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1, + "width" , GST_TYPE_INT_RANGE, 1, INT_MAX, + "height" , GST_TYPE_INT_RANGE, 1, INT_MAX, + "bpp" , G_TYPE_INT, qt_rgbColorLookup[i].bitsPerPixel, + "depth" , G_TYPE_INT, qt_rgbColorLookup[i].depth, + "endianness", G_TYPE_INT, qt_rgbColorLookup[i].endianness, + "red_mask" , G_TYPE_INT, qt_rgbColorLookup[i].red, + "green_mask", G_TYPE_INT, qt_rgbColorLookup[i].green, + "blue_mask" , G_TYPE_INT, qt_rgbColorLookup[i].blue, + NULL); + + if (qt_rgbColorLookup[i].alpha != 0) { + gst_structure_set( + structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, NULL); + } + gst_caps_append_structure(caps, structure); + } + } + } + + return caps; +} + +gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps) +{ + VO_SINK(base); + + //qDebug() << "set_caps"; + //qDebug() << gst_caps_to_string(caps); + + if (!caps) { + sink->delegate->stop(); + + return TRUE; + } else { + int bytesPerLine = 0; + QVideoSurfaceFormat format = formatForCaps(caps, &bytesPerLine); + + if (sink->delegate->isActive()) { + QVideoSurfaceFormat surfaceFormst = sink->delegate->surfaceFormat(); + + if (format.pixelFormat() == surfaceFormst.pixelFormat() && + format.frameSize() == surfaceFormst.frameSize()) + return TRUE; + else + sink->delegate->stop(); + } + + if (sink->lastRequestedCaps) + gst_caps_unref(sink->lastRequestedCaps); + sink->lastRequestedCaps = 0; + + //qDebug() << "Staring video surface:"; + //qDebug() << format; + //qDebug() << bytesPerLine; + + if (sink->delegate->start(format, bytesPerLine)) + return TRUE; + + } + + return FALSE; +} + +QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *bytesPerLine) +{ + const GstStructure *structure = gst_caps_get_structure(caps, 0); + + QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid; + int bitsPerPixel = 0; + + QSize size; + gst_structure_get_int(structure, "width", &size.rwidth()); + gst_structure_get_int(structure, "height", &size.rheight()); + + if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) { + guint32 fourcc = 0; + gst_structure_get_fourcc(structure, "format", &fourcc); + + int index = indexOfYuvColor(fourcc); + if (index != -1) { + pixelFormat = qt_yuvColorLookup[index].pixelFormat; + bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel; + } + } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) { + int depth = 0; + int endianness = 0; + int red = 0; + int green = 0; + int blue = 0; + int alpha = 0; + + gst_structure_get_int(structure, "bpp", &bitsPerPixel); + gst_structure_get_int(structure, "depth", &depth); + gst_structure_get_int(structure, "endianness", &endianness); + gst_structure_get_int(structure, "red_mask", &red); + gst_structure_get_int(structure, "green_mask", &green); + gst_structure_get_int(structure, "blue_mask", &blue); + gst_structure_get_int(structure, "alpha_mask", &alpha); + + int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha); + + if (index != -1) + pixelFormat = qt_rgbColorLookup[index].pixelFormat; + } + + if (pixelFormat != QVideoFrame::Format_Invalid) { + QVideoSurfaceFormat format(size, pixelFormat); + + QPair<int, int> rate; + gst_structure_get_fraction(structure, "framerate", &rate.first, &rate.second); + + if (rate.second) + format.setFrameRate(qreal(rate.first)/rate.second); + + gint aspectNum = 0; + gint aspectDenum = 0; + if (gst_structure_get_fraction( + structure, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) { + if (aspectDenum > 0) + format.setPixelAspectRatio(aspectNum, aspectDenum); + } + + if (bytesPerLine) + *bytesPerLine = ((size.width() * bitsPerPixel / 8) + 3) & ~3; + + return format; + } + + return QVideoSurfaceFormat(); +} + + +GstFlowReturn QVideoSurfaceGstSink::buffer_alloc( + GstBaseSink *base, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer) +{ + VO_SINK(base); + + Q_UNUSED(offset); + Q_UNUSED(size); + + *buffer = 0; + + if (sink->lastRequestedCaps && gst_caps_is_equal(sink->lastRequestedCaps, caps)) { + //qDebug() << "reusing last caps"; + *buffer = GST_BUFFER(sink->pool->takeBuffer(*sink->lastSurfaceFormat, sink->lastBufferCaps)); + return GST_FLOW_OK; + } + + if (sink->delegate->supportedPixelFormats(XvHandleType).isEmpty()) { + //qDebug() << "sink doesn't support Xv buffers, skip buffers allocation"; + return GST_FLOW_OK; + } + + GstCaps *intersection = gst_caps_intersect(get_caps(GST_BASE_SINK(sink)), caps); + + if (gst_caps_is_empty (intersection)) { + gst_caps_unref(intersection); + return GST_FLOW_NOT_NEGOTIATED; + } + + if (sink->delegate->isActive()) { + //if format was changed, restart the surface + QVideoSurfaceFormat format = formatForCaps(intersection); + QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat(); + + if (format.pixelFormat() != surfaceFormat.pixelFormat() || + format.frameSize() != surfaceFormat.frameSize()) { + //qDebug() << "new format requested, restart video surface"; + sink->delegate->stop(); + } + } + + if (!sink->delegate->isActive()) { + int bytesPerLine = 0; + QVideoSurfaceFormat format = formatForCaps(intersection, &bytesPerLine); + + if (!sink->delegate->start(format, bytesPerLine)) { + qDebug() << "failed to start video surface"; + return GST_FLOW_NOT_NEGOTIATED; + } + } + + QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat(); + + if (!sink->pool->isFormatSupported(surfaceFormat)) { + //qDebug() << "sink doesn't provide Xv buffer details, skip buffers allocation"; + return GST_FLOW_OK; + } + + if (sink->lastRequestedCaps) + gst_caps_unref(sink->lastRequestedCaps); + sink->lastRequestedCaps = caps; + gst_caps_ref(sink->lastRequestedCaps); + + if (sink->lastBufferCaps) + gst_caps_unref(sink->lastBufferCaps); + sink->lastBufferCaps = intersection; + gst_caps_ref(sink->lastBufferCaps); + + *sink->lastSurfaceFormat = surfaceFormat; + + *buffer = GST_BUFFER(sink->pool->takeBuffer(surfaceFormat, intersection)); + + return GST_FLOW_OK; +} + +gboolean QVideoSurfaceGstSink::start(GstBaseSink *base) +{ + Q_UNUSED(base); + + return TRUE; +} + +gboolean QVideoSurfaceGstSink::stop(GstBaseSink *base) +{ + Q_UNUSED(base); + + return TRUE; +} + +gboolean QVideoSurfaceGstSink::unlock(GstBaseSink *base) +{ + Q_UNUSED(base); + + return TRUE; +} + +gboolean QVideoSurfaceGstSink::event(GstBaseSink *base, GstEvent *event) +{ + Q_UNUSED(base); + Q_UNUSED(event); + + return TRUE; +} + +GstFlowReturn QVideoSurfaceGstSink::preroll(GstBaseSink *base, GstBuffer *buffer) +{ + VO_SINK(base); + + return sink->delegate->render(buffer); +} + +GstFlowReturn QVideoSurfaceGstSink::render(GstBaseSink *base, GstBuffer *buffer) +{ + VO_SINK(base); + return sink->delegate->render(buffer); +} + diff --git a/src/plugins/mediaservices/gstreamer/qvideosurfacegstsink.h b/src/plugins/mediaservices/gstreamer/qvideosurfacegstsink.h new file mode 100644 index 0000000..f59a43c --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qvideosurfacegstsink.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIDEOSURFACEGSTSINK_H +#define VIDEOSURFACEGSTSINK_H + +#include <gst/video/gstvideosink.h> + +#include <QtCore/qlist.h> +#include <QtCore/qmutex.h> +#include <QtCore/qpointer.h> +#include <QtCore/qwaitcondition.h> +#include <QtMultimedia/qvideosurfaceformat.h> +#include <QtMultimedia/qvideoframe.h> +#include <QtMultimedia/qabstractvideobuffer.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractVideoSurface; + +class QGstXvImageBuffer; +class QGstXvImageBufferPool; + + +class QVideoSurfaceGstDelegate : public QObject +{ + Q_OBJECT +public: + QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface); + + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; + + QVideoSurfaceFormat surfaceFormat() const; + + + bool start(const QVideoSurfaceFormat &format, int bytesPerLine); + void stop(); + + bool isActive(); + + GstFlowReturn render(GstBuffer *buffer); + +private slots: + void queuedStart(); + void queuedStop(); + void queuedRender(); + + void supportedFormatsChanged(); + +private: + QPointer<QAbstractVideoSurface> m_surface; + QList<QVideoFrame::PixelFormat> m_supportedPixelFormats; + QMutex m_mutex; + QWaitCondition m_setupCondition; + QWaitCondition m_renderCondition; + QVideoSurfaceFormat m_format; + QVideoFrame m_frame; + GstFlowReturn m_renderReturn; + int m_bytesPerLine; + bool m_started; +}; + +class QVideoSurfaceGstSink +{ +public: + GstVideoSink parent; + + static QVideoSurfaceGstSink *createSink(QAbstractVideoSurface *surface); + static QVideoSurfaceFormat formatForCaps(GstCaps *caps, int *bytesPerLine = 0); + +private: + static GType get_type(); + static void class_init(gpointer g_class, gpointer class_data); + static void base_init(gpointer g_class); + static void instance_init(GTypeInstance *instance, gpointer g_class); + + static void finalize(GObject *object); + + static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition); + + static GstCaps *get_caps(GstBaseSink *sink); + static gboolean set_caps(GstBaseSink *sink, GstCaps *caps); + + static GstFlowReturn buffer_alloc( + GstBaseSink *sink, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer); + + static gboolean start(GstBaseSink *sink); + static gboolean stop(GstBaseSink *sink); + + static gboolean unlock(GstBaseSink *sink); + + static gboolean event(GstBaseSink *sink, GstEvent *event); + static GstFlowReturn preroll(GstBaseSink *sink, GstBuffer *buffer); + static GstFlowReturn render(GstBaseSink *sink, GstBuffer *buffer); + +private: + QVideoSurfaceGstDelegate *delegate; + QGstXvImageBufferPool *pool; + GstCaps *lastRequestedCaps; + GstCaps *lastBufferCaps; + QVideoSurfaceFormat *lastSurfaceFormat; +}; + + +class QVideoSurfaceGstSinkClass +{ +public: + GstVideoSinkClass parent_class; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/gstreamer/qx11videosurface.cpp b/src/plugins/mediaservices/gstreamer/qx11videosurface.cpp new file mode 100644 index 0000000..6e282ff --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qx11videosurface.cpp @@ -0,0 +1,509 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qvariant.h> +#include <QtCore/qdebug.h> +#include <QtGui/qx11info_x11.h> +#include <QtMultimedia/qvideosurfaceformat.h> + +#include "qx11videosurface.h" + +Q_DECLARE_METATYPE(XvImage*); + +static QAbstractVideoBuffer::HandleType XvHandleType = QAbstractVideoBuffer::HandleType(4); + +struct XvFormatRgb +{ + QVideoFrame::PixelFormat pixelFormat; + int bits_per_pixel; + int format; + int num_planes; + + int depth; + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + +}; + +bool operator ==(const XvImageFormatValues &format, const XvFormatRgb &rgb) +{ + return format.type == XvRGB + && format.bits_per_pixel == rgb.bits_per_pixel + && format.format == rgb.format + && format.num_planes == rgb.num_planes + && format.depth == rgb.depth + && format.red_mask == rgb.red_mask + && format.blue_mask == rgb.blue_mask; +} + +static const XvFormatRgb qt_xvRgbLookup[] = +{ + { QVideoFrame::Format_ARGB32, 32, XvPacked, 1, 32, 0x00FF0000, 0x0000FF00, 0x000000FF }, + { QVideoFrame::Format_RGB32 , 32, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, + { QVideoFrame::Format_RGB24 , 24, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, + { QVideoFrame::Format_RGB565, 16, XvPacked, 1, 16, 0x0000F800, 0x000007E0, 0x0000001F }, + { QVideoFrame::Format_BGRA32, 32, XvPacked, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00 }, + { QVideoFrame::Format_BGR32 , 32, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, + { QVideoFrame::Format_BGR24 , 24, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, + { QVideoFrame::Format_BGR565, 16, XvPacked, 1, 16, 0x0000F800, 0x000007E0, 0x0000001F } +}; + +struct XvFormatYuv +{ + QVideoFrame::PixelFormat pixelFormat; + int bits_per_pixel; + int format; + int num_planes; + + unsigned int y_sample_bits; + unsigned int u_sample_bits; + unsigned int v_sample_bits; + unsigned int horz_y_period; + unsigned int horz_u_period; + unsigned int horz_v_period; + unsigned int vert_y_period; + unsigned int vert_u_period; + unsigned int vert_v_period; + char component_order[32]; +}; + +bool operator ==(const XvImageFormatValues &format, const XvFormatYuv &yuv) +{ + return format.type == XvYUV + && format.bits_per_pixel == yuv.bits_per_pixel + && format.format == yuv.format + && format.num_planes == yuv.num_planes + && format.y_sample_bits == yuv.y_sample_bits + && format.u_sample_bits == yuv.u_sample_bits + && format.v_sample_bits == yuv.v_sample_bits + && format.horz_y_period == yuv.horz_y_period + && format.horz_u_period == yuv.horz_u_period + && format.horz_v_period == yuv.horz_v_period + && format.horz_y_period == yuv.vert_y_period + && format.vert_u_period == yuv.vert_u_period + && format.vert_v_period == yuv.vert_v_period + && qstrncmp(format.component_order, yuv.component_order, 32) == 0; +} + +static const XvFormatYuv qt_xvYuvLookup[] = +{ + { QVideoFrame::Format_YUV444 , 24, XvPacked, 1, 8, 8, 8, 1, 1, 1, 1, 1, 1, "YUV" }, + { QVideoFrame::Format_YUV420P, 12, XvPlanar, 3, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YUV" }, + { QVideoFrame::Format_YV12 , 12, XvPlanar, 3, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU" }, + { QVideoFrame::Format_UYVY , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "UYVY" }, + { QVideoFrame::Format_YUYV , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUY2" }, + { QVideoFrame::Format_YUYV , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUYV" }, + { QVideoFrame::Format_NV12 , 12, XvPlanar, 2, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YUV" }, + { QVideoFrame::Format_NV12 , 12, XvPlanar, 2, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU" }, + { QVideoFrame::Format_Y8 , 8 , XvPlanar, 1, 8, 0, 0, 1, 0, 0, 1, 0, 0, "Y" } +}; + +QX11VideoSurface::QX11VideoSurface(QObject *parent) + : QAbstractVideoSurface(parent) + , m_winId(0) + , m_portId(0) + , m_gc(0) + , m_image(0) +{ +} + +QX11VideoSurface::~QX11VideoSurface() +{ + if (m_gc) + XFreeGC(QX11Info::display(), m_gc); + + if (m_portId != 0) + XvUngrabPort(QX11Info::display(), m_portId, 0); +} + +WId QX11VideoSurface::winId() const +{ + return m_winId; +} + +void QX11VideoSurface::setWinId(WId id) +{ + if (id == m_winId) + return; + + if (m_image) + XFree(m_image); + + if (m_gc) { + XFreeGC(QX11Info::display(), m_gc); + m_gc = 0; + } + + if (m_portId != 0) + XvUngrabPort(QX11Info::display(), m_portId, 0); + + m_supportedPixelFormats.clear(); + m_formatIds.clear(); + + m_winId = id; + + if (m_winId && findPort()) { + querySupportedFormats(); + + m_gc = XCreateGC(QX11Info::display(), m_winId, 0, 0); + + if (m_image) { + m_image = 0; + + if (!start(surfaceFormat())) + QAbstractVideoSurface::stop(); + } + } else if (m_image) { + m_image = 0; + + QAbstractVideoSurface::stop(); + } + + emit supportedFormatsChanged(); +} + +QRect QX11VideoSurface::displayRect() const +{ + return m_displayRect; +} + +void QX11VideoSurface::setDisplayRect(const QRect &rect) +{ + m_displayRect = rect; +} + +int QX11VideoSurface::brightness() const +{ + return getAttribute("XV_BRIGHTNESS", m_brightnessRange.first, m_brightnessRange.second); +} + +void QX11VideoSurface::setBrightness(int brightness) +{ + setAttribute("XV_BRIGHTNESS", brightness, m_brightnessRange.first, m_brightnessRange.second); +} + +int QX11VideoSurface::contrast() const +{ + return getAttribute("XV_CONTRAST", m_contrastRange.first, m_contrastRange.second); +} + +void QX11VideoSurface::setContrast(int contrast) +{ + setAttribute("XV_CONTRAST", contrast, m_contrastRange.first, m_contrastRange.second); +} + +int QX11VideoSurface::hue() const +{ + return getAttribute("XV_HUE", m_hueRange.first, m_hueRange.second); +} + +void QX11VideoSurface::setHue(int hue) +{ + setAttribute("XV_HUE", hue, m_hueRange.first, m_hueRange.second); +} + +int QX11VideoSurface::saturation() const +{ + return getAttribute("XV_SATURATION", m_saturationRange.first, m_saturationRange.second); +} + +void QX11VideoSurface::setSaturation(int saturation) +{ + setAttribute("XV_SATURATION", saturation, m_saturationRange.first, m_saturationRange.second); +} + +int QX11VideoSurface::getAttribute(const char *attribute, int minimum, int maximum) const +{ + if (m_portId != 0) { + Display *display = QX11Info::display(); + + Atom atom = XInternAtom(display, attribute, True); + + int value = 0; + + XvGetPortAttribute(display, m_portId, atom, &value); + + return redistribute(value, minimum, maximum, -100, 100); + } else { + return 0; + } +} + +void QX11VideoSurface::setAttribute(const char *attribute, int value, int minimum, int maximum) +{ + if (m_portId != 0) { + Display *display = QX11Info::display(); + + Atom atom = XInternAtom(display, attribute, True); + + XvSetPortAttribute( + display, m_portId, atom, redistribute(value, -100, 100, minimum, maximum)); + } +} + +int QX11VideoSurface::redistribute( + int value, int fromLower, int fromUpper, int toLower, int toUpper) +{ + return fromUpper != fromLower + ? ((value - fromLower) * (toUpper - toLower) / (fromUpper - fromLower)) + toLower + : 0; +} + +QList<QVideoFrame::PixelFormat> QX11VideoSurface::supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType) const +{ + return handleType == QAbstractVideoBuffer::NoHandle || handleType == XvHandleType + ? m_supportedPixelFormats + : QList<QVideoFrame::PixelFormat>(); +} + +bool QX11VideoSurface::start(const QVideoSurfaceFormat &format) +{ + if (m_image) + XFree(m_image); + + int xvFormatId = 0; + for (int i = 0; i < m_supportedPixelFormats.count(); ++i) { + if (m_supportedPixelFormats.at(i) == format.pixelFormat()) { + xvFormatId = m_formatIds.at(i); + break; + } + } + + if (xvFormatId == 0) { + setError(UnsupportedFormatError); + } else { + XvImage *image = XvCreateImage( + QX11Info::display(), + m_portId, + xvFormatId, + 0, + format.frameWidth(), + format.frameHeight()); + + if (!image) { + setError(ResourceError); + } else { + m_viewport = format.viewport(); + m_image = image; + + QVideoSurfaceFormat newFormat = format; + newFormat.setProperty("portId", QVariant(quint64(m_portId))); + newFormat.setProperty("xvFormatId", xvFormatId); + newFormat.setProperty("dataSize", image->data_size); + + return QAbstractVideoSurface::start(newFormat); + } + } + + if (m_image) { + m_image = 0; + + QAbstractVideoSurface::stop(); + } + + return false; +} + +void QX11VideoSurface::stop() +{ + if (m_image) { + XFree(m_image); + m_image = 0; + + QAbstractVideoSurface::stop(); + } +} + +bool QX11VideoSurface::present(const QVideoFrame &frame) +{ + if (!m_image) { + setError(StoppedError); + return false; + } else if (m_image->width != frame.width() || m_image->height != frame.height()) { + setError(IncorrectFormatError); + return false; + } else { + QVideoFrame frameCopy(frame); + + if (!frameCopy.map(QAbstractVideoBuffer::ReadOnly)) { + setError(IncorrectFormatError); + return false; + } else { + bool presented = false; + + if (frame.handleType() != XvHandleType && + m_image->data_size > frame.mappedBytes()) { + qWarning("Insufficient frame buffer size"); + setError(IncorrectFormatError); + } else if (frame.handleType() != XvHandleType && + m_image->num_planes > 0 && + m_image->pitches[0] != frame.bytesPerLine()) { + qWarning("Incompatible frame pitches"); + setError(IncorrectFormatError); + } else { + if (frame.handleType() != XvHandleType) { + m_image->data = reinterpret_cast<char *>(frameCopy.bits()); + + //qDebug() << "copy frame"; + XvPutImage( + QX11Info::display(), + m_portId, + m_winId, + m_gc, + m_image, + m_viewport.x(), + m_viewport.y(), + m_viewport.width(), + m_viewport.height(), + m_displayRect.x(), + m_displayRect.y(), + m_displayRect.width(), + m_displayRect.height()); + + m_image->data = 0; + } else { + XvImage *img = frame.handle().value<XvImage*>(); + + //qDebug() << "render directly"; + if (img) + XvShmPutImage( + QX11Info::display(), + m_portId, + m_winId, + m_gc, + img, + m_viewport.x(), + m_viewport.y(), + m_viewport.width(), + m_viewport.height(), + m_displayRect.x(), + m_displayRect.y(), + m_displayRect.width(), + m_displayRect.height(), + false); + } + + presented = true; + } + + frameCopy.unmap(); + + return presented; + } + } +} + +bool QX11VideoSurface::findPort() +{ + unsigned int count = 0; + XvAdaptorInfo *adaptors = 0; + bool portFound = false; + + if (XvQueryAdaptors(QX11Info::display(), m_winId, &count, &adaptors) == Success) { + for (unsigned int i = 0; i < count && !portFound; ++i) { + if (adaptors[i].type & XvImageMask) { + m_portId = adaptors[i].base_id; + + for (unsigned int j = 0; j < adaptors[i].num_ports && !portFound; ++j, ++m_portId) + portFound = XvGrabPort(QX11Info::display(), m_portId, 0) == Success; + } + } + XvFreeAdaptorInfo(adaptors); + } + + return portFound; +} + +void QX11VideoSurface::querySupportedFormats() +{ + int count = 0; + if (XvImageFormatValues *imageFormats = XvListImageFormats( + QX11Info::display(), m_portId, &count)) { + const int rgbCount = sizeof(qt_xvRgbLookup) / sizeof(XvFormatRgb); + const int yuvCount = sizeof(qt_xvYuvLookup) / sizeof(XvFormatYuv); + + for (int i = 0; i < count; ++i) { + switch (imageFormats[i].type) { + case XvRGB: + for (int j = 0; j < rgbCount; ++j) { + if (imageFormats[i] == qt_xvRgbLookup[j]) { + m_supportedPixelFormats.append(qt_xvRgbLookup[j].pixelFormat); + m_formatIds.append(imageFormats[i].id); + break; + } + } + break; + case XvYUV: + for (int j = 0; j < yuvCount; ++j) { + if (imageFormats[i] == qt_xvYuvLookup[j]) { + m_supportedPixelFormats.append(qt_xvYuvLookup[j].pixelFormat); + m_formatIds.append(imageFormats[i].id); + break; + } + } + break; + } + } + XFree(imageFormats); + } + + m_brightnessRange = qMakePair(0, 0); + m_contrastRange = qMakePair(0, 0); + m_hueRange = qMakePair(0, 0); + m_saturationRange = qMakePair(0, 0); + + if (XvAttribute *attributes = XvQueryPortAttributes(QX11Info::display(), m_portId, &count)) { + for (int i = 0; i < count; ++i) { + if (qstrcmp(attributes[i].name, "XV_BRIGHTNESS") == 0) + m_brightnessRange = qMakePair(attributes[i].min_value, attributes[i].max_value); + else if (qstrcmp(attributes[i].name, "XV_CONTRAST") == 0) + m_contrastRange = qMakePair(attributes[i].min_value, attributes[i].max_value); + else if (qstrcmp(attributes[i].name, "XV_HUE") == 0) + m_hueRange = qMakePair(attributes[i].min_value, attributes[i].max_value); + else if (qstrcmp(attributes[i].name, "XV_SATURATION") == 0) + m_saturationRange = qMakePair(attributes[i].min_value, attributes[i].max_value); + } + + XFree(attributes); + } +} diff --git a/src/plugins/mediaservices/gstreamer/qx11videosurface.h b/src/plugins/mediaservices/gstreamer/qx11videosurface.h new file mode 100644 index 0000000..1be963e --- /dev/null +++ b/src/plugins/mediaservices/gstreamer/qx11videosurface.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QX11VIDEOSURFACE_H +#define QX11VIDEOSURFACE_H + +#include <QtGui/qwidget.h> +#include <QtMultimedia/qabstractvideosurface.h> + +#include <X11/Xlib.h> +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvlib.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QX11VideoSurface : public QAbstractVideoSurface +{ + Q_OBJECT +public: + QX11VideoSurface(QObject *parent = 0); + ~QX11VideoSurface(); + + WId winId() const; + void setWinId(WId id); + + QRect displayRect() const; + void setDisplayRect(const QRect &rect); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + + QList<QVideoFrame::PixelFormat> supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const; + + bool start(const QVideoSurfaceFormat &format); + void stop(); + + bool present(const QVideoFrame &frame); + +private: + WId m_winId; + XvPortID m_portId; + GC m_gc; + XvImage *m_image; + QList<QVideoFrame::PixelFormat> m_supportedPixelFormats; + QVector<int> m_formatIds; + QRect m_viewport; + QRect m_displayRect; + QPair<int, int> m_brightnessRange; + QPair<int, int> m_contrastRange; + QPair<int, int> m_hueRange; + QPair<int, int> m_saturationRange; + + bool findPort(); + void querySupportedFormats(); + + int getAttribute(const char *attribute, int minimum, int maximum) const; + void setAttribute(const char *attribute, int value, int minimum, int maximum); + + static int redistribute(int value, int fromLower, int fromUpper, int toLower, int toUpper); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/mediaservices.pro b/src/plugins/mediaservices/mediaservices.pro new file mode 100644 index 0000000..55e6aba --- /dev/null +++ b/src/plugins/mediaservices/mediaservices.pro @@ -0,0 +1,18 @@ +TEMPLATE = subdirs + +win32:!wince: SUBDIRS += directshow + +mac: SUBDIRS += qt7 + +unix:!mac:!symbian { + TMP_GST_LIBS = \ + gstreamer-0.10 >= 0.10.19 \ + gstreamer-base-0.10 >= 0.10.19 \ + gstreamer-interfaces-0.10 >= 0.10.19 \ + gstreamer-audio-0.10 >= 0.10.19 \ + gstreamer-video-0.10 >= 0.10.19 + + system(pkg-config --exists \'$${TMP_GST_LIBS}\' --print-errors): { + SUBDIRS += gstreamer + } +} diff --git a/src/plugins/mediaservices/qt7/mediaplayer/mediaplayer.pri b/src/plugins/mediaservices/qt7/mediaplayer/mediaplayer.pri new file mode 100644 index 0000000..577209e --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/mediaplayer.pri @@ -0,0 +1,18 @@ +INCLUDEPATH += $$PWD + +DEFINES += QMEDIA_QT7_PLAYER + +HEADERS += \ + $$PWD/qt7playercontrol.h \ + $$PWD/qt7playermetadata.h \ + $$PWD/qt7playerservice.h \ + $$PWD/qt7playersession.h + +OBJECTIVE_SOURCES += \ + $$PWD/qt7playercontrol.mm \ + $$PWD/qt7playermetadata.mm \ + $$PWD/qt7playerservice.mm \ + $$PWD/qt7playersession.mm + + + diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.h new file mode 100644 index 0000000..907d13d --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7PLAYERCONTROL_H +#define QT7PLAYERCONTROL_H + +#include <QtCore/qobject.h> +#include <QtGui/qmacdefines_mac.h> + +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaplayer.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QT7PlayerSession; +class QT7PlayerService; +class QMediaPlaylist; +class QMediaPlaylistNavigator; + +class QT7PlayerControl : public QMediaPlayerControl +{ +Q_OBJECT +public: + QT7PlayerControl(QObject *parent = 0); + ~QT7PlayerControl(); + + void setSession(QT7PlayerSession *session); + + QMediaPlayer::State state() const; + QMediaPlayer::MediaStatus mediaStatus() const; + + QMediaContent media() const; + const QIODevice *mediaStream() const; + void setMedia(const QMediaContent &content, QIODevice *stream); + + qint64 position() const; + qint64 duration() const; + + int bufferStatus() const; + + int volume() const; + bool isMuted() const; + + bool isAudioAvailable() const; + bool isVideoAvailable() const; + + bool isSeekable() const; + + QMediaTimeRange availablePlaybackRanges() const; + + qreal playbackRate() const; + void setPlaybackRate(qreal rate); + +public Q_SLOTS: + void setPosition(qint64 pos); + + void play(); + void pause(); + void stop(); + + void setVolume(int volume); + void setMuted(bool muted); + +Q_SIGNALS: + void mediaChanged(const QMediaContent& content); + void durationChanged(qint64 duration); + void positionChanged(qint64 position); + void stateChanged(QMediaPlayer::State newState); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void volumeChanged(int volume); + void mutedChanged(bool muted); + void videoAvailableChanged(bool videoAvailable); + void bufferStatusChanged(int percentFilled); + void seekableChanged(bool); + void seekRangeChanged(const QPair<qint64,qint64>&); + void playbackRateChanged(qreal rate); + void error(int error, const QString &errorString); + +private: + QT7PlayerSession *m_session; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.mm new file mode 100644 index 0000000..0f4ac41 --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playercontrol.mm @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt7playercontrol.h" +#include "qt7playersession.h" + +#include <QtMultimedia/qmediaplaylistnavigator.h> + +#include <QtCore/qurl.h> +#include <QtCore/qdebug.h> + + +QT_BEGIN_NAMESPACE + +QT7PlayerControl::QT7PlayerControl(QObject *parent) + : QMediaPlayerControl(parent) +{ +} + +QT7PlayerControl::~QT7PlayerControl() +{ +} + +void QT7PlayerControl::setSession(QT7PlayerSession *session) +{ + m_session = session; + + connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64))); + connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); + connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)), + this, SIGNAL(stateChanged(QMediaPlayer::State))); + connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int))); + connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); + connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool))); + connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool))); + connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); +} + +qint64 QT7PlayerControl::position() const +{ + return m_session->position(); +} + +qint64 QT7PlayerControl::duration() const +{ + return m_session->duration(); +} + +QMediaPlayer::State QT7PlayerControl::state() const +{ + return m_session->state(); +} + +QMediaPlayer::MediaStatus QT7PlayerControl::mediaStatus() const +{ + return m_session->mediaStatus(); +} + +int QT7PlayerControl::bufferStatus() const +{ + return m_session->bufferStatus(); +} + +int QT7PlayerControl::volume() const +{ + return m_session->volume(); +} + +bool QT7PlayerControl::isMuted() const +{ + return m_session->isMuted(); +} + +bool QT7PlayerControl::isSeekable() const +{ + return m_session->isSeekable(); +} + +QMediaTimeRange QT7PlayerControl::availablePlaybackRanges() const +{ + return isSeekable() ? QMediaTimeRange(0, duration()) : QMediaTimeRange(); +} + +qreal QT7PlayerControl::playbackRate() const +{ + return m_session->playbackRate(); +} + +void QT7PlayerControl::setPlaybackRate(qreal rate) +{ + m_session->setPlaybackRate(rate); +} + +void QT7PlayerControl::setPosition(qint64 pos) +{ + m_session->setPosition(pos); +} + +void QT7PlayerControl::play() +{ + m_session->play(); +} + +void QT7PlayerControl::pause() +{ + m_session->pause(); +} + +void QT7PlayerControl::stop() +{ + m_session->stop(); +} + +void QT7PlayerControl::setVolume(int volume) +{ + m_session->setVolume(volume); +} + +void QT7PlayerControl::setMuted(bool muted) +{ + m_session->setMuted(muted); +} + +QMediaContent QT7PlayerControl::media() const +{ + return m_session->media(); +} + +const QIODevice *QT7PlayerControl::mediaStream() const +{ + return m_session->mediaStream(); +} + +void QT7PlayerControl::setMedia(const QMediaContent &content, QIODevice *stream) +{ + m_session->setMedia(content, stream); + + emit mediaChanged(content); +} + +bool QT7PlayerControl::isAudioAvailable() const +{ + return m_session->isAudioAvailable(); +} + +bool QT7PlayerControl::isVideoAvailable() const +{ + return m_session->isVideoAvailable(); +} + +#include "moc_qt7playercontrol.cpp" + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.h new file mode 100644 index 0000000..f16807a --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7PLAYERMETADATACONTROL_H +#define QT7PLAYERMETADATACONTROL_H + +#include <QtMultimedia/qmetadatacontrol.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QT7PlayerSession; + +class QT7PlayerMetaDataControl : public QMetaDataControl +{ + Q_OBJECT +public: + QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent); + virtual ~QT7PlayerMetaDataControl(); + + bool isMetaDataAvailable() const; + bool isWritable() const; + + QVariant metaData(QtMultimedia::MetaData key) const; + void setMetaData(QtMultimedia::MetaData key, const QVariant &value); + QList<QtMultimedia::MetaData> availableMetaData() const; + + QVariant extendedMetaData(const QString &key) const ; + void setExtendedMetaData(const QString &key, const QVariant &value); + QStringList availableExtendedMetaData() const; + +private slots: + void updateTags(); + +private: + QT7PlayerSession *m_session; + QMap<QtMultimedia::MetaData, QVariant> m_tags; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.mm new file mode 100644 index 0000000..a14981a --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playermetadata.mm @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt7backend.h" +#include "qt7playermetadata.h" +#include "qt7playersession.h" +#include <QtCore/qvarlengtharray.h> + +#import <QTKit/QTMovie.h> + +#ifdef QUICKTIME_C_API_AVAILABLE + #include <QuickTime/QuickTime.h> + #undef check // avoid name clash; +#endif + +QT_BEGIN_NAMESPACE + +QT7PlayerMetaDataControl::QT7PlayerMetaDataControl(QT7PlayerSession *session, QObject *parent) + :QMetaDataControl(parent), m_session(session) +{ +} + +QT7PlayerMetaDataControl::~QT7PlayerMetaDataControl() +{ +} + +bool QT7PlayerMetaDataControl::isMetaDataAvailable() const +{ + return !m_tags.isEmpty(); +} + +bool QT7PlayerMetaDataControl::isWritable() const +{ + return false; +} + +QVariant QT7PlayerMetaDataControl::metaData(QtMultimedia::MetaData key) const +{ + return m_tags.value(key); +} + +void QT7PlayerMetaDataControl::setMetaData(QtMultimedia::MetaData key, QVariant const &value) +{ + Q_UNUSED(key); + Q_UNUSED(value); +} + +QList<QtMultimedia::MetaData> QT7PlayerMetaDataControl::availableMetaData() const +{ + return m_tags.keys(); +} + +QVariant QT7PlayerMetaDataControl::extendedMetaData(const QString &key) const +{ + Q_UNUSED(key); + return QVariant(); +} + +void QT7PlayerMetaDataControl::setExtendedMetaData(const QString &key, QVariant const &value) +{ + Q_UNUSED(key); + Q_UNUSED(value); +} + +QStringList QT7PlayerMetaDataControl::availableExtendedMetaData() const +{ + return QStringList(); +} + +#ifdef QUICKTIME_C_API_AVAILABLE + +static QString stripCopyRightSymbol(const QString &key) +{ + return key.right(key.length()-1); +} + +static QString convertQuickTimeKeyToUserKey(const QString &key) +{ + if (key == QLatin1String("com.apple.quicktime.displayname")) + return QLatin1String("nam"); + else if (key == QLatin1String("com.apple.quicktime.album")) + return QLatin1String("alb"); + else if (key == QLatin1String("com.apple.quicktime.artist")) + return QLatin1String("ART"); + else + return QLatin1String("???"); +} + +static OSStatus readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass, + QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size) +{ + QTPropertyValueType type; + ByteCount propSize; + UInt32 propFlags; + OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags); + + + *value = malloc(propSize); + + err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size); + + if (type == 'code' || type == 'itsk' || type == 'itlk') { + // convert from native endian to big endian + OSTypePtr pType = (OSTypePtr)*value; + *pType = EndianU32_NtoB(*pType); + } + + return err; +} + +static UInt32 getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item) +{ + QTPropertyValuePtr value = 0; + ByteCount ignore = 0; + OSStatus err = readMetaValue( + metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore); + + UInt32 type = *((UInt32 *) value); + if (value) + free(value); + return type; +} + +static QString cFStringToQString(CFStringRef str) +{ + if(!str) + return QString(); + CFIndex length = CFStringGetLength(str); + const UniChar *chars = CFStringGetCharactersPtr(str); + if (chars) + return QString(reinterpret_cast<const QChar *>(chars), length); + + QVarLengthArray<UniChar> buffer(length); + CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data()); + return QString(reinterpret_cast<const QChar *>(buffer.constData()), length); +} + + +static QString getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id) +{ + QTPropertyValuePtr value = 0; + ByteCount size = 0; + OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size); + + QString string; + UInt32 dataType = getMetaType(metaDataRef, item); + switch (dataType){ + case kQTMetaDataTypeUTF8: + case kQTMetaDataTypeMacEncodedText: + string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false)); + break; + case kQTMetaDataTypeUTF16BE: + string = cFStringToQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false)); + break; + default: + break; + } + + if (value) + free(value); + return string; +} + + +static void readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result) +{ + QTMetaDataItem item = kQTMetaDataItemUninitialized; + OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item); + while (err == noErr){ + QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key); + if (format == kQTMetaDataStorageFormatQuickTime) + key = convertQuickTimeKeyToUserKey(key); + else + key = stripCopyRightSymbol(key); + + if (!result.contains(key)){ + QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value); + result.insert(key, val); + } + err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item); + } +} +#endif + + +void QT7PlayerMetaDataControl::updateTags() +{ + bool wasEmpty = m_tags.isEmpty(); + m_tags.clear(); + + QTMovie *movie = (QTMovie*)m_session->movie(); + + if (movie) { + QMultiMap<QString, QString> metaMap; + +#ifdef QUICKTIME_C_API_AVAILABLE + QTMetaDataRef metaDataRef; + OSStatus err = QTCopyMovieMetaData([movie quickTimeMovie], &metaDataRef); + + readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap); + readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap); + readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap); +#else + NSString *name = [movie attributeForKey:@"QTMovieDisplayNameAttribute"]; + metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String])); +#endif // QUICKTIME_C_API_AVAILABLE + + m_tags.insert(QtMultimedia::AlbumArtist, metaMap.value(QLatin1String("ART"))); + m_tags.insert(QtMultimedia::AlbumTitle, metaMap.value(QLatin1String("alb"))); + m_tags.insert(QtMultimedia::Title, metaMap.value(QLatin1String("nam"))); + m_tags.insert(QtMultimedia::Date, metaMap.value(QLatin1String("day"))); + m_tags.insert(QtMultimedia::Genre, metaMap.value(QLatin1String("gnre"))); + m_tags.insert(QtMultimedia::TrackNumber, metaMap.value(QLatin1String("trk"))); + m_tags.insert(QtMultimedia::Description, metaMap.value(QLatin1String("des"))); + } + + if (!wasEmpty || !m_tags.isEmpty()) + emit metaDataChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qt7playermetadata.cpp" diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.h new file mode 100644 index 0000000..d4b30b8 --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7PLAYERSERVICE_H +#define QT7PLAYERSERVICE_H + +#include <QtCore/qobject.h> +#include <QtMultimedia/qmediaservice.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaMetaData; +class QMediaPlayerControl; +class QMediaPlaylist; +class QMediaPlaylistNavigator; +class QT7PlayerControl; +class QT7PlayerMetaDataControl; +class QT7VideoOutputControl; +class QT7VideoWindowControl; +class QT7VideoWidgetControl; +class QT7VideoRendererControl; +class QT7VideoOutput; +class QT7PlayerSession; + +class QT7PlayerService : public QMediaService +{ +Q_OBJECT +public: + QT7PlayerService(QObject *parent = 0); + ~QT7PlayerService(); + + QMediaControl *control(const char *name) const; + +private slots: + void updateVideoOutput(); + +private: + QT7PlayerSession *m_session; + QT7PlayerControl *m_control; + QT7VideoOutputControl *m_videoOutputControl; + QT7VideoWindowControl *m_videoWidnowControl; + QT7VideoWidgetControl *m_videoWidgetControl; + QT7VideoRendererControl *m_videoRendererControl; + QT7PlayerMetaDataControl *m_playerMetaDataControl; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.mm new file mode 100644 index 0000000..df15fa8 --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playerservice.mm @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qvariant.h> +#include <QtCore/qdebug.h> +#include <QtGui/qwidget.h> + +#include "qt7backend.h" +#include "qt7playerservice.h" +#include "qt7playercontrol.h" +#include "qt7playersession.h" +#include "qt7videooutputcontrol.h" +#include "qt7movieviewoutput.h" +#include "qt7movieviewrenderer.h" +#include "qt7movierenderer.h" +#include "qt7movievideowidget.h" +#include "qt7playermetadata.h" + +#include <QtMultimedia/qmediaplaylistnavigator.h> +#include <QtMultimedia/qmediaplaylist.h> + +QT_BEGIN_NAMESPACE + +QT7PlayerService::QT7PlayerService(QObject *parent): + QMediaService(parent) +{ + m_session = new QT7PlayerSession; + + m_control = new QT7PlayerControl(this); + m_control->setSession(m_session); + + m_playerMetaDataControl = new QT7PlayerMetaDataControl(m_session, this); + connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags())); + + m_videoOutputControl = new QT7VideoOutputControl(this); + + m_videoWidnowControl = 0; + m_videoWidgetControl = 0; + m_videoRendererControl = 0; + +#if defined(QT_MAC_USE_COCOA) + m_videoWidnowControl = new QT7MovieViewOutput(this); + m_videoOutputControl->enableOutput(QVideoOutputControl::WindowOutput); + qDebug() << "Using cocoa"; +#endif + +#ifdef QUICKTIME_C_API_AVAILABLE + m_videoRendererControl = new QT7MovieRenderer(this); + m_videoOutputControl->enableOutput(QVideoOutputControl::RendererOutput); + + m_videoWidgetControl = new QT7MovieVideoWidget(this); + m_videoOutputControl->enableOutput(QVideoOutputControl::WidgetOutput); + qDebug() << "QuickTime C API is available"; +#else + m_videoRendererControl = new QT7MovieViewRenderer(this); + m_videoOutputControl->enableOutput(QVideoOutputControl::RendererOutput); + qDebug() << "QuickTime C API is not available"; +#endif + + + connect(m_videoOutputControl, SIGNAL(videoOutputChanged(QVideoOutputControl::Output)), + this, SLOT(updateVideoOutput())); +} + +QT7PlayerService::~QT7PlayerService() +{ +} + +QMediaControl *QT7PlayerService::control(const char *name) const +{ + if (qstrcmp(name, QMediaPlayerControl_iid) == 0) + return m_control; + + if (qstrcmp(name, QVideoOutputControl_iid) == 0) + return m_videoOutputControl; + + if (qstrcmp(name, QVideoWindowControl_iid) == 0) + return m_videoWidnowControl; + + if (qstrcmp(name, QVideoRendererControl_iid) == 0) + return m_videoRendererControl; + + if (qstrcmp(name, QVideoWidgetControl_iid) == 0) + return m_videoWidgetControl; + + if (qstrcmp(name, QMetaDataControl_iid) == 0) + return m_playerMetaDataControl; + + return 0; +} + +void QT7PlayerService::updateVideoOutput() +{ + qDebug() << "QT7PlayerService::updateVideoOutput" << m_videoOutputControl->output(); + + switch (m_videoOutputControl->output()) { + case QVideoOutputControl::WindowOutput: + m_session->setVideoOutput(m_videoWidnowControl); + break; + case QVideoOutputControl::RendererOutput: + m_session->setVideoOutput(m_videoRendererControl); + break; + case QVideoOutputControl::WidgetOutput: + m_session->setVideoOutput(m_videoWidgetControl); + break; + default: + m_session->setVideoOutput(0); + } +} + +QT_END_NAMESPACE + +#include "moc_qt7playerservice.cpp" diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h new file mode 100644 index 0000000..4742e2e --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7PLAYERSESSION_H +#define QT7PLAYERSESSION_H + +#include <QtCore/qobject.h> +#include <QtGui/qmacdefines_mac.h> + +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaplayer.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QT7PlayerControl; +class QMediaPlaylist; +class QMediaPlaylistNavigator; +class QT7VideoOutput; +class QT7PlayerSession; +class QT7PlayerService; + +class QT7PlayerSession : public QObject +{ +Q_OBJECT +public: + QT7PlayerSession(QObject *parent = 0); + ~QT7PlayerSession(); + + void *movie() const; + + void setControl(QT7PlayerControl *control); + void setVideoOutput(QT7VideoOutput *output); + + QMediaPlayer::State state() const; + QMediaPlayer::MediaStatus mediaStatus() const; + + QMediaContent media() const; + const QIODevice *mediaStream() const; + void setMedia(const QMediaContent &content, QIODevice *stream); + + qint64 position() const; + qint64 duration() const; + + int bufferStatus() const; + + int volume() const; + bool isMuted() const; + + bool isAudioAvailable() const; + bool isVideoAvailable() const; + + bool isSeekable() const; + + qreal playbackRate() const; + +public slots: + void setPlaybackRate(qreal rate); + + void setPosition(qint64 pos); + + void play(); + void pause(); + void stop(); + + void setVolume(int volume); + void setMuted(bool muted); + + void processEOS(); + void processStateChange(); + void processVolumeChange(); + void processNaturalSizeChange(); + +signals: + void positionChanged(qint64 position); + void durationChanged(qint64 duration); + void stateChanged(QMediaPlayer::State newState); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void volumeChanged(int volume); + void mutedChanged(bool muted); + void audioAvailableChanged(bool audioAvailable); + void videoAvailableChanged(bool videoAvailable); + void error(int error, const QString &errorString); + +private: + void *m_QTMovie; + void *m_movieObserver; + + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_mediaStatus; + QIODevice *m_mediaStream; + QMediaContent m_resources; + + QT7VideoOutput *m_videoOutput; + + mutable qint64 m_currentTime; + + bool m_muted; + int m_volume; + qreal m_rate; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm new file mode 100644 index 0000000..5507633 --- /dev/null +++ b/src/plugins/mediaservices/qt7/mediaplayer/qt7playersession.mm @@ -0,0 +1,517 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import <QTKit/QTDataReference.h> +#import <QTKit/QTMovie.h> + +#include "qt7backend.h" + +#include "qt7playersession.h" +#include "qt7playercontrol.h" +#include "qt7videooutputcontrol.h" + +#include <QtMultimedia/qmediaplaylistnavigator.h> + +#include <CoreFoundation/CoreFoundation.h> + +#include <QtCore/qurl.h> +#include <QtCore/qdebug.h> + + +QT_BEGIN_NAMESPACE + +@interface QTMovieObserver : NSObject +{ +@private + QT7PlayerSession *m_session; + QTMovie *m_movie; +} + +- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session; +- (void) setMovie:(QTMovie *)movie; +- (void) processEOS:(NSNotification *)notification; +- (void) processStateChange:(NSNotification *)notification; +@end + +@implementation QTMovieObserver + +- (QTMovieObserver *) initWithPlayerSession:(QT7PlayerSession*)session +{ + if (!(self = [super init])) + return nil; + + self->m_session = session; + return self; +} + +- (void) setMovie:(QTMovie *)movie +{ + if (m_movie == movie) + return; + + if (m_movie) { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [m_movie release]; + } + + m_movie = movie; + + if (movie) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(processEOS:) + name:QTMovieDidEndNotification + object:m_movie]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(processStateChange:) + name:QTMovieLoadStateDidChangeNotification + object:m_movie]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(processVolumeChange:) + name:QTMovieVolumeDidChangeNotification + object:m_movie]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(processNaturalSizeChange:) + name: +#if defined(MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) + QTMovieNaturalSizeDidChangeNotification +#else + QTMovieEditedNotification +#endif + object:m_movie]; + [movie retain]; + } +} + +- (void) processEOS:(NSNotification *)notification +{ + Q_UNUSED(notification); + m_session->processEOS(); +} + +- (void) processStateChange:(NSNotification *)notification +{ + Q_UNUSED(notification); + m_session->processStateChange(); +} + +- (void) processVolumeChange:(NSNotification *)notification +{ + Q_UNUSED(notification); + m_session->processVolumeChange(); +} + +- (void) processNaturalSizeChange :(NSNotification *)notification +{ + Q_UNUSED(notification); + m_session->processNaturalSizeChange(); +} + +@end + +static CFStringRef qString2CFStringRef(const QString &string) +{ + return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(string.unicode()), + string.length()); +} + +QT7PlayerSession::QT7PlayerSession(QObject *parent) + : QObject(parent) + , m_QTMovie(0) + , m_state(QMediaPlayer::StoppedState) + , m_mediaStatus(QMediaPlayer::NoMedia) + , m_mediaStream(0) + , m_videoOutput(0) + , m_muted(false) + , m_volume(100) + , m_rate(1.0) +{ + m_movieObserver = [[QTMovieObserver alloc] initWithPlayerSession:this]; +} + +QT7PlayerSession::~QT7PlayerSession() +{ + [(QTMovieObserver*)m_movieObserver setMovie:nil]; + [(QTMovieObserver*)m_movieObserver release]; +} + +void *QT7PlayerSession::movie() const +{ + return m_QTMovie; +} + +void QT7PlayerSession::setVideoOutput(QT7VideoOutput *output) +{ + if (m_videoOutput == output) + return; + + if (m_videoOutput) { + m_videoOutput->setEnabled(false); + m_videoOutput->setMovie(0); + } + + m_videoOutput = output; + + if (m_videoOutput) { + m_videoOutput->setEnabled(m_QTMovie != 0); + m_videoOutput->setMovie(m_QTMovie); + } +} + + +qint64 QT7PlayerSession::position() const +{ + if (!m_QTMovie || m_state == QMediaPlayer::PausedState) + return m_currentTime; + + AutoReleasePool pool; + + QTTime qtTime = [(QTMovie*)m_QTMovie currentTime]; + quint64 t = static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f); + m_currentTime = t; + + return m_currentTime; +} + +qint64 QT7PlayerSession::duration() const +{ + if (!m_QTMovie) + return 0; + + AutoReleasePool pool; + + QTTime qtTime = [(QTMovie*)m_QTMovie duration]; + + return static_cast<quint64>(float(qtTime.timeValue) / float(qtTime.timeScale) * 1000.0f); +} + +QMediaPlayer::State QT7PlayerSession::state() const +{ + return m_state; +} + +QMediaPlayer::MediaStatus QT7PlayerSession::mediaStatus() const +{ + return m_mediaStatus; +} + +int QT7PlayerSession::bufferStatus() const +{ + return 100; +} + +int QT7PlayerSession::volume() const +{ + return m_volume; +} + +bool QT7PlayerSession::isMuted() const +{ + return m_muted; +} + +bool QT7PlayerSession::isSeekable() const +{ + return true; +} + +qreal QT7PlayerSession::playbackRate() const +{ + return m_rate; +} + +void QT7PlayerSession::setPlaybackRate(qreal rate) +{ + if (qFuzzyCompare(m_rate, rate)) + return; + + m_rate = rate; + + if (m_QTMovie && m_state == QMediaPlayer::PlayingState) { + float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue]; + [(QTMovie*)m_QTMovie setRate:preferredRate*m_rate]; + } +} + +void QT7PlayerSession::setPosition(qint64 pos) +{ + if ( !isSeekable() || pos == position()) + return; + + AutoReleasePool pool; + + pos = qMin(pos, duration()); + + QTTime newQTTime = [(QTMovie*)m_QTMovie currentTime]; + newQTTime.timeValue = (pos / 1000.0f) * newQTTime.timeScale; + [(QTMovie*)m_QTMovie setCurrentTime:newQTTime]; +} + +void QT7PlayerSession::play() +{ + float preferredRate = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMoviePreferredRateAttribute"] floatValue]; + [(QTMovie*)m_QTMovie setRate:preferredRate*m_rate]; + + if (m_state != QMediaPlayer::PlayingState) + emit stateChanged(m_state = QMediaPlayer::PlayingState); +} + +void QT7PlayerSession::pause() +{ + m_state = QMediaPlayer::PausedState; + + [(QTMovie*)m_QTMovie setRate:0]; + + emit stateChanged(m_state); +} + +void QT7PlayerSession::stop() +{ + m_state = QMediaPlayer::StoppedState; + + [(QTMovie*)m_QTMovie setRate:0]; + setPosition(0); + + if (m_state == QMediaPlayer::StoppedState) + emit stateChanged(m_state); +} + +void QT7PlayerSession::setVolume(int volume) +{ + if (m_QTMovie) { + m_volume = volume; + [(QTMovie*)m_QTMovie setVolume:(volume/100.0f)]; + } +} + +void QT7PlayerSession::setMuted(bool muted) +{ + if (m_muted != muted) { + m_muted = muted; + + if (m_QTMovie) + [(QTMovie*)m_QTMovie setMuted:m_muted]; + + emit mutedChanged(muted); + } +} + +QMediaContent QT7PlayerSession::media() const +{ + return m_resources; +} + +const QIODevice *QT7PlayerSession::mediaStream() const +{ + return m_mediaStream; +} + +void QT7PlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) +{ + AutoReleasePool pool; + + if (m_QTMovie) { + [(QTMovieObserver*)m_movieObserver setMovie:nil]; + + if (m_videoOutput) { + m_videoOutput->setEnabled(false); + m_videoOutput->setMovie(0); + } + + [(QTMovie*)m_QTMovie release]; + m_QTMovie = 0; + } + + m_resources = content; + m_mediaStream = stream; + m_mediaStatus = QMediaPlayer::NoMedia; + + QUrl url; + + if (!content.isNull()) + url = content.canonicalUrl(); + else + return; + + qDebug() << "Open media" << url; + + NSError *err = 0; + NSString *urlString = (NSString *)qString2CFStringRef(url.toString()); + + NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys: + [NSURL URLWithString:urlString], QTMovieURLAttribute, + [NSNumber numberWithBool:YES], QTMovieOpenAsyncOKAttribute, + [NSNumber numberWithBool:YES], QTMovieIsActiveAttribute, + [NSNumber numberWithBool:YES], QTMovieResolveDataRefsAttribute, + [NSNumber numberWithBool:YES], QTMovieDontInteractWithUserAttribute, + nil]; + + m_QTMovie = [[QTMovie movieWithAttributes:attr error:&err] retain]; + + if (err) { + [(QTMovie*)m_QTMovie release]; + m_QTMovie = 0; + QString description = QString::fromUtf8([[err localizedDescription] UTF8String]); + + emit error(QMediaPlayer::FormatError, description ); + } else { + [(QTMovieObserver*)m_movieObserver setMovie:(QTMovie*)m_QTMovie]; + + if (m_videoOutput) { + m_videoOutput->setMovie(m_QTMovie); + m_videoOutput->setEnabled(true); + } + processStateChange(); + + [(QTMovie*)m_QTMovie setMuted:m_muted]; + setVolume(m_volume); + } +} + +bool QT7PlayerSession::isAudioAvailable() const +{ + if (!m_QTMovie) + return false; + + AutoReleasePool pool; + return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasAudioAttribute"] boolValue] == YES; +} + +bool QT7PlayerSession::isVideoAvailable() const +{ + if (!m_QTMovie) + return false; + + AutoReleasePool pool; + return [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieHasVideoAttribute"] boolValue] == YES; +} + +void QT7PlayerSession::processEOS() +{ + m_mediaStatus = QMediaPlayer::EndOfMedia; + emit stateChanged(m_state = QMediaPlayer::StoppedState); + emit mediaStatusChanged(m_mediaStatus); +} + +void QT7PlayerSession::processStateChange() +{ + signed long state = [[(QTMovie*)m_QTMovie attributeForKey:QTMovieLoadStateAttribute] + longValue]; + qDebug() << "Moview load state changed:" << state; + +#ifndef QUICKTIME_C_API_AVAILABLE + enum { + kMovieLoadStateError = -1L, + kMovieLoadStateLoading = 1000, + kMovieLoadStateLoaded = 2000, + kMovieLoadStatePlayable = 10000, + kMovieLoadStatePlaythroughOK = 20000, + kMovieLoadStateComplete = 100000 + }; +#endif + + QMediaPlayer::MediaStatus newStatus = QMediaPlayer::NoMedia; + bool isPlaying = (m_state != QMediaPlayer::StoppedState); + + if (state >= kMovieLoadStateComplete) { + newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia; + } else if (state >= kMovieLoadStatePlayable) + newStatus = isPlaying ? QMediaPlayer::BufferingMedia : QMediaPlayer::LoadingMedia; + else if (state >= kMovieLoadStateLoading) + newStatus = isPlaying ? QMediaPlayer::StalledMedia : QMediaPlayer::LoadingMedia; + + if (state == kMovieLoadStateError) { + newStatus = QMediaPlayer::InvalidMedia; + emit error(QMediaPlayer::FormatError, tr("Playback failed")); + } + + if (newStatus != m_mediaStatus) { + switch (newStatus) { + case QMediaPlayer::BufferedMedia: + case QMediaPlayer::BufferingMedia: + //delayed playback start is necessary for network sources + if (m_state == QMediaPlayer::PlayingState) { + QMetaObject::invokeMethod(this, "play", Qt::QueuedConnection); + } + //fall + case QMediaPlayer::LoadedMedia: + case QMediaPlayer::LoadingMedia: + emit durationChanged(duration()); + emit audioAvailableChanged(isAudioAvailable()); + emit videoAvailableChanged(isVideoAvailable()); + break; + case QMediaPlayer::InvalidMedia: + emit stateChanged(m_state = QMediaPlayer::StoppedState); + default: + break; + } + + emit mediaStatusChanged(m_mediaStatus = newStatus); + } +} + +void QT7PlayerSession::processVolumeChange() +{ + if (!m_QTMovie) + return; + + int newVolume = qRound(100.0f*[((QTMovie*)m_QTMovie) volume]); + + if (newVolume != m_volume) { + emit volumeChanged(m_volume = newVolume); + } +} + +void QT7PlayerSession::processNaturalSizeChange() +{ + if (m_videoOutput) { + NSSize size = [[(QTMovie*)m_QTMovie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue]; + qDebug() << "Native size changed:" << QSize(size.width, size.height); + m_videoOutput->updateNaturalSize(QSize(size.width, size.height)); + } +} + +#include "moc_qt7playersession.cpp" + +QT_END_NAMESPACE + diff --git a/src/plugins/mediaservices/qt7/qcvdisplaylink.h b/src/plugins/mediaservices/qt7/qcvdisplaylink.h new file mode 100644 index 0000000..5cd8f73 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qcvdisplaylink.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCVDISPLAYLINK_H +#define QCVDISPLAYLINK_H + +#include <QtCore/qobject.h> +#include <QtCore/qmutex.h> + +#include <CoreVideo/CVDisplayLink.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QCvDisplayLink : public QObject +{ +Q_OBJECT +public: + QCvDisplayLink(QObject *parent = 0); + virtual ~QCvDisplayLink(); + + bool isValid(); + bool isActive() const; + +public slots: + void start(); + void stop(); + +signals: + void tick(const CVTimeStamp &ts); + +public: + void displayLinkEvent(const CVTimeStamp *); + +protected: + virtual bool event(QEvent *); + +private: + CVDisplayLinkRef m_displayLink; + QMutex m_displayLinkMutex; + bool m_pendingDisplayLinkEvent; + bool m_isActive; + CVTimeStamp m_frameTimeStamp; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif + diff --git a/src/plugins/mediaservices/qt7/qcvdisplaylink.mm b/src/plugins/mediaservices/qt7/qcvdisplaylink.mm new file mode 100644 index 0000000..98ae71d --- /dev/null +++ b/src/plugins/mediaservices/qt7/qcvdisplaylink.mm @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcvdisplaylink.h" + +#include <QtCore/qcoreapplication.h> +#include <QtCore/qdebug.h> + + +QT_USE_NAMESPACE + +static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink, + const CVTimeStamp *inNow, + const CVTimeStamp *inOutputTime, + CVOptionFlags flagsIn, + CVOptionFlags *flagsOut, + void *displayLinkContext) +{ + Q_UNUSED(displayLink); + Q_UNUSED(inNow); + Q_UNUSED(flagsIn); + Q_UNUSED(flagsOut); + + QCvDisplayLink *link = (QCvDisplayLink *)displayLinkContext; + + link->displayLinkEvent(inOutputTime); + return kCVReturnSuccess; +} + + +QCvDisplayLink::QCvDisplayLink(QObject *parent) + :QObject(parent), + m_pendingDisplayLinkEvent(false), + m_isActive(false) +{ + // create display link for the main display + CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink); + if (m_displayLink) { + // set the current display of a display link. + CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay); + + // set the renderer output callback function + CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback, this); + } +} + +QCvDisplayLink::~QCvDisplayLink() +{ + if (m_displayLink) { + CVDisplayLinkStop(m_displayLink); + CVDisplayLinkRelease(m_displayLink); + m_displayLink = NULL; + } +} + +bool QCvDisplayLink::isValid() +{ + return m_displayLink != 0; +} + +bool QCvDisplayLink::isActive() const +{ + return m_isActive; +} + +void QCvDisplayLink::start() +{ + if (m_displayLink && !m_isActive) { + CVDisplayLinkStart(m_displayLink); + m_isActive = true; + } +} + +void QCvDisplayLink::stop() +{ + if (m_displayLink && m_isActive) { + CVDisplayLinkStop(m_displayLink); + m_isActive = false; + } +} + +void QCvDisplayLink::displayLinkEvent(const CVTimeStamp *ts) +{ + // This function is called from a + // thread != gui thread. So we post the event. + // But we need to make sure that we don't post faster + // than the event loop can eat: + m_displayLinkMutex.lock(); + bool pending = m_pendingDisplayLinkEvent; + m_pendingDisplayLinkEvent = true; + m_frameTimeStamp = *ts; + m_displayLinkMutex.unlock(); + + if (!pending) + qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); +} + +bool QCvDisplayLink::event(QEvent *event) +{ + switch (event->type()){ + case QEvent::User: { + m_displayLinkMutex.lock(); + m_pendingDisplayLinkEvent = false; + CVTimeStamp ts = m_frameTimeStamp; + m_displayLinkMutex.unlock(); + + emit tick(ts); + + return false; + } + break; + default: + break; + } + return QObject::event(event); +} + +QT_END_NAMESPACE + +#include "moc_qcvdisplaylink.cpp" + diff --git a/src/plugins/mediaservices/qt7/qt7.pro b/src/plugins/mediaservices/qt7/qt7.pro new file mode 100644 index 0000000..13d14d7 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7.pro @@ -0,0 +1,45 @@ +TARGET = qt7 +include(../../qpluginbase.pri) + +QT += opengl multimedia + +LIBS += -framework AppKit -framework AudioUnit \ + -framework AudioToolbox -framework CoreAudio \ + -framework QuartzCore -framework QTKit + +# The Quicktime framework is only awailable for 32-bit builds, so we +# need to check for this before linking against it. +# QMAKE_MAC_XARCH is not awailable on Tiger, but at the same time, +# we never build for 64-bit architechtures on Tiger either: +contains(QMAKE_MAC_XARCH, no) { + LIBS += -framework QuickTime +} else { + LIBS += -Xarch_i386 -framework QuickTime -Xarch_ppc -framework QuickTime +} + +HEADERS += \ + qt7backend.h \ + qt7videooutputcontrol.h \ + qt7movieviewoutput.h \ + qt7movievideowidget.h \ + qt7movieviewrenderer.h \ + qt7serviceplugin.h \ + qt7movierenderer.h \ + qcvdisplaylink.h + +OBJECTIVE_SOURCES += \ + qt7backend.mm \ + qt7serviceplugin.mm \ + qt7movieviewoutput.mm \ + qt7movievideowidget.mm \ + qt7movieviewrenderer.mm \ + qt7movierenderer.mm \ + qt7videooutputcontrol.mm \ + qcvdisplaylink.mm + +include(mediaplayer/mediaplayer.pri) + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mediaservices +target.path = $$[QT_INSTALL_PLUGINS]/plugins/mediaservices +INSTALLS += target + diff --git a/src/plugins/mediaservices/qt7/qt7backend.h b/src/plugins/mediaservices/qt7/qt7backend.h new file mode 100644 index 0000000..5668965 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7backend.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7BACKEND_H +#define QT7BACKEND_H + +#include <QtCore/qstring.h> + +#ifndef Q_WS_MAC64 +#define QUICKTIME_C_API_AVAILABLE +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class AutoReleasePool +{ +private: + void *pool; +public: + AutoReleasePool(); + ~AutoReleasePool(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/qt7backend.mm b/src/plugins/mediaservices/qt7/qt7backend.mm new file mode 100644 index 0000000..478589b --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7backend.mm @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt7backend.h" + +#import <Foundation/NSAutoreleasePool.h> +#include <CoreFoundation/CFBase.h> + + +QT_BEGIN_NAMESPACE + +AutoReleasePool::AutoReleasePool() +{ + pool = (void*)[[NSAutoreleasePool alloc] init]; +} + +AutoReleasePool::~AutoReleasePool() +{ + [(NSAutoreleasePool*)pool release]; +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/qt7/qt7movierenderer.h b/src/plugins/mediaservices/qt7/qt7movierenderer.h new file mode 100644 index 0000000..a547329 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movierenderer.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7MOVIERENDERER_H +#define QT7MOVIERENDERER_H + +#include "qt7backend.h" + +#include <QtCore/qobject.h> +#include <QtCore/qmutex.h> + +#include <qvideorenderercontrol.h> +#include <qmediaplayer.h> + +#include <QtGui/qmacdefines_mac.h> +#include "qt7videooutputcontrol.h" + +#include <CoreVideo/CVOpenGLTexture.h> +#include <QuickTime/QuickTime.h> + + +QT_BEGIN_HEADER + +class QGLContext; + +QT_BEGIN_NAMESPACE + +class QCvDisplayLink; +class QT7PlayerSession; +class QT7PlayerService; + +class QT7MovieRenderer : public QT7VideoRendererControl +{ +Q_OBJECT +public: + QT7MovieRenderer(QObject *parent = 0); + virtual ~QT7MovieRenderer(); + + void setEnabled(bool); + void setMovie(void *movie); + void updateNaturalSize(const QSize &newSize); + + QAbstractVideoSurface *surface() const; + void setSurface(QAbstractVideoSurface *surface); + + QSize nativeSize() const; + +private slots: + void updateVideoFrame(const CVTimeStamp &ts); + +private: + void setupVideoOutput(); + bool createPixelBufferVisualContext(); + bool createGLVisualContext(); + + void *m_movie; + + QMutex m_mutex; + + QCvDisplayLink *m_displayLink; +#ifdef QUICKTIME_C_API_AVAILABLE + QTVisualContextRef m_visualContext; + bool m_usingGLContext; + const QGLContext *m_currentGLContext; + QSize m_pixelBufferContextGeometry; +#endif + QAbstractVideoSurface *m_surface; + QSize m_nativeSize; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/qt7movierenderer.mm b/src/plugins/mediaservices/qt7/qt7movierenderer.mm new file mode 100644 index 0000000..587f3b9 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movierenderer.mm @@ -0,0 +1,454 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import <QTKit/QTKit.h> + +#include "qt7backend.h" + +#include "qt7playercontrol.h" +#include "qt7movierenderer.h" +#include "qt7playersession.h" +#include "qcvdisplaylink.h" +#include <QtCore/qdebug.h> +#include <QtCore/qcoreapplication.h> + +#include <QGLWidget> + +#include <QtMultimedia/qabstractvideobuffer.h> +#include <QtMultimedia/qabstractvideosurface.h> +#include <QtMultimedia/qvideosurfaceformat.h> + +QT_BEGIN_NAMESPACE + +class CVGLTextureVideoBuffer : public QAbstractVideoBuffer +{ +public: + CVGLTextureVideoBuffer(CVOpenGLTextureRef buffer) + : QAbstractVideoBuffer(NoHandle) + , m_buffer(buffer) + , m_mode(NotMapped) + { + CVOpenGLTextureRetain(m_buffer); + } + + virtual ~CVGLTextureVideoBuffer() + { + CVOpenGLTextureRelease(m_buffer); + } + + QVariant handle() const + { + GLuint id = CVOpenGLTextureGetName(m_buffer); + return QVariant(int(id)); + } + + HandleType handleType() const + { + return GLTextureHandle; + } + + MapMode mapMode() const { return m_mode; } + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) + { + if (numBytes) + *numBytes = 0; + + if (bytesPerLine) + *bytesPerLine = 0; + + m_mode = mode; + return 0; + } + + void unmap() { m_mode = NotMapped; } + +private: + CVOpenGLTextureRef m_buffer; + MapMode m_mode; +}; + + +class CVPixelBufferVideoBuffer : public QAbstractVideoBuffer +{ +public: + CVPixelBufferVideoBuffer(CVPixelBufferRef buffer) + : QAbstractVideoBuffer(NoHandle) + , m_buffer(buffer) + , m_mode(NotMapped) + { + CVPixelBufferRetain(m_buffer); + } + + virtual ~CVPixelBufferVideoBuffer() + { + CVPixelBufferRelease(m_buffer); + } + + MapMode mapMode() const { return m_mode; } + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) + { + if (mode != NotMapped && m_mode == NotMapped) { + CVPixelBufferLockBaseAddress(m_buffer, 0); + + if (numBytes) + *numBytes = CVPixelBufferGetDataSize(m_buffer); + + if (bytesPerLine) + *bytesPerLine = CVPixelBufferGetBytesPerRow(m_buffer); + + m_mode = mode; + + return (uchar*)CVPixelBufferGetBaseAddress(m_buffer); + } else { + return 0; + } + } + + void unmap() + { + if (m_mode != NotMapped) { + m_mode = NotMapped; + CVPixelBufferUnlockBaseAddress(m_buffer, 0); + } + } + +private: + CVPixelBufferRef m_buffer; + MapMode m_mode; +}; + + + +QT7MovieRenderer::QT7MovieRenderer(QObject *parent) + :QT7VideoRendererControl(parent), + m_movie(0), +#ifdef QUICKTIME_C_API_AVAILABLE + m_visualContext(0), + m_usingGLContext(false), + m_currentGLContext(0), +#endif + m_surface(0) +{ + qDebug() << "QT7MovieRenderer"; + + m_displayLink = new QCvDisplayLink(this); + connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp))); +} + + +bool QT7MovieRenderer::createGLVisualContext() +{ +#ifdef QUICKTIME_C_API_AVAILABLE + AutoReleasePool pool; + CGLContextObj cglContext = CGLGetCurrentContext(); + NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat]; + CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]); + + OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault, cglContext, + cglPixelFormat, NULL, &m_visualContext); + if (err != noErr) + qWarning() << "Could not create visual context (OpenGL)"; + + return (err == noErr); +#endif // QUICKTIME_C_API_AVAILABLE + + return false; +} + +#ifdef QUICKTIME_C_API_AVAILABLE +static bool DictionarySetValue(CFMutableDictionaryRef dict, CFStringRef key, SInt32 value) +{ + CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); + + if (number) { + CFDictionarySetValue( dict, key, number ); + CFRelease( number ); + return true; + } + return false; +} +#endif // QUICKTIME_C_API_AVAILABLE + +bool QT7MovieRenderer::createPixelBufferVisualContext() +{ +#ifdef QUICKTIME_C_API_AVAILABLE + if (m_visualContext) { + QTVisualContextRelease(m_visualContext); + m_visualContext = 0; + } + + m_pixelBufferContextGeometry = m_nativeSize; + + CFMutableDictionaryRef pixelBufferOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + //DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32ARGBPixelFormat ); + DictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, k32BGRAPixelFormat ); + DictionarySetValue(pixelBufferOptions, kCVPixelBufferWidthKey, m_nativeSize.width() ); + DictionarySetValue(pixelBufferOptions, kCVPixelBufferHeightKey, m_nativeSize.height() ); + DictionarySetValue(pixelBufferOptions, kCVPixelBufferBytesPerRowAlignmentKey, 16); + //CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue); + + CFMutableDictionaryRef visualContextOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(visualContextOptions, kQTVisualContextPixelBufferAttributesKey, pixelBufferOptions); + CFDictionarySetValue(visualContextOptions, kQTVisualContextWorkingColorSpaceKey, CGColorSpaceCreateDeviceRGB()); + + OSStatus err = QTPixelBufferContextCreate(kCFAllocatorDefault, + visualContextOptions, + &m_visualContext); + CFRelease(pixelBufferOptions); + CFRelease(visualContextOptions); + + if (err != noErr) { + qWarning() << "Could not create visual context (PixelBuffer)"; + return false; + } + + return true; +#endif // QUICKTIME_C_API_AVAILABLE + + return false; +} + + +QT7MovieRenderer::~QT7MovieRenderer() +{ + m_displayLink->stop(); +} + +void QT7MovieRenderer::setupVideoOutput() +{ + AutoReleasePool pool; + + qDebug() << "QT7MovieRenderer::setupVideoOutput" << m_movie; + + if (m_movie == 0 || m_surface == 0) { + m_displayLink->stop(); + return; + } + + NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue]; + m_nativeSize = QSize(size.width, size.height); + +#ifdef QUICKTIME_C_API_AVAILABLE + bool usedGLContext = m_usingGLContext; + + if (!m_nativeSize.isEmpty()) { + + bool glSupported = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty(); + + //Try rendering using opengl textures first: + if (glSupported) { + QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32, QAbstractVideoBuffer::GLTextureHandle); + + if (m_surface->isActive()) + m_surface->stop(); + + qDebug() << "Starting the surface with format" << format; + if (!m_surface->start(format)) { + qDebug() << "failed to start video surface" << m_surface->error(); + glSupported = false; + } else { + m_usingGLContext = true; + } + + } + + if (!glSupported) { + m_usingGLContext = false; + QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32); + + if (m_surface->isActive() && m_surface->surfaceFormat() != format) { + qDebug() << "Surface format was changed, stop the surface."; + m_surface->stop(); + } + + if (!m_surface->isActive()) { + qDebug() << "Starting the surface with format" << format; + if (!m_surface->start(format)) + qDebug() << "failed to start video surface" << m_surface->error(); + } + } + } + + + if (m_visualContext) { + //check if the visual context still can be reused + if (usedGLContext != m_usingGLContext || + (m_usingGLContext && (m_currentGLContext != QGLContext::currentContext())) || + (!m_usingGLContext && (m_pixelBufferContextGeometry != m_nativeSize))) { + QTVisualContextRelease(m_visualContext); + m_pixelBufferContextGeometry = QSize(); + m_visualContext = 0; + } + } + + if (!m_nativeSize.isEmpty()) { + if (!m_visualContext) { + if (m_usingGLContext) { + qDebug() << "Building OpenGL visual context" << m_nativeSize; + m_currentGLContext = QGLContext::currentContext(); + if (!createGLVisualContext()) { + qWarning() << "QT7MovieRenderer: failed to create visual context"; + return; + } + } else { + qDebug() << "Building Pixel Buffer visual context" << m_nativeSize; + if (!createPixelBufferVisualContext()) { + qWarning() << "QT7MovieRenderer: failed to create visual context"; + return; + } + } + } + + // targets a Movie to render into a visual context + SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext); + + m_displayLink->start(); + } +#endif + +} + +void QT7MovieRenderer::setEnabled(bool) +{ +} + +void QT7MovieRenderer::setMovie(void *movie) +{ + qDebug() << "QT7MovieRenderer::setMovie" << movie; + +#ifdef QUICKTIME_C_API_AVAILABLE + QMutexLocker locker(&m_mutex); + + if (m_movie != movie) { + if (m_movie) { + //ensure the old movie doesn't hold the visual context, otherwise it can't be reused + SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil); + [(QTMovie*)m_movie release]; + } + + m_movie = movie; + [(QTMovie*)m_movie retain]; + + setupVideoOutput(); + } +#endif +} + +void QT7MovieRenderer::updateNaturalSize(const QSize &newSize) +{ + if (m_nativeSize != newSize) { + m_nativeSize = newSize; + setupVideoOutput(); + } +} + +QAbstractVideoSurface *QT7MovieRenderer::surface() const +{ + return m_surface; +} + +void QT7MovieRenderer::setSurface(QAbstractVideoSurface *surface) +{ + qDebug() << "Set video surface" << surface; + + if (surface == m_surface) + return; + + QMutexLocker locker(&m_mutex); + + if (m_surface && m_surface->isActive()) + m_surface->stop(); + + m_surface = surface; + setupVideoOutput(); +} + + +QSize QT7MovieRenderer::nativeSize() const +{ + return m_nativeSize; +} + +void QT7MovieRenderer::updateVideoFrame(const CVTimeStamp &ts) +{ +#ifdef QUICKTIME_C_API_AVAILABLE + + QMutexLocker locker(&m_mutex); + + if (m_surface && m_surface->isActive() && + m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) { + + CVImageBufferRef imageBuffer = NULL; + + OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, &imageBuffer); + + if (status == noErr && imageBuffer) { + //qDebug() << "render video frame"; + QAbstractVideoBuffer *buffer = 0; + + if (m_usingGLContext) { + buffer = new CVGLTextureVideoBuffer((CVOpenGLTextureRef)imageBuffer); + CVOpenGLTextureRelease((CVOpenGLTextureRef)imageBuffer); + //qDebug() << "render GL video frame" << buffer->handle(); + } else { + buffer = new CVPixelBufferVideoBuffer((CVPixelBufferRef)imageBuffer); + CVPixelBufferRelease((CVPixelBufferRef)imageBuffer); + } + + QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_RGB32); + m_surface->present(frame); + QTVisualContextTask(m_visualContext); + } + } +#else + Q_UNUSED(ts); +#endif +} + +#include "moc_qt7movierenderer.cpp" + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/qt7/qt7movievideowidget.h b/src/plugins/mediaservices/qt7/qt7movievideowidget.h new file mode 100644 index 0000000..3acd373 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7MOVIEVIDEOWIDGET_H +#define QT7MOVIEVIDEOWIDGET_H + +#include <QtCore/qobject.h> +#include <QtCore/qmutex.h> + +#include <qvideowindowcontrol.h> +#include <qmediaplayer.h> + +#include <QtGui/qmacdefines_mac.h> +#include "qt7videooutputcontrol.h" + +#include <CoreVideo/CVOpenGLTexture.h> +#include <QuickTime/QuickTime.h> + + +QT_BEGIN_HEADER + +class GLVideoWidget; + +QT_BEGIN_NAMESPACE + +class QCvDisplayLink; +class QT7PlayerSession; +class QT7PlayerService; + +class QT7MovieVideoWidget : public QT7VideoWidgetControl +{ +Q_OBJECT +public: + QT7MovieVideoWidget(QObject *parent = 0); + virtual ~QT7MovieVideoWidget(); + + void setEnabled(bool); + void setMovie(void *movie); + void updateNaturalSize(const QSize &newSize); + + QWidget *videoWidget(); + + bool isFullScreen() const; + void setFullScreen(bool fullScreen); + + QSize nativeSize() const; + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + +private slots: + void updateVideoFrame(const CVTimeStamp &ts); + +private: + void setupVideoOutput(); + bool createVisualContext(); + + void updateColors(); + + void *m_movie; + GLVideoWidget *m_videoWidget; + + QCvDisplayLink *m_displayLink; + +#ifdef QUICKTIME_C_API_AVAILABLE + QTVisualContextRef m_visualContext; +#endif + + bool m_fullscreen; + QSize m_nativeSize; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + int m_brightness; + int m_contrast; + int m_hue; + int m_saturation; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/qt7movievideowidget.mm b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm new file mode 100644 index 0000000..6e74fcd --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movievideowidget.mm @@ -0,0 +1,417 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import <QTKit/QTKit.h> + +#include "qt7backend.h" + +#include "qt7playercontrol.h" +#include "qt7movievideowidget.h" +#include "qt7playersession.h" +#include "qcvdisplaylink.h" +#include <QtCore/qdebug.h> +#include <QtCore/qcoreapplication.h> + +#include <QGLWidget> + +#import <QuartzCore/QuartzCore.h> + +#include "math.h" + +QT_BEGIN_NAMESPACE + +class GLVideoWidget : public QGLWidget +{ +public: + + GLVideoWidget(QWidget *parent, const QGLFormat &format) + : QGLWidget(format, parent), + m_texRef(0), + m_nativeSize(640,480), + m_aspectRatioMode(QVideoWidget::KeepAspectRatio) + { + setAutoFillBackground(false); + } + + void initializeGL() + { + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + } + + void resizeGL(int w, int h) + { + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glViewport(0, 0, GLsizei(w), GLsizei(h)); + gluOrtho2D(0, GLsizei(w), 0, GLsizei(h)); + updateGL(); + } + + void paintGL() + { + glClear(GL_COLOR_BUFFER_BIT); + if (!m_texRef) + return; + + glPushMatrix(); + glDisable(GL_CULL_FACE); + GLenum target = CVOpenGLTextureGetTarget(m_texRef); + glEnable(target); + + glBindTexture(target, CVOpenGLTextureGetName(m_texRef)); + glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + GLfloat lowerLeft[2], lowerRight[2], upperRight[2], upperLeft[2]; + CVOpenGLTextureGetCleanTexCoords(m_texRef, lowerLeft, lowerRight, upperRight, upperLeft); + + glBegin(GL_QUADS); + QRect rect = displayRect(); + glTexCoord2f(lowerLeft[0], lowerLeft[1]); + glVertex2i(rect.topLeft().x(), rect.topLeft().y()); + glTexCoord2f(lowerRight[0], lowerRight[1]); + glVertex2i(rect.topRight().x() + 1, rect.topRight().y()); + glTexCoord2f(upperRight[0], upperRight[1]); + glVertex2i(rect.bottomRight().x() + 1, rect.bottomRight().y() + 1); + glTexCoord2f(upperLeft[0], upperLeft[1]); + glVertex2i(rect.bottomLeft().x(), rect.bottomLeft().y() + 1); + glEnd(); + glPopMatrix(); + } + + void setCVTexture(CVOpenGLTextureRef texRef) + { + if (m_texRef) + CVOpenGLTextureRelease(m_texRef); + + m_texRef = texRef; + + if (m_texRef) + CVOpenGLTextureRetain(m_texRef); + + if (isVisible()) { + makeCurrent(); + paintGL(); + swapBuffers(); + } + } + + QSize sizeHint() const + { + return m_nativeSize; + } + + void setNativeSize(const QSize &size) + { + m_nativeSize = size; + } + + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode) + { + if (m_aspectRatioMode != mode) { + m_aspectRatioMode = mode; + update(); + } + } + +private: + QRect displayRect() const + { + QRect displayRect = rect(); + + if (m_aspectRatioMode == QVideoWidget::KeepAspectRatio) { + QSize size = m_nativeSize; + size.scale(displayRect.size(), Qt::KeepAspectRatio); + + displayRect = QRect(QPoint(0, 0), size); + displayRect.moveCenter(rect().center()); + } + return displayRect; + } + + CVOpenGLTextureRef m_texRef; + QSize m_nativeSize; + QVideoWidget::AspectRatioMode m_aspectRatioMode; +}; + +QT7MovieVideoWidget::QT7MovieVideoWidget(QObject *parent) + :QT7VideoWidgetControl(parent), + m_movie(0), + m_videoWidget(0), + m_fullscreen(false), + m_aspectRatioMode(QVideoWidget::KeepAspectRatio), + m_brightness(0), + m_contrast(0), + m_hue(0), + m_saturation(0) +{ + qDebug() << "QT7MovieVideoWidget"; + + QGLFormat format = QGLFormat::defaultFormat(); + format.setSwapInterval(1); // Vertical sync (avoid tearing) + m_videoWidget = new GLVideoWidget(0, format); + + m_displayLink = new QCvDisplayLink(this); + + connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp))); + + if (!createVisualContext()) { + qWarning() << "QT7MovieVideoWidget: failed to create visual context"; + } +} + + +bool QT7MovieVideoWidget::createVisualContext() +{ +#ifdef QUICKTIME_C_API_AVAILABLE + m_videoWidget->makeCurrent(); + + AutoReleasePool pool; + CGLContextObj cglContext = CGLGetCurrentContext(); + NSOpenGLPixelFormat *nsglPixelFormat = [NSOpenGLView defaultPixelFormat]; + CGLPixelFormatObj cglPixelFormat = static_cast<CGLPixelFormatObj>([nsglPixelFormat CGLPixelFormatObj]); + + CFTypeRef keys[] = { kQTVisualContextWorkingColorSpaceKey }; + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CFDictionaryRef textureContextAttributes = CFDictionaryCreate(kCFAllocatorDefault, + (const void **)keys, + (const void **)&colorSpace, 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + OSStatus err = QTOpenGLTextureContextCreate(kCFAllocatorDefault, + cglContext, + cglPixelFormat, + textureContextAttributes, + &m_visualContext); + if (err != noErr) + qWarning() << "Could not create visual context (OpenGL)"; + + + return (err == noErr); +#endif // QUICKTIME_C_API_AVAILABLE + + return false; +} + +QT7MovieVideoWidget::~QT7MovieVideoWidget() +{ + m_displayLink->stop(); + [(QTMovie*)m_movie release]; + delete m_videoWidget; +} + +QWidget *QT7MovieVideoWidget::videoWidget() +{ + return m_videoWidget; +} + +void QT7MovieVideoWidget::setupVideoOutput() +{ + AutoReleasePool pool; + + qDebug() << "QT7MovieVideoWidget::setupVideoOutput" << m_movie; + + if (m_movie == 0) { + m_displayLink->stop(); + return; + } + + NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue]; + m_nativeSize = QSize(size.width, size.height); + m_videoWidget->setNativeSize(m_nativeSize); + +#ifdef QUICKTIME_C_API_AVAILABLE + // targets a Movie to render into a visual context + SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], m_visualContext); +#endif + + m_displayLink->start(); +} + +void QT7MovieVideoWidget::setEnabled(bool) +{ +} + +void QT7MovieVideoWidget::setMovie(void *movie) +{ + if (m_movie == movie) + return; + + if (m_movie) { +#ifdef QUICKTIME_C_API_AVAILABLE + SetMovieVisualContext([(QTMovie*)m_movie quickTimeMovie], nil); +#endif + [(QTMovie*)m_movie release]; + } + + m_movie = movie; + [(QTMovie*)m_movie retain]; + + setupVideoOutput(); +} + +void QT7MovieVideoWidget::updateNaturalSize(const QSize &newSize) +{ + if (m_nativeSize != newSize) { + m_nativeSize = newSize; + setupVideoOutput(); + } +} + +bool QT7MovieVideoWidget::isFullScreen() const +{ + return m_fullscreen; +} + +void QT7MovieVideoWidget::setFullScreen(bool fullScreen) +{ + m_fullscreen = fullScreen; +} + +QSize QT7MovieVideoWidget::nativeSize() const +{ + return m_nativeSize; +} + +QVideoWidget::AspectRatioMode QT7MovieVideoWidget::aspectRatioMode() const +{ + return m_aspectRatioMode; +} + +void QT7MovieVideoWidget::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + m_aspectRatioMode = mode; + m_videoWidget->setAspectRatioMode(mode); +} + +int QT7MovieVideoWidget::brightness() const +{ + return m_brightness; +} + +void QT7MovieVideoWidget::setBrightness(int brightness) +{ + m_brightness = brightness; + updateColors(); +} + +int QT7MovieVideoWidget::contrast() const +{ + return m_contrast; +} + +void QT7MovieVideoWidget::setContrast(int contrast) +{ + m_contrast = contrast; + updateColors(); +} + +int QT7MovieVideoWidget::hue() const +{ + return m_hue; +} + +void QT7MovieVideoWidget::setHue(int hue) +{ + m_hue = hue; + updateColors(); +} + +int QT7MovieVideoWidget::saturation() const +{ + return m_saturation; +} + +void QT7MovieVideoWidget::setSaturation(int saturation) +{ + m_saturation = saturation; + updateColors(); +} + +void QT7MovieVideoWidget::updateColors() +{ +#ifdef QUICKTIME_C_API_AVAILABLE + if (m_movie) { + QTMovie *movie = (QTMovie*)m_movie; + + Float32 value; + value = m_brightness/100.0; + SetMovieVisualBrightness([movie quickTimeMovie], value, 0); + value = pow(2, m_contrast/50.0); + SetMovieVisualContrast([movie quickTimeMovie], value, 0); + value = m_hue/100.0; + SetMovieVisualHue([movie quickTimeMovie], value, 0); + value = 1.0+m_saturation/100.0; + SetMovieVisualSaturation([movie quickTimeMovie], value, 0); + } +#endif +} + +void QT7MovieVideoWidget::updateVideoFrame(const CVTimeStamp &ts) +{ +#ifdef QUICKTIME_C_API_AVAILABLE + AutoReleasePool pool; + // check for new frame + if (m_visualContext && QTVisualContextIsNewImageAvailable(m_visualContext, &ts)) { + CVOpenGLTextureRef currentFrame = NULL; + + // get a "frame" (image buffer) from the Visual Context, indexed by the provided time + OSStatus status = QTVisualContextCopyImageForTime(m_visualContext, NULL, &ts, ¤tFrame); + + // the above call may produce a null frame so check for this first + // if we have a frame, then draw it + if (status == noErr && currentFrame) { + //qDebug() << "render video frame"; + m_videoWidget->setCVTexture(currentFrame); + CVOpenGLTextureRelease(currentFrame); + } + QTVisualContextTask(m_visualContext); + } +#else + Q_UNUSED(ts); +#endif +} + +#include "moc_qt7movievideowidget.cpp" + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.h b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h new file mode 100644 index 0000000..30eefa7 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7MOVIEVIEWOUTPUT_H +#define QT7MOVIEVIEWOUTPUT_H + +#include <QtCore/qobject.h> + +#include <QtMultimedia/qvideowindowcontrol.h> +#include <QtMultimedia/qmediaplayer.h> + +#include <QtGui/qmacdefines_mac.h> +#include "qt7videooutputcontrol.h" + + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +class QT7PlayerSession; +class QT7PlayerService; + +class QT7MovieViewOutput : public QT7VideoWindowControl +{ +public: + QT7MovieViewOutput(QObject *parent = 0); + ~QT7MovieViewOutput(); + + void setEnabled(bool); + void setMovie(void *movie); + void updateNaturalSize(const QSize &newSize); + + WId winId() const; + void setWinId(WId id); + + QRect displayRect() const; + void setDisplayRect(const QRect &rect); + + bool isFullScreen() const; + void setFullScreen(bool fullScreen); + + void repaint(); + + QSize nativeSize() const; + + QVideoWidget::AspectRatioMode aspectRatioMode() const; + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode); + + int brightness() const; + void setBrightness(int brightness); + + int contrast() const; + void setContrast(int contrast); + + int hue() const; + void setHue(int hue); + + int saturation() const; + void setSaturation(int saturation); + +private: + void setupVideoOutput(); + + void *m_movie; + void *m_movieView; + + WId m_winId; + QRect m_displayRect; + bool m_fullscreen; + QSize m_nativeSize; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + int m_brightness; + int m_contrast; + int m_hue; + int m_saturation; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm new file mode 100644 index 0000000..b549487 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movieviewoutput.mm @@ -0,0 +1,312 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import <QTKit/QTKit.h> + +#include "qt7backend.h" + +#include "qt7playercontrol.h" +#include "qt7movieviewoutput.h" +#include "qt7playersession.h" +#include <QtCore/qdebug.h> + + +QT_BEGIN_NAMESPACE + +#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];} + +@interface TransparentQTMovieView : QTMovieView +{ +@private + QRect *m_drawRect; + qreal m_brightness, m_contrast, m_saturation, m_hue; +} + +- (TransparentQTMovieView *) init; +- (void) setDrawRect:(QRect &)rect; +- (void) setContrast:(qreal) contrast; +@end + +@implementation TransparentQTMovieView + +- (TransparentQTMovieView *) init +{ + self = [super initWithFrame:NSZeroRect]; + if (self) { + [self setControllerVisible:NO]; + [self setContrast:1.0]; + [self setDelegate:self]; + } + return self; +} + +- (void) dealloc +{ + [super dealloc]; +} + +- (void) setContrast:(qreal) contrast +{ + m_hue = 0.0; + m_brightness = 0.0; + m_contrast = contrast; + m_saturation = 1.0; +} + + +- (void) setDrawRect:(QRect &)rect +{ + *m_drawRect = rect; + + NSRect nsrect; + nsrect.origin.x = m_drawRect->x(); + nsrect.origin.y = m_drawRect->y(); + nsrect.size.width = m_drawRect->width(); + nsrect.size.height = m_drawRect->height(); + [self setFrame:nsrect]; +} + +- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img +{ + // This method is called from QTMovieView just + // before the image will be drawn. + Q_UNUSED(view); + + if ( !qFuzzyCompare(m_brightness, 0.0) || + !qFuzzyCompare(m_contrast, 1.0) || + !qFuzzyCompare(m_saturation, 1.0)){ + CIFilter *colorFilter = [CIFilter filterWithName:@"CIColorControls"]; + [colorFilter setValue:[NSNumber numberWithFloat:m_brightness] forKey:@"inputBrightness"]; + [colorFilter setValue:[NSNumber numberWithFloat:(m_contrast < 1) ? m_contrast : 1 + ((m_contrast-1)*3)] forKey:@"inputContrast"]; + [colorFilter setValue:[NSNumber numberWithFloat:m_saturation] forKey:@"inputSaturation"]; + [colorFilter setValue:img forKey:@"inputImage"]; + img = [colorFilter valueForKey:@"outputImage"]; + } + + /*if (m_hue){ + CIFilter *colorFilter = [CIFilter filterWithName:@"CIHueAdjust"]; + [colorFilter setValue:[NSNumber numberWithFloat:(m_hue * 3.14)] forKey:@"inputAngle"]; + [colorFilter setValue:img forKey:@"inputImage"]; + img = [colorFilter valueForKey:@"outputImage"]; + }*/ + + return img; +} + + +VIDEO_TRANSPARENT(mouseDown); +VIDEO_TRANSPARENT(mouseDragged); +VIDEO_TRANSPARENT(mouseUp); +VIDEO_TRANSPARENT(mouseMoved); +VIDEO_TRANSPARENT(mouseEntered); +VIDEO_TRANSPARENT(mouseExited); +VIDEO_TRANSPARENT(rightMouseDown); +VIDEO_TRANSPARENT(rightMouseDragged); +VIDEO_TRANSPARENT(rightMouseUp); +VIDEO_TRANSPARENT(otherMouseDown); +VIDEO_TRANSPARENT(otherMouseDragged); +VIDEO_TRANSPARENT(otherMouseUp); +VIDEO_TRANSPARENT(keyDown); +VIDEO_TRANSPARENT(keyUp); +VIDEO_TRANSPARENT(scrollWheel) + +@end + + +QT7MovieViewOutput::QT7MovieViewOutput(QObject *parent) + :QT7VideoWindowControl(parent), + m_movie(0), + m_movieView(0), + m_winId(0), + m_fullscreen(false), + m_aspectRatioMode(QVideoWidget::KeepAspectRatio), + m_brightness(0), + m_contrast(0), + m_hue(0), + m_saturation(0) +{ +} + +QT7MovieViewOutput::~QT7MovieViewOutput() +{ +} + +void QT7MovieViewOutput::setupVideoOutput() +{ + AutoReleasePool pool; + + //qDebug() << "QT7MovieViewOutput::setupVideoOutput" << m_movie << m_winId; + if (m_movie == 0 || m_winId <= 0) + return; + + NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue]; + m_nativeSize = QSize(size.width, size.height); + + if (!m_movieView) + m_movieView = [[TransparentQTMovieView alloc] init]; + + [(QTMovieView*)m_movieView setControllerVisible:NO]; + [(QTMovieView*)m_movieView setMovie:(QTMovie*)m_movie]; + + [(NSView *)m_winId addSubview:(QTMovieView*)m_movieView]; + + setDisplayRect(m_displayRect); +} + +void QT7MovieViewOutput::setEnabled(bool) +{ +} + +void QT7MovieViewOutput::setMovie(void *movie) +{ + m_movie = movie; + setupVideoOutput(); +} + +void QT7MovieViewOutput::updateNaturalSize(const QSize &newSize) +{ + m_nativeSize = newSize; +} + +WId QT7MovieViewOutput::winId() const +{ + return m_winId; +} + +void QT7MovieViewOutput::setWinId(WId id) +{ + m_winId = id; + setupVideoOutput(); +} + +QRect QT7MovieViewOutput::displayRect() const +{ + return m_displayRect; +} + +void QT7MovieViewOutput::setDisplayRect(const QRect &rect) +{ + m_displayRect = rect; + + if (m_movieView) { + AutoReleasePool pool; + [(QTMovieView*)m_movieView setPreservesAspectRatio:(m_aspectRatioMode == QVideoWidget::KeepAspectRatio ? YES : NO)]; + [(QTMovieView*)m_movieView setFrame:NSMakeRect(m_displayRect.x(), + m_displayRect.y(), + m_displayRect.width(), + m_displayRect.height())]; + } + +} + +bool QT7MovieViewOutput::isFullScreen() const +{ + return m_fullscreen; +} + +void QT7MovieViewOutput::setFullScreen(bool fullScreen) +{ + m_fullscreen = fullScreen; + setDisplayRect(m_displayRect); +} + +void QT7MovieViewOutput::repaint() +{ +} + +QSize QT7MovieViewOutput::nativeSize() const +{ + return m_nativeSize; +} + +QVideoWidget::AspectRatioMode QT7MovieViewOutput::aspectRatioMode() const +{ + return m_aspectRatioMode; +} + +void QT7MovieViewOutput::setAspectRatioMode(QVideoWidget::AspectRatioMode mode) +{ + m_aspectRatioMode = mode; + setDisplayRect(m_displayRect); +} + +int QT7MovieViewOutput::brightness() const +{ + return m_brightness; +} + +void QT7MovieViewOutput::setBrightness(int brightness) +{ + m_brightness = brightness; +} + +int QT7MovieViewOutput::contrast() const +{ + return m_contrast; +} + +void QT7MovieViewOutput::setContrast(int contrast) +{ + m_contrast = contrast; + [(TransparentQTMovieView*)m_movieView setContrast:(contrast/100.0+1.0)]; +} + +int QT7MovieViewOutput::hue() const +{ + return m_hue; +} + +void QT7MovieViewOutput::setHue(int hue) +{ + m_hue = hue; +} + +int QT7MovieViewOutput::saturation() const +{ + return m_saturation; +} + +void QT7MovieViewOutput::setSaturation(int saturation) +{ + m_saturation = saturation; +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h new file mode 100644 index 0000000..336006c --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7MOVIEVIEWRENDERER_H +#define QT7MOVIEVIEWRENDERER_H + +#include <QtCore/qobject.h> +#include <QtCore/qmutex.h> + +#include <QtMultimedia/qvideowindowcontrol.h> +#include <QtMultimedia/qmediaplayer.h> + +#include <QtGui/qmacdefines_mac.h> +#include "qt7videooutputcontrol.h" +#include <QtMultimedia/qvideoframe.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class QVideoFrame; +class QT7PlayerSession; +class QT7PlayerService; + +class QT7MovieViewRenderer : public QT7VideoRendererControl +{ +public: + QT7MovieViewRenderer(QObject *parent = 0); + ~QT7MovieViewRenderer(); + + void setEnabled(bool); + void setMovie(void *movie); + void updateNaturalSize(const QSize &newSize); + + QAbstractVideoSurface *surface() const; + void setSurface(QAbstractVideoSurface *surface); + + void renderFrame(const QVideoFrame &); + +protected: + bool event(QEvent *event); + +private: + void setupVideoOutput(); + + void *m_movie; + void *m_movieView; + QSize m_nativeSize; + QAbstractVideoSurface *m_surface; + QVideoFrame m_currentFrame; + QMutex m_mutex; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm new file mode 100644 index 0000000..342feb8 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7movieviewrenderer.mm @@ -0,0 +1,349 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import <QTKit/QTKit.h> + +#include "qt7backend.h" + +#include "qt7playercontrol.h" +#include "qt7movieviewrenderer.h" +#include "qt7playersession.h" +#include <QtCore/qdebug.h> +#include <QtCore/qcoreevent.h> +#include <QtCore/qcoreapplication.h> + +#include <QtMultimedia/qabstractvideobuffer.h> +#include <QtMultimedia/qabstractvideosurface.h> +#include <QtMultimedia/qvideosurfaceformat.h> + + +QT_BEGIN_NAMESPACE + +class NSBitmapVideoBuffer : public QAbstractVideoBuffer +{ +public: + NSBitmapVideoBuffer(NSBitmapImageRep *buffer) + : QAbstractVideoBuffer(NoHandle) + , m_buffer(buffer) + , m_mode(NotMapped) + { + [m_buffer retain]; + } + + virtual ~NSBitmapVideoBuffer() + { + [m_buffer release]; + } + + MapMode mapMode() const { return m_mode; } + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) + { + if (mode != NotMapped && m_mode == NotMapped) { + if (numBytes) + *numBytes = [m_buffer bytesPerPlane]; + + if (bytesPerLine) + *bytesPerLine = [m_buffer bytesPerRow]; + + m_mode = mode; + + return [m_buffer bitmapData]; + } else { + return 0; + } + } + + void unmap() { m_mode = NotMapped; } + +private: + NSBitmapImageRep *m_buffer; + MapMode m_mode; +}; + + +#define VIDEO_TRANSPARENT(m) -(void)m:(NSEvent *)e{[[self superview] m:e];} + +@interface HiddenQTMovieView : QTMovieView +{ +@private + QWidget *m_window; + QT7MovieViewRenderer *m_renderer; +} + +- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer; +- (void) setRenderer:(QT7MovieViewRenderer *)renderer; +- (void) setDrawRect:(const QRect &)rect; +@end + +@implementation HiddenQTMovieView + +- (HiddenQTMovieView *) initWithRenderer:(QT7MovieViewRenderer *)renderer +{ + self = [super initWithFrame:NSZeroRect]; + if (self) { + [self setControllerVisible:NO]; + [self setDelegate:self]; + + self->m_renderer = renderer; + + self->m_window = new QWidget; + self->m_window->setWindowOpacity(0.0); + self->m_window->show(); + self->m_window->hide(); + + [(NSView *)(self->m_window->winId()) addSubview:self]; + [self setDrawRect:QRect(0,0,1,1)]; + } + return self; +} + +- (void) dealloc +{ + [super dealloc]; +} + +- (void) setRenderer:(QT7MovieViewRenderer *)renderer +{ + m_renderer = renderer; +} + +- (void) setDrawRect:(const QRect &)rect +{ + NSRect nsrect; + nsrect.origin.x = rect.x(); + nsrect.origin.y = rect.y(); + nsrect.size.width = rect.width(); + nsrect.size.height = rect.height(); + [self setFrame:nsrect]; +} + +- (CIImage *) view:(QTMovieView *)view willDisplayImage:(CIImage *)img +{ + // This method is called from QTMovieView just + // before the image will be drawn. + Q_UNUSED(view); + if (m_renderer) { + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCIImage:img]; + CGRect bounds = [img extent]; + int w = bounds.size.width; + int h = bounds.size.height; + + // Swap red and blue (same as QImage::rgbSwapped, but without copy) + uchar *data = [bitmap bitmapData]; + //qDebug() << data << w << h; + int bytesPerLine = [bitmap bytesPerRow]; + for (int i=0; i<h; ++i) { + quint32 *p = (quint32*)data; + data += bytesPerLine; + quint32 *end = p + w; + while (p < end) { + *p = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00); + p++; + } + } + + QVideoFrame frame( new NSBitmapVideoBuffer(bitmap), QSize(w,h), QVideoFrame::Format_RGB32 ); + + //static int i=0; + //i++; + //QImage img([bitmap bitmapData], w, h, QImage::Format_RGB32); + //img.save(QString("img%1.jpg").arg(i)); + + [bitmap release]; + + if (m_renderer) + m_renderer->renderFrame(frame); + } + + return img; +} + +// Override this method so that the movie doesn't stop if +// the window becomes invisible +- (void)viewWillMoveToWindow:(NSWindow *)newWindow +{ + Q_UNUSED(newWindow); +} + + +VIDEO_TRANSPARENT(mouseDown); +VIDEO_TRANSPARENT(mouseDragged); +VIDEO_TRANSPARENT(mouseUp); +VIDEO_TRANSPARENT(mouseMoved); +VIDEO_TRANSPARENT(mouseEntered); +VIDEO_TRANSPARENT(mouseExited); +VIDEO_TRANSPARENT(rightMouseDown); +VIDEO_TRANSPARENT(rightMouseDragged); +VIDEO_TRANSPARENT(rightMouseUp); +VIDEO_TRANSPARENT(otherMouseDown); +VIDEO_TRANSPARENT(otherMouseDragged); +VIDEO_TRANSPARENT(otherMouseUp); +VIDEO_TRANSPARENT(keyDown); +VIDEO_TRANSPARENT(keyUp); +VIDEO_TRANSPARENT(scrollWheel) + +@end + + +QT7MovieViewRenderer::QT7MovieViewRenderer(QObject *parent) + :QT7VideoRendererControl(parent), + m_movie(0), + m_movieView(0), + m_surface(0) +{ +} + +QT7MovieViewRenderer::~QT7MovieViewRenderer() +{ + [(HiddenQTMovieView*)m_movieView setRenderer:0]; + + QMutexLocker locker(&m_mutex); + m_currentFrame = QVideoFrame(); + [(HiddenQTMovieView*)m_movieView release]; +} + +void QT7MovieViewRenderer::setupVideoOutput() +{ + AutoReleasePool pool; + + qDebug() << "QT7MovieViewRenderer::setupVideoOutput" << m_movie << m_surface; + + HiddenQTMovieView *movieView = (HiddenQTMovieView*)m_movieView; + + if (movieView && !m_movie) { + [movieView setMovie:nil]; + } + + if (m_movie) { + NSSize size = [[(QTMovie*)m_movie attributeForKey:@"QTMovieNaturalSizeAttribute"] sizeValue]; + + m_nativeSize = QSize(size.width, size.height); + + if (!movieView) { + movieView = [[HiddenQTMovieView alloc] initWithRenderer:this]; + m_movieView = movieView; + [movieView setControllerVisible:NO]; + } + + [movieView setMovie:(QTMovie*)m_movie]; + //[movieView setDrawRect:QRect(QPoint(0,0), m_nativeSize)]; + } + + if (m_surface && !m_nativeSize.isEmpty()) { + QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32); + + if (m_surface->isActive() && m_surface->surfaceFormat() != format) { + qDebug() << "Surface format was changed, stop the surface."; + m_surface->stop(); + } + + if (!m_surface->isActive()) { + qDebug() << "Starting the surface with format" << format; + if (!m_surface->start(format)) + qDebug() << "failed to start video surface" << m_surface->error(); + } + } +} + +void QT7MovieViewRenderer::setEnabled(bool) +{ +} + +void QT7MovieViewRenderer::setMovie(void *movie) +{ + if (movie == m_movie) + return; + + QMutexLocker locker(&m_mutex); + m_movie = movie; + setupVideoOutput(); +} + +void QT7MovieViewRenderer::updateNaturalSize(const QSize &newSize) +{ + if (m_nativeSize != newSize) { + m_nativeSize = newSize; + setupVideoOutput(); + } +} + +QAbstractVideoSurface *QT7MovieViewRenderer::surface() const +{ + return m_surface; +} + +void QT7MovieViewRenderer::setSurface(QAbstractVideoSurface *surface) +{ + if (surface == m_surface) + return; + + QMutexLocker locker(&m_mutex); + + if (m_surface && m_surface->isActive()) + m_surface->stop(); + + m_surface = surface; + setupVideoOutput(); +} + +void QT7MovieViewRenderer::renderFrame(const QVideoFrame &frame) +{ + { + QMutexLocker locker(&m_mutex); + m_currentFrame = frame; + } + + qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); +} + +bool QT7MovieViewRenderer::event(QEvent *event) +{ + if (event->type() == QEvent::User) { + QMutexLocker locker(&m_mutex); + if (m_surface->isActive()) + m_surface->present(m_currentFrame); + } + + return QT7VideoRendererControl::event(event); +} + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/qt7/qt7serviceplugin.h b/src/plugins/mediaservices/qt7/qt7serviceplugin.h new file mode 100644 index 0000000..c5afda1 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7serviceplugin.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QT7SERVICEPLUGIN_H +#define QT7SERVICEPLUGIN_H + +#include <QtMultimedia/qmediaserviceproviderplugin.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QT7ServicePlugin : public QMediaServiceProviderPlugin +{ +public: + QStringList keys() const; + QMediaService* create(QString const& key); + void release(QMediaService *service); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGSTREAMERSERVICEPLUGIN_H diff --git a/src/plugins/mediaservices/qt7/qt7serviceplugin.mm b/src/plugins/mediaservices/qt7/qt7serviceplugin.mm new file mode 100644 index 0000000..c59a453 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7serviceplugin.mm @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qstring.h> +#include <QtCore/qdebug.h> + +#include "qt7serviceplugin.h" +#include "qt7playerservice.h" + +#include <QtMultimedia/qmediaserviceprovider.h> + +QT_BEGIN_NAMESPACE + +QStringList QT7ServicePlugin::keys() const +{ + return QStringList() +#ifdef QMEDIA_QT7_PLAYER + << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER); +#endif +} + +QMediaService* QT7ServicePlugin::create(QString const& key) +{ +#ifdef QMEDIA_QT7_PLAYER + if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) + return new QT7PlayerService; +#endif + + qWarning() << "Attempt to create unknown service with key" << key; + return 0; +} + +void QT7ServicePlugin::release(QMediaService *service) +{ + delete service; +} + +Q_EXPORT_PLUGIN2(qt7_serviceplugin, QT7ServicePlugin); + +QT_END_NAMESPACE diff --git a/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h new file mode 100644 index 0000000..2c60919 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT7VIDEOOUTPUTCONTROL_H +#define QT7VIDEOOUTPUTCONTROL_H + +#include <QtCore/qobject.h> +#include <QtCore/qsize.h> + +#include <QtMultimedia/qvideooutputcontrol.h> +#include <QtMultimedia/qvideowindowcontrol.h> +#include <QtMultimedia/qvideowidgetcontrol.h> +#include <QtMultimedia/qvideorenderercontrol.h> +#include <QtMultimedia/qmediaplayer.h> + +#include <QtGui/qmacdefines_mac.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QMediaPlaylist; +class QMediaPlaylistNavigator; +class QT7PlayerSession; +class QT7PlayerService; + + +class QT7VideoOutput { +public: + virtual ~QT7VideoOutput() {} + virtual void setEnabled(bool enabled) = 0; + virtual void setMovie(void *movie) = 0; + virtual void updateNaturalSize(const QSize &newSize) = 0; +}; + +class QT7VideoWindowControl : public QVideoWindowControl, public QT7VideoOutput +{ +public: + virtual ~QT7VideoWindowControl() {} + +protected: + QT7VideoWindowControl(QObject *parent) + :QVideoWindowControl(parent) + {} +}; + +class QT7VideoRendererControl : public QVideoRendererControl, public QT7VideoOutput +{ +public: + virtual ~QT7VideoRendererControl() {} + +protected: + QT7VideoRendererControl(QObject *parent) + :QVideoRendererControl(parent) + {} +}; + +class QT7VideoWidgetControl : public QVideoWidgetControl, public QT7VideoOutput +{ +public: + virtual ~QT7VideoWidgetControl() {} + +protected: + QT7VideoWidgetControl(QObject *parent) + :QVideoWidgetControl(parent) + {} +}; + +class QT7VideoOutputControl : public QVideoOutputControl +{ +Q_OBJECT +public: + QT7VideoOutputControl(QObject *parent = 0); + ~QT7VideoOutputControl(); + + void setSession(QT7PlayerSession *session); + + QList<Output> availableOutputs() const; + void enableOutput(Output); + + Output output() const; + void setOutput(Output output); + +signals: + void videoOutputChanged(QVideoOutputControl::Output); + +private: + QT7PlayerSession *m_session; + Output m_output; + QList<Output> m_outputs; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm new file mode 100644 index 0000000..a468431 --- /dev/null +++ b/src/plugins/mediaservices/qt7/qt7videooutputcontrol.mm @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt7playercontrol.h" +#include "qt7videooutputcontrol.h" +#include "qt7playersession.h" +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +QT7VideoOutputControl::QT7VideoOutputControl(QObject *parent) + :QVideoOutputControl(parent), + m_session(0), + m_output(QVideoOutputControl::NoOutput) +{ +} + +QT7VideoOutputControl::~QT7VideoOutputControl() +{ +} + +void QT7VideoOutputControl::setSession(QT7PlayerSession *session) +{ + m_session = session; +} + +QList<QVideoOutputControl::Output> QT7VideoOutputControl::availableOutputs() const +{ + return m_outputs; +} + +void QT7VideoOutputControl::enableOutput(QVideoOutputControl::Output output) +{ + if (!m_outputs.contains(output)) + m_outputs.append(output); +} + +QVideoOutputControl::Output QT7VideoOutputControl::output() const +{ + return m_output; +} + +void QT7VideoOutputControl::setOutput(Output output) +{ + if (m_output != output) { + m_output = output; + emit videoOutputChanged(m_output); + } + +} + +QT_END_NAMESPACE + +#include "moc_qt7videooutputcontrol.cpp" + diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 004b816..dc2266b 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -11,4 +11,7 @@ embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers !win32:!embedded:!mac:!symbian:SUBDIRS *= inputmethods symbian:SUBDIRS += s60 contains(QT_CONFIG, phonon): SUBDIRS *= phonon -contains(QT_CONFIG, multimedia): SUBDIRS *= audio +contains(QT_CONFIG, multimedia): SUBDIRS *= audio mediaservices +contains(QT_CONFIG, declarative): SUBDIRS *= qmlmodules + + diff --git a/src/plugins/qmlmodules/multimedia/multimedia.cpp b/src/plugins/qmlmodules/multimedia/multimedia.cpp new file mode 100644 index 0000000..381fb56 --- /dev/null +++ b/src/plugins/qmlmodules/multimedia/multimedia.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtDeclarative/qmlmoduleplugin.h> +#include <QtDeclarative/qml.h> +#include <QtMultimedia/private/qsoundeffect_p.h> +#include <QtMultimedia/private/qmlaudio_p.h> +#include <QtMultimedia/private/qmlgraphicsvideo_p.h> + +QT_BEGIN_NAMESPACE + +class QMultimediaQmlModule : public QmlModulePlugin +{ + Q_OBJECT +public: + QStringList keys() const + { + return QStringList() << QLatin1String("Qt.multimedia"); + } + + void defineModule(const QString& uri) + { + Q_UNUSED(uri) + Q_ASSERT(uri == QLatin1String("Qt.multimedia")); + + qmlRegisterType<QSoundEffect>("Qt.multimedia", 4, 7, "SoundEffect", "SoundEffect"); + qmlRegisterType<QmlAudio>("Qt.multimedia", 4, 7, "Audio", "Audio"); + qmlRegisterType<QmlGraphicsVideo>("Qt.multimedia", 4, 7, "Video", "Video"); + } +}; + +QT_END_NAMESPACE + +#include "multimedia.moc" + +Q_EXPORT_PLUGIN2(qmultimediaqmlmodule, QT_PREPEND_NAMESPACE(QMultimediaQmlModule)); + diff --git a/src/plugins/qmlmodules/multimedia/multimedia.pro b/src/plugins/qmlmodules/multimedia/multimedia.pro new file mode 100644 index 0000000..f04cc14 --- /dev/null +++ b/src/plugins/qmlmodules/multimedia/multimedia.pro @@ -0,0 +1,11 @@ +TARGET = multimedia +include(../../qpluginbase.pri) + +QT += multimedia declarative + +SOURCES += multimedia.cpp + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/qmlmodules +target.path = $$[QT_INSTALL_PLUGINS]/plugins/qmlmodules +INSTALLS += target + diff --git a/src/plugins/qmlmodules/qmlmodules.pro b/src/plugins/qmlmodules/qmlmodules.pro new file mode 100644 index 0000000..b1dc0ef --- /dev/null +++ b/src/plugins/qmlmodules/qmlmodules.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs + +contains(QT_CONFIG, multimedia): SUBDIRS += multimedia + diff --git a/src/plugins/sqldrivers/psql/psql.pro b/src/plugins/sqldrivers/psql/psql.pro index 29fbada..0a38ee4 100644 --- a/src/plugins/sqldrivers/psql/psql.pro +++ b/src/plugins/sqldrivers/psql/psql.pro @@ -4,18 +4,15 @@ HEADERS = ../../../sql/drivers/psql/qsql_psql.h SOURCES = main.cpp \ ../../../sql/drivers/psql/qsql_psql.cpp -unix: { +unix|win32-g++: { !isEmpty(QT_LFLAGS_PSQL) { - LIBS *= $$QT_LFLAGS_PSQL + !contains(QT_CONFIG, system-zlib): QT_LFLAGS_PSQL -= -lz + !static:LIBS *= $$QT_LFLAGS_PSQL QMAKE_CXXFLAGS *= $$QT_CFLAGS_PSQL } !contains(LIBS, .*pq.*):LIBS *= -lpq } -win32:!contains(LIBS, .*pq.* ) { - !win32-g++:LIBS *= -llibpq - win32-g++:LIBS *= -lpq - LIBS *= -lws2_32 -ladvapi32 -} +win32:!win32-g++:!contains(LIBS, .*pq.* ) LIBS *= -llibpq -lws2_32 -ladvapi32 include(../qsqldriverbase.pri) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 1bd7377..237b6fd 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -846,8 +846,7 @@ QScriptEnginePrivate::~QScriptEnginePrivate() QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v) { - Q_Q(QScriptEngine); - QScriptValue result = q->create(v.userType(), v.data()); + QScriptValue result = create(v.userType(), v.data()); Q_ASSERT(result.isValid()); return result; } diff --git a/src/sql/drivers/drivers.pri b/src/sql/drivers/drivers.pri index 184eca9..aac0267 100644 --- a/src/sql/drivers/drivers.pri +++ b/src/sql/drivers/drivers.pri @@ -6,19 +6,16 @@ contains(sql-drivers, psql) { HEADERS += drivers/psql/qsql_psql.h SOURCES += drivers/psql/qsql_psql.cpp - unix { - !isEmpty(QT_LFLAGS_PSQL) { - LIBS *= $$QT_LFLAGS_PSQL + unix|win32-g++ { + !static:!isEmpty(QT_LFLAGS_PSQL) { + !contains(QT_CONFIG, system-zlib): QT_LFLAGS_PSQL -= -lz + !static:LIBS *= $$QT_LFLAGS_PSQL QMAKE_CXXFLAGS *= $$QT_CFLAGS_PSQL } !contains(LIBS, .*pq.*):LIBS *= -lpq } - win32 { - !win32-g++:!contains( LIBS, .*pq.* ):LIBS *= -llibpq - win32-g++:!contains( LIBS, .*pq.* ):LIBS *= -lpq - LIBS *= -lws2_32 -ladvapi32 - } + win32:!win32-g++:!contains(LIBS, .*pq.* ) LIBS *= -llibpq -lws2_32 -ladvapi32 } contains(sql-drivers, mysql) { diff --git a/src/src.pro b/src/src.pro index f2070ae..2b9dc30 100644 --- a/src/src.pro +++ b/src/src.pro @@ -19,7 +19,6 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, o contains(QT_CONFIG, openvg): SRC_SUBDIRS += src_openvg contains(QT_CONFIG, xmlpatterns): SRC_SUBDIRS += src_xmlpatterns contains(QT_CONFIG, phonon): SRC_SUBDIRS += src_phonon -contains(QT_CONFIG, multimedia): SRC_SUBDIRS += src_multimedia contains(QT_CONFIG, svg): SRC_SUBDIRS += src_svg contains(QT_CONFIG, webkit) { #exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): SRC_SUBDIRS += src_javascriptcore @@ -28,6 +27,7 @@ contains(QT_CONFIG, webkit) { contains(QT_CONFIG, script): SRC_SUBDIRS += src_script contains(QT_CONFIG, scripttools): SRC_SUBDIRS += src_scripttools contains(QT_CONFIG, declarative): SRC_SUBDIRS += src_declarative +contains(QT_CONFIG, multimedia): SRC_SUBDIRS += src_multimedia SRC_SUBDIRS += src_plugins src_s60main.subdir = $$QT_SOURCE_TREE/src/s60main @@ -102,7 +102,7 @@ src_declarative.target = sub-declarative src_multimedia.depends = src_gui src_tools_activeqt.depends = src_tools_idc src_gui src_declarative.depends = src_xml src_gui src_script src_network src_svg - src_plugins.depends = src_gui src_sql src_svg + src_plugins.depends = src_gui src_sql src_svg src_multimedia contains(QT_CONFIG, webkit) { src_webkit.depends = src_gui src_sql src_network src_xml contains(QT_CONFIG, phonon):src_webkit.depends += src_phonon @@ -116,6 +116,7 @@ src_declarative.target = sub-declarative src_phonon.depends += src_dbus } contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2): src_plugins.depends += src_opengl + contains(QT_CONFIG, declarative): src_multimedia.depends += src_declarative } !symbian { diff --git a/src/testlib/qbenchmarkmetric.h b/src/testlib/qbenchmarkmetric.h index 302c1aa..1815527 100644 --- a/src/testlib/qbenchmarkmetric.h +++ b/src/testlib/qbenchmarkmetric.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/testlib/qbenchmarkmetric_p.h b/src/testlib/qbenchmarkmetric_p.h index c919d2e..f0afc04 100644 --- a/src/testlib/qbenchmarkmetric_p.h +++ b/src/testlib/qbenchmarkmetric_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index a9afa5d..a2c682b 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -153,8 +153,6 @@ SUBDIRS += \ qfontmetrics \ qftp \ qgetputenv \ - qgl \ - qgl_threads \ qglobal \ qgraphicseffect \ qgraphicseffectsource \ @@ -173,6 +171,7 @@ SUBDIRS += \ qgraphicsscene \ qgraphicssceneindex \ qgraphicstransform \ + qgraphicsvideoitem \ qgraphicsview \ qgraphicswidget \ qgridlayout \ @@ -301,6 +300,19 @@ SUBDIRS += \ qaudioformat \ qaudiooutput \ qaudioinput \ + qmediacontent \ + qmediaobject \ + qmediaplayer \ + qmediaplaylist \ + qmediaplaylistnavigator \ + qmediapluginloader \ + qmediaresource \ + qmediaservice \ + qmediaserviceprovider \ + qmediatimerange \ + qvideowidget \ + qmlaudio \ + qmlgraphicsvideo \ qspinbox \ qsplitter \ qsql \ @@ -465,7 +477,7 @@ SUBDIRS += \ rcc \ windowsmobile -contains(QT_CONFIG,opengl):SUBDIRS += qgl qglbuffer +contains(QT_CONFIG,opengl):SUBDIRS += qgl qglbuffer qgl_threads contains(QT_CONFIG,qt3support):!wince*:SUBDIRS += $$Q3SUBDIRS diff --git a/tests/auto/declarative/examples/tst_examples.cpp b/tests/auto/declarative/examples/tst_examples.cpp index fa4526a1..104c2d3 100644 --- a/tests/auto/declarative/examples/tst_examples.cpp +++ b/tests/auto/declarative/examples/tst_examples.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/graphicswidgets/tst_graphicswidgets.cpp b/tests/auto/declarative/graphicswidgets/tst_graphicswidgets.cpp index 1bb8c14..cb618c6 100644 --- a/tests/auto/declarative/graphicswidgets/tst_graphicswidgets.cpp +++ b/tests/auto/declarative/graphicswidgets/tst_graphicswidgets.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/layouts/tst_layouts.cpp b/tests/auto/declarative/layouts/tst_layouts.cpp index 0f832bf..050df52 100644 --- a/tests/auto/declarative/layouts/tst_layouts.cpp +++ b/tests/auto/declarative/layouts/tst_layouts.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/parserstress/tst_parserstress.cpp b/tests/auto/declarative/parserstress/tst_parserstress.cpp index a607bb3..8af1b12 100644 --- a/tests/auto/declarative/parserstress/tst_parserstress.cpp +++ b/tests/auto/declarative/parserstress/tst_parserstress.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index b82372a..c1dc924 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlanimations/tst_qmlanimations.cpp b/tests/auto/declarative/qmlanimations/tst_qmlanimations.cpp index a00e911..34bb7e3 100644 --- a/tests/auto/declarative/qmlanimations/tst_qmlanimations.cpp +++ b/tests/auto/declarative/qmlanimations/tst_qmlanimations.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlbehaviors/tst_qmlbehaviors.cpp b/tests/auto/declarative/qmlbehaviors/tst_qmlbehaviors.cpp index 73ab35e..126c506 100644 --- a/tests/auto/declarative/qmlbehaviors/tst_qmlbehaviors.cpp +++ b/tests/auto/declarative/qmlbehaviors/tst_qmlbehaviors.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlbinding/tst_qmlbinding.cpp b/tests/auto/declarative/qmlbinding/tst_qmlbinding.cpp index 19f4d77..92d1b69 100644 --- a/tests/auto/declarative/qmlbinding/tst_qmlbinding.cpp +++ b/tests/auto/declarative/qmlbinding/tst_qmlbinding.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlconnection/tst_qmlconnection.cpp b/tests/auto/declarative/qmlconnection/tst_qmlconnection.cpp index b3c04f1..2aba7b5 100644 --- a/tests/auto/declarative/qmlconnection/tst_qmlconnection.cpp +++ b/tests/auto/declarative/qmlconnection/tst_qmlconnection.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlcontext/tst_qmlcontext.cpp b/tests/auto/declarative/qmlcontext/tst_qmlcontext.cpp index f82f202..7ff7af2 100644 --- a/tests/auto/declarative/qmlcontext/tst_qmlcontext.cpp +++ b/tests/auto/declarative/qmlcontext/tst_qmlcontext.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmldatetimeformatter/tst_qmldatetimeformatter.cpp b/tests/auto/declarative/qmldatetimeformatter/tst_qmldatetimeformatter.cpp index 2ce6186..bb607ae 100644 --- a/tests/auto/declarative/qmldatetimeformatter/tst_qmldatetimeformatter.cpp +++ b/tests/auto/declarative/qmldatetimeformatter/tst_qmldatetimeformatter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmldebug/tst_qmldebug.cpp b/tests/auto/declarative/qmldebug/tst_qmldebug.cpp index 82e74ce..effc2c5 100644 --- a/tests/auto/declarative/qmldebug/tst_qmldebug.cpp +++ b/tests/auto/declarative/qmldebug/tst_qmldebug.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp b/tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp index 4ee0837..3c87d71 100644 --- a/tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp +++ b/tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp b/tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp index 4e7bc27..45a06c4 100644 --- a/tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp +++ b/tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmldom/tst_qmldom.cpp b/tests/auto/declarative/qmldom/tst_qmldom.cpp index eb4d419..6dbcedd 100644 --- a/tests/auto/declarative/qmldom/tst_qmldom.cpp +++ b/tests/auto/declarative/qmldom/tst_qmldom.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmleasefollow/tst_qmleasefollow.cpp b/tests/auto/declarative/qmleasefollow/tst_qmleasefollow.cpp index 384ce25b..f28311f 100644 --- a/tests/auto/declarative/qmleasefollow/tst_qmleasefollow.cpp +++ b/tests/auto/declarative/qmleasefollow/tst_qmleasefollow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlecmascript/testtypes.cpp b/tests/auto/declarative/qmlecmascript/testtypes.cpp index df0cb18..3c6b256 100644 --- a/tests/auto/declarative/qmlecmascript/testtypes.cpp +++ b/tests/auto/declarative/qmlecmascript/testtypes.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlecmascript/testtypes.h b/tests/auto/declarative/qmlecmascript/testtypes.h index 09c850d..330664f 100644 --- a/tests/auto/declarative/qmlecmascript/testtypes.h +++ b/tests/auto/declarative/qmlecmascript/testtypes.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index a6baf10..4e66548 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp index af8e44f..6504d03 100644 --- a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp +++ b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlerror/tst_qmlerror.cpp b/tests/auto/declarative/qmlerror/tst_qmlerror.cpp index 70fef1d..12dde57 100644 --- a/tests/auto/declarative/qmlerror/tst_qmlerror.cpp +++ b/tests/auto/declarative/qmlerror/tst_qmlerror.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlfontloader/tst_qmlfontloader.cpp b/tests/auto/declarative/qmlfontloader/tst_qmlfontloader.cpp index 19372a0..41b5359 100644 --- a/tests/auto/declarative/qmlfontloader/tst_qmlfontloader.cpp +++ b/tests/auto/declarative/qmlfontloader/tst_qmlfontloader.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsanchors/tst_qmlgraphicsanchors.cpp b/tests/auto/declarative/qmlgraphicsanchors/tst_qmlgraphicsanchors.cpp index 70e70d0..24d6f44 100644 --- a/tests/auto/declarative/qmlgraphicsanchors/tst_qmlgraphicsanchors.cpp +++ b/tests/auto/declarative/qmlgraphicsanchors/tst_qmlgraphicsanchors.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsanimatedimage/tst_qmlgraphicsanimatedimage.cpp b/tests/auto/declarative/qmlgraphicsanimatedimage/tst_qmlgraphicsanimatedimage.cpp index bc10e30..136e4cd 100644 --- a/tests/auto/declarative/qmlgraphicsanimatedimage/tst_qmlgraphicsanimatedimage.cpp +++ b/tests/auto/declarative/qmlgraphicsanimatedimage/tst_qmlgraphicsanimatedimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp b/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp index 1ae0227..183f7e4 100644 --- a/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp +++ b/tests/auto/declarative/qmlgraphicsborderimage/tst_qmlgraphicsborderimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsflickable/tst_qmlgraphicsflickable.cpp b/tests/auto/declarative/qmlgraphicsflickable/tst_qmlgraphicsflickable.cpp index c0ffeb7..7fdc4fb 100644 --- a/tests/auto/declarative/qmlgraphicsflickable/tst_qmlgraphicsflickable.cpp +++ b/tests/auto/declarative/qmlgraphicsflickable/tst_qmlgraphicsflickable.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsflipable/tst_qmlgraphicsflipable.cpp b/tests/auto/declarative/qmlgraphicsflipable/tst_qmlgraphicsflipable.cpp index e571e4e..24dc2e8 100644 --- a/tests/auto/declarative/qmlgraphicsflipable/tst_qmlgraphicsflipable.cpp +++ b/tests/auto/declarative/qmlgraphicsflipable/tst_qmlgraphicsflipable.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp b/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp index c157e62..40b54d2 100644 --- a/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp +++ b/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp index 79dc290..503b05e 100644 --- a/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp +++ b/tests/auto/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsitem/tst_qmlgraphicsitem.cpp b/tests/auto/declarative/qmlgraphicsitem/tst_qmlgraphicsitem.cpp index c671dae..6673ced2 100644 --- a/tests/auto/declarative/qmlgraphicsitem/tst_qmlgraphicsitem.cpp +++ b/tests/auto/declarative/qmlgraphicsitem/tst_qmlgraphicsitem.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp index 6f97030..560e625 100644 --- a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp +++ b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp b/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp index 43f58c1..b38e8de 100644 --- a/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp +++ b/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp index 5458d68..d9ddf4b 100644 --- a/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp +++ b/tests/auto/declarative/qmlgraphicsparticles/tst_qmlgraphicsparticles.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicspathview/tst_qmlgraphicspathview.cpp b/tests/auto/declarative/qmlgraphicspathview/tst_qmlgraphicspathview.cpp index 4c2ecbd..90e0de3 100644 --- a/tests/auto/declarative/qmlgraphicspathview/tst_qmlgraphicspathview.cpp +++ b/tests/auto/declarative/qmlgraphicspathview/tst_qmlgraphicspathview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicspositioners/tst_qmlgraphicspositioners.cpp b/tests/auto/declarative/qmlgraphicspositioners/tst_qmlgraphicspositioners.cpp index da541c8..d6b4f87 100644 --- a/tests/auto/declarative/qmlgraphicspositioners/tst_qmlgraphicspositioners.cpp +++ b/tests/auto/declarative/qmlgraphicspositioners/tst_qmlgraphicspositioners.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicsrepeater/tst_qmlgraphicsrepeater.cpp b/tests/auto/declarative/qmlgraphicsrepeater/tst_qmlgraphicsrepeater.cpp index 4297901..a81b990 100644 --- a/tests/auto/declarative/qmlgraphicsrepeater/tst_qmlgraphicsrepeater.cpp +++ b/tests/auto/declarative/qmlgraphicsrepeater/tst_qmlgraphicsrepeater.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicstext/tst_qmlgraphicstext.cpp b/tests/auto/declarative/qmlgraphicstext/tst_qmlgraphicstext.cpp index 4626fe6..2c1e09b 100644 --- a/tests/auto/declarative/qmlgraphicstext/tst_qmlgraphicstext.cpp +++ b/tests/auto/declarative/qmlgraphicstext/tst_qmlgraphicstext.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicstextedit/tst_qmlgraphicstextedit.cpp b/tests/auto/declarative/qmlgraphicstextedit/tst_qmlgraphicstextedit.cpp index a197ced..11fe689 100644 --- a/tests/auto/declarative/qmlgraphicstextedit/tst_qmlgraphicstextedit.cpp +++ b/tests/auto/declarative/qmlgraphicstextedit/tst_qmlgraphicstextedit.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicstextinput/tst_qmlgraphicstextinput.cpp b/tests/auto/declarative/qmlgraphicstextinput/tst_qmlgraphicstextinput.cpp index 906dbc2..cf08bff 100644 --- a/tests/auto/declarative/qmlgraphicstextinput/tst_qmlgraphicstextinput.cpp +++ b/tests/auto/declarative/qmlgraphicstextinput/tst_qmlgraphicstextinput.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicswebview/testtypes.cpp b/tests/auto/declarative/qmlgraphicswebview/testtypes.cpp index e21f286..00c1b67 100644 --- a/tests/auto/declarative/qmlgraphicswebview/testtypes.cpp +++ b/tests/auto/declarative/qmlgraphicswebview/testtypes.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicswebview/testtypes.h b/tests/auto/declarative/qmlgraphicswebview/testtypes.h index 7ab7c78..0b3176d 100644 --- a/tests/auto/declarative/qmlgraphicswebview/testtypes.h +++ b/tests/auto/declarative/qmlgraphicswebview/testtypes.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlgraphicswebview/tst_qmlgraphicswebview.cpp b/tests/auto/declarative/qmlgraphicswebview/tst_qmlgraphicswebview.cpp index 6996a6c..e7b996d 100644 --- a/tests/auto/declarative/qmlgraphicswebview/tst_qmlgraphicswebview.cpp +++ b/tests/auto/declarative/qmlgraphicswebview/tst_qmlgraphicswebview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlinfo/tst_qmlinfo.cpp b/tests/auto/declarative/qmlinfo/tst_qmlinfo.cpp index 880f7b8..e4da993 100644 --- a/tests/auto/declarative/qmlinfo/tst_qmlinfo.cpp +++ b/tests/auto/declarative/qmlinfo/tst_qmlinfo.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlinstruction/tst_qmlinstruction.cpp b/tests/auto/declarative/qmlinstruction/tst_qmlinstruction.cpp index ea99a9e..9c753ce 100644 --- a/tests/auto/declarative/qmlinstruction/tst_qmlinstruction.cpp +++ b/tests/auto/declarative/qmlinstruction/tst_qmlinstruction.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmllanguage/testtypes.cpp b/tests/auto/declarative/qmllanguage/testtypes.cpp index f30f47e..a295054 100644 --- a/tests/auto/declarative/qmllanguage/testtypes.cpp +++ b/tests/auto/declarative/qmllanguage/testtypes.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmllanguage/testtypes.h b/tests/auto/declarative/qmllanguage/testtypes.h index d6ca898..0dc957f 100644 --- a/tests/auto/declarative/qmllanguage/testtypes.h +++ b/tests/auto/declarative/qmllanguage/testtypes.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp index 3029501..c4636f3 100644 --- a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp +++ b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmllist/tst_qmllist.cpp b/tests/auto/declarative/qmllist/tst_qmllist.cpp index c59ff1d..4ffbbb8 100644 --- a/tests/auto/declarative/qmllist/tst_qmllist.cpp +++ b/tests/auto/declarative/qmllist/tst_qmllist.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp b/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp index ddf9a07..3efe847 100644 --- a/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp +++ b/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp index 9d072dd..fa45a01 100644 --- a/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp +++ b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp b/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp index ec6b87f..d668bf6 100644 --- a/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp +++ b/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp b/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp index ccb8f30..4ca132e 100644 --- a/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp +++ b/tests/auto/declarative/qmlmetatype/tst_qmlmetatype.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlmoduleplugin/plugin/plugin.cpp b/tests/auto/declarative/qmlmoduleplugin/plugin/plugin.cpp index 10adda0..0d7f985 100644 --- a/tests/auto/declarative/qmlmoduleplugin/plugin/plugin.cpp +++ b/tests/auto/declarative/qmlmoduleplugin/plugin/plugin.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlmoduleplugin/tst_qmlmoduleplugin.cpp b/tests/auto/declarative/qmlmoduleplugin/tst_qmlmoduleplugin.cpp index 3f97abd..87125fc 100644 --- a/tests/auto/declarative/qmlmoduleplugin/tst_qmlmoduleplugin.cpp +++ b/tests/auto/declarative/qmlmoduleplugin/tst_qmlmoduleplugin.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlnumberformatter/tst_qmlnumberformatter.cpp b/tests/auto/declarative/qmlnumberformatter/tst_qmlnumberformatter.cpp index bf71625..3161cbc 100644 --- a/tests/auto/declarative/qmlnumberformatter/tst_qmlnumberformatter.cpp +++ b/tests/auto/declarative/qmlnumberformatter/tst_qmlnumberformatter.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlpixmapcache/tst_qmlpixmapcache.cpp b/tests/auto/declarative/qmlpixmapcache/tst_qmlpixmapcache.cpp index 50de8d5..019fc2a 100644 --- a/tests/auto/declarative/qmlpixmapcache/tst_qmlpixmapcache.cpp +++ b/tests/auto/declarative/qmlpixmapcache/tst_qmlpixmapcache.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlpropertymap/tst_qmlpropertymap.cpp b/tests/auto/declarative/qmlpropertymap/tst_qmlpropertymap.cpp index 8c457e6..26b89a6 100644 --- a/tests/auto/declarative/qmlpropertymap/tst_qmlpropertymap.cpp +++ b/tests/auto/declarative/qmlpropertymap/tst_qmlpropertymap.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp index 78f39be..c3c2521 100644 --- a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp +++ b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlspringfollow/tst_qmlspringfollow.cpp b/tests/auto/declarative/qmlspringfollow/tst_qmlspringfollow.cpp index f17b5d4..393b351 100644 --- a/tests/auto/declarative/qmlspringfollow/tst_qmlspringfollow.cpp +++ b/tests/auto/declarative/qmlspringfollow/tst_qmlspringfollow.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlstates/tst_qmlstates.cpp b/tests/auto/declarative/qmlstates/tst_qmlstates.cpp index 4e4f3fb..4402d03 100644 --- a/tests/auto/declarative/qmlstates/tst_qmlstates.cpp +++ b/tests/auto/declarative/qmlstates/tst_qmlstates.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlsystempalette/tst_qmlsystempalette.cpp b/tests/auto/declarative/qmlsystempalette/tst_qmlsystempalette.cpp index 7da7f68..06e4d1c 100644 --- a/tests/auto/declarative/qmlsystempalette/tst_qmlsystempalette.cpp +++ b/tests/auto/declarative/qmlsystempalette/tst_qmlsystempalette.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp index 83094d2..b8b5e62 100644 --- a/tests/auto/declarative/qmltimer/tst_qmltimer.cpp +++ b/tests/auto/declarative/qmltimer/tst_qmltimer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlvaluetypes/testtypes.cpp b/tests/auto/declarative/qmlvaluetypes/testtypes.cpp index 565eb1c..c51b777 100644 --- a/tests/auto/declarative/qmlvaluetypes/testtypes.cpp +++ b/tests/auto/declarative/qmlvaluetypes/testtypes.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlvaluetypes/testtypes.h b/tests/auto/declarative/qmlvaluetypes/testtypes.h index 67e32f5..b57fbff 100644 --- a/tests/auto/declarative/qmlvaluetypes/testtypes.h +++ b/tests/auto/declarative/qmlvaluetypes/testtypes.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlvaluetypes/tst_qmlvaluetypes.cpp b/tests/auto/declarative/qmlvaluetypes/tst_qmlvaluetypes.cpp index 49655db..47b35f7 100644 --- a/tests/auto/declarative/qmlvaluetypes/tst_qmlvaluetypes.cpp +++ b/tests/auto/declarative/qmlvaluetypes/tst_qmlvaluetypes.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlxmlhttprequest/tst_qmlxmlhttprequest.cpp b/tests/auto/declarative/qmlxmlhttprequest/tst_qmlxmlhttprequest.cpp index df5442c..54738f6 100644 --- a/tests/auto/declarative/qmlxmlhttprequest/tst_qmlxmlhttprequest.cpp +++ b/tests/auto/declarative/qmlxmlhttprequest/tst_qmlxmlhttprequest.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp b/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp index 966d7de..df1931f 100644 --- a/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp +++ b/tests/auto/declarative/qmlxmllistmodel/tst_qmlxmllistmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp index 60631d2..45947e3 100644 --- a/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp +++ b/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/runall.sh b/tests/auto/declarative/runall.sh index 33087a1..5e32c90 100755 --- a/tests/auto/declarative/runall.sh +++ b/tests/auto/declarative/runall.sh @@ -1,4 +1,45 @@ #!/bin/sh +# +############################################################################# +## +## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################/ Xnest :7 2>/dev/null & sleep 1 diff --git a/tests/auto/declarative/shared/debugutil.cpp b/tests/auto/declarative/shared/debugutil.cpp index aa0cd31..56518d7 100644 --- a/tests/auto/declarative/shared/debugutil.cpp +++ b/tests/auto/declarative/shared/debugutil.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/shared/debugutil_p.h b/tests/auto/declarative/shared/debugutil_p.h index 313d16c..d32e8ac 100644 --- a/tests/auto/declarative/shared/debugutil_p.h +++ b/tests/auto/declarative/shared/debugutil_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/shared/testhttpserver.cpp b/tests/auto/declarative/shared/testhttpserver.cpp index 490fc95..fe2b2cf 100644 --- a/tests/auto/declarative/shared/testhttpserver.cpp +++ b/tests/auto/declarative/shared/testhttpserver.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/shared/testhttpserver.h b/tests/auto/declarative/shared/testhttpserver.h index 178122d..638237d 100644 --- a/tests/auto/declarative/shared/testhttpserver.h +++ b/tests/auto/declarative/shared/testhttpserver.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/sql/tst_sql.cpp b/tests/auto/declarative/sql/tst_sql.cpp index 9bc667d..2384101 100644 --- a/tests/auto/declarative/sql/tst_sql.cpp +++ b/tests/auto/declarative/sql/tst_sql.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/declarative/visual/tst_visual.cpp b/tests/auto/declarative/visual/tst_visual.cpp index 5a5318a..8f41bef 100644 --- a/tests/auto/declarative/visual/tst_visual.cpp +++ b/tests/auto/declarative/visual/tst_visual.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 952136b..e6de590 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -333,6 +333,7 @@ private slots: void unregisterRecognizer(); void autoCancelGestures(); void autoCancelGestures2(); + void graphicsViewParentPropagation(); }; tst_Gestures::tst_Gestures() @@ -698,6 +699,9 @@ public: bool acceptGestureOverride; QSet<Qt::GestureType> ignoredGestures; + QSet<Qt::GestureType> ignoredStartedGestures; + QSet<Qt::GestureType> ignoredUpdatedGestures; + QSet<Qt::GestureType> ignoredFinishedGestures; QRectF size; int instanceNumber; @@ -710,6 +714,9 @@ public: events.clear(); overrideEvents.clear(); ignoredGestures.clear(); + ignoredStartedGestures.clear(); + ignoredUpdatedGestures.clear(); + ignoredFinishedGestures.clear(); } protected: @@ -732,6 +739,24 @@ protected: QGestureEvent *e = static_cast<QGestureEvent *>(event); foreach(Qt::GestureType type, ignoredGestures) e->ignore(e->gesture(type)); + foreach(QGesture *g, e->gestures()) { + switch (g->state()) { + case Qt::GestureStarted: + if (ignoredStartedGestures.contains(g->gestureType())) + e->ignore(g); + break; + case Qt::GestureUpdated: + if (ignoredUpdatedGestures.contains(g->gestureType())) + e->ignore(g); + break; + case Qt::GestureFinished: + if (ignoredFinishedGestures.contains(g->gestureType())) + e->ignore(g); + break; + default: + break; + } + } } else if (event->type() == QEvent::GestureOverride) { ++gestureOverrideEventsReceived; eventsPtr = &overrideEvents; @@ -1471,5 +1496,66 @@ void tst_Gestures::autoCancelGestures2() QCOMPARE(parent->events.all.count(), 2); } +void tst_Gestures::graphicsViewParentPropagation() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); + + GestureItem *item0 = new GestureItem("item0"); + scene.addItem(item0); + item0->setPos(0, 0); + item0->grabGesture(CustomGesture::GestureType); + item0->setZValue(1); + + GestureItem *item1 = new GestureItem("item1"); + scene.addItem(item1); + item1->setPos(0, 0); + item1->setZValue(5); + + GestureItem *item1_c1 = new GestureItem("item1_child1"); + item1_c1->setParentItem(item1); + item1_c1->setPos(0, 0); + + GestureItem *item1_c1_c1 = new GestureItem("item1_child1_child1"); + item1_c1_c1->setParentItem(item1_c1); + item1_c1_c1->setPos(0, 0); + + view.show(); + QTest::qWaitForWindowShown(&view); + view.ensureVisible(scene.sceneRect()); + + view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); + item0->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures | Qt::IgnoredGesturesPropagateToParent); + item1->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures | Qt::IgnoredGesturesPropagateToParent); + item1_c1->grabGesture(CustomGesture::GestureType, Qt::IgnoredGesturesPropagateToParent); + item1_c1_c1->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures | Qt::IgnoredGesturesPropagateToParent); + + item0->ignoredUpdatedGestures << CustomGesture::GestureType; + item0->ignoredFinishedGestures << CustomGesture::GestureType; + item1->ignoredUpdatedGestures << CustomGesture::GestureType; + item1->ignoredFinishedGestures << CustomGesture::GestureType; + item1_c1->ignoredUpdatedGestures << CustomGesture::GestureType; + item1_c1->ignoredFinishedGestures << CustomGesture::GestureType; + item1_c1_c1->ignoredUpdatedGestures << CustomGesture::GestureType; + item1_c1_c1->ignoredFinishedGestures << CustomGesture::GestureType; + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + + CustomEvent event; + event.hotSpot = mapToGlobal(QPointF(10, 10), item1_c1, &view); + event.hasHotSpot = true; + sendCustomGesture(&event, item0, &scene); + + QCOMPARE(item1_c1_c1->gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(item1_c1_c1->gestureOverrideEventsReceived, 1); + QCOMPARE(item1_c1->gestureEventsReceived, 0); + QCOMPARE(item1_c1->gestureOverrideEventsReceived, 1); + QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount-1); + QCOMPARE(item1->gestureOverrideEventsReceived, 1); + QCOMPARE(item0->gestureEventsReceived, 0); + QCOMPARE(item0->gestureOverrideEventsReceived, 1); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 5f79923..bf7ec3f 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -192,19 +192,20 @@ void tst_Headers::licenseCheck() QByteArray data = f.readAll(); data.replace("\r\n", "\n"); // Windows data.replace('\r', '\n'); // Mac OS9 - QStringList content = QString::fromLocal8Bit(data).split("\n"); + QStringList content = QString::fromLocal8Bit(data).split("\n", QString::SkipEmptyParts); + + if (content.count() <= 2) // likely a #include line and empty line only. Not a copyright issue. + return; if (content.first().contains("generated")) { content.takeFirst(); - if (content.first().isEmpty()) - content.takeFirst(); } if (sourceFile.endsWith("/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp") || sourceFile.endsWith("/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp")) { // These files are meant to start with empty lines. - while (content.first().isEmpty() || content.first().startsWith("//")) + while (content.first().startsWith("//")) content.takeFirst(); } diff --git a/tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp b/tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp index 33642c4..3327d1e 100644 --- a/tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/respfile/source1.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/auto/qgl_threads/tst_openglthreading.pro b/tests/auto/qgl_threads/qgl_threads.pro index 9312c05..9312c05 100644 --- a/tests/auto/qgl_threads/tst_openglthreading.pro +++ b/tests/auto/qgl_threads/qgl_threads.pro diff --git a/tests/auto/qgl_threads/tst_openglthreading.cpp b/tests/auto/qgl_threads/tst_openglthreading.cpp index 6634869..cf100cb 100644 --- a/tests/auto/qgl_threads/tst_openglthreading.cpp +++ b/tests/auto/qgl_threads/tst_openglthreading.cpp @@ -145,6 +145,10 @@ public: void tst_OpenGLThreading::swapInThread() { +#ifdef Q_OS_MAC + QSKIP("OpenGL threading tests are currently disabled on mac as they were causing reboots", SkipAll); +#endif + QGLFormat format; format.setSwapInterval(1); ForegroundWidget widget(format); @@ -247,6 +251,10 @@ private: void tst_OpenGLThreading::textureUploadInThread() { +#ifdef Q_OS_MAC + QSKIP("OpenGL threading tests are currently disabled on mac as they were causing reboots", SkipAll); +#endif + TextureDisplay display; CreateAndUploadThread thread(&display); @@ -417,6 +425,10 @@ void tst_OpenGLThreading::renderInThread_data() void tst_OpenGLThreading::renderInThread() { +#ifdef Q_OS_MAC + QSKIP("OpenGL threading tests are currently disabled on mac as they were causing reboots", SkipAll); +#endif + QFETCH(bool, resize); QFETCH(bool, update); diff --git a/tests/auto/qgraphicsvideoitem/qgraphicsvideoitem.pro b/tests/auto/qgraphicsvideoitem/qgraphicsvideoitem.pro new file mode 100644 index 0000000..da00baf --- /dev/null +++ b/tests/auto/qgraphicsvideoitem/qgraphicsvideoitem.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +SOURCES += tst_qgraphicsvideoitem.cpp + +QT += multimedia +requires(contains(QT_CONFIG, multimedia)) diff --git a/tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp b/tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp new file mode 100644 index 0000000..7fb6005 --- /dev/null +++ b/tests/auto/qgraphicsvideoitem/tst_qgraphicsvideoitem.cpp @@ -0,0 +1,670 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtMultimedia/qgraphicsvideoitem.h> + +#include <QtGui/qapplication.h> +#include <QtGui/qgraphicsscene.h> +#include <QtGui/qgraphicsview.h> +#include <QtMultimedia/qabstractvideosurface.h> +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qvideooutputcontrol.h> +#include <QtMultimedia/qvideorenderercontrol.h> +#include <QtMultimedia/qvideosurfaceformat.h> + +#include <QtMultimedia/private/qpaintervideosurface_p.h> + +class tst_QGraphicsVideoItem : public QObject +{ + Q_OBJECT +public slots: + void initTestCase(); + +private slots: + void nullObject(); + void nullService(); + void nullOutputControl(); + void noOutputs(); + void serviceDestroyed(); + void mediaObjectDestroyed(); + void setMediaObject(); + + void show(); + + void aspectRatioMode(); + void offset(); + void size(); + void nativeSize_data(); + void nativeSize(); + + void boundingRect_data(); + void boundingRect(); + + void paint(); +}; + +Q_DECLARE_METATYPE(const uchar *) +Q_DECLARE_METATYPE(Qt::AspectRatioMode) + +class QtTestOutputControl : public QVideoOutputControl +{ +public: + QtTestOutputControl() : m_output(NoOutput) {} + + QList<Output> availableOutputs() const { return m_outputs; } + void setAvailableOutputs(const QList<Output> outputs) { m_outputs = outputs; } + + Output output() const { return m_output; } + virtual void setOutput(Output output) { m_output = output; } + +private: + Output m_output; + QList<Output> m_outputs; +}; + +class QtTestRendererControl : public QVideoRendererControl +{ +public: + QtTestRendererControl() + : m_surface(0) + { + } + + QAbstractVideoSurface *surface() const { return m_surface; } + void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; } + +private: + QAbstractVideoSurface *m_surface; +}; + +class QtTestVideoService : public QMediaService +{ + Q_OBJECT +public: + QtTestVideoService( + QtTestOutputControl *output, + QtTestRendererControl *renderer) + : QMediaService(0) + , outputControl(output) + , rendererControl(renderer) + { + } + + ~QtTestVideoService() + { + delete outputControl; + delete rendererControl; + } + + QMediaControl *control(const char *name) const + { + if (qstrcmp(name, QVideoOutputControl_iid) == 0) + return outputControl; + else if (qstrcmp(name, QVideoRendererControl_iid) == 0) + return rendererControl; + else + return 0; + } + + QtTestOutputControl *outputControl; + QtTestRendererControl *rendererControl; +}; + +class QtTestVideoObject : public QMediaObject +{ + Q_OBJECT +public: + QtTestVideoObject(QtTestRendererControl *renderer): + QMediaObject(0, new QtTestVideoService(new QtTestOutputControl, renderer)) + { + testService = qobject_cast<QtTestVideoService*>(service()); + QList<QVideoOutputControl::Output> outputs; + + if (renderer) + outputs.append(QVideoOutputControl::RendererOutput); + + testService->outputControl->setAvailableOutputs(outputs); + } + + QtTestVideoObject(QtTestVideoService *service): + QMediaObject(0, service), + testService(service) + { + } + + ~QtTestVideoObject() + { + delete testService; + } + + QtTestVideoService *testService; +}; + +class QtTestGraphicsVideoItem : public QGraphicsVideoItem +{ +public: + QtTestGraphicsVideoItem(QGraphicsItem *parent = 0) + : QGraphicsVideoItem(parent) + , m_paintCount(0) + { + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + ++m_paintCount; + + QTestEventLoop::instance().exitLoop(); + + QGraphicsVideoItem::paint(painter, option, widget); + } + + bool waitForPaint(int secs) + { + const int paintCount = m_paintCount; + + QTestEventLoop::instance().enterLoop(secs); + + return m_paintCount != paintCount; + } + + int paintCount() const + { + return m_paintCount; + } + +private: + int m_paintCount; +}; + +void tst_QGraphicsVideoItem::initTestCase() +{ + qRegisterMetaType<Qt::AspectRatioMode>(); +} + +void tst_QGraphicsVideoItem::nullObject() +{ + QGraphicsVideoItem item(0); + + QVERIFY(item.boundingRect().isEmpty()); +} + +void tst_QGraphicsVideoItem::nullService() +{ + QtTestVideoService *service = 0; + + QtTestVideoObject object(service); + + QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; + item->setMediaObject(&object); + + QVERIFY(item->boundingRect().isEmpty()); + + item->hide(); + item->show(); + + QGraphicsScene graphicsScene; + graphicsScene.addItem(item); + QGraphicsView graphicsView(&graphicsScene); + graphicsView.show(); +} + +void tst_QGraphicsVideoItem::nullOutputControl() +{ + QtTestVideoObject object(new QtTestVideoService(0, 0)); + + QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; + item->setMediaObject(&object); + + QVERIFY(item->boundingRect().isEmpty()); + + item->hide(); + item->show(); + + QGraphicsScene graphicsScene; + graphicsScene.addItem(item); + QGraphicsView graphicsView(&graphicsScene); + graphicsView.show(); +} + +void tst_QGraphicsVideoItem::noOutputs() +{ + QtTestRendererControl *control = 0; + QtTestVideoObject object(control); + + QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; + item->setMediaObject(&object); + + QVERIFY(item->boundingRect().isEmpty()); + + item->hide(); + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + item->show(); + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + QGraphicsScene graphicsScene; + graphicsScene.addItem(item); + QGraphicsView graphicsView(&graphicsScene); + graphicsView.show(); +} + +void tst_QGraphicsVideoItem::serviceDestroyed() +{ + QtTestVideoObject object(new QtTestRendererControl); + + QGraphicsVideoItem item; + item.setMediaObject(&object); + + QtTestVideoService *service = object.testService; + object.testService = 0; + + delete service; + + QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object)); + QVERIFY(item.boundingRect().isEmpty()); +} + +void tst_QGraphicsVideoItem::mediaObjectDestroyed() +{ + QtTestVideoObject *object = new QtTestVideoObject(new QtTestRendererControl); + + QGraphicsVideoItem item; + item.setMediaObject(object); + + delete object; + object = 0; + + QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(object)); + QVERIFY(item.boundingRect().isEmpty()); +} + +void tst_QGraphicsVideoItem::setMediaObject() +{ + QMediaObject *nullObject = 0; + QtTestVideoObject object(new QtTestRendererControl); + + QGraphicsVideoItem item; + + QCOMPARE(item.mediaObject(), nullObject); + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + item.setMediaObject(&object); + QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object)); + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); + QVERIFY(object.testService->rendererControl->surface() != 0); + + item.setMediaObject(0); + QCOMPARE(item.mediaObject(), nullObject); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + item.setVisible(false); + + item.setMediaObject(&object); + QCOMPARE(item.mediaObject(), static_cast<QMediaObject *>(&object)); + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + QVERIFY(object.testService->rendererControl->surface() != 0); +} + +void tst_QGraphicsVideoItem::show() +{ + QtTestVideoObject object(new QtTestRendererControl); + QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; + item->setMediaObject(&object); + + // Graphics items are visible by default + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); + QVERIFY(object.testService->rendererControl->surface() != 0); + + item->hide(); + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); + + item->show(); + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); + QVERIFY(object.testService->rendererControl->surface() != 0); + + QVERIFY(item->boundingRect().isEmpty()); + + QVideoSurfaceFormat format(QSize(320,240),QVideoFrame::Format_RGB32); + QVERIFY(object.testService->rendererControl->surface()->start(format)); + + QVERIFY(!item->boundingRect().isEmpty()); + + QGraphicsScene graphicsScene; + graphicsScene.addItem(item); + QGraphicsView graphicsView(&graphicsScene); + graphicsView.show(); + + QVERIFY(item->paintCount() || item->waitForPaint(1)); +} + +void tst_QGraphicsVideoItem::aspectRatioMode() +{ + QGraphicsVideoItem item; + + QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatio); + + item.setAspectRatioMode(Qt::IgnoreAspectRatio); + QCOMPARE(item.aspectRatioMode(), Qt::IgnoreAspectRatio); + + item.setAspectRatioMode(Qt::KeepAspectRatioByExpanding); + QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatioByExpanding); + + item.setAspectRatioMode(Qt::KeepAspectRatio); + QCOMPARE(item.aspectRatioMode(), Qt::KeepAspectRatio); +} + +void tst_QGraphicsVideoItem::offset() +{ + QGraphicsVideoItem item; + + QCOMPARE(item.offset(), QPointF(0, 0)); + + item.setOffset(QPointF(-32.4, 43.0)); + QCOMPARE(item.offset(), QPointF(-32.4, 43.0)); + + item.setOffset(QPointF(1, 1)); + QCOMPARE(item.offset(), QPointF(1, 1)); + + item.setOffset(QPointF(12, -30.4)); + QCOMPARE(item.offset(), QPointF(12, -30.4)); + + item.setOffset(QPointF(-90.4, -75)); + QCOMPARE(item.offset(), QPointF(-90.4, -75)); +} + +void tst_QGraphicsVideoItem::size() +{ + QGraphicsVideoItem item; + + QCOMPARE(item.size(), QSizeF(320, 240)); + + item.setSize(QSizeF(542.5, 436.3)); + QCOMPARE(item.size(), QSizeF(542.5, 436.3)); + + item.setSize(QSizeF(-43, 12)); + QCOMPARE(item.size(), QSizeF(0, 0)); + + item.setSize(QSizeF(54, -9)); + QCOMPARE(item.size(), QSizeF(0, 0)); + + item.setSize(QSizeF(-90, -65)); + QCOMPARE(item.size(), QSizeF(0, 0)); + + item.setSize(QSizeF(1000, 1000)); + QCOMPARE(item.size(), QSizeF(1000, 1000)); +} + +void tst_QGraphicsVideoItem::nativeSize_data() +{ + QTest::addColumn<QSize>("frameSize"); + QTest::addColumn<QRect>("viewport"); + QTest::addColumn<QSize>("pixelAspectRatio"); + QTest::addColumn<QSizeF>("nativeSize"); + + QTest::newRow("640x480") + << QSize(640, 480) + << QRect(0, 0, 640, 480) + << QSize(1, 1) + << QSizeF(640, 480); + + QTest::newRow("800x600, (80,60, 640x480) viewport") + << QSize(800, 600) + << QRect(80, 60, 640, 480) + << QSize(1, 1) + << QSizeF(640, 480); + + QTest::newRow("800x600, (80,60, 640x480) viewport, 4:3") + << QSize(800, 600) + << QRect(80, 60, 640, 480) + << QSize(4, 3) + << QSizeF(853, 480); +} + +void tst_QGraphicsVideoItem::nativeSize() +{ + QFETCH(QSize, frameSize); + QFETCH(QRect, viewport); + QFETCH(QSize, pixelAspectRatio); + QFETCH(QSizeF, nativeSize); + + QtTestVideoObject object(new QtTestRendererControl); + QGraphicsVideoItem item; + item.setMediaObject(&object); + + QCOMPARE(item.nativeSize(), QSizeF()); + + QSignalSpy spy(&item, SIGNAL(nativeSizeChanged(QSizeF))); + + QVideoSurfaceFormat format(frameSize, QVideoFrame::Format_ARGB32); + format.setViewport(viewport); + format.setPixelAspectRatio(pixelAspectRatio); + + QVERIFY(object.testService->rendererControl->surface()->start(format)); + + QCOMPARE(item.nativeSize(), nativeSize); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.last().first().toSizeF(), nativeSize); + + object.testService->rendererControl->surface()->stop(); + + QCOMPARE(item.nativeSize(), QSizeF(0, 0)); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.last().first().toSizeF(), QSizeF(0, 0)); +} + +void tst_QGraphicsVideoItem::boundingRect_data() +{ + QTest::addColumn<QSize>("frameSize"); + QTest::addColumn<QPointF>("offset"); + QTest::addColumn<QSizeF>("size"); + QTest::addColumn<Qt::AspectRatioMode>("aspectRatioMode"); + QTest::addColumn<QRectF>("expectedRect"); + + + QTest::newRow("640x480: (0,0 640x480), Keep") + << QSize(640, 480) + << QPointF(0, 0) + << QSizeF(640, 480) + << Qt::KeepAspectRatio + << QRectF(0, 0, 640, 480); + + QTest::newRow("800x600, (0,0, 640x480), Keep") + << QSize(800, 600) + << QPointF(0, 0) + << QSizeF(640, 480) + << Qt::KeepAspectRatio + << QRectF(0, 0, 640, 480); + + QTest::newRow("800x600, (0,0, 640x480), KeepByExpanding") + << QSize(800, 600) + << QPointF(0, 0) + << QSizeF(640, 480) + << Qt::KeepAspectRatioByExpanding + << QRectF(0, 0, 640, 480); + + QTest::newRow("800x600, (0,0, 640x480), Ignore") + << QSize(800, 600) + << QPointF(0, 0) + << QSizeF(640, 480) + << Qt::IgnoreAspectRatio + << QRectF(0, 0, 640, 480); + + QTest::newRow("800x600, (100,100, 640x480), Keep") + << QSize(800, 600) + << QPointF(100, 100) + << QSizeF(640, 480) + << Qt::KeepAspectRatio + << QRectF(100, 100, 640, 480); + + QTest::newRow("800x600, (100,-100, 640x480), KeepByExpanding") + << QSize(800, 600) + << QPointF(100, -100) + << QSizeF(640, 480) + << Qt::KeepAspectRatioByExpanding + << QRectF(100, -100, 640, 480); + + QTest::newRow("800x600, (-100,-100, 640x480), Ignore") + << QSize(800, 600) + << QPointF(-100, -100) + << QSizeF(640, 480) + << Qt::IgnoreAspectRatio + << QRectF(-100, -100, 640, 480); + + QTest::newRow("800x600, (0,0, 1920x1024), Keep") + << QSize(800, 600) + << QPointF(0, 0) + << QSizeF(1920, 1024) + << Qt::KeepAspectRatio + << QRectF(832.0 / 3, 0, 4096.0 / 3, 1024); + + QTest::newRow("800x600, (0,0, 1920x1024), KeepByExpanding") + << QSize(800, 600) + << QPointF(0, 0) + << QSizeF(1920, 1024) + << Qt::KeepAspectRatioByExpanding + << QRectF(0, 0, 1920, 1024); + + QTest::newRow("800x600, (0,0, 1920x1024), Ignore") + << QSize(800, 600) + << QPointF(0, 0) + << QSizeF(1920, 1024) + << Qt::IgnoreAspectRatio + << QRectF(0, 0, 1920, 1024); + + QTest::newRow("800x600, (100,100, 1920x1024), Keep") + << QSize(800, 600) + << QPointF(100, 100) + << QSizeF(1920, 1024) + << Qt::KeepAspectRatio + << QRectF(100 + 832.0 / 3, 100, 4096.0 / 3, 1024); + + QTest::newRow("800x600, (100,-100, 1920x1024), KeepByExpanding") + << QSize(800, 600) + << QPointF(100, -100) + << QSizeF(1920, 1024) + << Qt::KeepAspectRatioByExpanding + << QRectF(100, -100, 1920, 1024); + + QTest::newRow("800x600, (-100,-100, 1920x1024), Ignore") + << QSize(800, 600) + << QPointF(-100, -100) + << QSizeF(1920, 1024) + << Qt::IgnoreAspectRatio + << QRectF(-100, -100, 1920, 1024); +} + +void tst_QGraphicsVideoItem::boundingRect() +{ + QFETCH(QSize, frameSize); + QFETCH(QPointF, offset); + QFETCH(QSizeF, size); + QFETCH(Qt::AspectRatioMode, aspectRatioMode); + QFETCH(QRectF, expectedRect); + + QtTestVideoObject object(new QtTestRendererControl); + QGraphicsVideoItem item; + item.setMediaObject(&object); + + item.setOffset(offset); + item.setSize(size); + item.setAspectRatioMode(aspectRatioMode); + + QVideoSurfaceFormat format(frameSize, QVideoFrame::Format_ARGB32); + + QVERIFY(object.testService->rendererControl->surface()->start(format)); + + QCOMPARE(item.boundingRect(), expectedRect); +} + +static const uchar rgb32ImageData[] = +{ + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00 +}; + +void tst_QGraphicsVideoItem::paint() +{ + QtTestVideoObject object(new QtTestRendererControl); + QtTestGraphicsVideoItem *item = new QtTestGraphicsVideoItem; + item->setMediaObject(&object); + + QGraphicsScene graphicsScene; + graphicsScene.addItem(item); + QGraphicsView graphicsView(&graphicsScene); + graphicsView.show(); + + QPainterVideoSurface *surface = qobject_cast<QPainterVideoSurface *>( + object.testService->rendererControl->surface()); + + QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32); + + QVERIFY(surface->start(format)); + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), true); + + QVERIFY(item->waitForPaint(1)); + + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), true); + + QVideoFrame frame(sizeof(rgb32ImageData), QSize(2, 2), 8, QVideoFrame::Format_RGB32); + + frame.map(QAbstractVideoBuffer::WriteOnly); + memcpy(frame.bits(), rgb32ImageData, frame.mappedBytes()); + frame.unmap(); + + QVERIFY(surface->present(frame)); + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), false); + + QVERIFY(item->waitForPaint(1)); + + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), true); +} + + +QTEST_MAIN(tst_QGraphicsVideoItem) + +#include "tst_qgraphicsvideoitem.moc" diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp index 3dc4dad..5a87154 100644 --- a/tests/auto/qlocale/tst_qlocale.cpp +++ b/tests/auto/qlocale/tst_qlocale.cpp @@ -1017,6 +1017,9 @@ void tst_QLocale::toDateTime_data() QTest::newRow("RFC-1123") << "C" << QDateTime(QDate(2007, 11, 1), QTime(18, 8, 30)) << "ddd, dd MMM yyyy hh:mm:ss 'GMT'" << "Thu, 01 Nov 2007 18:08:30 GMT"; + + QTest::newRow("longFormat") << "en_US" << QDateTime(QDate(2009, 1, 5), QTime(11, 48, 32)) + << "dddd, MMMM d, yyyy h:mm:ss AP " << "Monday, January 5, 2009 11:48:32 AM "; } void tst_QLocale::toDateTime() @@ -1028,6 +1031,8 @@ void tst_QLocale::toDateTime() QLocale l(localeName); QCOMPARE(l.toDateTime(string, format), result); + if (l.dateTimeFormat(QLocale::LongFormat) == format) + QCOMPARE(l.toDateTime(string, QLocale::LongFormat), result); } void tst_QLocale::macDefaultLocale() diff --git a/tests/auto/qmediacontent/qmediacontent.pro b/tests/auto/qmediacontent/qmediacontent.pro new file mode 100644 index 0000000..f7884f6 --- /dev/null +++ b/tests/auto/qmediacontent/qmediacontent.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES += tst_qmediacontent.cpp + +QT = core multimedia + diff --git a/tests/auto/qmediacontent/tst_qmediacontent.cpp b/tests/auto/qmediacontent/tst_qmediacontent.cpp new file mode 100644 index 0000000..35dd0a9 --- /dev/null +++ b/tests/auto/qmediacontent/tst_qmediacontent.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtMultimedia/qmediacontent.h> + + +class tst_QMediaContent : public QObject +{ + Q_OBJECT + +private slots: + void testNull(); + void testUrlCtor(); + void testResourceCtor(); + void testResourceListCtor(); + void testCopy(); + void testAssignment(); + void testEquality(); + void testResources(); +}; + +void tst_QMediaContent::testNull() +{ + QMediaContent media; + + QCOMPARE(media.isNull(), true); + QCOMPARE(media.canonicalUrl(), QUrl()); + QCOMPARE(media.canonicalResource(), QMediaResource()); + QCOMPARE(media.resources(), QMediaResourceList()); +} + +void tst_QMediaContent::testUrlCtor() +{ + QMediaContent media(QUrl("http://example.com/movie.mov")); + + QCOMPARE(media.canonicalUrl(), QUrl("http://example.com/movie.mov")); + QCOMPARE(media.canonicalResource().url(), QUrl("http://example.com/movie.mov")); +} + +void tst_QMediaContent::testResourceCtor() +{ + QMediaContent media(QMediaResource(QUrl("http://example.com/movie.mov"))); + + QCOMPARE(media.canonicalResource(), QMediaResource(QUrl("http://example.com/movie.mov"))); +} + +void tst_QMediaContent::testResourceListCtor() +{ + QMediaResourceList resourceList; + resourceList << QMediaResource(QUrl("http://example.com/movie.mov")); + + QMediaContent media(resourceList); + + QCOMPARE(media.canonicalUrl(), QUrl("http://example.com/movie.mov")); + QCOMPARE(media.canonicalResource().url(), QUrl("http://example.com/movie.mov")); +} + +void tst_QMediaContent::testCopy() +{ + QMediaContent media1(QMediaResource(QUrl("http://example.com/movie.mov"))); + QMediaContent media2(media1); + + QVERIFY(media1 == media2); +} + +void tst_QMediaContent::testAssignment() +{ + QMediaContent media1(QMediaResource(QUrl("http://example.com/movie.mov"))); + QMediaContent media2; + QMediaContent media3; + + media2 = media1; + QVERIFY(media2 == media1); + + media2 = media3; + QVERIFY(media2 == media3); +} + +void tst_QMediaContent::testEquality() +{ + QMediaContent media1; + QMediaContent media2; + QMediaContent media3(QMediaResource(QUrl("http://example.com/movie.mov"))); + QMediaContent media4(QMediaResource(QUrl("http://example.com/movie.mov"))); + QMediaContent media5(QMediaResource(QUrl("file:///some/where/over/the/rainbow.mp3"))); + + // null == null + QCOMPARE(media1 == media2, true); + QCOMPARE(media1 != media2, false); + + // null != something + QCOMPARE(media1 == media3, false); + QCOMPARE(media1 != media3, true); + + // equiv + QCOMPARE(media3 == media4, true); + QCOMPARE(media3 != media4, false); + + // not equiv + QCOMPARE(media4 == media5, false); + QCOMPARE(media4 != media5, true); +} + +void tst_QMediaContent::testResources() +{ + QMediaResourceList resourceList; + + resourceList << QMediaResource(QUrl("http://example.com/movie-main.mov")); + resourceList << QMediaResource(QUrl("http://example.com/movie-big.mov")); + QMediaContent media(resourceList); + + QMediaResourceList res = media.resources(); + QCOMPARE(res.size(), 2); + QCOMPARE(res[0], QMediaResource(QUrl("http://example.com/movie-main.mov"))); + QCOMPARE(res[1], QMediaResource(QUrl("http://example.com/movie-big.mov"))); +} + +QTEST_MAIN(tst_QMediaContent) + +#include "tst_qmediacontent.moc" diff --git a/tests/auto/qmediaobject/qmediaobject.pro b/tests/auto/qmediaobject/qmediaobject.pro new file mode 100644 index 0000000..e59bfdc --- /dev/null +++ b/tests/auto/qmediaobject/qmediaobject.pro @@ -0,0 +1,4 @@ +load(qttest_p4) + +SOURCES += tst_qmediaobject.cpp +QT = core multimedia diff --git a/tests/auto/qmediaobject/tst_qmediaobject.cpp b/tests/auto/qmediaobject/tst_qmediaobject.cpp new file mode 100644 index 0000000..2128b35 --- /dev/null +++ b/tests/auto/qmediaobject/tst_qmediaobject.cpp @@ -0,0 +1,549 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtCore/qtimer.h> + +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmetadatacontrol.h> + + +class tst_QMediaObject : public QObject +{ + Q_OBJECT + +private slots: + void propertyWatch(); + void notifySignals_data(); + void notifySignals(); + void notifyInterval_data(); + void notifyInterval(); + + void nullMetaDataControl(); + void isMetaDataAvailable(); + void isWritable(); + void metaDataChanged(); + void metaData_data(); + void metaData(); + void setMetaData_data(); + void setMetaData(); + void extendedMetaData_data() { metaData_data(); } + void extendedMetaData(); + void setExtendedMetaData_data() { extendedMetaData_data(); } + void setExtendedMetaData(); + + +private: + void setupNotifyTests(); +}; + +class QtTestMetaDataProvider : public QMetaDataControl +{ + Q_OBJECT +public: + QtTestMetaDataProvider(QObject *parent = 0) + : QMetaDataControl(parent) + , m_available(false) + , m_writable(false) + { + } + + bool isMetaDataAvailable() const { return m_available; } + void setMetaDataAvailable(bool available) { + if (m_available != available) + emit metaDataAvailableChanged(m_available = available); + } + QList<QtMultimedia::MetaData> availableMetaData() const { return m_data.keys(); } + + bool isWritable() const { return m_writable; } + void setWritable(bool writable) { emit writableChanged(m_writable = writable); } + + QVariant metaData(QtMultimedia::MetaData key) const { return m_data.value(key); } + void setMetaData(QtMultimedia::MetaData key, const QVariant &value) { + m_data.insert(key, value); } + + QVariant extendedMetaData(const QString &key) const { return m_extendedData.value(key); } + void setExtendedMetaData(const QString &key, const QVariant &value) { + m_extendedData.insert(key, value); } + + QStringList availableExtendedMetaData() const { return m_extendedData.keys(); } + + using QMetaDataControl::metaDataChanged; + + void populateMetaData() + { + m_available = true; + } + + bool m_available; + bool m_writable; + QMap<QtMultimedia::MetaData, QVariant> m_data; + QMap<QString, QVariant> m_extendedData; +}; + +class QtTestMetaDataService : public QMediaService +{ + Q_OBJECT +public: + QtTestMetaDataService(QObject *parent = 0):QMediaService(parent), hasMetaData(true) + { + } + + QMediaControl *control(const char *iid) const + { + if (hasMetaData && qstrcmp(iid, QMetaDataControl_iid) == 0) + return const_cast<QtTestMetaDataProvider *>(&metaData); + else + return 0; + } + + QtTestMetaDataProvider metaData; + bool hasMetaData; +}; + + +class QtTestMediaObject : public QMediaObject +{ + Q_OBJECT + Q_PROPERTY(int a READ a WRITE setA NOTIFY aChanged) + Q_PROPERTY(int b READ b WRITE setB NOTIFY bChanged) + Q_PROPERTY(int c READ c WRITE setC NOTIFY cChanged) + Q_PROPERTY(int d READ d WRITE setD) +public: + QtTestMediaObject(QMediaService *service = 0): QMediaObject(0, service), m_a(0), m_b(0), m_c(0), m_d(0) {} + + using QMediaObject::addPropertyWatch; + using QMediaObject::removePropertyWatch; + + int a() const { return m_a; } + void setA(int a) { m_a = a; } + + int b() const { return m_b; } + void setB(int b) { m_b = b; } + + int c() const { return m_c; } + void setC(int c) { m_c = c; } + + int d() const { return m_d; } + void setD(int d) { m_d = d; } + +Q_SIGNALS: + void aChanged(int a); + void bChanged(int b); + void cChanged(int c); + +private: + int m_a; + int m_b; + int m_c; + int m_d; +}; + +void tst_QMediaObject::propertyWatch() +{ + QtTestMediaObject object; + object.setNotifyInterval(0); + + QEventLoop loop; + connect(&object, SIGNAL(aChanged(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&object, SIGNAL(bChanged(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&object, SIGNAL(cChanged(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QSignalSpy aSpy(&object, SIGNAL(aChanged(int))); + QSignalSpy bSpy(&object, SIGNAL(bChanged(int))); + QSignalSpy cSpy(&object, SIGNAL(cChanged(int))); + + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(aSpy.count(), 0); + QCOMPARE(bSpy.count(), 0); + QCOMPARE(cSpy.count(), 0); + + int aCount = 0; + int bCount = 0; + int cCount = 0; + + object.addPropertyWatch("a"); + + QTestEventLoop::instance().enterLoop(1); + + QVERIFY(aSpy.count() > aCount); + QCOMPARE(bSpy.count(), 0); + QCOMPARE(cSpy.count(), 0); + QCOMPARE(aSpy.last().value(0).toInt(), 0); + + aCount = aSpy.count(); + + object.setA(54); + object.setB(342); + object.setC(233); + + QTestEventLoop::instance().enterLoop(1); + + QVERIFY(aSpy.count() > aCount); + QCOMPARE(bSpy.count(), 0); + QCOMPARE(cSpy.count(), 0); + QCOMPARE(aSpy.last().value(0).toInt(), 54); + + aCount = aSpy.count(); + + object.addPropertyWatch("b"); + object.addPropertyWatch("d"); + object.removePropertyWatch("e"); + object.setA(43); + object.setB(235); + object.setC(90); + + QTestEventLoop::instance().enterLoop(1); + + QVERIFY(aSpy.count() > aCount); + QVERIFY(bSpy.count() > bCount); + QCOMPARE(cSpy.count(), 0); + QCOMPARE(aSpy.last().value(0).toInt(), 43); + QCOMPARE(bSpy.last().value(0).toInt(), 235); + + aCount = aSpy.count(); + bCount = bSpy.count(); + + object.removePropertyWatch("a"); + object.addPropertyWatch("c"); + object.addPropertyWatch("e"); + + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(aSpy.count(), aCount); + QVERIFY(bSpy.count() > bCount); + QVERIFY(cSpy.count() > cCount); + QCOMPARE(bSpy.last().value(0).toInt(), 235); + QCOMPARE(cSpy.last().value(0).toInt(), 90); + + bCount = bSpy.count(); + cCount = cSpy.count(); + + object.setA(435); + object.setC(9845); + + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(aSpy.count(), aCount); + QVERIFY(bSpy.count() > bCount); + QVERIFY(cSpy.count() > cCount); + QCOMPARE(bSpy.last().value(0).toInt(), 235); + QCOMPARE(cSpy.last().value(0).toInt(), 9845); + + bCount = bSpy.count(); + cCount = cSpy.count(); + + object.setA(8432); + object.setB(324); + object.setC(443); + object.removePropertyWatch("c"); + object.removePropertyWatch("d"); + + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(aSpy.count(), aCount); + QVERIFY(bSpy.count() > bCount); + QCOMPARE(cSpy.count(), cCount); + QCOMPARE(bSpy.last().value(0).toInt(), 324); + QCOMPARE(cSpy.last().value(0).toInt(), 9845); + + bCount = bSpy.count(); + + object.removePropertyWatch("b"); + + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(aSpy.count(), aCount); + QCOMPARE(bSpy.count(), bCount); + QCOMPARE(cSpy.count(), cCount); +} + +void tst_QMediaObject::setupNotifyTests() +{ + QTest::addColumn<int>("interval"); + QTest::addColumn<int>("count"); + + QTest::newRow("single 750ms") + << 750 + << 1; + QTest::newRow("single 600ms") + << 600 + << 1; + QTest::newRow("x3 300ms") + << 300 + << 3; + QTest::newRow("x5 180ms") + << 180 + << 5; +} + +void tst_QMediaObject::notifySignals_data() +{ + setupNotifyTests(); +} + +void tst_QMediaObject::notifySignals() +{ + QFETCH(int, interval); + QFETCH(int, count); + + QtTestMediaObject object; + object.setNotifyInterval(interval); + object.addPropertyWatch("a"); + + QSignalSpy spy(&object, SIGNAL(aChanged(int))); + + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(spy.count(), count); +} + +void tst_QMediaObject::notifyInterval_data() +{ + setupNotifyTests(); +} + +void tst_QMediaObject::notifyInterval() +{ + QFETCH(int, interval); + + QtTestMediaObject object; + QSignalSpy spy(&object, SIGNAL(notifyIntervalChanged(int))); + + object.setNotifyInterval(interval); + QCOMPARE(object.notifyInterval(), interval); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.last().value(0).toInt(), interval); + + object.setNotifyInterval(interval); + QCOMPARE(object.notifyInterval(), interval); + QCOMPARE(spy.count(), 1); +} + +void tst_QMediaObject::nullMetaDataControl() +{ + const QString titleKey(QLatin1String("Title")); + const QString title(QLatin1String("Host of Seraphim")); + + QtTestMetaDataService service; + service.hasMetaData = false; + + QtTestMediaObject object(&service); + + QSignalSpy spy(&object, SIGNAL(metaDataChanged())); + + QCOMPARE(object.isMetaDataAvailable(), false); + QCOMPARE(object.isMetaDataWritable(), false); + + object.setMetaData(QtMultimedia::Title, title); + object.setExtendedMetaData(titleKey, title); + + QCOMPARE(object.metaData(QtMultimedia::Title).toString(), QString()); + QCOMPARE(object.extendedMetaData(titleKey).toString(), QString()); + QCOMPARE(object.availableMetaData(), QList<QtMultimedia::MetaData>()); + QCOMPARE(object.availableExtendedMetaData(), QStringList()); + QCOMPARE(spy.count(), 0); +} + +void tst_QMediaObject::isMetaDataAvailable() +{ + QtTestMetaDataService service; + service.metaData.setMetaDataAvailable(false); + + QtTestMediaObject object(&service); + QCOMPARE(object.isMetaDataAvailable(), false); + + QSignalSpy spy(&object, SIGNAL(metaDataAvailableChanged(bool))); + service.metaData.setMetaDataAvailable(true); + + QCOMPARE(object.isMetaDataAvailable(), true); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + + service.metaData.setMetaDataAvailable(false); + + QCOMPARE(object.isMetaDataAvailable(), false); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.at(1).at(0).toBool(), false); +} + +void tst_QMediaObject::isWritable() +{ + QtTestMetaDataService service; + service.metaData.setWritable(false); + + QtTestMediaObject object(&service); + + QSignalSpy spy(&object, SIGNAL(metaDataWritableChanged(bool))); + + QCOMPARE(object.isMetaDataWritable(), false); + + service.metaData.setWritable(true); + + QCOMPARE(object.isMetaDataWritable(), true); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + + service.metaData.setWritable(false); + + QCOMPARE(object.isMetaDataWritable(), false); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.at(1).at(0).toBool(), false); +} + +void tst_QMediaObject::metaDataChanged() +{ + QtTestMetaDataService service; + QtTestMediaObject object(&service); + + QSignalSpy spy(&object, SIGNAL(metaDataChanged())); + + service.metaData.metaDataChanged(); + QCOMPARE(spy.count(), 1); + + service.metaData.metaDataChanged(); + QCOMPARE(spy.count(), 2); +} + +void tst_QMediaObject::metaData_data() +{ + QTest::addColumn<QString>("artist"); + QTest::addColumn<QString>("title"); + QTest::addColumn<QString>("genre"); + + QTest::newRow("") + << QString::fromLatin1("Dead Can Dance") + << QString::fromLatin1("Host of Seraphim") + << QString::fromLatin1("Awesome"); +} + +void tst_QMediaObject::metaData() +{ + QFETCH(QString, artist); + QFETCH(QString, title); + QFETCH(QString, genre); + + QtTestMetaDataService service; + service.metaData.populateMetaData(); + + QtTestMediaObject object(&service); + QVERIFY(object.availableMetaData().isEmpty()); + + service.metaData.m_data.insert(QtMultimedia::AlbumArtist, artist); + service.metaData.m_data.insert(QtMultimedia::Title, title); + service.metaData.m_data.insert(QtMultimedia::Genre, genre); + + QCOMPARE(object.metaData(QtMultimedia::AlbumArtist).toString(), artist); + QCOMPARE(object.metaData(QtMultimedia::Title).toString(), title); + + QList<QtMultimedia::MetaData> metaDataKeys = object.availableMetaData(); + QCOMPARE(metaDataKeys.size(), 3); + QVERIFY(metaDataKeys.contains(QtMultimedia::AlbumArtist)); + QVERIFY(metaDataKeys.contains(QtMultimedia::Title)); + QVERIFY(metaDataKeys.contains(QtMultimedia::Genre)); +} + +void tst_QMediaObject::setMetaData_data() +{ + QTest::addColumn<QString>("title"); + + QTest::newRow("") + << QString::fromLatin1("In the Kingdom of the Blind the One eyed are Kings"); +} + +void tst_QMediaObject::setMetaData() +{ + QFETCH(QString, title); + + QtTestMetaDataService service; + service.metaData.populateMetaData(); + + QtTestMediaObject object(&service); + + object.setMetaData(QtMultimedia::Title, title); + QCOMPARE(object.metaData(QtMultimedia::Title).toString(), title); + QCOMPARE(service.metaData.m_data.value(QtMultimedia::Title).toString(), title); +} + +void tst_QMediaObject::extendedMetaData() +{ + QFETCH(QString, artist); + QFETCH(QString, title); + QFETCH(QString, genre); + + QtTestMetaDataService service; + QtTestMediaObject object(&service); + QVERIFY(object.availableExtendedMetaData().isEmpty()); + + service.metaData.m_extendedData.insert(QLatin1String("Artist"), artist); + service.metaData.m_extendedData.insert(QLatin1String("Title"), title); + service.metaData.m_extendedData.insert(QLatin1String("Genre"), genre); + + QCOMPARE(object.extendedMetaData(QLatin1String("Artist")).toString(), artist); + QCOMPARE(object.extendedMetaData(QLatin1String("Title")).toString(), title); + + QStringList extendedKeys = object.availableExtendedMetaData(); + QCOMPARE(extendedKeys.size(), 3); + QVERIFY(extendedKeys.contains(QLatin1String("Artist"))); + QVERIFY(extendedKeys.contains(QLatin1String("Title"))); + QVERIFY(extendedKeys.contains(QLatin1String("Genre"))); +} + +void tst_QMediaObject::setExtendedMetaData() +{ + QtTestMetaDataService service; + service.metaData.populateMetaData(); + + QtTestMediaObject object(&service); + + QString title(QLatin1String("In the Kingdom of the Blind the One eyed are Kings")); + + object.setExtendedMetaData(QLatin1String("Title"), title); + QCOMPARE(object.extendedMetaData(QLatin1String("Title")).toString(), title); + QCOMPARE(service.metaData.m_extendedData.value(QLatin1String("Title")).toString(), title); +} + +QTEST_MAIN(tst_QMediaObject) + +#include "tst_qmediaobject.moc" diff --git a/tests/auto/qmediaplayer/qmediaplayer.pro b/tests/auto/qmediaplayer/qmediaplayer.pro new file mode 100644 index 0000000..21008f9 --- /dev/null +++ b/tests/auto/qmediaplayer/qmediaplayer.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES += tst_qmediaplayer.cpp + +QT = core multimedia + diff --git a/tests/auto/qmediaplayer/tst_qmediaplayer.cpp b/tests/auto/qmediaplayer/tst_qmediaplayer.cpp new file mode 100644 index 0000000..a96e08d --- /dev/null +++ b/tests/auto/qmediaplayer/tst_qmediaplayer.cpp @@ -0,0 +1,986 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/qdebug.h> +#include <QtCore/qbuffer.h> + +#include <QtMultimedia/qmediaplayer.h> +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaplaylist.h> +#include <QtMultimedia/qmediaservice.h> + + + +class AutoConnection +{ +public: + AutoConnection(QObject *sender, const char *signal, QObject *receiver, const char *method) + : sender(sender), signal(signal), receiver(receiver), method(method) + { + QObject::connect(sender, signal, receiver, method); + } + + ~AutoConnection() + { + QObject::disconnect(sender, signal, receiver, method); + } + +private: + QObject *sender; + const char *signal; + QObject *receiver; + const char *method; +}; + + +class MockPlayerControl : public QMediaPlayerControl +{ + friend class MockPlayerService; + +public: + MockPlayerControl():QMediaPlayerControl(0) {} + + QMediaPlayer::State state() const { return _state; } + QMediaPlayer::MediaStatus mediaStatus() const { return _mediaStatus; } + + qint64 duration() const { return _duration; } + + qint64 position() const { return _position; } + + void setPosition(qint64 position) { if (position != _position) emit positionChanged(_position = position); } + + int volume() const { return _volume; } + void setVolume(int volume) { emit volumeChanged(_volume = volume); } + + bool isMuted() const { return _muted; } + void setMuted(bool muted) { if (muted != _muted) emit mutedChanged(_muted = muted); } + + int bufferStatus() const { return _bufferStatus; } + + bool isAudioAvailable() const { return _audioAvailable; } + bool isVideoAvailable() const { return _videoAvailable; } + + bool isSeekable() const { return _isSeekable; } + QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(_seekRange.first, _seekRange.second); } + void setSeekRange(qint64 minimum, qint64 maximum) { _seekRange = qMakePair(minimum, maximum); } + + qreal playbackRate() const { return _playbackRate; } + void setPlaybackRate(qreal rate) { if (rate != _playbackRate) emit playbackRateChanged(_playbackRate = rate); } + + QMediaContent media() const { return _media; } + void setMedia(const QMediaContent &content, QIODevice *stream) + { + _stream = stream; + _media = content; + if (_state != QMediaPlayer::StoppedState) { + _mediaStatus = _media.isNull() ? QMediaPlayer::NoMedia : QMediaPlayer::LoadingMedia; + emit stateChanged(_state = QMediaPlayer::StoppedState); + emit mediaStatusChanged(_mediaStatus); + } + emit mediaChanged(_media = content); + } + QIODevice *mediaStream() const { return _stream; } + + void play() { if (_isValid && !_media.isNull() && _state != QMediaPlayer::PlayingState) emit stateChanged(_state = QMediaPlayer::PlayingState); } + void pause() { if (_isValid && !_media.isNull() && _state != QMediaPlayer::PausedState) emit stateChanged(_state = QMediaPlayer::PausedState); } + void stop() { if (_state != QMediaPlayer::StoppedState) emit stateChanged(_state = QMediaPlayer::StoppedState); } + + QMediaPlayer::State _state; + QMediaPlayer::MediaStatus _mediaStatus; + QMediaPlayer::Error _error; + qint64 _duration; + qint64 _position; + int _volume; + bool _muted; + int _bufferStatus; + bool _audioAvailable; + bool _videoAvailable; + bool _isSeekable; + QPair<qint64, qint64> _seekRange; + qreal _playbackRate; + QMediaContent _media; + QIODevice *_stream; + bool _isValid; + QString _errorString; +}; + + +class MockPlayerService : public QMediaService +{ + Q_OBJECT + +public: + MockPlayerService():QMediaService(0) + { + mockControl = new MockPlayerControl; + } + + ~MockPlayerService() + { + delete mockControl; + } + + QMediaControl* control(const char *iid) const + { + if (qstrcmp(iid, QMediaPlayerControl_iid) == 0) + return mockControl; + + return 0; + } + + void setState(QMediaPlayer::State state) { emit mockControl->stateChanged(mockControl->_state = state); } + void setState(QMediaPlayer::State state, QMediaPlayer::MediaStatus status) { + mockControl->_state = state; + mockControl->_mediaStatus = status; + emit mockControl->mediaStatusChanged(status); + emit mockControl->stateChanged(state); + } + void setMediaStatus(QMediaPlayer::MediaStatus status) { emit mockControl->mediaStatusChanged(mockControl->_mediaStatus = status); } + void setIsValid(bool isValid) { mockControl->_isValid = isValid; } + void setMedia(QMediaContent media) { mockControl->_media = media; } + void setDuration(qint64 duration) { mockControl->_duration = duration; } + void setPosition(qint64 position) { mockControl->_position = position; } + void setSeekable(bool seekable) { mockControl->_isSeekable = seekable; } + void setVolume(int volume) { mockControl->_volume = volume; } + void setMuted(bool muted) { mockControl->_muted = muted; } + void setVideoAvailable(bool videoAvailable) { mockControl->_videoAvailable = videoAvailable; } + void setBufferStatus(int bufferStatus) { mockControl->_bufferStatus = bufferStatus; } + void setPlaybackRate(qreal playbackRate) { mockControl->_playbackRate = playbackRate; } + void setError(QMediaPlayer::Error error) { mockControl->_error = error; emit mockControl->error(mockControl->_error, mockControl->_errorString); } + void setErrorString(QString errorString) { mockControl->_errorString = errorString; emit mockControl->error(mockControl->_error, mockControl->_errorString); } + + void reset() + { + mockControl->_state = QMediaPlayer::StoppedState; + mockControl->_mediaStatus = QMediaPlayer::UnknownMediaStatus; + mockControl->_error = QMediaPlayer::NoError; + mockControl->_duration = 0; + mockControl->_position = 0; + mockControl->_volume = 0; + mockControl->_muted = false; + mockControl->_bufferStatus = 0; + mockControl->_videoAvailable = false; + mockControl->_isSeekable = false; + mockControl->_playbackRate = 0.0; + mockControl->_media = QMediaContent(); + mockControl->_stream = 0; + mockControl->_isValid = false; + mockControl->_errorString = QString(); + } + + MockPlayerControl *mockControl; +}; + +class MockProvider : public QMediaServiceProvider +{ +public: + MockProvider(MockPlayerService *service):mockService(service) {} + QMediaService *requestService(const QByteArray &, const QMediaServiceProviderHint &) + { + return mockService; + } + + void releaseService(QMediaService *service) { delete service; } + + MockPlayerService *mockService; +}; + +class tst_QMediaPlayer: public QObject +{ + Q_OBJECT + +public slots: + void initTestCase_data(); + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void testNullService(); + void testValid(); + void testMedia(); + void testDuration(); + void testPosition(); + void testVolume(); + void testMuted(); + void testVideoAvailable(); + void testBufferStatus(); + void testSeekable(); + void testPlaybackRate(); + void testError(); + void testErrorString(); + void testService(); + void testPlay(); + void testPause(); + void testStop(); + void testMediaStatus(); + void testPlaylist(); + +private: + MockProvider *mockProvider; + MockPlayerService *mockService; + QMediaPlayer *player; +}; + +void tst_QMediaPlayer::initTestCase_data() +{ + QTest::addColumn<bool>("valid"); + QTest::addColumn<QMediaPlayer::State>("state"); + QTest::addColumn<QMediaPlayer::MediaStatus>("status"); + QTest::addColumn<QMediaContent>("mediaContent"); + QTest::addColumn<qint64>("duration"); + QTest::addColumn<qint64>("position"); + QTest::addColumn<bool>("seekable"); + QTest::addColumn<int>("volume"); + QTest::addColumn<bool>("muted"); + QTest::addColumn<bool>("videoAvailable"); + QTest::addColumn<int>("bufferStatus"); + QTest::addColumn<qreal>("playbackRate"); + QTest::addColumn<QMediaPlayer::Error>("error"); + QTest::addColumn<QString>("errorString"); + + QTest::newRow("invalid") << false << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << + QMediaContent() << qint64(0) << qint64(0) << false << 0 << false << false << 0 << + qreal(0) << QMediaPlayer::NoError << QString(); + QTest::newRow("valid+null") << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << + QMediaContent() << qint64(0) << qint64(0) << false << 0 << false << false << 50 << + qreal(0) << QMediaPlayer::NoError << QString(); + QTest::newRow("valid+content+stopped") << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << + QMediaContent(QUrl("file:///some.mp3")) << qint64(0) << qint64(0) << false << 50 << false << false << 0 << + qreal(1) << QMediaPlayer::NoError << QString(); + QTest::newRow("valid+content+playing") << true << QMediaPlayer::PlayingState << QMediaPlayer::LoadedMedia << + QMediaContent(QUrl("file:///some.mp3")) << qint64(10000) << qint64(10) << true << 50 << true << false << 0 << + qreal(1) << QMediaPlayer::NoError << QString(); + QTest::newRow("valid+content+paused") << true << QMediaPlayer::PausedState << QMediaPlayer::LoadedMedia << + QMediaContent(QUrl("file:///some.mp3")) << qint64(10000) << qint64(10) << true << 50 << true << false << 0 << + qreal(1) << QMediaPlayer::NoError << QString(); + QTest::newRow("valud+streaming") << true << QMediaPlayer::PlayingState << QMediaPlayer::LoadedMedia << + QMediaContent(QUrl("http://example.com/stream")) << qint64(10000) << qint64(10000) << false << 50 << false << true << 0 << + qreal(1) << QMediaPlayer::NoError << QString(); + QTest::newRow("valid+error") << true << QMediaPlayer::StoppedState << QMediaPlayer::UnknownMediaStatus << + QMediaContent(QUrl("http://example.com/stream")) << qint64(0) << qint64(0) << false << 50 << false << false << 0 << + qreal(0) << QMediaPlayer::ResourceError << QString("Resource unavailable"); +} + +void tst_QMediaPlayer::initTestCase() +{ + qRegisterMetaType<QMediaContent>(); + + mockService = new MockPlayerService; + mockProvider = new MockProvider(mockService); + player = new QMediaPlayer(0, 0, mockProvider); +} + +void tst_QMediaPlayer::cleanupTestCase() +{ + delete player; +} + +void tst_QMediaPlayer::init() +{ + mockService->reset(); +} + +void tst_QMediaPlayer::cleanup() +{ +} + +void tst_QMediaPlayer::testNullService() +{ + MockProvider provider(0); + QMediaPlayer player(0, 0, &provider); + + const QIODevice *nullDevice = 0; + + QCOMPARE(player.media(), QMediaContent()); + QCOMPARE(player.mediaStream(), nullDevice); + QCOMPARE(player.state(), QMediaPlayer::StoppedState); + QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); + QCOMPARE(player.duration(), qint64(-1)); + QCOMPARE(player.position(), qint64(0)); + QCOMPARE(player.volume(), 0); + QCOMPARE(player.isMuted(), false); + QCOMPARE(player.isVideoAvailable(), false); + QCOMPARE(player.bufferStatus(), 0); + QCOMPARE(player.isSeekable(), false); + QCOMPARE(player.playbackRate(), qreal(0)); + QCOMPARE(player.error(), QMediaPlayer::ServiceMissingError); + + { + QFETCH_GLOBAL(QMediaContent, mediaContent); + + QSignalSpy spy(&player, SIGNAL(mediaChanged(QMediaContent))); + QFile file; + + player.setMedia(mediaContent, &file); + QCOMPARE(player.media(), QMediaContent()); + QCOMPARE(player.mediaStream(), nullDevice); + QCOMPARE(spy.count(), 0); + } { + QSignalSpy stateSpy(&player, SIGNAL(stateChanged(QMediaPlayer::State))); + QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + + player.play(); + QCOMPARE(player.state(), QMediaPlayer::StoppedState); + QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); + QCOMPARE(stateSpy.count(), 0); + QCOMPARE(statusSpy.count(), 0); + + player.pause(); + QCOMPARE(player.state(), QMediaPlayer::StoppedState); + QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); + QCOMPARE(stateSpy.count(), 0); + QCOMPARE(statusSpy.count(), 0); + + player.stop(); + QCOMPARE(player.state(), QMediaPlayer::StoppedState); + QCOMPARE(player.mediaStatus(), QMediaPlayer::UnknownMediaStatus); + QCOMPARE(stateSpy.count(), 0); + QCOMPARE(statusSpy.count(), 0); + } { + QFETCH_GLOBAL(int, volume); + QFETCH_GLOBAL(bool, muted); + + QSignalSpy volumeSpy(&player, SIGNAL(volumeChanged(int))); + QSignalSpy mutingSpy(&player, SIGNAL(mutedChanged(bool))); + + player.setVolume(volume); + QCOMPARE(player.volume(), 0); + QCOMPARE(volumeSpy.count(), 0); + + player.setMuted(muted); + QCOMPARE(player.isMuted(), false); + QCOMPARE(mutingSpy.count(), 0); + } { + QFETCH_GLOBAL(qint64, position); + + QSignalSpy spy(&player, SIGNAL(positionChanged(qint64))); + + player.setPosition(position); + QCOMPARE(player.position(), qint64(0)); + QCOMPARE(spy.count(), 0); + } { + QFETCH_GLOBAL(qreal, playbackRate); + + QSignalSpy spy(&player, SIGNAL(playbackRateChanged(qreal))); + + player.setPlaybackRate(playbackRate); + QCOMPARE(player.playbackRate(), qreal(0)); + QCOMPARE(spy.count(), 0); + } { + QMediaPlaylist playlist; + playlist.setMediaObject(&player); + + QSignalSpy mediaSpy(&player, SIGNAL(mediaChanged(QMediaContent))); + QSignalSpy statusSpy(&player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + + playlist.addMedia(QUrl("http://example.com/stream")); + playlist.addMedia(QUrl("file:///some.mp3")); + + playlist.setCurrentIndex(0); + QCOMPARE(playlist.currentIndex(), 0); + QCOMPARE(player.media(), QMediaContent()); + QCOMPARE(mediaSpy.count(), 0); + QCOMPARE(statusSpy.count(), 0); + + playlist.next(); + QCOMPARE(playlist.currentIndex(), 1); + QCOMPARE(player.media(), QMediaContent()); + QCOMPARE(mediaSpy.count(), 0); + QCOMPARE(statusSpy.count(), 0); + } +} + +void tst_QMediaPlayer::testValid() +{ + /* + QFETCH_GLOBAL(bool, valid); + + mockService->setIsValid(valid); + QCOMPARE(player->isValid(), valid); + */ +} + +void tst_QMediaPlayer::testMedia() +{ + QFETCH_GLOBAL(QMediaContent, mediaContent); + + mockService->setMedia(mediaContent); + QCOMPARE(player->media(), mediaContent); + + QBuffer stream; + player->setMedia(mediaContent, &stream); + QCOMPARE(player->media(), mediaContent); + QCOMPARE((QBuffer*)player->mediaStream(), &stream); +} + +void tst_QMediaPlayer::testDuration() +{ + QFETCH_GLOBAL(qint64, duration); + + mockService->setDuration(duration); + QVERIFY(player->duration() == duration); +} + +void tst_QMediaPlayer::testPosition() +{ + QFETCH_GLOBAL(bool, valid); + QFETCH_GLOBAL(bool, seekable); + QFETCH_GLOBAL(qint64, position); + QFETCH_GLOBAL(qint64, duration); + + mockService->setIsValid(valid); + mockService->setSeekable(seekable); + mockService->setPosition(position); + mockService->setDuration(duration); + QVERIFY(player->isSeekable() == seekable); + QVERIFY(player->position() == position); + QVERIFY(player->duration() == duration); + + if (seekable) { + { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); + player->setPosition(position); + QCOMPARE(player->position(), position); + QCOMPARE(spy.count(), 0); } + + mockService->setPosition(position); + { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); + player->setPosition(0); + QCOMPARE(player->position(), qint64(0)); + QCOMPARE(spy.count(), position == 0 ? 0 : 1); } + + mockService->setPosition(position); + { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); + player->setPosition(duration); + QCOMPARE(player->position(), duration); + QCOMPARE(spy.count(), position == duration ? 0 : 1); } + + mockService->setPosition(position); + { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); + player->setPosition(-1); + QCOMPARE(player->position(), qint64(0)); + QCOMPARE(spy.count(), position == 0 ? 0 : 1); } + + mockService->setPosition(position); + { QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); + player->setPosition(duration + 1); + QCOMPARE(player->position(), duration); + QCOMPARE(spy.count(), position == duration ? 0 : 1); } + } + else { + QSignalSpy spy(player, SIGNAL(positionChanged(qint64))); + player->setPosition(position); + + QCOMPARE(player->position(), position); + QCOMPARE(spy.count(), 0); + } +} + +void tst_QMediaPlayer::testVolume() +{ + QFETCH_GLOBAL(bool, valid); + QFETCH_GLOBAL(int, volume); + + mockService->setVolume(volume); + QVERIFY(player->volume() == volume); + + if (valid) { + { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); + player->setVolume(10); + QCOMPARE(player->volume(), 10); + QCOMPARE(spy.count(), 1); } + + { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); + player->setVolume(-1000); + QCOMPARE(player->volume(), 0); + QCOMPARE(spy.count(), 1); } + + { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); + player->setVolume(100); + QCOMPARE(player->volume(), 100); + QCOMPARE(spy.count(), 1); } + + { QSignalSpy spy(player, SIGNAL(volumeChanged(int))); + player->setVolume(1000); + QCOMPARE(player->volume(), 100); + QCOMPARE(spy.count(), 0); } + } +} + +void tst_QMediaPlayer::testMuted() +{ + QFETCH_GLOBAL(bool, valid); + QFETCH_GLOBAL(bool, muted); + QFETCH_GLOBAL(int, volume); + + if (valid) { + mockService->setMuted(muted); + mockService->setVolume(volume); + QVERIFY(player->isMuted() == muted); + + QSignalSpy spy(player, SIGNAL(mutedChanged(bool))); + player->setMuted(!muted); + QCOMPARE(player->isMuted(), !muted); + QCOMPARE(player->volume(), volume); + QCOMPARE(spy.count(), 1); + } +} + +void tst_QMediaPlayer::testVideoAvailable() +{ + QFETCH_GLOBAL(bool, videoAvailable); + + mockService->setVideoAvailable(videoAvailable); + QVERIFY(player->isVideoAvailable() == videoAvailable); +} + +void tst_QMediaPlayer::testBufferStatus() +{ + QFETCH_GLOBAL(int, bufferStatus); + + mockService->setBufferStatus(bufferStatus); + QVERIFY(player->bufferStatus() == bufferStatus); +} + +void tst_QMediaPlayer::testSeekable() +{ + QFETCH_GLOBAL(bool, seekable); + + mockService->setSeekable(seekable); + QVERIFY(player->isSeekable() == seekable); +} + +void tst_QMediaPlayer::testPlaybackRate() +{ + QFETCH_GLOBAL(bool, valid); + QFETCH_GLOBAL(qreal, playbackRate); + + if (valid) { + mockService->setPlaybackRate(playbackRate); + QVERIFY(player->playbackRate() == playbackRate); + + QSignalSpy spy(player, SIGNAL(playbackRateChanged(qreal))); + player->setPlaybackRate(playbackRate + 0.5f); + QCOMPARE(player->playbackRate(), playbackRate + 0.5f); + QCOMPARE(spy.count(), 1); + } +} + +void tst_QMediaPlayer::testError() +{ + QFETCH_GLOBAL(QMediaPlayer::Error, error); + + mockService->setError(error); + QVERIFY(player->error() == error); +} + +void tst_QMediaPlayer::testErrorString() +{ + QFETCH_GLOBAL(QString, errorString); + + mockService->setErrorString(errorString); + QVERIFY(player->errorString() == errorString); +} + +void tst_QMediaPlayer::testService() +{ + /* + QFETCH_GLOBAL(bool, valid); + + mockService->setIsValid(valid); + + if (valid) + QVERIFY(player->service() != 0); + else + QVERIFY(player->service() == 0); + */ +} + +void tst_QMediaPlayer::testPlay() +{ + QFETCH_GLOBAL(bool, valid); + QFETCH_GLOBAL(QMediaContent, mediaContent); + QFETCH_GLOBAL(QMediaPlayer::State, state); + + mockService->setIsValid(valid); + mockService->setState(state); + mockService->setMedia(mediaContent); + QVERIFY(player->state() == state); + QVERIFY(player->media() == mediaContent); + + QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State))); + + player->play(); + + if (!valid || mediaContent.isNull()) { + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(spy.count(), 0); + } + else { + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(spy.count(), state == QMediaPlayer::PlayingState ? 0 : 1); + } +} + +void tst_QMediaPlayer::testPause() +{ + QFETCH_GLOBAL(bool, valid); + QFETCH_GLOBAL(QMediaContent, mediaContent); + QFETCH_GLOBAL(QMediaPlayer::State, state); + + mockService->setIsValid(valid); + mockService->setState(state); + mockService->setMedia(mediaContent); + QVERIFY(player->state() == state); + QVERIFY(player->media() == mediaContent); + + QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State))); + + player->pause(); + + if (!valid || mediaContent.isNull()) { + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(spy.count(), 0); + } + else { + QCOMPARE(player->state(), QMediaPlayer::PausedState); + QCOMPARE(spy.count(), state == QMediaPlayer::PausedState ? 0 : 1); + } +} + +void tst_QMediaPlayer::testStop() +{ + QFETCH_GLOBAL(QMediaContent, mediaContent); + QFETCH_GLOBAL(QMediaPlayer::State, state); + + mockService->setState(state); + mockService->setMedia(mediaContent); + QVERIFY(player->state() == state); + QVERIFY(player->media() == mediaContent); + + QSignalSpy spy(player, SIGNAL(stateChanged(QMediaPlayer::State))); + + player->stop(); + + if (mediaContent.isNull() || state == QMediaPlayer::StoppedState) { + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(spy.count(), 0); + } + else { + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(spy.count(), 1); + } +} + +void tst_QMediaPlayer::testMediaStatus() +{ + QFETCH_GLOBAL(int, bufferStatus); + int bufferSignals = 0; + + player->setNotifyInterval(10); + + mockService->setMediaStatus(QMediaPlayer::NoMedia); + mockService->setBufferStatus(bufferStatus); + + AutoConnection connection( + player, SIGNAL(bufferStatusChanged(int)), + &QTestEventLoop::instance(), SLOT(exitLoop())); + + QSignalSpy statusSpy(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + QSignalSpy bufferSpy(player, SIGNAL(bufferStatusChanged(int))); + + QCOMPARE(player->mediaStatus(), QMediaPlayer::NoMedia); + + mockService->setMediaStatus(QMediaPlayer::LoadingMedia); + QCOMPARE(player->mediaStatus(), QMediaPlayer::LoadingMedia); + QCOMPARE(statusSpy.count(), 1); + + QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), + QMediaPlayer::LoadingMedia); + + mockService->setMediaStatus(QMediaPlayer::LoadedMedia); + QCOMPARE(player->mediaStatus(), QMediaPlayer::LoadedMedia); + QCOMPARE(statusSpy.count(), 2); + + QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), + QMediaPlayer::LoadedMedia); + + // Verify the bufferStatusChanged() signal isn't being emitted. + QTestEventLoop::instance().enterLoop(1); + QCOMPARE(bufferSpy.count(), 0); + + mockService->setMediaStatus(QMediaPlayer::StalledMedia); + QCOMPARE(player->mediaStatus(), QMediaPlayer::StalledMedia); + QCOMPARE(statusSpy.count(), 3); + + QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), + QMediaPlayer::StalledMedia); + + // Verify the bufferStatusChanged() signal is being emitted. + QTestEventLoop::instance().enterLoop(1); + QVERIFY(bufferSpy.count() > bufferSignals); + QCOMPARE(bufferSpy.last().value(0).toInt(), bufferStatus); + bufferSignals = bufferSpy.count(); + + mockService->setMediaStatus(QMediaPlayer::BufferingMedia); + QCOMPARE(player->mediaStatus(), QMediaPlayer::BufferingMedia); + QCOMPARE(statusSpy.count(), 4); + + QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), + QMediaPlayer::BufferingMedia); + + // Verify the bufferStatusChanged() signal is being emitted. + QTestEventLoop::instance().enterLoop(1); + QVERIFY(bufferSpy.count() > bufferSignals); + QCOMPARE(bufferSpy.last().value(0).toInt(), bufferStatus); + bufferSignals = bufferSpy.count(); + + mockService->setMediaStatus(QMediaPlayer::BufferedMedia); + QCOMPARE(player->mediaStatus(), QMediaPlayer::BufferedMedia); + QCOMPARE(statusSpy.count(), 5); + + QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), + QMediaPlayer::BufferedMedia); + + // Verify the bufferStatusChanged() signal isn't being emitted. + QTestEventLoop::instance().enterLoop(1); + QCOMPARE(bufferSpy.count(), bufferSignals); + + mockService->setMediaStatus(QMediaPlayer::EndOfMedia); + QCOMPARE(player->mediaStatus(), QMediaPlayer::EndOfMedia); + QCOMPARE(statusSpy.count(), 6); + + QCOMPARE(qvariant_cast<QMediaPlayer::MediaStatus>(statusSpy.last().value(0)), + QMediaPlayer::EndOfMedia); +} + +void tst_QMediaPlayer::testPlaylist() +{ + QMediaContent content0(QUrl(QLatin1String("test://audio/song1.mp3"))); + QMediaContent content1(QUrl(QLatin1String("test://audio/song2.mp3"))); + QMediaContent content2(QUrl(QLatin1String("test://video/movie1.mp4"))); + QMediaContent content3(QUrl(QLatin1String("test://video/movie2.mp4"))); + QMediaContent content4(QUrl(QLatin1String("test://image/photo.jpg"))); + + mockService->setIsValid(true); + mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::NoMedia); + + QMediaPlaylist *playlist = new QMediaPlaylist; + playlist->setMediaObject(player); + + QSignalSpy stateSpy(player, SIGNAL(stateChanged(QMediaPlayer::State))); + QSignalSpy mediaSpy(player, SIGNAL(mediaChanged(QMediaContent))); + + // Test the player does nothing with an empty playlist attached. + player->play(); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(player->media(), QMediaContent()); + QCOMPARE(stateSpy.count(), 0); + QCOMPARE(mediaSpy.count(), 0); + + playlist->addMedia(content0); + playlist->addMedia(content1); + playlist->addMedia(content2); + playlist->addMedia(content3); + + // Test changing the playlist position, changes the current media, but not the playing state. + playlist->setCurrentIndex(1); + QCOMPARE(player->media(), content1); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(stateSpy.count(), 0); + QCOMPARE(mediaSpy.count(), 1); + + // Test playing starts with the current media. + player->play(); + QCOMPARE(player->media(), content1); + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(stateSpy.count(), 1); + QCOMPARE(mediaSpy.count(), 1); + + // Test pausing doesn't change the current media. + player->pause(); + QCOMPARE(player->media(), content1); + QCOMPARE(player->state(), QMediaPlayer::PausedState); + QCOMPARE(stateSpy.count(), 2); + QCOMPARE(mediaSpy.count(), 1); + + // Test stopping doesn't change the current media. + player->stop(); + QCOMPARE(player->media(), content1); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(stateSpy.count(), 3); + QCOMPARE(mediaSpy.count(), 1); + + // Test when the player service reaches the end of the current media, the player moves onto + // the next item without stopping. + player->play(); + QCOMPARE(player->media(), content1); + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(stateSpy.count(), 4); + QCOMPARE(mediaSpy.count(), 1); + + mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::EndOfMedia); + QCOMPARE(player->media(), content2); + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(stateSpy.count(), 4); + QCOMPARE(mediaSpy.count(), 2); + + // Test skipping the current media doesn't change the state. + playlist->next(); + QCOMPARE(player->media(), content3); + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(stateSpy.count(), 4); + QCOMPARE(mediaSpy.count(), 3); + + // Test changing the current media while paused doesn't change the state. + player->pause(); + mockService->setMediaStatus(QMediaPlayer::BufferedMedia); + QCOMPARE(player->media(), content3); + QCOMPARE(player->state(), QMediaPlayer::PausedState); + QCOMPARE(stateSpy.count(), 5); + QCOMPARE(mediaSpy.count(), 3); + + playlist->previous(); + QCOMPARE(player->media(), content2); + QCOMPARE(player->state(), QMediaPlayer::PausedState); + QCOMPARE(stateSpy.count(), 5); + QCOMPARE(mediaSpy.count(), 4); + + // Test changing the current media while stopped doesn't change the state. + player->stop(); + mockService->setMediaStatus(QMediaPlayer::LoadedMedia); + QCOMPARE(player->media(), content2); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(stateSpy.count(), 6); + QCOMPARE(mediaSpy.count(), 4); + + playlist->next(); + QCOMPARE(player->media(), content3); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(stateSpy.count(), 6); + QCOMPARE(mediaSpy.count(), 5); + + // Test the player is stopped and the current media cleared when it reaches the end of the last + // item in the playlist. + player->play(); + QCOMPARE(player->media(), content3); + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(stateSpy.count(), 7); + QCOMPARE(mediaSpy.count(), 5); + + // Double up the signals to ensure some noise doesn't destabalize things. + mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::EndOfMedia); + mockService->setState(QMediaPlayer::StoppedState, QMediaPlayer::EndOfMedia); + QCOMPARE(player->media(), QMediaContent()); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(stateSpy.count(), 8); + QCOMPARE(mediaSpy.count(), 6); + + // Test starts playing from the start of the playlist if there is no current media selected. + player->play(); + QCOMPARE(player->media(), content0); + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(stateSpy.count(), 9); + QCOMPARE(mediaSpy.count(), 7); + + // Test deleting the playlist stops the player and clears the media it set. + delete playlist; + QCOMPARE(player->media(), QMediaContent()); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(stateSpy.count(), 10); + QCOMPARE(mediaSpy.count(), 8); + + // Test the player works as normal with the playlist removed. + player->play(); + QCOMPARE(player->media(), QMediaContent()); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + QCOMPARE(stateSpy.count(), 10); + QCOMPARE(mediaSpy.count(), 8); + + player->setMedia(content1); + player->play(); + + QCOMPARE(player->media(), content1); + QCOMPARE(player->state(), QMediaPlayer::PlayingState); + QCOMPARE(stateSpy.count(), 11); + QCOMPARE(mediaSpy.count(), 9); + + // Test the player can bind to playlist again + playlist = new QMediaPlaylist; + playlist->setMediaObject(player); + QCOMPARE(playlist->mediaObject(), qobject_cast<QMediaObject*>(player)); + + QCOMPARE(player->media(), QMediaContent()); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + + playlist->addMedia(content0); + playlist->addMedia(content1); + playlist->addMedia(content2); + playlist->addMedia(content3); + + playlist->setCurrentIndex(1); + QCOMPARE(player->media(), content1); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + + // Test attaching the new playlist, + // player should detach the current one + QMediaPlaylist *playlist2 = new QMediaPlaylist; + playlist2->addMedia(content1); + playlist2->addMedia(content2); + playlist2->addMedia(content3); + playlist2->setCurrentIndex(2); + + player->play(); + playlist2->setMediaObject(player); + QCOMPARE(playlist2->mediaObject(), qobject_cast<QMediaObject*>(player)); + QVERIFY(playlist->mediaObject() == 0); + QCOMPARE(player->media(), playlist2->currentMedia()); + QCOMPARE(player->state(), QMediaPlayer::StoppedState); + + playlist2->setCurrentIndex(1); + QCOMPARE(player->media(), playlist2->currentMedia()); +} + +QTEST_MAIN(tst_QMediaPlayer) + +#include "tst_qmediaplayer.moc" diff --git a/tests/auto/qmediaplaylist/qmediaplaylist.pro b/tests/auto/qmediaplaylist/qmediaplaylist.pro new file mode 100644 index 0000000..b114bda --- /dev/null +++ b/tests/auto/qmediaplaylist/qmediaplaylist.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qmediaplaylist.cpp + +QT = core multimedia + diff --git a/tests/auto/qmediaplaylist/tmp.unsupported_format b/tests/auto/qmediaplaylist/tmp.unsupported_format new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/auto/qmediaplaylist/tmp.unsupported_format diff --git a/tests/auto/qmediaplaylist/tst_qmediaplaylist.cpp b/tests/auto/qmediaplaylist/tst_qmediaplaylist.cpp new file mode 100644 index 0000000..383a407 --- /dev/null +++ b/tests/auto/qmediaplaylist/tst_qmediaplaylist.cpp @@ -0,0 +1,593 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QDebug> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediaplaylist.h> +#include <QtMultimedia/qmediaplaylistcontrol.h> +#include <QtMultimedia/qmediaplaylistnavigator.h> +#include <QtMultimedia/private/qmediapluginloader_p.h> + + +class MockReadOnlyPlaylistProvider : public QMediaPlaylistProvider +{ + Q_OBJECT +public: + MockReadOnlyPlaylistProvider(QObject *parent) + :QMediaPlaylistProvider(parent) + { + m_items.append(QMediaContent(QUrl(QLatin1String("file:///1")))); + m_items.append(QMediaContent(QUrl(QLatin1String("file:///2")))); + m_items.append(QMediaContent(QUrl(QLatin1String("file:///3")))); + } + + int mediaCount() const { return m_items.size(); } + QMediaContent media(int index) const + { + return index >=0 && index < mediaCount() ? m_items.at(index) : QMediaContent(); + } + +private: + QList<QMediaContent> m_items; +}; + +class MockPlaylistControl : public QMediaPlaylistControl +{ + Q_OBJECT +public: + MockPlaylistControl(QObject *parent) : QMediaPlaylistControl(parent) + { + m_navigator = new QMediaPlaylistNavigator(new MockReadOnlyPlaylistProvider(this), this); + } + + ~MockPlaylistControl() + { + } + + QMediaPlaylistProvider* playlistProvider() const { return m_navigator->playlist(); } + bool setPlaylistProvider(QMediaPlaylistProvider *playlist) { m_navigator->setPlaylist(playlist); return true; } + + int currentIndex() const { return m_navigator->currentIndex(); } + void setCurrentIndex(int position) { m_navigator->jump(position); } + int nextIndex(int steps) const { return m_navigator->nextIndex(steps); } + int previousIndex(int steps) const { return m_navigator->previousIndex(steps); } + + void next() { m_navigator->next(); } + void previous() { m_navigator->previous(); } + + QMediaPlaylist::PlaybackMode playbackMode() const { return m_navigator->playbackMode(); } + void setPlaybackMode(QMediaPlaylist::PlaybackMode mode) { m_navigator->setPlaybackMode(mode); } + +private: + QMediaPlaylistNavigator *m_navigator; +}; + +class MockPlaylistService : public QMediaService +{ + Q_OBJECT + +public: + MockPlaylistService():QMediaService(0) + { + mockControl = new MockPlaylistControl(this); + } + + ~MockPlaylistService() + { + } + + QMediaControl* control(const char *iid) const + { + if (qstrcmp(iid, QMediaPlaylistControl_iid) == 0) + return mockControl; + return 0; + } + + MockPlaylistControl *mockControl; +}; + +class MockReadOnlyPlaylistObject : public QMediaObject +{ + Q_OBJECT +public: + MockReadOnlyPlaylistObject(QObject *parent = 0) + :QMediaObject(parent, new MockPlaylistService) + { + } +}; + + +class tst_QMediaPlaylist : public QObject +{ + Q_OBJECT +public slots: + void init(); + void cleanup(); + void initTestCase(); + +private slots: + void construction(); + void append(); + void insert(); + void clear(); + void removeMedia(); + void currentItem(); + void saveAndLoad(); + void playbackMode(); + void playbackMode_data(); + void shuffle(); + void readOnlyPlaylist(); + void setMediaObject(); + +private: + QMediaContent content1; + QMediaContent content2; + QMediaContent content3; +}; + +void tst_QMediaPlaylist::init() +{ +} + +void tst_QMediaPlaylist::initTestCase() +{ + content1 = QMediaContent(QUrl(QLatin1String("file:///1"))); + content2 = QMediaContent(QUrl(QLatin1String("file:///2"))); + content3 = QMediaContent(QUrl(QLatin1String("file:///3"))); +} + +void tst_QMediaPlaylist::cleanup() +{ +} + +void tst_QMediaPlaylist::construction() +{ + QMediaPlaylist playlist; + QCOMPARE(playlist.mediaCount(), 0); + QVERIFY(playlist.isEmpty()); +} + +void tst_QMediaPlaylist::append() +{ + QMediaPlaylist playlist; + QVERIFY(!playlist.isReadOnly()); + + playlist.addMedia(content1); + QCOMPARE(playlist.mediaCount(), 1); + QCOMPARE(playlist.media(0), content1); + + QSignalSpy aboutToBeInsertedSignalSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int,int))); + QSignalSpy insertedSignalSpy(&playlist, SIGNAL(mediaInserted(int,int))); + playlist.addMedia(content2); + QCOMPARE(playlist.mediaCount(), 2); + QCOMPARE(playlist.media(1), content2); + + QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); + QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 1); + QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1); + + QCOMPARE(insertedSignalSpy.count(), 1); + QCOMPARE(insertedSignalSpy.first()[0].toInt(), 1); + QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1); + + aboutToBeInsertedSignalSpy.clear(); + insertedSignalSpy.clear(); + + QMediaContent content4(QUrl(QLatin1String("file:///4"))); + QMediaContent content5(QUrl(QLatin1String("file:///5"))); + playlist.addMedia(QList<QMediaContent>() << content3 << content4 << content5); + QCOMPARE(playlist.mediaCount(), 5); + QCOMPARE(playlist.media(2), content3); + QCOMPARE(playlist.media(3), content4); + QCOMPARE(playlist.media(4), content5); + + QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); + QCOMPARE(aboutToBeInsertedSignalSpy[0][0].toInt(), 2); + QCOMPARE(aboutToBeInsertedSignalSpy[0][1].toInt(), 4); + + QCOMPARE(insertedSignalSpy.count(), 1); + QCOMPARE(insertedSignalSpy[0][0].toInt(), 2); + QCOMPARE(insertedSignalSpy[0][1].toInt(), 4); + + aboutToBeInsertedSignalSpy.clear(); + insertedSignalSpy.clear(); + + playlist.addMedia(QList<QMediaContent>()); + QCOMPARE(aboutToBeInsertedSignalSpy.count(), 0); + QCOMPARE(insertedSignalSpy.count(), 0); +} + +void tst_QMediaPlaylist::insert() +{ + QMediaPlaylist playlist; + QVERIFY(!playlist.isReadOnly()); + + playlist.addMedia(content1); + QCOMPARE(playlist.mediaCount(), 1); + QCOMPARE(playlist.media(0), content1); + + playlist.addMedia(content2); + QCOMPARE(playlist.mediaCount(), 2); + QCOMPARE(playlist.media(1), content2); + + QSignalSpy aboutToBeInsertedSignalSpy(&playlist, SIGNAL(mediaAboutToBeInserted(int,int))); + QSignalSpy insertedSignalSpy(&playlist, SIGNAL(mediaInserted(int,int))); + + playlist.insertMedia(1, content3); + QCOMPARE(playlist.mediaCount(), 3); + QCOMPARE(playlist.media(0), content1); + QCOMPARE(playlist.media(1), content3); + QCOMPARE(playlist.media(2), content2); + + QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); + QCOMPARE(aboutToBeInsertedSignalSpy.first()[0].toInt(), 1); + QCOMPARE(aboutToBeInsertedSignalSpy.first()[1].toInt(), 1); + + QCOMPARE(insertedSignalSpy.count(), 1); + QCOMPARE(insertedSignalSpy.first()[0].toInt(), 1); + QCOMPARE(insertedSignalSpy.first()[1].toInt(), 1); + + aboutToBeInsertedSignalSpy.clear(); + insertedSignalSpy.clear(); + + QMediaContent content4(QUrl(QLatin1String("file:///4"))); + QMediaContent content5(QUrl(QLatin1String("file:///5"))); + playlist.insertMedia(1, QList<QMediaContent>() << content4 << content5); + + QCOMPARE(playlist.media(0), content1); + QCOMPARE(playlist.media(1), content4); + QCOMPARE(playlist.media(2), content5); + QCOMPARE(playlist.media(3), content3); + QCOMPARE(playlist.media(4), content2); + QCOMPARE(aboutToBeInsertedSignalSpy.count(), 1); + QCOMPARE(aboutToBeInsertedSignalSpy[0][0].toInt(), 1); + QCOMPARE(aboutToBeInsertedSignalSpy[0][1].toInt(), 2); + + QCOMPARE(insertedSignalSpy.count(), 1); + QCOMPARE(insertedSignalSpy[0][0].toInt(), 1); + QCOMPARE(insertedSignalSpy[0][1].toInt(), 2); + + aboutToBeInsertedSignalSpy.clear(); + insertedSignalSpy.clear(); + + playlist.insertMedia(1, QList<QMediaContent>()); + QCOMPARE(aboutToBeInsertedSignalSpy.count(), 0); + QCOMPARE(insertedSignalSpy.count(), 0); +} + + +void tst_QMediaPlaylist::currentItem() +{ + QMediaPlaylist playlist; + playlist.addMedia(content1); + playlist.addMedia(content2); + + QCOMPARE(playlist.currentIndex(), -1); + QCOMPARE(playlist.currentMedia(), QMediaContent()); + + QCOMPARE(playlist.nextIndex(), 0); + QCOMPARE(playlist.nextIndex(2), 1); + QCOMPARE(playlist.previousIndex(), 1); + QCOMPARE(playlist.previousIndex(2), 0); + + playlist.setCurrentIndex(0); + QCOMPARE(playlist.currentIndex(), 0); + QCOMPARE(playlist.currentMedia(), content1); + + QCOMPARE(playlist.nextIndex(), 1); + QCOMPARE(playlist.nextIndex(2), -1); + QCOMPARE(playlist.previousIndex(), -1); + QCOMPARE(playlist.previousIndex(2), -1); + + playlist.setCurrentIndex(1); + QCOMPARE(playlist.currentIndex(), 1); + QCOMPARE(playlist.currentMedia(), content2); + + QCOMPARE(playlist.nextIndex(), -1); + QCOMPARE(playlist.nextIndex(2), -1); + QCOMPARE(playlist.previousIndex(), 0); + QCOMPARE(playlist.previousIndex(2), -1); + + QTest::ignoreMessage(QtWarningMsg, "QMediaPlaylistNavigator: Jump outside playlist range "); + playlist.setCurrentIndex(2); + + QCOMPARE(playlist.currentIndex(), -1); + QCOMPARE(playlist.currentMedia(), QMediaContent()); +} + +void tst_QMediaPlaylist::clear() +{ + QMediaPlaylist playlist; + playlist.addMedia(content1); + playlist.addMedia(content2); + + playlist.clear(); + QVERIFY(playlist.isEmpty()); + QCOMPARE(playlist.mediaCount(), 0); +} + +void tst_QMediaPlaylist::removeMedia() +{ + QMediaPlaylist playlist; + playlist.addMedia(content1); + playlist.addMedia(content2); + playlist.addMedia(content3); + + QSignalSpy aboutToBeRemovedSignalSpy(&playlist, SIGNAL(mediaAboutToBeRemoved(int,int))); + QSignalSpy removedSignalSpy(&playlist, SIGNAL(mediaRemoved(int,int))); + playlist.removeMedia(1); + QCOMPARE(playlist.mediaCount(), 2); + QCOMPARE(playlist.media(1), content3); + + QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1); + QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 1); + QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1); + + QCOMPARE(removedSignalSpy.count(), 1); + QCOMPARE(removedSignalSpy.first()[0].toInt(), 1); + QCOMPARE(removedSignalSpy.first()[1].toInt(), 1); + + aboutToBeRemovedSignalSpy.clear(); + removedSignalSpy.clear(); + + playlist.removeMedia(0,1); + QVERIFY(playlist.isEmpty()); + + QCOMPARE(aboutToBeRemovedSignalSpy.count(), 1); + QCOMPARE(aboutToBeRemovedSignalSpy.first()[0].toInt(), 0); + QCOMPARE(aboutToBeRemovedSignalSpy.first()[1].toInt(), 1); + + QCOMPARE(removedSignalSpy.count(), 1); + QCOMPARE(removedSignalSpy.first()[0].toInt(), 0); + QCOMPARE(removedSignalSpy.first()[1].toInt(), 1); + + + playlist.addMedia(content1); + playlist.addMedia(content2); + playlist.addMedia(content3); + + playlist.removeMedia(0,1); + QCOMPARE(playlist.mediaCount(), 1); + QCOMPARE(playlist.media(0), content3); +} + +void tst_QMediaPlaylist::saveAndLoad() +{ + QMediaPlaylist playlist; + playlist.addMedia(content1); + playlist.addMedia(content2); + playlist.addMedia(content3); + + QCOMPARE(playlist.error(), QMediaPlaylist::NoError); + QVERIFY(playlist.errorString().isEmpty()); + + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + + bool res = playlist.save(&buffer, "unsupported_format"); + QVERIFY(!res); + QVERIFY(playlist.error() != QMediaPlaylist::NoError); + QVERIFY(!playlist.errorString().isEmpty()); + + QSignalSpy errorSignal(&playlist, SIGNAL(loadFailed())); + playlist.load(&buffer, "unsupported_format"); + QCOMPARE(errorSignal.size(), 1); + QVERIFY(playlist.error() != QMediaPlaylist::NoError); + QVERIFY(!playlist.errorString().isEmpty()); + + res = playlist.save(QUrl(QLatin1String("tmp.unsupported_format")), "unsupported_format"); + QVERIFY(!res); + QVERIFY(playlist.error() != QMediaPlaylist::NoError); + QVERIFY(!playlist.errorString().isEmpty()); + + errorSignal.clear(); + playlist.load(QUrl(QLatin1String("tmp.unsupported_format")), "unsupported_format"); + QCOMPARE(errorSignal.size(), 1); + QVERIFY(playlist.error() != QMediaPlaylist::NoError); + QVERIFY(!playlist.errorString().isEmpty()); +} + +void tst_QMediaPlaylist::playbackMode_data() +{ + QTest::addColumn<QMediaPlaylist::PlaybackMode>("playbackMode"); + QTest::addColumn<int>("expectedPrevious"); + QTest::addColumn<int>("pos"); + QTest::addColumn<int>("expectedNext"); + + QTest::newRow("Linear, 0") << QMediaPlaylist::Linear << -1 << 0 << 1; + QTest::newRow("Linear, 1") << QMediaPlaylist::Linear << 0 << 1 << 2; + QTest::newRow("Linear, 2") << QMediaPlaylist::Linear << 1 << 2 << -1; + + QTest::newRow("Loop, 0") << QMediaPlaylist::Loop << 2 << 0 << 1; + QTest::newRow("Loop, 1") << QMediaPlaylist::Loop << 0 << 1 << 2; + QTest::newRow("Lopp, 2") << QMediaPlaylist::Loop << 1 << 2 << 0; + + QTest::newRow("ItemOnce, 1") << QMediaPlaylist::CurrentItemOnce << -1 << 1 << -1; + QTest::newRow("ItemInLoop, 1") << QMediaPlaylist::CurrentItemInLoop << 1 << 1 << 1; + +} + +void tst_QMediaPlaylist::playbackMode() +{ + QFETCH(QMediaPlaylist::PlaybackMode, playbackMode); + QFETCH(int, expectedPrevious); + QFETCH(int, pos); + QFETCH(int, expectedNext); + + QMediaPlaylist playlist; + playlist.addMedia(content1); + playlist.addMedia(content2); + playlist.addMedia(content3); + + QCOMPARE(playlist.playbackMode(), QMediaPlaylist::Linear); + QCOMPARE(playlist.currentIndex(), -1); + + playlist.setPlaybackMode(playbackMode); + QCOMPARE(playlist.playbackMode(), playbackMode); + + playlist.setCurrentIndex(pos); + QCOMPARE(playlist.currentIndex(), pos); + QCOMPARE(playlist.nextIndex(), expectedNext); + QCOMPARE(playlist.previousIndex(), expectedPrevious); + + playlist.next(); + QCOMPARE(playlist.currentIndex(), expectedNext); + + playlist.setCurrentIndex(pos); + playlist.previous(); + QCOMPARE(playlist.currentIndex(), expectedPrevious); +} + +void tst_QMediaPlaylist::shuffle() +{ + QMediaPlaylist playlist; + QList<QMediaContent> contentList; + + for (int i=0; i<100; i++) { + QMediaContent content(QUrl(QString::number(i))); + contentList.append(content); + playlist.addMedia(content); + } + + playlist.shuffle(); + + QList<QMediaContent> shuffledContentList; + for (int i=0; i<playlist.mediaCount(); i++) + shuffledContentList.append(playlist.media(i)); + + QVERIFY(contentList != shuffledContentList); + +} + +void tst_QMediaPlaylist::readOnlyPlaylist() +{ + MockReadOnlyPlaylistObject mediaObject; + QMediaPlaylist playlist; + playlist.setMediaObject(&mediaObject); + + QVERIFY(playlist.isReadOnly()); + QVERIFY(!playlist.isEmpty()); + QCOMPARE(playlist.mediaCount(), 3); + + QCOMPARE(playlist.media(0), content1); + QCOMPARE(playlist.media(1), content2); + QCOMPARE(playlist.media(2), content3); + QCOMPARE(playlist.media(3), QMediaContent()); + + //it's a read only playlist, so all the modification should fail + QVERIFY(!playlist.addMedia(content1)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(!playlist.addMedia(QList<QMediaContent>() << content1 << content2)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(!playlist.insertMedia(1, content1)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(!playlist.insertMedia(1, QList<QMediaContent>() << content1 << content2)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(!playlist.removeMedia(1)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(!playlist.removeMedia(0,2)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(!playlist.clear()); + QCOMPARE(playlist.mediaCount(), 3); + + //but it is still allowed to append/insert an empty list + QVERIFY(playlist.addMedia(QList<QMediaContent>())); + QVERIFY(playlist.insertMedia(1, QList<QMediaContent>())); + + playlist.shuffle(); + //it's still the same + QCOMPARE(playlist.media(0), content1); + QCOMPARE(playlist.media(1), content2); + QCOMPARE(playlist.media(2), content3); + QCOMPARE(playlist.media(3), QMediaContent()); + + + //load to read only playlist should fail, + //unless underlaying provider supports it + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + buffer.write(QByteArray("file:///1\nfile:///2")); + buffer.seek(0); + + QSignalSpy errorSignal(&playlist, SIGNAL(loadFailed())); + playlist.load(&buffer, "m3u"); + QCOMPARE(errorSignal.size(), 1); + QCOMPARE(playlist.error(), QMediaPlaylist::AccessDeniedError); + QVERIFY(!playlist.errorString().isEmpty()); + QCOMPARE(playlist.mediaCount(), 3); + + errorSignal.clear(); + playlist.load(QUrl(QLatin1String("tmp.m3u")), "m3u"); + + QCOMPARE(errorSignal.size(), 1); + QCOMPARE(playlist.error(), QMediaPlaylist::AccessDeniedError); + QVERIFY(!playlist.errorString().isEmpty()); + QCOMPARE(playlist.mediaCount(), 3); +} + +void tst_QMediaPlaylist::setMediaObject() +{ + MockReadOnlyPlaylistObject mediaObject; + + QMediaPlaylist playlist; + QVERIFY(playlist.mediaObject() == 0); + QVERIFY(!playlist.isReadOnly()); + + playlist.setMediaObject(&mediaObject); + QCOMPARE(playlist.mediaObject(), qobject_cast<QMediaObject*>(&mediaObject)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(playlist.isReadOnly()); + + playlist.setMediaObject(0); + QVERIFY(playlist.mediaObject() == 0); + QCOMPARE(playlist.mediaCount(), 0); + QVERIFY(!playlist.isReadOnly()); + + playlist.setMediaObject(&mediaObject); + QCOMPARE(playlist.mediaObject(), qobject_cast<QMediaObject*>(&mediaObject)); + QCOMPARE(playlist.mediaCount(), 3); + QVERIFY(playlist.isReadOnly()); +} + +QTEST_MAIN(tst_QMediaPlaylist) +#include "tst_qmediaplaylist.moc" + diff --git a/tests/auto/qmediaplaylistnavigator/qmediaplaylistnavigator.pro b/tests/auto/qmediaplaylistnavigator/qmediaplaylistnavigator.pro new file mode 100644 index 0000000..ea9bc0f --- /dev/null +++ b/tests/auto/qmediaplaylistnavigator/qmediaplaylistnavigator.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qmediaplaylistnavigator.cpp + +QT = core multimedia + diff --git a/tests/auto/qmediaplaylistnavigator/tst_qmediaplaylistnavigator.cpp b/tests/auto/qmediaplaylistnavigator/tst_qmediaplaylistnavigator.cpp new file mode 100644 index 0000000..9130db0 --- /dev/null +++ b/tests/auto/qmediaplaylistnavigator/tst_qmediaplaylistnavigator.cpp @@ -0,0 +1,316 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QDebug> +#include <QtMultimedia/qlocalmediaplaylistprovider.h> +#include <QtMultimedia/qmediaplaylistnavigator.h> + + +class tst_QMediaPlaylistNavigator : public QObject +{ + Q_OBJECT +public slots: + void init(); + void cleanup(); + +private slots: + void construction(); + void setPlaylist(); + void linearPlayback(); + void loopPlayback(); + void currentItemOnce(); + void currentItemInLoop(); + void randomPlayback(); +}; + +void tst_QMediaPlaylistNavigator::init() +{ +} + +void tst_QMediaPlaylistNavigator::cleanup() +{ +} + +void tst_QMediaPlaylistNavigator::construction() +{ + QLocalMediaPlaylistProvider playlist; + QCOMPARE(playlist.mediaCount(), 0); + + QMediaPlaylistNavigator navigator(&playlist); + QVERIFY(navigator.currentItem().isNull()); + QCOMPARE(navigator.currentIndex(), -1); +} + +void tst_QMediaPlaylistNavigator::setPlaylist() +{ + QMediaPlaylistNavigator navigator(0); + QVERIFY(navigator.playlist() != 0); + QCOMPARE(navigator.playlist()->mediaCount(), 0); + QCOMPARE(navigator.playlist()->media(0), QMediaContent()); + QVERIFY(navigator.playlist()->isReadOnly() ); + + QLocalMediaPlaylistProvider playlist; + QCOMPARE(playlist.mediaCount(), 0); + + navigator.setPlaylist(&playlist); + QCOMPARE(navigator.playlist(), (QMediaPlaylistProvider*)&playlist); + QCOMPARE(navigator.playlist()->mediaCount(), 0); + QVERIFY(!navigator.playlist()->isReadOnly() ); +} + +void tst_QMediaPlaylistNavigator::linearPlayback() +{ + QLocalMediaPlaylistProvider playlist; + QMediaPlaylistNavigator navigator(&playlist); + + navigator.setPlaybackMode(QMediaPlaylist::Linear); + QTest::ignoreMessage(QtWarningMsg, "QMediaPlaylistNavigator: Jump outside playlist range "); + navigator.jump(0);//it's ok to have warning here + QVERIFY(navigator.currentItem().isNull()); + QCOMPARE(navigator.currentIndex(), -1); + + QMediaContent content1(QUrl(QLatin1String("file:///1"))); + playlist.addMedia(content1); + navigator.jump(0); + QVERIFY(!navigator.currentItem().isNull()); + + QCOMPARE(navigator.currentIndex(), 0); + QCOMPARE(navigator.currentItem(), content1); + QCOMPARE(navigator.nextItem(), QMediaContent()); + QCOMPARE(navigator.nextItem(2), QMediaContent()); + QCOMPARE(navigator.previousItem(), QMediaContent()); + QCOMPARE(navigator.previousItem(2), QMediaContent()); + + QMediaContent content2(QUrl(QLatin1String("file:///2"))); + playlist.addMedia(content2); + QCOMPARE(navigator.currentIndex(), 0); + QCOMPARE(navigator.currentItem(), content1); + QCOMPARE(navigator.nextItem(), content2); + QCOMPARE(navigator.nextItem(2), QMediaContent()); + QCOMPARE(navigator.previousItem(), QMediaContent()); + QCOMPARE(navigator.previousItem(2), QMediaContent()); + + navigator.jump(1); + QCOMPARE(navigator.currentIndex(), 1); + QCOMPARE(navigator.currentItem(), content2); + QCOMPARE(navigator.nextItem(), QMediaContent()); + QCOMPARE(navigator.nextItem(2), QMediaContent()); + QCOMPARE(navigator.previousItem(), content1); + QCOMPARE(navigator.previousItem(2), QMediaContent()); + + navigator.jump(0); + navigator.next(); + QCOMPARE(navigator.currentIndex(), 1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), -1); + navigator.next();//jump to the first item + QCOMPARE(navigator.currentIndex(), 0); + + navigator.previous(); + QCOMPARE(navigator.currentIndex(), -1); + navigator.previous();//jump to the last item + QCOMPARE(navigator.currentIndex(), 1); +} + +void tst_QMediaPlaylistNavigator::loopPlayback() +{ + QLocalMediaPlaylistProvider playlist; + QMediaPlaylistNavigator navigator(&playlist); + + navigator.setPlaybackMode(QMediaPlaylist::Loop); + QTest::ignoreMessage(QtWarningMsg, "QMediaPlaylistNavigator: Jump outside playlist range "); + navigator.jump(0); + QVERIFY(navigator.currentItem().isNull()); + QCOMPARE(navigator.currentIndex(), -1); + + QMediaContent content1(QUrl(QLatin1String("file:///1"))); + playlist.addMedia(content1); + navigator.jump(0); + QVERIFY(!navigator.currentItem().isNull()); + + QCOMPARE(navigator.currentIndex(), 0); + QCOMPARE(navigator.currentItem(), content1); + QCOMPARE(navigator.nextItem(), content1); + QCOMPARE(navigator.nextItem(2), content1); + QCOMPARE(navigator.previousItem(), content1); + QCOMPARE(navigator.previousItem(2), content1); + + QMediaContent content2(QUrl(QLatin1String("file:///2"))); + playlist.addMedia(content2); + QCOMPARE(navigator.currentIndex(), 0); + QCOMPARE(navigator.currentItem(), content1); + QCOMPARE(navigator.nextItem(), content2); + QCOMPARE(navigator.nextItem(2), content1); //loop over end of the list + QCOMPARE(navigator.previousItem(), content2); + QCOMPARE(navigator.previousItem(2), content1); + + navigator.jump(1); + QCOMPARE(navigator.currentIndex(), 1); + QCOMPARE(navigator.currentItem(), content2); + QCOMPARE(navigator.nextItem(), content1); + QCOMPARE(navigator.nextItem(2), content2); + QCOMPARE(navigator.previousItem(), content1); + QCOMPARE(navigator.previousItem(2), content2); + + navigator.jump(0); + navigator.next(); + QCOMPARE(navigator.currentIndex(), 1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), 0); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), 1); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), 0); +} + +void tst_QMediaPlaylistNavigator::currentItemOnce() +{ + QLocalMediaPlaylistProvider playlist; + QMediaPlaylistNavigator navigator(&playlist); + + navigator.setPlaybackMode(QMediaPlaylist::CurrentItemOnce); + + QCOMPARE(navigator.playbackMode(), QMediaPlaylist::CurrentItemOnce); + QCOMPARE(navigator.currentIndex(), -1); + + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///1")))); + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///2")))); + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///3")))); + + QCOMPARE(navigator.currentIndex(), -1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), -1); + + navigator.jump(1); + QCOMPARE(navigator.currentIndex(), 1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), -1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), -1); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), -1); + navigator.jump(1); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), -1); +} + +void tst_QMediaPlaylistNavigator::currentItemInLoop() +{ + QLocalMediaPlaylistProvider playlist; + QMediaPlaylistNavigator navigator(&playlist); + + navigator.setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); + + QCOMPARE(navigator.playbackMode(), QMediaPlaylist::CurrentItemInLoop); + QCOMPARE(navigator.currentIndex(), -1); + + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///1")))); + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///2")))); + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///3")))); + + QCOMPARE(navigator.currentIndex(), -1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), -1); + navigator.jump(1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), 1); + navigator.next(); + QCOMPARE(navigator.currentIndex(), 1); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), 1); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), 1); +} + +void tst_QMediaPlaylistNavigator::randomPlayback() +{ + QLocalMediaPlaylistProvider playlist; + QMediaPlaylistNavigator navigator(&playlist); + + navigator.setPlaybackMode(QMediaPlaylist::Random); + + QCOMPARE(navigator.playbackMode(), QMediaPlaylist::Random); + QCOMPARE(navigator.currentIndex(), -1); + + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///1")))); + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///2")))); + playlist.addMedia(QMediaContent(QUrl(QLatin1String("file:///3")))); + + playlist.shuffle(); + + QCOMPARE(navigator.currentIndex(), -1); + navigator.next(); + int pos1 = navigator.currentIndex(); + navigator.next(); + int pos2 = navigator.currentIndex(); + navigator.next(); + int pos3 = navigator.currentIndex(); + + QVERIFY(pos1 != -1); + QVERIFY(pos2 != -1); + QVERIFY(pos3 != -1); + + navigator.previous(); + QCOMPARE(navigator.currentIndex(), pos2); + navigator.next(); + QCOMPARE(navigator.currentIndex(), pos3); + navigator.next(); + int pos4 = navigator.currentIndex(); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), pos3); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), pos2); + navigator.previous(); + QCOMPARE(navigator.currentIndex(), pos1); + navigator.previous(); + int pos0 = navigator.currentIndex(); + QVERIFY(pos0 != -1); + navigator.next(); + navigator.next(); + navigator.next(); + navigator.next(); + QCOMPARE(navigator.currentIndex(), pos4); + +} + +QTEST_MAIN(tst_QMediaPlaylistNavigator) +#include "tst_qmediaplaylistnavigator.moc" diff --git a/tests/auto/qmediapluginloader/qmediapluginloader.pro b/tests/auto/qmediapluginloader/qmediapluginloader.pro new file mode 100644 index 0000000..66950e9 --- /dev/null +++ b/tests/auto/qmediapluginloader/qmediapluginloader.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qmediapluginloader.cpp + +QT = core multimedia + diff --git a/tests/auto/qmediapluginloader/tst_qmediapluginloader.cpp b/tests/auto/qmediapluginloader/tst_qmediapluginloader.cpp new file mode 100644 index 0000000..0d35b05 --- /dev/null +++ b/tests/auto/qmediapluginloader/tst_qmediapluginloader.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QDebug> + +#include <QtMultimedia/private/qmediapluginloader_p.h> +#include <QtMultimedia/qmediaserviceproviderplugin.h> + + + +class tst_QMediaPluginLoader : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + +private slots: + void testInstance(); + void testInstances(); + void testInvalidKey(); + +private: + QMediaPluginLoader *loader; +}; + +void tst_QMediaPluginLoader::initTestCase() +{ + loader = new QMediaPluginLoader(QMediaServiceProviderFactoryInterface_iid, + QLatin1String("/mediaservice"), + Qt::CaseInsensitive); +} + +void tst_QMediaPluginLoader::cleanupTestCase() +{ + delete loader; +} + +void tst_QMediaPluginLoader::testInstance() +{ + const QStringList keys = loader->keys(); + + if (keys.isEmpty()) // Test is invalidated, skip. + QSKIP("No plug-ins available", SkipAll); + + foreach (const QString &key, keys) + QVERIFY(loader->instance(key) != 0); +} + +void tst_QMediaPluginLoader::testInstances() +{ + const QStringList keys = loader->keys(); + + if (keys.isEmpty()) // Test is invalidated, skip. + QSKIP("No plug-ins available", SkipAll); + + foreach (const QString &key, keys) + QVERIFY(loader->instances(key).size() > 0); +} + +// Last so as to not interfere with the other tests if there is a failure. +void tst_QMediaPluginLoader::testInvalidKey() +{ + const QString key(QLatin1String("invalid-key")); + + // This test assumes there is no 'invalid-key' in the key list, verify that. + if (loader->keys().contains(key)) + QSKIP("a plug-in includes the invalid key", SkipAll); + + QVERIFY(loader->instance(key) == 0); + + // Test looking up the key hasn't inserted it into the list. See QMap::operator[]. + QVERIFY(!loader->keys().contains(key)); + + QVERIFY(loader->instances(key).isEmpty()); + QVERIFY(!loader->keys().contains(key)); +} + +QTEST_MAIN(tst_QMediaPluginLoader) + +#include "tst_qmediapluginloader.moc" diff --git a/tests/auto/qmediaresource/qmediaresource.pro b/tests/auto/qmediaresource/qmediaresource.pro new file mode 100644 index 0000000..c8e3d9c --- /dev/null +++ b/tests/auto/qmediaresource/qmediaresource.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qmediaresource.cpp + +QT = core multimedia network + diff --git a/tests/auto/qmediaresource/tst_qmediaresource.cpp b/tests/auto/qmediaresource/tst_qmediaresource.cpp new file mode 100644 index 0000000..546c415 --- /dev/null +++ b/tests/auto/qmediaresource/tst_qmediaresource.cpp @@ -0,0 +1,516 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtMultimedia/qmediaresource.h> + + +class tst_QMediaResource : public QObject +{ + Q_OBJECT +private slots: + void constructNull(); + void construct_data(); + void construct(); + void setResolution(); + void equality(); + void copy(); + void assign(); +}; + +void tst_QMediaResource::constructNull() +{ + QMediaResource resource; + + QCOMPARE(resource.isNull(), true); + QCOMPARE(resource.url(), QUrl()); + QCOMPARE(resource.request(), QNetworkRequest()); + QCOMPARE(resource.mimeType(), QString()); + QCOMPARE(resource.language(), QString()); + QCOMPARE(resource.audioCodec(), QString()); + QCOMPARE(resource.videoCodec(), QString()); + QCOMPARE(resource.dataSize(), qint64(0)); + QCOMPARE(resource.audioBitRate(), 0); + QCOMPARE(resource.sampleRate(), 0); + QCOMPARE(resource.channelCount(), 0); + QCOMPARE(resource.videoBitRate(), 0); + QCOMPARE(resource.resolution(), QSize()); +} + +void tst_QMediaResource::construct_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::addColumn<QNetworkRequest>("request"); + QTest::addColumn<QString>("mimeType"); + QTest::addColumn<QString>("language"); + QTest::addColumn<QString>("audioCodec"); + QTest::addColumn<QString>("videoCodec"); + QTest::addColumn<qint64>("dataSize"); + QTest::addColumn<int>("audioBitRate"); + QTest::addColumn<int>("sampleRate"); + QTest::addColumn<int>("channelCount"); + QTest::addColumn<int>("videoBitRate"); + QTest::addColumn<QSize>("resolution"); + + QTest::newRow("audio content") + << QUrl(QString::fromLatin1("http:://test.com/test.mp3")) + << QNetworkRequest(QUrl(QString::fromLatin1("http:://test.com/test.mp3"))) + << QString::fromLatin1("audio/mpeg") + << QString::fromLatin1("eng") + << QString::fromLatin1("mp3") + << QString() + << qint64(5465433) + << 128000 + << 44100 + << 2 + << 0 + << QSize(); + QTest::newRow("image content") + << QUrl(QString::fromLatin1("http:://test.com/test.jpg")) + << QNetworkRequest(QUrl(QString::fromLatin1("http:://test.com/test.jpg"))) + << QString::fromLatin1("image/jpeg") + << QString() + << QString() + << QString() + << qint64(23600) + << 0 + << 0 + << 0 + << 0 + << QSize(640, 480); + QTest::newRow("video content") + << QUrl(QString::fromLatin1("http:://test.com/test.mp4")) + << QNetworkRequest(QUrl(QString::fromLatin1("http:://test.com/test.mp4"))) + << QString::fromLatin1("video/mp4") + << QString() + << QString::fromLatin1("aac") + << QString::fromLatin1("h264") + << qint64(36245851) + << 96000 + << 44000 + << 5 + << 750000 + << QSize(720, 576); + QTest::newRow("thumbnail") + << QUrl(QString::fromLatin1("file::///thumbs/test.png")) + << QNetworkRequest(QUrl(QString::fromLatin1("file::///thumbs/test.png"))) + << QString::fromLatin1("image/png") + << QString() + << QString() + << QString() + << qint64(2360) + << 0 + << 0 + << 0 + << 0 + << QSize(128, 128); +} + +void tst_QMediaResource::construct() +{ + QFETCH(QUrl, url); + QFETCH(QNetworkRequest, request); + QFETCH(QString, mimeType); + QFETCH(QString, language); + QFETCH(QString, audioCodec); + QFETCH(QString, videoCodec); + QFETCH(qint64, dataSize); + QFETCH(int, audioBitRate); + QFETCH(int, sampleRate); + QFETCH(int, channelCount); + QFETCH(int, videoBitRate); + QFETCH(QSize, resolution); + + { + QMediaResource resource(url); + + QCOMPARE(resource.isNull(), false); + QCOMPARE(resource.url(), url); + QCOMPARE(resource.mimeType(), QString()); + QCOMPARE(resource.language(), QString()); + QCOMPARE(resource.audioCodec(), QString()); + QCOMPARE(resource.videoCodec(), QString()); + QCOMPARE(resource.dataSize(), qint64(0)); + QCOMPARE(resource.audioBitRate(), 0); + QCOMPARE(resource.sampleRate(), 0); + QCOMPARE(resource.channelCount(), 0); + QCOMPARE(resource.videoBitRate(), 0); + QCOMPARE(resource.resolution(), QSize()); + } + { + QMediaResource resource(url, mimeType); + + QCOMPARE(resource.isNull(), false); + QCOMPARE(resource.url(), url); + QCOMPARE(resource.request(), request); + QCOMPARE(resource.mimeType(), mimeType); + QCOMPARE(resource.language(), QString()); + QCOMPARE(resource.audioCodec(), QString()); + QCOMPARE(resource.videoCodec(), QString()); + QCOMPARE(resource.dataSize(), qint64(0)); + QCOMPARE(resource.audioBitRate(), 0); + QCOMPARE(resource.sampleRate(), 0); + QCOMPARE(resource.channelCount(), 0); + QCOMPARE(resource.videoBitRate(), 0); + QCOMPARE(resource.resolution(), QSize()); + + resource.setLanguage(language); + resource.setAudioCodec(audioCodec); + resource.setVideoCodec(videoCodec); + resource.setDataSize(dataSize); + resource.setAudioBitRate(audioBitRate); + resource.setSampleRate(sampleRate); + resource.setChannelCount(channelCount); + resource.setVideoBitRate(videoBitRate); + resource.setResolution(resolution); + + QCOMPARE(resource.language(), language); + QCOMPARE(resource.audioCodec(), audioCodec); + QCOMPARE(resource.videoCodec(), videoCodec); + QCOMPARE(resource.dataSize(), dataSize); + QCOMPARE(resource.audioBitRate(), audioBitRate); + QCOMPARE(resource.sampleRate(), sampleRate); + QCOMPARE(resource.channelCount(), channelCount); + QCOMPARE(resource.videoBitRate(), videoBitRate); + QCOMPARE(resource.resolution(), resolution); + } + { + QMediaResource resource(request, mimeType); + + QCOMPARE(resource.isNull(), false); + QCOMPARE(resource.url(), url); + QCOMPARE(resource.request(), request); + QCOMPARE(resource.mimeType(), mimeType); + QCOMPARE(resource.language(), QString()); + QCOMPARE(resource.audioCodec(), QString()); + QCOMPARE(resource.videoCodec(), QString()); + QCOMPARE(resource.dataSize(), qint64(0)); + QCOMPARE(resource.audioBitRate(), 0); + QCOMPARE(resource.sampleRate(), 0); + QCOMPARE(resource.channelCount(), 0); + QCOMPARE(resource.videoBitRate(), 0); + QCOMPARE(resource.resolution(), QSize()); + + resource.setLanguage(language); + resource.setAudioCodec(audioCodec); + resource.setVideoCodec(videoCodec); + resource.setDataSize(dataSize); + resource.setAudioBitRate(audioBitRate); + resource.setSampleRate(sampleRate); + resource.setChannelCount(channelCount); + resource.setVideoBitRate(videoBitRate); + resource.setResolution(resolution); + + QCOMPARE(resource.language(), language); + QCOMPARE(resource.audioCodec(), audioCodec); + QCOMPARE(resource.videoCodec(), videoCodec); + QCOMPARE(resource.dataSize(), dataSize); + QCOMPARE(resource.audioBitRate(), audioBitRate); + QCOMPARE(resource.sampleRate(), sampleRate); + QCOMPARE(resource.channelCount(), channelCount); + QCOMPARE(resource.videoBitRate(), videoBitRate); + QCOMPARE(resource.resolution(), resolution); + } +} + +void tst_QMediaResource::setResolution() +{ + QMediaResource resource( + QUrl(QString::fromLatin1("file::///thumbs/test.png")), + QString::fromLatin1("image/png")); + + QCOMPARE(resource.resolution(), QSize()); + + resource.setResolution(QSize(120, 80)); + QCOMPARE(resource.resolution(), QSize(120, 80)); + + resource.setResolution(QSize(-1, 23)); + QCOMPARE(resource.resolution(), QSize(-1, 23)); + + resource.setResolution(QSize(-43, 34)); + QCOMPARE(resource.resolution(), QSize(-43, 34)); + + resource.setResolution(QSize(64, -1)); + QCOMPARE(resource.resolution(), QSize(64, -1)); + + resource.setResolution(QSize(64, -83)); + QCOMPARE(resource.resolution(), QSize(64, -83)); + + resource.setResolution(QSize(-12, -83)); + QCOMPARE(resource.resolution(), QSize(-12, -83)); + + resource.setResolution(QSize()); + QCOMPARE(resource.resolution(), QSize(-1, -1)); + + resource.setResolution(120, 80); + QCOMPARE(resource.resolution(), QSize(120, 80)); + + resource.setResolution(-1, 23); + QCOMPARE(resource.resolution(), QSize(-1, 23)); + + resource.setResolution(-43, 34); + QCOMPARE(resource.resolution(), QSize(-43, 34)); + + resource.setResolution(64, -1); + QCOMPARE(resource.resolution(), QSize(64, -1)); + + resource.setResolution(64, -83); + QCOMPARE(resource.resolution(), QSize(64, -83)); + + resource.setResolution(-12, -83); + QCOMPARE(resource.resolution(), QSize(-12, -83)); + + resource.setResolution(-1, -1); + QCOMPARE(resource.resolution(), QSize()); +} + +void tst_QMediaResource::equality() +{ + QMediaResource resource1( + QUrl(QString::fromLatin1("http://test.com/test.mp4")), + QString::fromLatin1("video/mp4")); + QMediaResource resource2( + QUrl(QString::fromLatin1("http://test.com/test.mp4")), + QString::fromLatin1("video/mp4")); + QMediaResource resource3( + QUrl(QString::fromLatin1("file:///thumbs/test.jpg"))); + QMediaResource resource4( + QUrl(QString::fromLatin1("file:///thumbs/test.jpg"))); + QMediaResource resource5( + QUrl(QString::fromLatin1("http://test.com/test.mp3")), + QString::fromLatin1("audio/mpeg")); + + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + QCOMPARE(resource3 == resource4, true); + QCOMPARE(resource3 != resource4, false); + + QCOMPARE(resource1 == resource3, false); + QCOMPARE(resource1 != resource3, true); + + QCOMPARE(resource1 == resource5, false); + QCOMPARE(resource1 != resource5, true); + + resource1.setAudioCodec(QString::fromLatin1("mp3")); + resource2.setAudioCodec(QString::fromLatin1("aac")); + + // Not equal differing audio codecs. + QCOMPARE(resource1 == resource2, false); + QCOMPARE(resource1 != resource2, true); + + resource1.setAudioCodec(QString::fromLatin1("aac")); + + // Equal. + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource1.setVideoCodec(QString()); + + // Equal. + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource1.setVideoCodec(QString::fromLatin1("h264")); + + // Not equal differing video codecs. + QCOMPARE(resource1 == resource2, false); + QCOMPARE(resource1 != resource2, true); + + resource2.setVideoCodec(QString::fromLatin1("h264")); + + // Equal. + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource2.setDataSize(0); + + // Equal. + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource1.setDataSize(546423); + + // Not equal differing video codecs. + QCOMPARE(resource1 == resource2, false); + QCOMPARE(resource1 != resource2, true); + + resource2.setDataSize(546423); + + // Equal. + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource1.setAudioBitRate(96000); + resource1.setSampleRate(48000); + resource2.setSampleRate(44100); + resource1.setChannelCount(0); + resource1.setVideoBitRate(900000); + resource2.setLanguage(QString::fromLatin1("eng")); + + // Not equal, audio bit rate, sample rate, video bit rate, and + // language. + QCOMPARE(resource1 == resource2, false); + QCOMPARE(resource1 != resource2, true); + + resource2.setAudioBitRate(96000); + resource1.setSampleRate(44100); + + // Not equal, differing video bit rate, and language. + QCOMPARE(resource1 == resource2, false); + QCOMPARE(resource1 != resource2, true); + + resource2.setVideoBitRate(900000); + resource1.setLanguage(QString::fromLatin1("eng")); + + // Equal + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource1.setResolution(QSize()); + + // Equal + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource2.setResolution(-1, -1); + + // Equal + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); + + resource1.setResolution(QSize(-640, -480)); + + // Not equal, differing resolution. + QCOMPARE(resource1 == resource2, false); + QCOMPARE(resource1 != resource2, true); + resource1.setResolution(QSize(640, 480)); + resource2.setResolution(QSize(800, 600)); + + // Not equal, differing resolution. + QCOMPARE(resource1 == resource2, false); + QCOMPARE(resource1 != resource2, true); + + resource1.setResolution(800, 600); + + // Equal + QCOMPARE(resource1 == resource2, true); + QCOMPARE(resource1 != resource2, false); +} + +void tst_QMediaResource::copy() +{ + const QUrl url(QString::fromLatin1("http://test.com/test.mp4")); + const QString mimeType(QLatin1String("video/mp4")); + const QString amrCodec(QLatin1String("amr")); + const QString mp3Codec(QLatin1String("mp3")); + const QString aacCodec(QLatin1String("aac")); + const QString h264Codec(QLatin1String("h264")); + + QMediaResource original(url, mimeType); + original.setAudioCodec(amrCodec); + + QMediaResource copy(original); + + QCOMPARE(copy.url(), url); + QCOMPARE(copy.mimeType(), mimeType); + QCOMPARE(copy.audioCodec(), amrCodec); + + QCOMPARE(original == copy, true); + QCOMPARE(original != copy, false); + + original.setAudioCodec(mp3Codec); + + QCOMPARE(copy.audioCodec(), amrCodec); + QCOMPARE(original == copy, false); + QCOMPARE(original != copy, true); + + copy.setAudioCodec(aacCodec); + copy.setVideoCodec(h264Codec); + + QCOMPARE(copy.url(), url); + QCOMPARE(copy.mimeType(), mimeType); + + QCOMPARE(original.audioCodec(), mp3Codec); +} + +void tst_QMediaResource::assign() +{ + const QUrl url(QString::fromLatin1("http://test.com/test.mp4")); + const QString mimeType(QLatin1String("video/mp4")); + const QString amrCodec(QLatin1String("amr")); + const QString mp3Codec(QLatin1String("mp3")); + const QString aacCodec(QLatin1String("aac")); + const QString h264Codec(QLatin1String("h264")); + + QMediaResource copy(QUrl(QString::fromLatin1("file:///thumbs/test.jpg"))); + + QMediaResource original(url, mimeType); + original.setAudioCodec(amrCodec); + + copy = original; + + QCOMPARE(copy.url(), url); + QCOMPARE(copy.mimeType(), mimeType); + QCOMPARE(copy.audioCodec(), amrCodec); + + QCOMPARE(original == copy, true); + QCOMPARE(original != copy, false); + + original.setAudioCodec(mp3Codec); + + QCOMPARE(copy.audioCodec(), amrCodec); + QCOMPARE(original == copy, false); + QCOMPARE(original != copy, true); + + copy.setAudioCodec(aacCodec); + copy.setVideoCodec(h264Codec); + + QCOMPARE(copy.url(), url); + QCOMPARE(copy.mimeType(), mimeType); + + QCOMPARE(original.audioCodec(), mp3Codec); +} + +QTEST_MAIN(tst_QMediaResource) + +#include "tst_qmediaresource.moc" diff --git a/tests/auto/qmediaservice/qmediaservice.pro b/tests/auto/qmediaservice/qmediaservice.pro new file mode 100644 index 0000000..f877665 --- /dev/null +++ b/tests/auto/qmediaservice/qmediaservice.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qmediaservice.cpp + +QT = core gui multimedia + diff --git a/tests/auto/qmediaservice/tst_qmediaservice.cpp b/tests/auto/qmediaservice/tst_qmediaservice.cpp new file mode 100644 index 0000000..35f661d --- /dev/null +++ b/tests/auto/qmediaservice/tst_qmediaservice.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtMultimedia/qvideodevicecontrol.h> +#include <QtMultimedia/qmediacontrol.h> +#include <QtMultimedia/qmediaservice.h> + +#include <QtGui/qapplication.h> +#include <QtGui/qstyle.h> + +class QtTestMediaService; + + +class tst_QMediaService : public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + + void control_iid(); + void control(); +}; + + +class QtTestMediaControlA : public QMediaControl +{ + Q_OBJECT +}; + + +#define QtTestMediaControlA_iid "com.nokia.QtTestMediaControlA" +Q_MEDIA_DECLARE_CONTROL(QtTestMediaControlA, QtTestMediaControlA_iid) + + +class QtTestMediaControlB : public QMediaControl +{ + Q_OBJECT +}; + +#define QtTestMediaControlB_iid "com.nokia.QtTestMediaControlB" +Q_MEDIA_DECLARE_CONTROL(QtTestMediaControlB, QtTestMediaControlB_iid) + + +class QtTestMediaControlC : public QMediaControl +{ + Q_OBJECT +}; + +#define QtTestMediaControlC_iid "com.nokia.QtTestMediaControlC" +Q_MEDIA_DECLARE_CONTROL(QtTestMediaControlC, QtTestMediaControlA_iid) // Yes A. + +class QtTestMediaControlD : public QMediaControl +{ + Q_OBJECT +}; + +#define QtTestMediaControlD_iid "com.nokia.QtTestMediaControlD" +Q_MEDIA_DECLARE_CONTROL(QtTestMediaControlD, QtTestMediaControlD_iid) + +class QtTestMediaControlE : public QMediaControl +{ + Q_OBJECT +}; + +struct QtTestDevice +{ + QtTestDevice() {} + QtTestDevice(const QString &name, const QString &description, const QIcon &icon) + : name(name), description(description), icon(icon) + { + } + + QString name; + QString description; + QIcon icon; +}; + +class QtTestVideoDeviceControl : public QVideoDeviceControl +{ +public: + QtTestVideoDeviceControl(QObject *parent = 0) + : QVideoDeviceControl(parent) + , m_selectedDevice(-1) + , m_defaultDevice(-1) + { + } + + int deviceCount() const { return devices.count(); } + + QString deviceName(int index) const { return devices.value(index).name; } + QString deviceDescription(int index) const { return devices.value(index).description; } + QIcon deviceIcon(int index) const { return devices.value(index).icon; } + + int defaultDevice() const { return m_defaultDevice; } + void setDefaultDevice(int index) { m_defaultDevice = index; } + + int selectedDevice() const { return m_selectedDevice; } + void setSelectedDevice(int index) + { + emit selectedDeviceChanged(m_selectedDevice = index); + emit selectedDeviceChanged(devices.value(index).name); + } + + QList<QtTestDevice> devices; + +private: + int m_selectedDevice; + int m_defaultDevice; +}; + +class QtTestMediaService : public QMediaService +{ + Q_OBJECT +public: + QtTestMediaService() + : QMediaService(0) + , hasDeviceControls(false) + { + } + + QMediaControl* control(const char *name) const + { + if (strcmp(name, QtTestMediaControlA_iid) == 0) + return const_cast<QtTestMediaControlA *>(&controlA); + else if (strcmp(name, QtTestMediaControlB_iid) == 0) + return const_cast<QtTestMediaControlB *>(&controlB); + else if (strcmp(name, QtTestMediaControlC_iid) == 0) + return const_cast<QtTestMediaControlC *>(&controlC); + else if (hasDeviceControls && strcmp(name, QVideoDeviceControl_iid) == 0) + return const_cast<QtTestVideoDeviceControl *>(&videoDeviceControl); + else + return 0; + } + + using QMediaService::control; + + QtTestMediaControlA controlA; + QtTestMediaControlB controlB; + QtTestMediaControlC controlC; + QtTestVideoDeviceControl videoDeviceControl; + bool hasDeviceControls; +}; + +void tst_QMediaService::initTestCase() +{ +} + +void tst_QMediaService::control_iid() +{ + const char *nullString = 0; + + // Default implementation. + QCOMPARE(qmediacontrol_iid<QtTestMediaControlE *>(), nullString); + + // Partial template. + QVERIFY(qstrcmp(qmediacontrol_iid<QtTestMediaControlA *>(), QtTestMediaControlA_iid) == 0); +} + +void tst_QMediaService::control() +{ + QtTestMediaService service; + + QCOMPARE(service.control<QtTestMediaControlA *>(), &service.controlA); + QCOMPARE(service.control<QtTestMediaControlB *>(), &service.controlB); + QVERIFY(!service.control<QtTestMediaControlC *>()); // Faulty implementation returns A. + QVERIFY(!service.control<QtTestMediaControlD *>()); // No control of that type. +} + +QTEST_MAIN(tst_QMediaService) + +#include "tst_qmediaservice.moc" diff --git a/tests/auto/qmediaserviceprovider/qmediaserviceprovider.pro b/tests/auto/qmediaserviceprovider/qmediaserviceprovider.pro new file mode 100644 index 0000000..9aaa9e5 --- /dev/null +++ b/tests/auto/qmediaserviceprovider/qmediaserviceprovider.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qmediaserviceprovider.cpp + +QT = core gui multimedia + diff --git a/tests/auto/qmediaserviceprovider/tst_qmediaserviceprovider.cpp b/tests/auto/qmediaserviceprovider/tst_qmediaserviceprovider.cpp new file mode 100644 index 0000000..9bca189 --- /dev/null +++ b/tests/auto/qmediaserviceprovider/tst_qmediaserviceprovider.cpp @@ -0,0 +1,409 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QDebug> +#include <QStringList> + +#include <QtMultimedia/qmediaserviceprovider.h> +#include <QtMultimedia/qmediaserviceproviderplugin.h> +#include <QtMultimedia/private/qmediapluginloader_p.h> +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmediaplayer.h> + +class MockMediaService : public QMediaService +{ + Q_OBJECT +public: + MockMediaService(const QString& name, QObject *parent = 0) : QMediaService(parent) + { setObjectName(name); } + ~MockMediaService() {} + + QMediaControl* control(const char *) const {return 0;} +}; + +class MockServicePlugin1 : public QMediaServiceProviderPlugin, + public QMediaServiceSupportedFormatsInterface, + public QMediaServiceSupportedDevicesInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceSupportedFormatsInterface) + Q_INTERFACES(QMediaServiceSupportedDevicesInterface) +public: + QStringList keys() const + { + return QStringList() << + QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER); + } + + QMediaService* create(QString const& key) + { + if (keys().contains(key)) + return new MockMediaService("MockServicePlugin1"); + else + return 0; + } + + void release(QMediaService *service) + { + delete service; + } + + QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const + { + if (codecs.contains(QLatin1String("mpeg4"))) + return QtMultimedia::NotSupported; + + if (mimeType == "audio/ogg") { + return QtMultimedia::ProbablySupported; + } + + return QtMultimedia::MaybeSupported; + } + + QStringList supportedMimeTypes() const + { + return QStringList("audio/ogg"); + } + + QList<QByteArray> devices(const QByteArray &service) const + { + Q_UNUSED(service); + QList<QByteArray> res; + return res; + } + + QString deviceDescription(const QByteArray &service, const QByteArray &device) + { + if (devices(service).contains(device)) + return QString(device)+" description"; + else + return QString(); + } +}; + +class MockServicePlugin2 : public QMediaServiceProviderPlugin, + public QMediaServiceSupportedFormatsInterface, + public QMediaServiceFeaturesInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceSupportedFormatsInterface) + Q_INTERFACES(QMediaServiceFeaturesInterface) +public: + QStringList keys() const + { + return QStringList() << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER); + } + + QMediaService* create(QString const& key) + { + if (keys().contains(key)) + return new MockMediaService("MockServicePlugin2"); + else + return 0; + } + + void release(QMediaService *service) + { + delete service; + } + + QtMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const + { + Q_UNUSED(codecs); + + if (mimeType == "audio/wav") + return QtMultimedia::PreferedService; + + return QtMultimedia::NotSupported; + } + + QStringList supportedMimeTypes() const + { + return QStringList("audio/wav"); + } + + QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const + { + if (service == QByteArray(Q_MEDIASERVICE_MEDIAPLAYER)) + return QMediaServiceProviderHint::LowLatencyPlayback; + else + return 0; + } +}; + + +class MockServicePlugin3 : public QMediaServiceProviderPlugin, + public QMediaServiceSupportedDevicesInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceSupportedDevicesInterface) +public: + QStringList keys() const + { + return QStringList() << + QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER); + } + + QMediaService* create(QString const& key) + { + if (keys().contains(key)) + return new MockMediaService("MockServicePlugin3"); + else + return 0; + } + + void release(QMediaService *service) + { + delete service; + } + + QList<QByteArray> devices(const QByteArray &service) const + { + Q_UNUSED(service); + QList<QByteArray> res; + return res; + } + + QString deviceDescription(const QByteArray &service, const QByteArray &device) + { + if (devices(service).contains(device)) + return QString(device)+" description"; + else + return QString(); + } +}; + + + +class MockMediaServiceProvider : public QMediaServiceProvider +{ + QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &) + { + Q_UNUSED(type); + return 0; + } + + void releaseService(QMediaService *service) + { + Q_UNUSED(service); + } +}; + + +class tst_QMediaServiceProvider : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + +private slots: + void testDefaultProviderAvailable(); + void testObtainService(); + void testHasSupport(); + void testSupportedMimeTypes(); + void testProviderHints(); + +private: + QObjectList plugins; +}; + +void tst_QMediaServiceProvider::initTestCase() +{ + plugins << new MockServicePlugin1; + plugins << new MockServicePlugin2; + plugins << new MockServicePlugin3; + + QMediaPluginLoader::setStaticPlugins(QLatin1String("/mediaservices"), plugins); +} + +void tst_QMediaServiceProvider::testDefaultProviderAvailable() +{ + // Must always be a default provider available + QVERIFY(QMediaServiceProvider::defaultServiceProvider() != 0); +} + +void tst_QMediaServiceProvider::testObtainService() +{ + QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider(); + + if (provider == 0) + QSKIP("No default provider", SkipSingle); + + QMediaService *service = 0; + + // Player + service = provider->requestService(Q_MEDIASERVICE_MEDIAPLAYER); + QVERIFY(service != 0); + provider->releaseService(service); +} + +void tst_QMediaServiceProvider::testHasSupport() +{ + MockMediaServiceProvider mockProvider; + QCOMPARE(mockProvider.hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER), "video/ogv", QStringList()), + QtMultimedia::MaybeSupported); + + QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider(); + + if (provider == 0) + QSKIP("No default provider", SkipSingle); + + QCOMPARE(provider->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER), "video/ogv", QStringList()), + QtMultimedia::MaybeSupported); + + QCOMPARE(provider->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER), "audio/ogg", QStringList()), + QtMultimedia::ProbablySupported); + + //while the service returns PreferredService, provider should return ProbablySupported + QCOMPARE(provider->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER), "audio/wav", QStringList()), + QtMultimedia::ProbablySupported); + + //even while all the plugins with "hasSupport" returned NotSupported, + //MockServicePlugin3 has no "hasSupport" interface, so MaybeSupported + QCOMPARE(provider->hasSupport(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER), "video/avi", + QStringList() << "mpeg4"), + QtMultimedia::MaybeSupported); + + QCOMPARE(provider->hasSupport(QByteArray("non existing service"), "video/ogv", QStringList()), + QtMultimedia::NotSupported); + + QCOMPARE(QMediaPlayer::hasSupport("video/ogv"), QtMultimedia::MaybeSupported); + QCOMPARE(QMediaPlayer::hasSupport("audio/ogg"), QtMultimedia::ProbablySupported); + QCOMPARE(QMediaPlayer::hasSupport("audio/wav"), QtMultimedia::ProbablySupported); + + //ensure the correct media player plugin is choosen for mime type + QMediaPlayer simplePlayer(0, QMediaPlayer::LowLatency); + QCOMPARE(simplePlayer.service()->objectName(), QLatin1String("MockServicePlugin2")); + + QMediaPlayer mediaPlayer; + QVERIFY(mediaPlayer.service()->objectName() != QLatin1String("MockServicePlugin2")); +} + +void tst_QMediaServiceProvider::testSupportedMimeTypes() +{ + QMediaServiceProvider *provider = QMediaServiceProvider::defaultServiceProvider(); + + if (provider == 0) + QSKIP("No default provider", SkipSingle); + + QVERIFY(provider->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER)).contains("audio/ogg")); + QVERIFY(!provider->supportedMimeTypes(QByteArray(Q_MEDIASERVICE_MEDIAPLAYER)).contains("audio/mp3")); +} + +void tst_QMediaServiceProvider::testProviderHints() +{ + { + QMediaServiceProviderHint hint; + QVERIFY(hint.isNull()); + QCOMPARE(hint.type(), QMediaServiceProviderHint::Null); + QVERIFY(hint.device().isEmpty()); + QVERIFY(hint.mimeType().isEmpty()); + QVERIFY(hint.codecs().isEmpty()); + QCOMPARE(hint.features(), 0); + } + + { + QByteArray deviceName(QByteArray("testDevice")); + QMediaServiceProviderHint hint(deviceName); + QVERIFY(!hint.isNull()); + QCOMPARE(hint.type(), QMediaServiceProviderHint::Device); + QCOMPARE(hint.device(), deviceName); + QVERIFY(hint.mimeType().isEmpty()); + QVERIFY(hint.codecs().isEmpty()); + QCOMPARE(hint.features(), 0); + } + + { + QMediaServiceProviderHint hint(QMediaServiceProviderHint::LowLatencyPlayback); + QVERIFY(!hint.isNull()); + QCOMPARE(hint.type(), QMediaServiceProviderHint::SupportedFeatures); + QVERIFY(hint.device().isEmpty()); + QVERIFY(hint.mimeType().isEmpty()); + QVERIFY(hint.codecs().isEmpty()); + QCOMPARE(hint.features(), QMediaServiceProviderHint::LowLatencyPlayback); + } + + { + QString mimeType(QLatin1String("video/ogg")); + QStringList codecs; + codecs << "theora" << "vorbis"; + + QMediaServiceProviderHint hint(mimeType,codecs); + QVERIFY(!hint.isNull()); + QCOMPARE(hint.type(), QMediaServiceProviderHint::ContentType); + QVERIFY(hint.device().isEmpty()); + QCOMPARE(hint.mimeType(), mimeType); + QCOMPARE(hint.codecs(), codecs); + + QMediaServiceProviderHint hint2(hint); + + QVERIFY(!hint2.isNull()); + QCOMPARE(hint2.type(), QMediaServiceProviderHint::ContentType); + QVERIFY(hint2.device().isEmpty()); + QCOMPARE(hint2.mimeType(), mimeType); + QCOMPARE(hint2.codecs(), codecs); + + QMediaServiceProviderHint hint3; + QVERIFY(hint3.isNull()); + hint3 = hint; + QVERIFY(!hint3.isNull()); + QCOMPARE(hint3.type(), QMediaServiceProviderHint::ContentType); + QVERIFY(hint3.device().isEmpty()); + QCOMPARE(hint3.mimeType(), mimeType); + QCOMPARE(hint3.codecs(), codecs); + + QCOMPARE(hint, hint2); + QCOMPARE(hint3, hint2); + + QMediaServiceProviderHint hint4(mimeType,codecs); + QCOMPARE(hint, hint4); + + QMediaServiceProviderHint hint5(mimeType,QStringList()); + QVERIFY(hint != hint5); + } +} + +QTEST_MAIN(tst_QMediaServiceProvider) + +#include "tst_qmediaserviceprovider.moc" diff --git a/tests/auto/qmediatimerange/qmediatimerange.pro b/tests/auto/qmediatimerange/qmediatimerange.pro new file mode 100644 index 0000000..b1b436e --- /dev/null +++ b/tests/auto/qmediatimerange/qmediatimerange.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qmediatimerange.cpp + +QT = core multimedia + diff --git a/tests/auto/qmediatimerange/tst_qmediatimerange.cpp b/tests/auto/qmediatimerange/tst_qmediatimerange.cpp new file mode 100644 index 0000000..54de3f1 --- /dev/null +++ b/tests/auto/qmediatimerange/tst_qmediatimerange.cpp @@ -0,0 +1,735 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/qdebug.h> + +#include <QtMultimedia/qmediatimerange.h> + +class tst_QMediaTimeRange: public QObject +{ + Q_OBJECT + +public slots: + +private slots: + void testCtor(); + void testGetters(); + void testAssignment(); + void testNormalize(); + void testTranslated(); + void testEarliestLatest(); + void testContains(); + void testAddInterval(); + void testAddTimeRange(); + void testRemoveInterval(); + void testRemoveTimeRange(); + void testClear(); + void testComparisons(); + void testArithmetic(); +}; + +void tst_QMediaTimeRange::testCtor() +{ + // Default Ctor + QMediaTimeRange a; + QVERIFY(a.isEmpty()); + + // (qint, qint) Ctor + QMediaTimeRange b(10, 20); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 20); + + // Interval Ctor + QMediaTimeRange c(QMediaTimeInterval(30, 40)); + + QVERIFY(!c.isEmpty()); + QVERIFY(c.isContinuous()); + QVERIFY(c.earliestTime() == 30); + QVERIFY(c.latestTime() == 40); + + // Abnormal Interval Ctor + QMediaTimeRange d(QMediaTimeInterval(20, 10)); + + QVERIFY(d.isEmpty()); + + // Copy Ctor + QMediaTimeRange e(b); + + QVERIFY(!e.isEmpty()); + QVERIFY(e.isContinuous()); + QVERIFY(e.earliestTime() == 10); + QVERIFY(e.latestTime() == 20); +} + +void tst_QMediaTimeRange::testGetters() +{ + QMediaTimeRange x; + + // isEmpty + QVERIFY(x.isEmpty()); + + x.addInterval(10, 20); + + // isEmpty + isContinuous + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + + x.addInterval(30, 40); + + // isEmpty + isContinuous + intervals + start + end + QVERIFY(!x.isEmpty()); + QVERIFY(!x.isContinuous()); + QVERIFY(x.intervals().count() == 2); + QVERIFY(x.intervals()[0].start() == 10); + QVERIFY(x.intervals()[0].end() == 20); + QVERIFY(x.intervals()[1].start() == 30); + QVERIFY(x.intervals()[1].end() == 40); +} + +void tst_QMediaTimeRange::testAssignment() +{ + QMediaTimeRange x; + + // Range Assignment + x = QMediaTimeRange(10, 20); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 10); + QVERIFY(x.latestTime() == 20); + + // Interval Assignment + x = QMediaTimeInterval(30, 40); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 30); + QVERIFY(x.latestTime() == 40); + + // Shared Data Check + QMediaTimeRange y; + + y = x; + y.addInterval(10, 20); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 30); + QVERIFY(x.latestTime() == 40); +} + +void tst_QMediaTimeRange::testNormalize() +{ + QMediaTimeInterval x(20, 10); + + QVERIFY(!x.isNormal()); + + x = x.normalized(); + + QVERIFY(x.isNormal()); + QVERIFY(x.start() == 10); + QVERIFY(x.end() == 20); +} + +void tst_QMediaTimeRange::testTranslated() +{ + QMediaTimeInterval x(10, 20); + x = x.translated(10); + + QVERIFY(x.start() == 20); + QVERIFY(x.end() == 30); +} + +void tst_QMediaTimeRange::testEarliestLatest() +{ + // Test over a single interval + QMediaTimeRange x(30, 40); + + QVERIFY(x.earliestTime() == 30); + QVERIFY(x.latestTime() == 40); + + // Test over multiple intervals + x.addInterval(50, 60); + + QVERIFY(x.earliestTime() == 30); + QVERIFY(x.latestTime() == 60); +} + +void tst_QMediaTimeRange::testContains() +{ + // Test over a single interval + QMediaTimeRange x(10, 20); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.contains(15)); + QVERIFY(x.contains(10)); + QVERIFY(x.contains(20)); + QVERIFY(!x.contains(25)); + + // Test over multiple intervals + x.addInterval(40, 50); + + QVERIFY(!x.isEmpty()); + QVERIFY(!x.isContinuous()); + QVERIFY(x.contains(15)); + QVERIFY(x.contains(45)); + QVERIFY(!x.contains(30)); + + // Test over a concrete interval + QMediaTimeInterval y(10, 20); + QVERIFY(y.contains(15)); + QVERIFY(y.contains(10)); + QVERIFY(y.contains(20)); + QVERIFY(!y.contains(25)); +} + +void tst_QMediaTimeRange::testAddInterval() +{ + // All intervals Overlap + QMediaTimeRange x; + x.addInterval(10, 40); + x.addInterval(30, 50); + x.addInterval(20, 60); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 10); + QVERIFY(x.latestTime() == 60); + + // 1 adjacent interval, 1 encompassed interval + x = QMediaTimeRange(); + x.addInterval(10, 40); + x.addInterval(20, 30); + x.addInterval(41, 50); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 10); + QVERIFY(x.latestTime() == 50); + + // 1 overlapping interval, 1 disjoint interval + x = QMediaTimeRange(); + x.addInterval(10, 30); + x.addInterval(20, 40); + x.addInterval(50, 60); + + QVERIFY(!x.isEmpty()); + QVERIFY(!x.isContinuous()); + QVERIFY(x.intervals().count() == 2); + QVERIFY(x.intervals()[0].start() == 10); + QVERIFY(x.intervals()[0].end() == 40); + QVERIFY(x.intervals()[1].start() == 50); + QVERIFY(x.intervals()[1].end() == 60); + + // Identical Add + x = QMediaTimeRange(); + x.addInterval(10, 20); + x.addInterval(10, 20); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 10); + QVERIFY(x.latestTime() == 20); + + // Multi-Merge + x = QMediaTimeRange(); + x.addInterval(10, 20); + x.addInterval(30, 40); + x.addInterval(50, 60); + x.addInterval(15, 55); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 10); + QVERIFY(x.latestTime() == 60); + + // Interval Parameter - All intervals Overlap + x = QMediaTimeRange(); + x.addInterval(QMediaTimeInterval(10, 40)); + x.addInterval(QMediaTimeInterval(30, 50)); + x.addInterval(QMediaTimeInterval(20, 60)); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 10); + QVERIFY(x.latestTime() == 60); + + // Interval Parameter - Abnormal Interval + x = QMediaTimeRange(); + x.addInterval(QMediaTimeInterval(20, 10)); + + QVERIFY(x.isEmpty()); +} + +void tst_QMediaTimeRange::testAddTimeRange() +{ + // Add Time Range uses Add Interval internally, + // so in this test the focus is on combinations of number + // of intervals added, rather than the different types of + // merges which can occur. + QMediaTimeRange a, b; + + // Add Single into Single + a = QMediaTimeRange(10, 30); + b = QMediaTimeRange(20, 40); + + b.addTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 40); + + // Add Multiple into Single + a = QMediaTimeRange(); + a.addInterval(10, 30); + a.addInterval(40, 60); + + b = QMediaTimeRange(20, 50); + + b.addTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 60); + + // Add Single into Multiple + a = QMediaTimeRange(20, 50); + + b = QMediaTimeRange(); + b.addInterval(10, 30); + b.addInterval(40, 60); + + b.addTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 60); + + // Add Multiple into Multiple + a = QMediaTimeRange(); + a.addInterval(10, 30); + a.addInterval(40, 70); + a.addInterval(80, 100); + + b = QMediaTimeRange(); + b.addInterval(20, 50); + b.addInterval(60, 90); + + b.addTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 100); + + // Add Nothing to Single + a = QMediaTimeRange(); + b = QMediaTimeRange(10, 20); + + b.addTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 20); + + // Add Single to Nothing + a = QMediaTimeRange(10, 20); + b = QMediaTimeRange(); + + b.addTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 20); + + // Add Nothing to Nothing + a = QMediaTimeRange(); + b = QMediaTimeRange(); + + b.addTimeRange(a); + + QVERIFY(b.isEmpty()); +} + +void tst_QMediaTimeRange::testRemoveInterval() +{ + // Removing an interval, causing a split + QMediaTimeRange x; + x.addInterval(10, 50); + x.removeInterval(20, 40); + + QVERIFY(!x.isEmpty()); + QVERIFY(!x.isContinuous()); + QVERIFY(x.intervals().count() == 2); + QVERIFY(x.intervals()[0].start() == 10); + QVERIFY(x.intervals()[0].end() == 19); + QVERIFY(x.intervals()[1].start() == 41); + QVERIFY(x.intervals()[1].end() == 50); + + // Removing an interval, causing a deletion + x = QMediaTimeRange(); + x.addInterval(20, 30); + x.removeInterval(10, 40); + + QVERIFY(x.isEmpty()); + + // Removing an interval, causing a tail trim + x = QMediaTimeRange(); + x.addInterval(20, 40); + x.removeInterval(30, 50); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 20); + QVERIFY(x.latestTime() == 29); + + // Removing an interval, causing a head trim + x = QMediaTimeRange(); + x.addInterval(20, 40); + x.removeInterval(10, 30); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 31); + QVERIFY(x.latestTime() == 40); + + // Identical Remove + x = QMediaTimeRange(); + x.addInterval(10, 20); + x.removeInterval(10, 20); + + QVERIFY(x.isEmpty()); + + // Multi-Trim + x = QMediaTimeRange(); + x.addInterval(10, 20); + x.addInterval(30, 40); + x.removeInterval(15, 35); + + QVERIFY(!x.isEmpty()); + QVERIFY(!x.isContinuous()); + QVERIFY(x.intervals().count() == 2); + QVERIFY(x.intervals()[0].start() == 10); + QVERIFY(x.intervals()[0].end() == 14); + QVERIFY(x.intervals()[1].start() == 36); + QVERIFY(x.intervals()[1].end() == 40); + + // Multi-Delete + x = QMediaTimeRange(); + x.addInterval(10, 20); + x.addInterval(30, 40); + x.addInterval(50, 60); + x.removeInterval(10, 60); + + QVERIFY(x.isEmpty()); + + // Interval Parameter - Removing an interval, causing a split + x = QMediaTimeRange(); + x.addInterval(10, 50); + x.removeInterval(QMediaTimeInterval(20, 40)); + + QVERIFY(!x.isEmpty()); + QVERIFY(!x.isContinuous()); + QVERIFY(x.intervals().count() == 2); + QVERIFY(x.intervals()[0].start() == 10); + QVERIFY(x.intervals()[0].end() == 19); + QVERIFY(x.intervals()[1].start() == 41); + QVERIFY(x.intervals()[1].end() == 50); + + // Interval Parameter - Abnormal Interval + x = QMediaTimeRange(); + x.addInterval(10, 40); + x.removeInterval(QMediaTimeInterval(30, 20)); + + QVERIFY(!x.isEmpty()); + QVERIFY(x.isContinuous()); + QVERIFY(x.earliestTime() == 10); + QVERIFY(x.latestTime() == 40); +} + +void tst_QMediaTimeRange::testRemoveTimeRange() +{ + // Remove Time Range uses Remove Interval internally, + // so in this test the focus is on combinations of number + // of intervals removed, rather than the different types of + // deletions which can occur. + QMediaTimeRange a, b; + + // Remove Single from Single + a = QMediaTimeRange(10, 30); + b = QMediaTimeRange(20, 40); + + b.removeTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 31); + QVERIFY(b.latestTime() == 40); + + // Remove Multiple from Single + a = QMediaTimeRange(); + a.addInterval(10, 30); + a.addInterval(40, 60); + + b = QMediaTimeRange(20, 50); + + b.removeTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 31); + QVERIFY(b.latestTime() == 39); + + // Remove Single from Multiple + a = QMediaTimeRange(20, 50); + + b = QMediaTimeRange(); + b.addInterval(10, 30); + b.addInterval(40, 60); + + b.removeTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(!b.isContinuous()); + QVERIFY(b.intervals().count() == 2); + QVERIFY(b.intervals()[0].start() == 10); + QVERIFY(b.intervals()[0].end() == 19); + QVERIFY(b.intervals()[1].start() == 51); + QVERIFY(b.intervals()[1].end() == 60); + + // Remove Multiple from Multiple + a = QMediaTimeRange(); + a.addInterval(20, 50); + a.addInterval(50, 90); + + + b = QMediaTimeRange(); + b.addInterval(10, 30); + b.addInterval(40, 70); + b.addInterval(80, 100); + + b.removeTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(!b.isContinuous()); + QVERIFY(b.intervals().count() == 2); + QVERIFY(b.intervals()[0].start() == 10); + QVERIFY(b.intervals()[0].end() == 19); + QVERIFY(b.intervals()[1].start() == 91); + QVERIFY(b.intervals()[1].end() == 100); + + // Remove Nothing from Single + a = QMediaTimeRange(); + b = QMediaTimeRange(10, 20); + + b.removeTimeRange(a); + + QVERIFY(!b.isEmpty()); + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 10); + QVERIFY(b.latestTime() == 20); + + // Remove Single from Nothing + a = QMediaTimeRange(10, 20); + b = QMediaTimeRange(); + + b.removeTimeRange(a); + + QVERIFY(b.isEmpty()); + + // Remove Nothing from Nothing + a = QMediaTimeRange(); + b = QMediaTimeRange(); + + b.removeTimeRange(a); + + QVERIFY(b.isEmpty()); +} + +void tst_QMediaTimeRange::testClear() +{ + QMediaTimeRange x; + + // Clear Nothing + x.clear(); + + QVERIFY(x.isEmpty()); + + // Clear Single + x = QMediaTimeRange(10, 20); + x.clear(); + + QVERIFY(x.isEmpty()); + + // Clear Multiple + x = QMediaTimeRange(); + x.addInterval(10, 20); + x.addInterval(30, 40); + x.clear(); + + QVERIFY(x.isEmpty()); +} + +void tst_QMediaTimeRange::testComparisons() +{ + // Interval equality + QVERIFY(QMediaTimeInterval(10, 20) == QMediaTimeInterval(10, 20)); + QVERIFY(QMediaTimeInterval(10, 20) != QMediaTimeInterval(10, 30)); + QVERIFY(!(QMediaTimeInterval(10, 20) != QMediaTimeInterval(10, 20))); + QVERIFY(!(QMediaTimeInterval(10, 20) == QMediaTimeInterval(10, 30))); + + // Time range equality - Single Interval + QMediaTimeRange a(10, 20), b(20, 30), c(10, 20); + + QVERIFY(a == c); + QVERIFY(!(a == b)); + QVERIFY(a != b); + QVERIFY(!(a != c)); + + // Time Range Equality - Multiple Intervals + QMediaTimeRange x, y, z; + + x.addInterval(10, 20); + x.addInterval(30, 40); + x.addInterval(50, 60); + + y.addInterval(10, 20); + y.addInterval(35, 45); + y.addInterval(50, 60); + + z.addInterval(10, 20); + z.addInterval(30, 40); + z.addInterval(50, 60); + + QVERIFY(x == z); + QVERIFY(!(x == y)); + QVERIFY(x != y); + QVERIFY(!(x != z)); +} + +void tst_QMediaTimeRange::testArithmetic() +{ + QMediaTimeRange a(10, 20), b(20, 30); + + // Test += + a += b; + + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 30); + + // Test -= + a -= b; + + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 19); + + // Test += and -= on intervals + a -= QMediaTimeInterval(10, 20); + a += QMediaTimeInterval(40, 50); + + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 40); + QVERIFY(a.latestTime() == 50); + + // Test Interval + Interval + a = QMediaTimeInterval(10, 20) + QMediaTimeInterval(20, 30); + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 30); + + // Test Range + Interval + a = a + QMediaTimeInterval(30, 40); + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 40); + + // Test Interval + Range + a = QMediaTimeInterval(40, 50) + a; + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 50); + + // Test Range + Range + a = a + QMediaTimeRange(50, 60); + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 60); + + // Test Range - Interval + a = a - QMediaTimeInterval(50, 60); + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 49); + + // Test Range - Range + a = a - QMediaTimeRange(40, 50); + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 39); + + // Test Interval - Range + b = QMediaTimeInterval(0, 20) - a; + QVERIFY(b.isContinuous()); + QVERIFY(b.earliestTime() == 0); + QVERIFY(b.latestTime() == 9); + + // Test Interval - Interval + a = QMediaTimeInterval(10, 20) - QMediaTimeInterval(15, 30); + QVERIFY(a.isContinuous()); + QVERIFY(a.earliestTime() == 10); + QVERIFY(a.latestTime() == 14); +} + +QTEST_MAIN(tst_QMediaTimeRange) + +#include "tst_qmediatimerange.moc" diff --git a/tests/auto/qmlaudio/qmlaudio.pro b/tests/auto/qmlaudio/qmlaudio.pro new file mode 100644 index 0000000..fe18761 --- /dev/null +++ b/tests/auto/qmlaudio/qmlaudio.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +SOURCES += tst_qmlaudio.cpp + +QT += multimedia declarative +requires(contains(QT_CONFIG, multimedia)) +requires(contains(QT_CONFIG, declarative)) diff --git a/tests/auto/qmlaudio/tst_qmlaudio.cpp b/tests/auto/qmlaudio/tst_qmlaudio.cpp new file mode 100644 index 0000000..068317f --- /dev/null +++ b/tests/auto/qmlaudio/tst_qmlaudio.cpp @@ -0,0 +1,1200 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtMultimedia/private/qmlaudio_p.h> + +#include <QtGui/qapplication.h> +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qmetadatacontrol.h> + + +class tst_QmlAudio : public QObject +{ + Q_OBJECT +public slots: + void initTestCase(); + +private slots: + void nullPlayerControl(); + void nullMetaDataControl(); + void nullService(); + + void source(); + void playing(); + void paused(); + void duration(); + void position(); + void volume(); + void muted(); + void bufferProgress(); + void seekable(); + void playbackRate(); + void status(); + void metaData_data(); + void metaData(); + void error(); +}; + +Q_DECLARE_METATYPE(QtMultimedia::MetaData); +Q_DECLARE_METATYPE(QmlAudio::Error); + +class QtTestMediaPlayerControl : public QMediaPlayerControl +{ + Q_OBJECT +public: + QtTestMediaPlayerControl(QObject *parent = 0) + : QMediaPlayerControl(parent) + , m_state(QMediaPlayer::StoppedState) + , m_mediaStatus(QMediaPlayer::NoMedia) + , m_duration(0) + , m_position(0) + , m_playbackRate(1.0) + , m_volume(50) + , m_bufferStatus(0) + , m_muted(false) + , m_audioAvailable(false) + , m_videoAvailable(false) + , m_seekable(false) + { + } + + QMediaPlayer::State state() const { return m_state; } + void updateState(QMediaPlayer::State state) { emit stateChanged(m_state = state); } + + QMediaPlayer::MediaStatus mediaStatus() const { return m_mediaStatus; } + void updateMediaStatus(QMediaPlayer::MediaStatus status) { + emit mediaStatusChanged(m_mediaStatus = status); } + void updateMediaStatus(QMediaPlayer::MediaStatus status, QMediaPlayer::State state) + { + m_mediaStatus = status; + m_state = state; + + emit mediaStatusChanged(m_mediaStatus); + emit stateChanged(m_state); + } + + qint64 duration() const { return m_duration; } + void setDuration(qint64 duration) { emit durationChanged(m_duration = duration); } + + qint64 position() const { return m_position; } + void setPosition(qint64 position) { emit positionChanged(m_position = position); } + + int volume() const { return m_volume; } + void setVolume(int volume) { emit volumeChanged(m_volume = volume); } + + bool isMuted() const { return m_muted; } + void setMuted(bool muted) { emit mutedChanged(m_muted = muted); } + + int bufferStatus() const { return m_bufferStatus; } + void setBufferStatus(int status) { emit bufferStatusChanged(m_bufferStatus = status); } + + bool isAudioAvailable() const { return m_audioAvailable; } + void setAudioAvailable(bool available) { + emit audioAvailableChanged(m_audioAvailable = available); } + bool isVideoAvailable() const { return m_videoAvailable; } + void setVideoAvailable(bool available) { + emit videoAvailableChanged(m_videoAvailable = available); } + + bool isSeekable() const { return m_seekable; } + void setSeekable(bool seekable) { emit seekableChanged(m_seekable = seekable); } + + QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(); } + + qreal playbackRate() const { return m_playbackRate; } + void setPlaybackRate(qreal rate) { emit playbackRateChanged(m_playbackRate = rate); } + + QMediaContent media() const { return m_media; } + const QIODevice *mediaStream() const { return 0; } + void setMedia(const QMediaContent &media, QIODevice *) + { + m_media = media; + + m_mediaStatus = m_media.isNull() + ? QMediaPlayer::NoMedia + : QMediaPlayer::LoadingMedia; + + emit mediaChanged(m_media); + emit mediaStatusChanged(m_mediaStatus); + } + + void play() { emit stateChanged(m_state = QMediaPlayer::PlayingState); } + void pause() { emit stateChanged(m_state = QMediaPlayer::PausedState); } + void stop() { emit stateChanged(m_state = QMediaPlayer::StoppedState); } + + void emitError(QMediaPlayer::Error err, const QString &errorString) { + emit error(err, errorString); } + +private: + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_mediaStatus; + qint64 m_duration; + qint64 m_position; + qreal m_playbackRate; + int m_volume; + int m_bufferStatus; + bool m_muted; + bool m_audioAvailable; + bool m_videoAvailable; + bool m_seekable; + QMediaContent m_media; +}; + +class QtTestMetaDataControl : public QMetaDataControl +{ + Q_OBJECT +public: + QtTestMetaDataControl(QObject *parent = 0) + : QMetaDataControl(parent) + { + } + + bool isWritable() const { return true; } + bool isMetaDataAvailable() const { return true; } + + QVariant metaData(QtMultimedia::MetaData key) const { return m_metaData.value(key); } + void setMetaData(QtMultimedia::MetaData key, const QVariant &value) { + m_metaData.insert(key, value); emit metaDataChanged(); } + void setMetaData(const QMap<QtMultimedia::MetaData, QVariant> &metaData) { + m_metaData = metaData; emit metaDataChanged(); } + + QList<QtMultimedia::MetaData> availableMetaData() const { return m_metaData.keys(); } + + QVariant extendedMetaData(const QString &) const { return QVariant(); } + void setExtendedMetaData(const QString &, const QVariant &) {} + QStringList availableExtendedMetaData() const { return QStringList(); } + +private: + QMap<QtMultimedia::MetaData, QVariant> m_metaData; +}; + +class QtTestMediaService : public QMediaService +{ + Q_OBJECT +public: + QtTestMediaService( + QtTestMediaPlayerControl *playerControl, + QtTestMetaDataControl *metaDataControl, + QObject *parent) + : QMediaService(parent) + , playerControl(playerControl) + , metaDataControl(metaDataControl) + { + } + + QMediaControl *control(const char *name) const + { + if (qstrcmp(name, QMediaPlayerControl_iid) == 0) + return playerControl; + else if (qstrcmp(name, QMetaDataControl_iid) == 0) + return metaDataControl; + else + return 0; + } + + QtTestMediaPlayerControl *playerControl; + QtTestMetaDataControl *metaDataControl; +}; + +class QtTestMediaServiceProvider : public QMediaServiceProvider +{ + Q_OBJECT +public: + QtTestMediaServiceProvider() + : service(new QtTestMediaService( + new QtTestMediaPlayerControl(this), new QtTestMetaDataControl(this), this)) + { + setDefaultServiceProvider(this); + } + + QtTestMediaServiceProvider(QtTestMediaService *service) + : service(service) + { + setDefaultServiceProvider(this); + } + + QtTestMediaServiceProvider( + QtTestMediaPlayerControl *playerControl, QtTestMetaDataControl *metaDataControl) + : service(new QtTestMediaService(playerControl, metaDataControl, this)) + { + setDefaultServiceProvider(this); + } + + ~QtTestMediaServiceProvider() + { + setDefaultServiceProvider(0); + } + + QMediaService *requestService( + const QByteArray &type, + const QMediaServiceProviderHint & = QMediaServiceProviderHint()) + { + requestedService = type; + + return service; + } + + void releaseService(QMediaService *) {} + + inline QtTestMediaPlayerControl *playerControl() { return service->playerControl; } + inline QtTestMetaDataControl *metaDataControl() { return service->metaDataControl; } + + QtTestMediaService *service; + QByteArray requestedService; +}; + + +void tst_QmlAudio::initTestCase() +{ + qRegisterMetaType<QmlAudio::Error>(); +} + +void tst_QmlAudio::nullPlayerControl() +{ + QtTestMetaDataControl metaDataControl; + QtTestMediaServiceProvider provider(0, &metaDataControl); + + QmlAudio audio; + + QCOMPARE(audio.source(), QUrl()); + audio.setSource(QUrl("http://example.com")); + QCOMPARE(audio.source(), QUrl()); + + QCOMPARE(audio.isPlaying(), false); + audio.setPlaying(true); + QCOMPARE(audio.isPlaying(), false); + audio.play(); + QCOMPARE(audio.isPlaying(), false); + + QCOMPARE(audio.isPaused(), false); + audio.pause(); + QCOMPARE(audio.isPaused(), false); + audio.setPaused(true); + QCOMPARE(audio.isPaused(), true); + + QCOMPARE(audio.duration(), 0); + + QCOMPARE(audio.position(), 0); + audio.setPosition(10000); + QCOMPARE(audio.position(), 0); + + QCOMPARE(audio.volume(), qreal(0)); + audio.setVolume(50); + QCOMPARE(audio.volume(), qreal(0)); + + QCOMPARE(audio.isMuted(), false); + audio.setMuted(true); + QCOMPARE(audio.isMuted(), false); + + QCOMPARE(audio.bufferProgress(), qreal(0)); + + QCOMPARE(audio.isSeekable(), false); + + QCOMPARE(audio.playbackRate(), qreal(1.0)); + + QCOMPARE(audio.status(), QmlAudio::NoMedia); + + QCOMPARE(audio.error(), QmlAudio::ServiceMissing); +} + +void tst_QmlAudio::nullMetaDataControl() +{ + QtTestMediaPlayerControl playerControl; + QtTestMediaServiceProvider provider(&playerControl, 0); + + QmlAudio audio; + + QCOMPARE(audio.metaObject()->indexOfProperty("title"), -1); + QCOMPARE(audio.metaObject()->indexOfProperty("genre"), -1); + QCOMPARE(audio.metaObject()->indexOfProperty("description"), -1); +} + +void tst_QmlAudio::nullService() +{ + QtTestMediaServiceProvider provider(0); + + QmlAudio audio; + + QCOMPARE(audio.source(), QUrl()); + audio.setSource(QUrl("http://example.com")); + QCOMPARE(audio.source(), QUrl()); + + QCOMPARE(audio.isPlaying(), false); + audio.setPlaying(true); + QCOMPARE(audio.isPlaying(), false); + audio.play(); + QCOMPARE(audio.isPlaying(), false); + + QCOMPARE(audio.isPaused(), false); + audio.pause(); + QCOMPARE(audio.isPaused(), false); + audio.setPaused(true); + QCOMPARE(audio.isPaused(), true); + + QCOMPARE(audio.duration(), 0); + + QCOMPARE(audio.position(), 0); + audio.setPosition(10000); + QCOMPARE(audio.position(), 0); + + QCOMPARE(audio.volume(), qreal(0)); + audio.setVolume(50); + QCOMPARE(audio.volume(), qreal(0)); + + QCOMPARE(audio.isMuted(), false); + audio.setMuted(true); + QCOMPARE(audio.isMuted(), false); + + QCOMPARE(audio.bufferProgress(), qreal(0)); + + QCOMPARE(audio.isSeekable(), false); + + QCOMPARE(audio.playbackRate(), qreal(1.0)); + + QCOMPARE(audio.status(), QmlAudio::NoMedia); + + QCOMPARE(audio.error(), QmlAudio::ServiceMissing); + + QCOMPARE(audio.metaObject()->indexOfProperty("title"), -1); + QCOMPARE(audio.metaObject()->indexOfProperty("genre"), -1); + QCOMPARE(audio.metaObject()->indexOfProperty("description"), -1); +} + +void tst_QmlAudio::source() +{ + const QUrl url1("http://example.com"); + const QUrl url2("file:///local/path"); + const QUrl url3; + + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(sourceChanged())); + + audio.setSource(url1); + QCOMPARE(audio.source(), url1); + QCOMPARE(provider.playerControl()->media().canonicalUrl(), url1); + QCOMPARE(spy.count(), 1); + + audio.setSource(url2); + QCOMPARE(audio.source(), url2); + QCOMPARE(provider.playerControl()->media().canonicalUrl(), url2); + QCOMPARE(spy.count(), 2); + + audio.setSource(url3); + QCOMPARE(audio.source(), url3); + QCOMPARE(provider.playerControl()->media().canonicalUrl(), url3); + QCOMPARE(spy.count(), 3); +} + +void tst_QmlAudio::playing() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy playingChangedSpy(&audio, SIGNAL(playingChanged())); + QSignalSpy startedSpy(&audio, SIGNAL(started())); + QSignalSpy stoppedSpy(&audio, SIGNAL(stopped())); + + int playingChanged = 0; + int started = 0; + int stopped = 0; + + QCOMPARE(audio.isPlaying(), false); + + // setPlaying(true) when stopped. + audio.setPlaying(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when playing. + audio.setPlaying(false); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // play() when stopped. + audio.play(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(stoppedSpy.count(), stopped); + + // stop() when playing. + audio.stop(); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // stop() when stopped. + audio.stop(); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when stopped. + audio.setPlaying(false); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); + + audio.setPlaying(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(true) when playing. + audio.setPlaying(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); + + // play() when playing. + audio.play(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); +} + +void tst_QmlAudio::paused() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy playingChangedSpy(&audio, SIGNAL(playingChanged())); + QSignalSpy pausedChangedSpy(&audio, SIGNAL(pausedChanged())); + QSignalSpy startedSpy(&audio, SIGNAL(started())); + QSignalSpy pausedSpy(&audio, SIGNAL(paused())); + QSignalSpy resumedSpy(&audio, SIGNAL(resumed())); + QSignalSpy stoppedSpy(&audio, SIGNAL(stopped())); + + int playingChanged = 0; + int pausedChanged = 0; + int started = 0; + int paused = 0; + int resumed = 0; + int stopped = 0; + + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), false); + + // setPlaying(true) when stopped. + audio.setPlaying(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when playing. + audio.setPaused(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when paused. + audio.setPaused(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // pause() when paused. + audio.pause(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(false) when paused. + audio.setPaused(false); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), ++resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(false) when playing. + audio.setPaused(false); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // pause() when playing. + audio.pause(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when paused. + audio.setPlaying(false); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // setPaused(true) when stopped and paused. + audio.setPaused(true); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(false) when stopped and paused. + audio.setPaused(false); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when stopped. + audio.setPaused(true); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(true) when stopped and paused. + audio.setPlaying(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // play() when paused. + audio.play(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), ++resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when playing. + audio.setPaused(true); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // stop() when paused. + audio.stop(); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // setPaused(true) when stopped. + audio.setPaused(true); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // stop() when stopped and paused. + audio.stop(); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // pause() when stopped. + audio.pause(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when paused. + audio.setPlaying(false); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // pause() when stopped and paused. + audio.pause(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when paused. + audio.setPlaying(false); + QCOMPARE(audio.isPlaying(), false); + QCOMPARE(audio.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // play() when stopped and paused. + audio.play(); + QCOMPARE(audio.isPlaying(), true); + QCOMPARE(audio.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); +} + +void tst_QmlAudio::duration() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(durationChanged())); + + QCOMPARE(audio.duration(), 0); + + provider.playerControl()->setDuration(4040); + QCOMPARE(audio.duration(), 4040); + QCOMPARE(spy.count(), 1); + + provider.playerControl()->setDuration(-129); + QCOMPARE(audio.duration(), -129); + QCOMPARE(spy.count(), 2); + + provider.playerControl()->setDuration(0); + QCOMPARE(audio.duration(), 0); + QCOMPARE(spy.count(), 3); + + // Unnecessary duration changed signals aren't filtered. + provider.playerControl()->setDuration(0); + QCOMPARE(audio.duration(), 0); + QCOMPARE(spy.count(), 4); +} + +void tst_QmlAudio::position() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(positionChanged())); + + QCOMPARE(audio.position(), 0); + + // QmlAudio won't bound set positions to the duration. A media service may though. + QCOMPARE(audio.duration(), 0); + + audio.setPosition(450); + QCOMPARE(audio.position(), 450); + QCOMPARE(provider.playerControl()->position(), qint64(450)); + QCOMPARE(spy.count(), 1); + + audio.setPosition(-5403); + QCOMPARE(audio.position(), -5403); + QCOMPARE(provider.playerControl()->position(), qint64(-5403)); + QCOMPARE(spy.count(), 2); + + audio.setPosition(-5403); + QCOMPARE(audio.position(), -5403); + QCOMPARE(provider.playerControl()->position(), qint64(-5403)); + QCOMPARE(spy.count(), 3); + + // Check the signal change signal is emitted if the change originates from the media service. + provider.playerControl()->setPosition(0); + QCOMPARE(audio.position(), 0); + QCOMPARE(spy.count(), 4); + + connect(&audio, SIGNAL(positionChanged()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + provider.playerControl()->updateState(QMediaPlayer::PlayingState); + QTestEventLoop::instance().enterLoop(1); + QVERIFY(spy.count() > 4 && spy.count() < 7); // 5 or 6 + + provider.playerControl()->updateState(QMediaPlayer::PausedState); + QTestEventLoop::instance().enterLoop(1); + QVERIFY(spy.count() < 7); +} + +void tst_QmlAudio::volume() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(volumeChanged())); + + QCOMPARE(audio.volume(), qreal(0.5)); + + audio.setVolume(0.7); + QCOMPARE(audio.volume(), qreal(0.7)); + QCOMPARE(provider.playerControl()->volume(), 70); + QCOMPARE(spy.count(), 1); + + audio.setVolume(0.7); + QCOMPARE(audio.volume(), qreal(0.7)); + QCOMPARE(provider.playerControl()->volume(), 70); + QCOMPARE(spy.count(), 2); + + provider.playerControl()->setVolume(30); + QCOMPARE(audio.volume(), qreal(0.3)); + QCOMPARE(spy.count(), 3); +} + +void tst_QmlAudio::muted() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(mutedChanged())); + + QCOMPARE(audio.isMuted(), false); + + audio.setMuted(true); + QCOMPARE(audio.isMuted(), true); + QCOMPARE(provider.playerControl()->isMuted(), true); + QCOMPARE(spy.count(), 1); + + provider.playerControl()->setMuted(false); + QCOMPARE(audio.isMuted(), false); + QCOMPARE(spy.count(), 2); + + audio.setMuted(false); + QCOMPARE(audio.isMuted(), false); + QCOMPARE(provider.playerControl()->isMuted(), false); + QCOMPARE(spy.count(), 3); +} + +void tst_QmlAudio::bufferProgress() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(bufferProgressChanged())); + + QCOMPARE(audio.bufferProgress(), qreal(0.0)); + + provider.playerControl()->setBufferStatus(20); + QCOMPARE(audio.bufferProgress(), qreal(0.2)); + QCOMPARE(spy.count(), 1); + + provider.playerControl()->setBufferStatus(20); + QCOMPARE(audio.bufferProgress(), qreal(0.2)); + QCOMPARE(spy.count(), 2); + + provider.playerControl()->setBufferStatus(40); + QCOMPARE(audio.bufferProgress(), qreal(0.4)); + QCOMPARE(spy.count(), 3); + + connect(&audio, SIGNAL(positionChanged()), &QTestEventLoop::instance(), SLOT(exitLoop())); + + provider.playerControl()->updateMediaStatus( + QMediaPlayer::BufferingMedia, QMediaPlayer::PlayingState); + QTestEventLoop::instance().enterLoop(1); + QVERIFY(spy.count() > 3 && spy.count() < 6); // 4 or 5 + + provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferedMedia); + QTestEventLoop::instance().enterLoop(1); + QVERIFY(spy.count() < 6); +} + +void tst_QmlAudio::seekable() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(seekableChanged())); + + QCOMPARE(audio.isSeekable(), false); + + provider.playerControl()->setSeekable(true); + QCOMPARE(audio.isSeekable(), true); + QCOMPARE(spy.count(), 1); + + provider.playerControl()->setSeekable(true); + QCOMPARE(audio.isSeekable(), true); + QCOMPARE(spy.count(), 2); + + provider.playerControl()->setSeekable(false); + QCOMPARE(audio.isSeekable(), false); + QCOMPARE(spy.count(), 3); +} + +void tst_QmlAudio::playbackRate() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(playbackRateChanged())); + + QCOMPARE(audio.playbackRate(), qreal(1.0)); + + audio.setPlaybackRate(0.5); + QCOMPARE(audio.playbackRate(), qreal(0.5)); + QCOMPARE(provider.playerControl()->playbackRate(), qreal(0.5)); + QCOMPARE(spy.count(), 1); + + provider.playerControl()->setPlaybackRate(2.0); + QCOMPARE(provider.playerControl()->playbackRate(), qreal(2.0)); + QCOMPARE(spy.count(), 2); + + audio.setPlaybackRate(2.0); + QCOMPARE(audio.playbackRate(), qreal(2.0)); + QCOMPARE(provider.playerControl()->playbackRate(), qreal(2.0)); + QCOMPARE(spy.count(), 3); +} + +void tst_QmlAudio::status() +{ + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy statusChangedSpy(&audio, SIGNAL(statusChanged())); + QSignalSpy loadedSpy(&audio, SIGNAL(loaded())); + QSignalSpy bufferingSpy(&audio, SIGNAL(buffering())); + QSignalSpy stalledSpy(&audio, SIGNAL(stalled())); + QSignalSpy bufferedSpy(&audio, SIGNAL(buffered())); + QSignalSpy endOfMediaSpy(&audio, SIGNAL(endOfMedia())); + + QCOMPARE(audio.status(), QmlAudio::NoMedia); + + // Set media, start loading. + provider.playerControl()->updateMediaStatus(QMediaPlayer::LoadingMedia); + QCOMPARE(audio.status(), QmlAudio::Loading); + QCOMPARE(statusChangedSpy.count(), 1); + QCOMPARE(loadedSpy.count(), 0); + QCOMPARE(bufferingSpy.count(), 0); + QCOMPARE(stalledSpy.count(), 0); + QCOMPARE(bufferedSpy.count(), 0); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Finish loading. + provider.playerControl()->updateMediaStatus(QMediaPlayer::LoadedMedia); + QCOMPARE(audio.status(), QmlAudio::Loaded); + QCOMPARE(statusChangedSpy.count(), 2); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 0); + QCOMPARE(stalledSpy.count(), 0); + QCOMPARE(bufferedSpy.count(), 0); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Play, start buffering. + provider.playerControl()->updateMediaStatus( + QMediaPlayer::StalledMedia, QMediaPlayer::PlayingState); + QCOMPARE(audio.status(), QmlAudio::Stalled); + QCOMPARE(statusChangedSpy.count(), 3); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 0); + QCOMPARE(stalledSpy.count(), 1); + QCOMPARE(bufferedSpy.count(), 0); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Enough data buffered to proceed. + provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferingMedia); + QCOMPARE(audio.status(), QmlAudio::Buffering); + QCOMPARE(statusChangedSpy.count(), 4); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 1); + QCOMPARE(stalledSpy.count(), 1); + QCOMPARE(bufferedSpy.count(), 0); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Errant second buffering status changed. + provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferingMedia); + QCOMPARE(audio.status(), QmlAudio::Buffering); + QCOMPARE(statusChangedSpy.count(), 4); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 1); + QCOMPARE(stalledSpy.count(), 1); + QCOMPARE(bufferedSpy.count(), 0); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Buffer full. + provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferedMedia); + QCOMPARE(audio.status(), QmlAudio::Buffered); + QCOMPARE(statusChangedSpy.count(), 5); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 1); + QCOMPARE(stalledSpy.count(), 1); + QCOMPARE(bufferedSpy.count(), 1); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Buffer getting low. + provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferingMedia); + QCOMPARE(audio.status(), QmlAudio::Buffering); + QCOMPARE(statusChangedSpy.count(), 6); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 2); + QCOMPARE(stalledSpy.count(), 1); + QCOMPARE(bufferedSpy.count(), 1); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Buffer full. + provider.playerControl()->updateMediaStatus(QMediaPlayer::BufferedMedia); + QCOMPARE(audio.status(), QmlAudio::Buffered); + QCOMPARE(statusChangedSpy.count(), 7); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 2); + QCOMPARE(stalledSpy.count(), 1); + QCOMPARE(bufferedSpy.count(), 2); + QCOMPARE(endOfMediaSpy.count(), 0); + + // Finished. + provider.playerControl()->updateMediaStatus( + QMediaPlayer::EndOfMedia, QMediaPlayer::StoppedState); + QCOMPARE(audio.status(), QmlAudio::EndOfMedia); + QCOMPARE(statusChangedSpy.count(), 8); + QCOMPARE(loadedSpy.count(), 1); + QCOMPARE(bufferingSpy.count(), 2); + QCOMPARE(stalledSpy.count(), 1); + QCOMPARE(bufferedSpy.count(), 2); + QCOMPARE(endOfMediaSpy.count(), 1); +} + +void tst_QmlAudio::metaData_data() +{ + QTest::addColumn<QByteArray>("propertyName"); + QTest::addColumn<QtMultimedia::MetaData>("propertyKey"); + QTest::addColumn<QVariant>("value1"); + QTest::addColumn<QVariant>("value2"); + + QTest::newRow("title") + << QByteArray("title") + << QtMultimedia::Title + << QVariant(QString::fromLatin1("This is a title")) + << QVariant(QString::fromLatin1("This is another title")); + + QTest::newRow("genre") + << QByteArray("genre") + << QtMultimedia::Genre + << QVariant(QString::fromLatin1("rock")) + << QVariant(QString::fromLatin1("pop")); + + QTest::newRow("trackNumber") + << QByteArray("trackNumber") + << QtMultimedia::TrackNumber + << QVariant(8) + << QVariant(12); +} + +void tst_QmlAudio::metaData() +{ + QFETCH(QByteArray, propertyName); + QFETCH(QtMultimedia::MetaData, propertyKey); + QFETCH(QVariant, value1); + QFETCH(QVariant, value2); + + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy spy(&audio, SIGNAL(__metaDataChanged())); + + const int index = audio.metaObject()->indexOfProperty(propertyName.constData()); + QVERIFY(index != -1); + + QMetaProperty property = audio.metaObject()->property(index); + QCOMPARE(property.read(&audio), QVariant()); + + property.write(&audio, value1); + QCOMPARE(property.read(&audio), value1); + QCOMPARE(provider.metaDataControl()->metaData(propertyKey), value1); + QCOMPARE(spy.count(), 1); + + provider.metaDataControl()->setMetaData(propertyKey, value2); + QCOMPARE(property.read(&audio), value2); + QCOMPARE(spy.count(), 2); +} + +void tst_QmlAudio::error() +{ + const QString errorString = QLatin1String("Failed to open device."); + + QtTestMediaServiceProvider provider; + QmlAudio audio; + + QSignalSpy errorSpy(&audio, SIGNAL(error(QmlAudio::Error,QString))); + QSignalSpy errorChangedSpy(&audio, SIGNAL(errorChanged())); + + QCOMPARE(audio.error(), QmlAudio::NoError); + QCOMPARE(audio.errorString(), QString()); + + provider.playerControl()->emitError(QMediaPlayer::ResourceError, errorString); + + QCOMPARE(audio.error(), QmlAudio::ResourceError); + QCOMPARE(audio.errorString(), errorString); + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(errorChangedSpy.count(), 1); + + // Changing the source resets the error properties. + audio.setSource(QUrl("http://example.com")); + QCOMPARE(audio.error(), QmlAudio::NoError); + QCOMPARE(audio.errorString(), QString()); + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(errorChangedSpy.count(), 2); + + // But isn't noisy. + audio.setSource(QUrl("file:///file/path")); + QCOMPARE(audio.error(), QmlAudio::NoError); + QCOMPARE(audio.errorString(), QString()); + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(errorChangedSpy.count(), 2); +} + + +QTEST_MAIN(tst_QmlAudio) + +#include "tst_qmlaudio.moc" diff --git a/tests/auto/qmlgraphicsvideo/qmlgraphicsvideo.pro b/tests/auto/qmlgraphicsvideo/qmlgraphicsvideo.pro new file mode 100644 index 0000000..0a83124 --- /dev/null +++ b/tests/auto/qmlgraphicsvideo/qmlgraphicsvideo.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +SOURCES += tst_qmlgraphicsvideo.cpp + +QT += multimedia declarative +requires(contains(QT_CONFIG, multimedia)) +requires(contains(QT_CONFIG, declarative)) diff --git a/tests/auto/qmlgraphicsvideo/tst_qmlgraphicsvideo.cpp b/tests/auto/qmlgraphicsvideo/tst_qmlgraphicsvideo.cpp new file mode 100644 index 0000000..0da094d --- /dev/null +++ b/tests/auto/qmlgraphicsvideo/tst_qmlgraphicsvideo.cpp @@ -0,0 +1,911 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtMultimedia/private/qmlgraphicsvideo_p.h> + +#include <QtGui/qapplication.h> +#include <QtMultimedia/qabstractvideosurface.h> +#include <QtMultimedia/qgraphicsvideoitem.h> +#include <QtMultimedia/qmediaplayercontrol.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qvideooutputcontrol.h> +#include <QtMultimedia/qvideorenderercontrol.h> +#include <QtMultimedia/qvideosurfaceformat.h> + + +class tst_QmlGraphicsVideo : public QObject +{ + Q_OBJECT +public slots: + void initTestCase(); + +private slots: + void nullPlayerControl(); + void nullService(); + + void playing(); + void paused(); + void error(); + + void hasAudio(); + void hasVideo(); + void fillMode(); + void geometry(); +}; + +Q_DECLARE_METATYPE(QtMultimedia::MetaData); +Q_DECLARE_METATYPE(QmlGraphicsVideo::Error); + +class QtTestMediaPlayerControl : public QMediaPlayerControl +{ + Q_OBJECT +public: + QtTestMediaPlayerControl(QObject *parent = 0) + : QMediaPlayerControl(parent) + , m_state(QMediaPlayer::StoppedState) + , m_mediaStatus(QMediaPlayer::NoMedia) + , m_duration(0) + , m_position(0) + , m_playbackRate(1.0) + , m_volume(50) + , m_bufferStatus(0) + , m_muted(false) + , m_audioAvailable(false) + , m_videoAvailable(false) + , m_seekable(false) + { + } + + QMediaPlayer::State state() const { return m_state; } + void updateState(QMediaPlayer::State state) { emit stateChanged(m_state = state); } + + QMediaPlayer::MediaStatus mediaStatus() const { return m_mediaStatus; } + void updateMediaStatus(QMediaPlayer::MediaStatus status) { + emit mediaStatusChanged(m_mediaStatus = status); } + void updateMediaStatus(QMediaPlayer::MediaStatus status, QMediaPlayer::State state) + { + m_mediaStatus = status; + m_state = state; + + emit mediaStatusChanged(m_mediaStatus); + emit stateChanged(m_state); + } + + qint64 duration() const { return m_duration; } + void setDuration(qint64 duration) { emit durationChanged(m_duration = duration); } + + qint64 position() const { return m_position; } + void setPosition(qint64 position) { emit positionChanged(m_position = position); } + + int volume() const { return m_volume; } + void setVolume(int volume) { emit volumeChanged(m_volume = volume); } + + bool isMuted() const { return m_muted; } + void setMuted(bool muted) { emit mutedChanged(m_muted = muted); } + + int bufferStatus() const { return m_bufferStatus; } + void setBufferStatus(int status) { emit bufferStatusChanged(m_bufferStatus = status); } + + bool isAudioAvailable() const { return m_audioAvailable; } + void setAudioAvailable(bool available) { + emit audioAvailableChanged(m_audioAvailable = available); } + bool isVideoAvailable() const { return m_videoAvailable; } + void setVideoAvailable(bool available) { + emit videoAvailableChanged(m_videoAvailable = available); } + + bool isSeekable() const { return m_seekable; } + void setSeekable(bool seekable) { emit seekableChanged(m_seekable = seekable); } + + QMediaTimeRange availablePlaybackRanges() const { return QMediaTimeRange(); } + + qreal playbackRate() const { return m_playbackRate; } + void setPlaybackRate(qreal rate) { emit playbackRateChanged(m_playbackRate = rate); } + + QMediaContent media() const { return m_media; } + const QIODevice *mediaStream() const { return 0; } + void setMedia(const QMediaContent &media, QIODevice *) + { + m_media = media; + + m_mediaStatus = m_media.isNull() + ? QMediaPlayer::NoMedia + : QMediaPlayer::LoadingMedia; + + emit mediaChanged(m_media); + emit mediaStatusChanged(m_mediaStatus); + } + + void play() { emit stateChanged(m_state = QMediaPlayer::PlayingState); } + void pause() { emit stateChanged(m_state = QMediaPlayer::PausedState); } + void stop() { emit stateChanged(m_state = QMediaPlayer::StoppedState); } + + void emitError(QMediaPlayer::Error err, const QString &errorString) { + emit error(err, errorString); } + +private: + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_mediaStatus; + qint64 m_duration; + qint64 m_position; + qreal m_playbackRate; + int m_volume; + int m_bufferStatus; + bool m_muted; + bool m_audioAvailable; + bool m_videoAvailable; + bool m_seekable; + QMediaContent m_media; +}; + +class QtTestOutputControl : public QVideoOutputControl +{ +public: + QtTestOutputControl(QObject *parent) : QVideoOutputControl(parent), m_output(NoOutput) {} + + QList<Output> availableOutputs() const { return m_outputs; } + void setAvailableOutputs(const QList<Output> outputs) { m_outputs = outputs; } + + Output output() const { return m_output; } + virtual void setOutput(Output output) { m_output = output; } + +private: + Output m_output; + QList<Output> m_outputs; +}; + +class QtTestRendererControl : public QVideoRendererControl +{ +public: + QtTestRendererControl(QObject *parent ) : QVideoRendererControl(parent), m_surface(0) {} + + QAbstractVideoSurface *surface() const { return m_surface; } + void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; } + +private: + QAbstractVideoSurface *m_surface; +}; + +class QtTestMediaService : public QMediaService +{ + Q_OBJECT +public: + QtTestMediaService( + QtTestMediaPlayerControl *playerControl, + QtTestOutputControl *outputControl, + QtTestRendererControl *rendererControl, + QObject *parent) + : QMediaService(parent) + , playerControl(playerControl) + , outputControl(outputControl) + , rendererControl(rendererControl) + { + } + + QMediaControl *control(const char *name) const + { + if (qstrcmp(name, QMediaPlayerControl_iid) == 0) + return playerControl; + else if (qstrcmp(name, QVideoOutputControl_iid) == 0) + return outputControl; + else if (qstrcmp(name, QVideoRendererControl_iid) == 0) + return rendererControl; + else + return 0; + } + + QtTestMediaPlayerControl *playerControl; + QtTestOutputControl *outputControl; + QtTestRendererControl *rendererControl; +}; + +class QtTestMediaServiceProvider : public QMediaServiceProvider +{ + Q_OBJECT +public: + QtTestMediaServiceProvider() + : service(new QtTestMediaService( + new QtTestMediaPlayerControl(this), + new QtTestOutputControl(this), + new QtTestRendererControl(this), + this)) + { + setDefaultServiceProvider(this); + } + + QtTestMediaServiceProvider(QtTestMediaService *service) + : service(service) + { + setDefaultServiceProvider(this); + } + + QtTestMediaServiceProvider( + QtTestMediaPlayerControl *playerControl, + QtTestOutputControl *outputControl, + QtTestRendererControl *rendererControl) + : service(new QtTestMediaService(playerControl, outputControl, rendererControl, this)) + { + setDefaultServiceProvider(this); + } + + ~QtTestMediaServiceProvider() + { + setDefaultServiceProvider(0); + } + + QMediaService *requestService( + const QByteArray &type, + const QMediaServiceProviderHint & = QMediaServiceProviderHint()) + { + requestedService = type; + + return service; + } + + void releaseService(QMediaService *) {} + + inline QtTestMediaPlayerControl *playerControl() { return service->playerControl; } + inline QtTestRendererControl *rendererControl() { return service->rendererControl; } + + QtTestMediaService *service; + QByteArray requestedService; +}; + + +void tst_QmlGraphicsVideo::initTestCase() +{ + qRegisterMetaType<QmlGraphicsVideo::Error>(); +} + +void tst_QmlGraphicsVideo::nullPlayerControl() +{ + QtTestMediaServiceProvider provider(0, 0, 0); + + QmlGraphicsVideo video; + + QCOMPARE(video.source(), QUrl()); + video.setSource(QUrl("http://example.com")); + QCOMPARE(video.source(), QUrl()); + + QCOMPARE(video.isPlaying(), false); + video.setPlaying(true); + QCOMPARE(video.isPlaying(), false); + video.play(); + QCOMPARE(video.isPlaying(), false); + + QCOMPARE(video.isPaused(), false); + video.pause(); + QCOMPARE(video.isPaused(), false); + video.setPaused(true); + QCOMPARE(video.isPaused(), true); + + QCOMPARE(video.duration(), 0); + + QCOMPARE(video.position(), 0); + video.setPosition(10000); + QCOMPARE(video.position(), 0); + + QCOMPARE(video.volume(), qreal(0)); + video.setVolume(50); + QCOMPARE(video.volume(), qreal(0)); + + QCOMPARE(video.isMuted(), false); + video.setMuted(true); + QCOMPARE(video.isMuted(), false); + + QCOMPARE(video.bufferProgress(), qreal(0)); + + QCOMPARE(video.isSeekable(), false); + + QCOMPARE(video.playbackRate(), qreal(1.0)); + + QCOMPARE(video.hasAudio(), false); + QCOMPARE(video.hasVideo(), false); + + QCOMPARE(video.status(), QmlGraphicsVideo::NoMedia); + + QCOMPARE(video.error(), QmlGraphicsVideo::ServiceMissing); +} + +void tst_QmlGraphicsVideo::nullService() +{ + QtTestMediaServiceProvider provider(0); + + QmlGraphicsVideo video; + + QCOMPARE(video.source(), QUrl()); + video.setSource(QUrl("http://example.com")); + QCOMPARE(video.source(), QUrl()); + + QCOMPARE(video.isPlaying(), false); + video.setPlaying(true); + QCOMPARE(video.isPlaying(), false); + video.play(); + QCOMPARE(video.isPlaying(), false); + + QCOMPARE(video.isPaused(), false); + video.pause(); + QCOMPARE(video.isPaused(), false); + video.setPaused(true); + QCOMPARE(video.isPaused(), true); + + QCOMPARE(video.duration(), 0); + + QCOMPARE(video.position(), 0); + video.setPosition(10000); + QCOMPARE(video.position(), 0); + + QCOMPARE(video.volume(), qreal(0)); + video.setVolume(50); + QCOMPARE(video.volume(), qreal(0)); + + QCOMPARE(video.isMuted(), false); + video.setMuted(true); + QCOMPARE(video.isMuted(), false); + + QCOMPARE(video.bufferProgress(), qreal(0)); + + QCOMPARE(video.isSeekable(), false); + + QCOMPARE(video.playbackRate(), qreal(1.0)); + + QCOMPARE(video.hasAudio(), false); + QCOMPARE(video.hasVideo(), false); + + QCOMPARE(video.status(), QmlGraphicsVideo::NoMedia); + + QCOMPARE(video.error(), QmlGraphicsVideo::ServiceMissing); + + QCOMPARE(video.metaObject()->indexOfProperty("title"), -1); + QCOMPARE(video.metaObject()->indexOfProperty("genre"), -1); + QCOMPARE(video.metaObject()->indexOfProperty("description"), -1); +} + +void tst_QmlGraphicsVideo::playing() +{ + QtTestMediaServiceProvider provider; + QmlGraphicsVideo video; + + QSignalSpy playingChangedSpy(&video, SIGNAL(playingChanged())); + QSignalSpy startedSpy(&video, SIGNAL(started())); + QSignalSpy stoppedSpy(&video, SIGNAL(stopped())); + + int playingChanged = 0; + int started = 0; + int stopped = 0; + + QCOMPARE(video.isPlaying(), false); + + // setPlaying(true) when stopped. + video.setPlaying(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when playing. + video.setPlaying(false); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // play() when stopped. + video.play(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(stoppedSpy.count(), stopped); + + // stop() when playing. + video.stop(); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // stop() when stopped. + video.stop(); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when stopped. + video.setPlaying(false); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); + + video.setPlaying(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(true) when playing. + video.setPlaying(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); + + // play() when playing. + video.play(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(stoppedSpy.count(), stopped); +} + +void tst_QmlGraphicsVideo::paused() +{ + QtTestMediaServiceProvider provider; + QmlGraphicsVideo video; + + QSignalSpy playingChangedSpy(&video, SIGNAL(playingChanged())); + QSignalSpy pausedChangedSpy(&video, SIGNAL(pausedChanged())); + QSignalSpy startedSpy(&video, SIGNAL(started())); + QSignalSpy pausedSpy(&video, SIGNAL(paused())); + QSignalSpy resumedSpy(&video, SIGNAL(resumed())); + QSignalSpy stoppedSpy(&video, SIGNAL(stopped())); + + int playingChanged = 0; + int pausedChanged = 0; + int started = 0; + int paused = 0; + int resumed = 0; + int stopped = 0; + + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), false); + + // setPlaying(true) when stopped. + video.setPlaying(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when playing. + video.setPaused(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when paused. + video.setPaused(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // pause() when paused. + video.pause(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(false) when paused. + video.setPaused(false); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), ++resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(false) when playing. + video.setPaused(false); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // pause() when playing. + video.pause(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when paused. + video.setPlaying(false); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // setPaused(true) when stopped and paused. + video.setPaused(true); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(false) when stopped and paused. + video.setPaused(false); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when stopped. + video.setPaused(true); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(true) when stopped and paused. + video.setPlaying(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // play() when paused. + video.play(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), ++resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPaused(true) when playing. + video.setPaused(true); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // stop() when paused. + video.stop(); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // setPaused(true) when stopped. + video.setPaused(true); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // stop() when stopped and paused. + video.stop(); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // pause() when stopped. + video.pause(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when paused. + video.setPlaying(false); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // pause() when stopped and paused. + video.pause(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PausedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), ++paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); + + // setPlaying(false) when paused. + video.setPlaying(false); + QCOMPARE(video.isPlaying(), false); + QCOMPARE(video.isPaused(), true); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::StoppedState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), pausedChanged); + QCOMPARE(startedSpy.count(), started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), ++stopped); + + // play() when stopped and paused. + video.play(); + QCOMPARE(video.isPlaying(), true); + QCOMPARE(video.isPaused(), false); + QCOMPARE(provider.playerControl()->state(), QMediaPlayer::PlayingState); + QCOMPARE(playingChangedSpy.count(), ++playingChanged); + QCOMPARE(pausedChangedSpy.count(), ++pausedChanged); + QCOMPARE(startedSpy.count(), ++started); + QCOMPARE(pausedSpy.count(), paused); + QCOMPARE(resumedSpy.count(), resumed); + QCOMPARE(stoppedSpy.count(), stopped); +} + +void tst_QmlGraphicsVideo::error() +{ + const QString errorString = QLatin1String("Failed to open device."); + + QtTestMediaServiceProvider provider; + QmlGraphicsVideo video; + + QSignalSpy errorSpy(&video, SIGNAL(error(QmlGraphicsVideo::Error,QString))); + QSignalSpy errorChangedSpy(&video, SIGNAL(errorChanged())); + + QCOMPARE(video.error(), QmlGraphicsVideo::NoError); + QCOMPARE(video.errorString(), QString()); + + provider.playerControl()->emitError(QMediaPlayer::ResourceError, errorString); + + QCOMPARE(video.error(), QmlGraphicsVideo::ResourceError); + QCOMPARE(video.errorString(), errorString); + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(errorChangedSpy.count(), 1); + + // Changing the source resets the error properties. + video.setSource(QUrl("http://example.com")); + QCOMPARE(video.error(), QmlGraphicsVideo::NoError); + QCOMPARE(video.errorString(), QString()); + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(errorChangedSpy.count(), 2); + + // But isn't noisy. + video.setSource(QUrl("file:///file/path")); + QCOMPARE(video.error(), QmlGraphicsVideo::NoError); + QCOMPARE(video.errorString(), QString()); + QCOMPARE(errorSpy.count(), 1); + QCOMPARE(errorChangedSpy.count(), 2); +} + + +void tst_QmlGraphicsVideo::hasAudio() +{ + QtTestMediaServiceProvider provider; + QmlGraphicsVideo video; + + QSignalSpy spy(&video, SIGNAL(hasAudioChanged())); + + QCOMPARE(video.hasAudio(), false); + + provider.playerControl()->setAudioAvailable(true); + QCOMPARE(video.hasAudio(), true); + QCOMPARE(spy.count(), 1); + + provider.playerControl()->setAudioAvailable(true); + QCOMPARE(video.hasAudio(), true); + QCOMPARE(spy.count(), 2); + + provider.playerControl()->setAudioAvailable(false); + QCOMPARE(video.hasAudio(), false); + QCOMPARE(spy.count(), 3); +} + +void tst_QmlGraphicsVideo::hasVideo() +{ + QtTestMediaServiceProvider provider; + QmlGraphicsVideo video; + + QSignalSpy spy(&video, SIGNAL(hasVideoChanged())); + + QCOMPARE(video.hasVideo(), false); + + provider.playerControl()->setVideoAvailable(true); + QCOMPARE(video.hasVideo(), true); + QCOMPARE(spy.count(), 1); + + provider.playerControl()->setVideoAvailable(true); + QCOMPARE(video.hasVideo(), true); + QCOMPARE(spy.count(), 2); + + provider.playerControl()->setVideoAvailable(false); + QCOMPARE(video.hasVideo(), false); + QCOMPARE(spy.count(), 3); +} + +void tst_QmlGraphicsVideo::fillMode() +{ + QtTestMediaServiceProvider provider; + QmlGraphicsVideo video; + + QList<QGraphicsItem *> children = video.childItems(); + QCOMPARE(children.count(), 1); + QGraphicsVideoItem *videoItem = qgraphicsitem_cast<QGraphicsVideoItem *>(children.first()); + QVERIFY(videoItem != 0); + + QCOMPARE(video.fillMode(), QmlGraphicsVideo::PreserveAspectFit); + + video.setFillMode(QmlGraphicsVideo::PreserveAspectCrop); + QCOMPARE(video.fillMode(), QmlGraphicsVideo::PreserveAspectCrop); + QCOMPARE(videoItem->aspectRatioMode(), Qt::KeepAspectRatioByExpanding); + + video.setFillMode(QmlGraphicsVideo::Stretch); + QCOMPARE(video.fillMode(), QmlGraphicsVideo::Stretch); + QCOMPARE(videoItem->aspectRatioMode(), Qt::IgnoreAspectRatio); + + video.setFillMode(QmlGraphicsVideo::PreserveAspectFit); + QCOMPARE(video.fillMode(), QmlGraphicsVideo::PreserveAspectFit); + QCOMPARE(videoItem->aspectRatioMode(), Qt::KeepAspectRatio); +} + +void tst_QmlGraphicsVideo::geometry() +{ + QtTestMediaServiceProvider provider; + QmlGraphicsVideo video; + + QAbstractVideoSurface *surface = provider.rendererControl()->surface(); + QVERIFY(surface != 0); + + QList<QGraphicsItem *> children = video.childItems(); + QCOMPARE(children.count(), 1); + QGraphicsVideoItem *videoItem = qgraphicsitem_cast<QGraphicsVideoItem *>(children.first()); + QVERIFY(videoItem != 0); + + QVideoSurfaceFormat format(QSize(640, 480), QVideoFrame::Format_RGB32); + + QVERIFY(surface->start(format)); + + QCOMPARE(video.implicitWidth(), qreal(640)); + QCOMPARE(video.implicitHeight(), qreal(480)); + + video.setWidth(560); + video.setHeight(328); + + QCOMPARE(videoItem->size().width(), qreal(560)); + QCOMPARE(videoItem->size().height(), qreal(328)); +} + +QTEST_MAIN(tst_QmlGraphicsVideo) + +#include "tst_qmlgraphicsvideo.moc" diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index eec4797..05e2e1b 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -82,6 +82,7 @@ Q_DECLARE_METATYPE(QNetworkProxy) Q_DECLARE_METATYPE(QNetworkProxyQuery) Q_DECLARE_METATYPE(QList<QNetworkProxy>) Q_DECLARE_METATYPE(QNetworkReply::NetworkError) +Q_DECLARE_METATYPE(QBuffer*) class QNetworkReplyPtr: public QSharedPointer<QNetworkReply> { @@ -129,6 +130,9 @@ public: QString runSimpleRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QNetworkReplyPtr &reply, const QByteArray &data = QByteArray()); + QString runCustomRequest(const QNetworkRequest &request, QNetworkReplyPtr &reply, + const QByteArray &verb, QIODevice *data); + public Q_SLOTS: void finished(); void gotError(); @@ -175,6 +179,8 @@ private Q_SLOTS: void deleteFromHttp(); void putGetDeleteGetFromHttp_data(); void putGetDeleteGetFromHttp(); + void sendCustomRequestToHttp_data(); + void sendCustomRequestToHttp(); void ioGetFromData_data(); void ioGetFromData(); @@ -778,6 +784,32 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, return QString(); } +QString tst_QNetworkReply::runCustomRequest(const QNetworkRequest &request, + QNetworkReplyPtr &reply, + const QByteArray &verb, + QIODevice *data) +{ + reply = manager.sendCustomRequest(request, verb, data); + reply->setParent(this); + connect(reply, SIGNAL(finished()), SLOT(finished())); + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(gotError())); + + returnCode = Timeout; + loop = new QEventLoop; + QTimer::singleShot(20000, loop, SLOT(quit())); + int code = returnCode == Timeout ? loop->exec() : returnCode; + delete loop; + loop = 0; + + switch (code) { + case Failure: + return "Request failed: " + reply->errorString(); + case Timeout: + return "Network timeout"; + } + return QString(); +} + void tst_QNetworkReply::finished() { loop->exit(returnCode = Success); @@ -1436,6 +1468,57 @@ void tst_QNetworkReply::putGetDeleteGetFromHttp() } +void tst_QNetworkReply::sendCustomRequestToHttp_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::addColumn<QByteArray>("verb"); + QTest::addColumn<QBuffer *>("device"); + QTest::addColumn<int>("resultCode"); + QTest::addColumn<QNetworkReply::NetworkError>("error"); + QTest::addColumn<QByteArray>("expectedContent"); + + QTest::newRow("options") << QUrl("http://" + QtNetworkSettings::serverName()) << + QByteArray("OPTIONS") << (QBuffer *) 0 << 200 << QNetworkReply::NoError << QByteArray(); + QTest::newRow("trace") << QUrl("http://" + QtNetworkSettings::serverName()) << + QByteArray("TRACE") << (QBuffer *) 0 << 200 << QNetworkReply::NoError << QByteArray(); + QTest::newRow("connect") << QUrl("http://" + QtNetworkSettings::serverName()) << + QByteArray("CONNECT") << (QBuffer *) 0 << 400 << QNetworkReply::UnknownContentError << QByteArray(); // 400 = Bad Request + QTest::newRow("nonsense") << QUrl("http://" + QtNetworkSettings::serverName()) << + QByteArray("NONSENSE") << (QBuffer *) 0 << 501 << QNetworkReply::ProtocolUnknownError << QByteArray(); // 501 = Method Not Implemented + + QByteArray ba("test"); + QBuffer *buffer = new QBuffer; + buffer->setData(ba); + buffer->open(QIODevice::ReadOnly); + QTest::newRow("post") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi") << QByteArray("POST") + << buffer << 200 << QNetworkReply::NoError << QByteArray("098f6bcd4621d373cade4e832627b4f6\n"); + + QByteArray ba2("test"); + QBuffer *buffer2 = new QBuffer; + buffer2->setData(ba2); + buffer2->open(QIODevice::ReadOnly); + QTest::newRow("put") << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi") << QByteArray("PUT") + << buffer2 << 200 << QNetworkReply::NoError << QByteArray("098f6bcd4621d373cade4e832627b4f6\n"); +} + +void tst_QNetworkReply::sendCustomRequestToHttp() +{ + QFETCH(QUrl, url); + QNetworkRequest request(url); + QNetworkReplyPtr reply; + QFETCH(QByteArray, verb); + QFETCH(QBuffer *, device); + runCustomRequest(request, reply, verb, device); + QCOMPARE(reply->url(), url); + QFETCH(QNetworkReply::NetworkError, error); + QCOMPARE(reply->error(), error); + QFETCH(int, resultCode); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), resultCode); + QFETCH(QByteArray, expectedContent); + if (! expectedContent.isEmpty()) + QCOMPARE(reply->readAll(), expectedContent); +} + void tst_QNetworkReply::ioGetFromData_data() { QTest::addColumn<QString>("urlStr"); diff --git a/tests/auto/qobject/moc_oldnormalizeobject.cpp b/tests/auto/qobject/moc_oldnormalizeobject.cpp index bde9c39..3b1e658 100644 --- a/tests/auto/qobject/moc_oldnormalizeobject.cpp +++ b/tests/auto/qobject/moc_oldnormalizeobject.cpp @@ -1,4 +1,45 @@ /**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** ** Meta object code from reading C++ file 'oldnormalizeobject.h' ** ** Created: Wed Nov 18 11:43:05 2009 diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 7cfa868..07df707 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -42,6 +42,8 @@ #define QT_SHAREDPOINTER_TRACK_POINTERS #include "qsharedpointer.h" #include <QtTest/QtTest> +#include <QtCore/QHash> +#include <QtCore/QMap> #include <QtCore/QThread> #include <QtCore/QVector> @@ -68,6 +70,7 @@ class tst_QSharedPointer: public QObject private slots: void basics_data(); void basics(); + void operators(); void swap(); void forwardDeclaration1(); void forwardDeclaration2(); @@ -94,6 +97,8 @@ private slots: void mixTrackingPointerCode(); void threadStressTest_data(); void threadStressTest(); + void map(); + void hash(); void validConstructs(); void invalidConstructs_data(); void invalidConstructs(); @@ -271,6 +276,35 @@ void tst_QSharedPointer::basics() // aData is deleted here } +void tst_QSharedPointer::operators() +{ + QSharedPointer<char> p1; + QSharedPointer<char> p2(new char); + qptrdiff diff = p2.data() - p1.data(); + Q_ASSERT(p1.data() < p2.data()); + Q_ASSERT(diff > 0); + + // operator- + QCOMPARE(p2 - p1.data(), diff); + QCOMPARE(p2.data() - p1, diff); + QCOMPARE(p2 - p1, diff); + QCOMPARE(p1 - p2, -diff); + QCOMPARE(p1 - p1, qptrdiff(0)); + QCOMPARE(p2 - p2, qptrdiff(0)); + + // operator< + QVERIFY(p1 < p2.data()); + QVERIFY(p1.data() < p2); + QVERIFY(p1 < p2); + QVERIFY(!(p2 < p1)); + QVERIFY(!(p2 < p2)); + QVERIFY(!(p1 < p1)); + + // qHash + QCOMPARE(qHash(p1), qHash(p1.data())); + QCOMPARE(qHash(p2), qHash(p2.data())); +} + void tst_QSharedPointer::swap() { QSharedPointer<int> p1, p2(new int(42)), control = p2; @@ -1544,6 +1578,72 @@ void tst_QSharedPointer::threadStressTest() } } +template<typename Container, bool Ordered> +void hashAndMapTest() +{ + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Value; + + Container c; + QVERIFY(c.isEmpty()); + + Key k0; + c.insert(k0, Value(0)); + QVERIFY(!c.isEmpty()); + + typename Container::iterator it; + it = c.find(k0); + QVERIFY(it != c.end()); + it = c.find(Key()); + QVERIFY(it != c.end()); + it = c.find(Key(0)); + QVERIFY(it != c.end()); + + Key k1(new typename Key::value_type(42)); + it = c.find(k1); + QVERIFY(it == c.end()); + + c.insert(k1, Value(42)); + it = c.find(k1); + QVERIFY(it != c.end()); + QVERIFY(it != c.find(Key())); + + if (Ordered) { + Q_ASSERT(k0 < k1); + + it = c.begin(); + QCOMPARE(it.key(), k0); + QCOMPARE(it.value(), Value(0)); + + ++it; + QCOMPARE(it.key(), k1); + QCOMPARE(it.value(), Value(42)); + + ++it; + QVERIFY(it == c.end()); + } + + c.insertMulti(k1, Value(47)); + it = c.find(k1); + QVERIFY(it != c.end()); + QCOMPARE(it.key(), k1); + ++it; + QVERIFY(it != c.end()); + QCOMPARE(it.key(), k1); + ++it; + QVERIFY(it == c.end()); +} + +void tst_QSharedPointer::map() +{ + hashAndMapTest<QMap<QSharedPointer<int>, int>, true>(); +} + +void tst_QSharedPointer::hash() +{ + hashAndMapTest<QHash<QSharedPointer<int>, int>, false>(); +} + void tst_QSharedPointer::validConstructs() { { diff --git a/tests/auto/qvideowidget/qvideowidget.pro b/tests/auto/qvideowidget/qvideowidget.pro new file mode 100644 index 0000000..ca0fc24 --- /dev/null +++ b/tests/auto/qvideowidget/qvideowidget.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +SOURCES = tst_qvideowidget.cpp + +QT = core gui multimedia + diff --git a/tests/auto/qvideowidget/tst_qvideowidget.cpp b/tests/auto/qvideowidget/tst_qvideowidget.cpp new file mode 100644 index 0000000..f703055 --- /dev/null +++ b/tests/auto/qvideowidget/tst_qvideowidget.cpp @@ -0,0 +1,1600 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtMultimedia/qvideowidget.h> + +#include <QtMultimedia/qmediaobject.h> +#include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/private/qpaintervideosurface_p.h> +#include <QtMultimedia/qvideooutputcontrol.h> +#include <QtMultimedia/qvideowindowcontrol.h> +#include <QtMultimedia/qvideowidgetcontrol.h> +#include <QtMultimedia/qvideorenderercontrol.h> +#include <QtMultimedia/qabstractvideosurface.h> +#include <QtMultimedia/qvideosurfaceformat.h> + +#include <QtGui/qapplication.h> + + +class tst_QVideoWidget : public QObject +{ + Q_OBJECT +private slots: + void nullObject(); + void nullService(); + void nullOutputControl(); + void noOutputs(); + void serviceDestroyed(); + void objectDestroyed(); + void setMediaObject(); + + void showWindowControl(); + void aspectRatioWindowControl(); + void sizeHintWindowControl_data() { sizeHint_data(); } + void sizeHintWindowControl(); + void brightnessWindowControl_data() { color_data(); } + void brightnessWindowControl(); + void contrastWindowControl_data() { color_data(); } + void contrastWindowControl(); + void hueWindowControl_data() { color_data(); } + void hueWindowControl(); + void saturationWindowControl_data() { color_data(); } + void saturationWindowControl(); + + void showWidgetControl(); + void aspectRatioWidgetControl(); + void sizeHintWidgetControl_data() { sizeHint_data(); } + void sizeHintWidgetControl(); + void brightnessWidgetControl_data() { color_data(); } + void brightnessWidgetControl(); + void contrastWidgetControl_data() { color_data(); } + void contrastWidgetControl(); + void hueWidgetControl_data() { color_data(); } + void hueWidgetControl(); + void saturationWidgetControl_data() { color_data(); } + void saturationWidgetControl(); + + void showRendererControl(); + void aspectRatioRendererControl(); + void sizeHintRendererControl_data(); + void sizeHintRendererControl(); + void brightnessRendererControl_data() { color_data(); } + void brightnessRendererControl(); + void contrastRendererControl_data() { color_data(); } + void contrastRendererControl(); + void hueRendererControl_data() { color_data(); } + void hueRendererControl(); + void saturationRendererControl_data() { color_data(); } + void saturationRendererControl(); + + void paintRendererControl(); + +#ifndef Q_WS_X11 + void fullScreenWindowControl(); + void fullScreenWidgetControl(); + void fullScreenRendererControl(); +#endif + +private: + void sizeHint_data(); + void color_data(); +}; + +Q_DECLARE_METATYPE(QVideoWidget::AspectRatioMode) +Q_DECLARE_METATYPE(const uchar *) + +class QtTestOutputControl : public QVideoOutputControl +{ +public: + QtTestOutputControl() : m_output(NoOutput) {} + + QList<Output> availableOutputs() const { return m_outputs; } + void setAvailableOutputs(const QList<Output> outputs) { m_outputs = outputs; } + + Output output() const { return m_output; } + virtual void setOutput(Output output) { m_output = output; } + +private: + Output m_output; + QList<Output> m_outputs; +}; + +class QtTestWindowControl : public QVideoWindowControl +{ +public: + QtTestWindowControl() + : m_winId(0) + , m_repaintCount(0) + , m_brightness(0) + , m_contrast(0) + , m_saturation(0) + , m_aspectRatioMode(QVideoWidget::KeepAspectRatio) + , m_fullScreen(0) + { + } + + WId winId() const { return m_winId; } + void setWinId(WId id) { m_winId = id; } + + QRect displayRect() const { return m_displayRect; } + void setDisplayRect(const QRect &rect) { m_displayRect = rect; } + + bool isFullScreen() const { return m_fullScreen; } + void setFullScreen(bool fullScreen) { emit fullScreenChanged(m_fullScreen = fullScreen); } + + int repaintCount() const { return m_repaintCount; } + void setRepaintCount(int count) { m_repaintCount = count; } + void repaint() { ++m_repaintCount; } + + QSize nativeSize() const { return m_nativeSize; } + void setNativeSize(const QSize &size) { m_nativeSize = size; emit nativeSizeChanged(); } + + QVideoWidget::AspectRatioMode aspectRatioMode() const { return m_aspectRatioMode; } + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode) { m_aspectRatioMode = mode; } + + int brightness() const { return m_brightness; } + void setBrightness(int brightness) { emit brightnessChanged(m_brightness = brightness); } + + int contrast() const { return m_contrast; } + void setContrast(int contrast) { emit contrastChanged(m_contrast = contrast); } + + int hue() const { return m_hue; } + void setHue(int hue) { emit hueChanged(m_hue = hue); } + + int saturation() const { return m_saturation; } + void setSaturation(int saturation) { emit saturationChanged(m_saturation = saturation); } + +private: + WId m_winId; + int m_repaintCount; + int m_brightness; + int m_contrast; + int m_hue; + int m_saturation; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + QRect m_displayRect; + QSize m_nativeSize; + bool m_fullScreen; +}; + +class QtTestWidgetControl : public QVideoWidgetControl +{ +public: + QtTestWidgetControl() + : m_brightness(1.0) + , m_contrast(1.0) + , m_hue(1.0) + , m_saturation(1.0) + , m_aspectRatioMode(QVideoWidget::KeepAspectRatio) + , m_fullScreen(false) + { + } + + bool isFullScreen() const { return m_fullScreen; } + void setFullScreen(bool fullScreen) { emit fullScreenChanged(m_fullScreen = fullScreen); } + + QVideoWidget::AspectRatioMode aspectRatioMode() const { return m_aspectRatioMode; } + void setAspectRatioMode(QVideoWidget::AspectRatioMode mode) { m_aspectRatioMode = mode; } + + int brightness() const { return m_brightness; } + void setBrightness(int brightness) { emit brightnessChanged(m_brightness = brightness); } + + int contrast() const { return m_contrast; } + void setContrast(int contrast) { emit contrastChanged(m_contrast = contrast); } + + int hue() const { return m_hue; } + void setHue(int hue) { emit hueChanged(m_hue = hue); } + + int saturation() const { return m_saturation; } + void setSaturation(int saturation) { emit saturationChanged(m_saturation = saturation); } + + void setSizeHint(const QSize &size) { m_widget.setSizeHint(size); } + + QWidget *videoWidget() { return &m_widget; } + +private: + class Widget : public QWidget + { + public: + QSize sizeHint() const { return m_sizeHint; } + void setSizeHint(const QSize &size) { m_sizeHint = size; updateGeometry(); } + private: + QSize m_sizeHint; + } m_widget; + int m_brightness; + int m_contrast; + int m_hue; + int m_saturation; + QVideoWidget::AspectRatioMode m_aspectRatioMode; + QSize m_sizeHint; + bool m_fullScreen; +}; + +class QtTestRendererControl : public QVideoRendererControl +{ +public: + QtTestRendererControl() + : m_surface(0) + { + } + + QAbstractVideoSurface *surface() const { return m_surface; } + void setSurface(QAbstractVideoSurface *surface) { m_surface = surface; } + +private: + QAbstractVideoSurface *m_surface; +}; + +class QtTestVideoService : public QMediaService +{ + Q_OBJECT +public: + QtTestVideoService( + QtTestOutputControl *output, + QtTestWindowControl *window, + QtTestWidgetControl *widget, + QtTestRendererControl *renderer) + : QMediaService(0) + , outputControl(output) + , windowControl(window) + , widgetControl(widget) + , rendererControl(renderer) + { + } + + ~QtTestVideoService() + { + delete outputControl; + delete windowControl; + delete widgetControl; + delete rendererControl; + } + + QMediaControl *control(const char *name) const + { + if (qstrcmp(name, QVideoOutputControl_iid) == 0) + return outputControl; + else if (qstrcmp(name, QVideoWindowControl_iid) == 0) + return windowControl; + else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) + return widgetControl; + else if (qstrcmp(name, QVideoRendererControl_iid) == 0) + return rendererControl; + else + return 0; + } + + QtTestOutputControl *outputControl; + QtTestWindowControl *windowControl; + QtTestWidgetControl *widgetControl; + QtTestRendererControl *rendererControl; +}; + +class QtTestVideoObject : public QMediaObject +{ + Q_OBJECT +public: + QtTestVideoObject( + QtTestWindowControl *window, + QtTestWidgetControl *widget, + QtTestRendererControl *renderer): + QMediaObject(0, new QtTestVideoService(new QtTestOutputControl, window, widget, renderer)) + { + testService = qobject_cast<QtTestVideoService*>(service()); + QList<QVideoOutputControl::Output> outputs; + + if (window) + outputs.append(QVideoOutputControl::WindowOutput); + if (widget) + outputs.append(QVideoOutputControl::WidgetOutput); + if (renderer) + outputs.append(QVideoOutputControl::RendererOutput); + + testService->outputControl->setAvailableOutputs(outputs); + } + + QtTestVideoObject(QtTestVideoService *service): + QMediaObject(0, service), + testService(service) + { + } + + ~QtTestVideoObject() + { + delete testService; + } + + QtTestVideoService *testService; +}; + +void tst_QVideoWidget::nullObject() +{ + QVideoWidget widget; + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QVERIFY(widget.sizeHint().isEmpty()); + + widget.setFullScreen(true); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), true); + + widget.setAspectRatioMode(QVideoWidget::IgnoreAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::IgnoreAspectRatio); + + { + QSignalSpy spy(&widget, SIGNAL(brightnessChanged(int))); + + widget.setBrightness(100); + QCOMPARE(widget.brightness(), 100); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), 100); + + widget.setBrightness(100); + QCOMPARE(widget.brightness(), 100); + QCOMPARE(spy.count(), 1); + + widget.setBrightness(-120); + QCOMPARE(widget.brightness(), -100); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), -100); + } { + QSignalSpy spy(&widget, SIGNAL(contrastChanged(int))); + + widget.setContrast(100); + QCOMPARE(widget.contrast(), 100); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), 100); + + widget.setContrast(100); + QCOMPARE(widget.contrast(), 100); + QCOMPARE(spy.count(), 1); + + widget.setContrast(-120); + QCOMPARE(widget.contrast(), -100); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), -100); + } { + QSignalSpy spy(&widget, SIGNAL(hueChanged(int))); + + widget.setHue(100); + QCOMPARE(widget.hue(), 100); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), 100); + + widget.setHue(100); + QCOMPARE(widget.hue(), 100); + QCOMPARE(spy.count(), 1); + + widget.setHue(-120); + QCOMPARE(widget.hue(), -100); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), -100); + } { + QSignalSpy spy(&widget, SIGNAL(saturationChanged(int))); + + widget.setSaturation(100); + QCOMPARE(widget.saturation(), 100); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), 100); + + widget.setSaturation(100); + QCOMPARE(widget.saturation(), 100); + QCOMPARE(spy.count(), 1); + + widget.setSaturation(-120); + QCOMPARE(widget.saturation(), -100); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), -100); + } +} + +void tst_QVideoWidget::nullService() +{ + QtTestVideoObject object(0); + + QVideoWidget widget; + widget.setMediaObject(&object); + + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QVERIFY(widget.sizeHint().isEmpty()); + + widget.setFullScreen(true); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), true); + + widget.setAspectRatioMode(QVideoWidget::IgnoreAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::IgnoreAspectRatio); + + widget.setBrightness(100); + QCOMPARE(widget.brightness(), 100); + + widget.setContrast(100); + QCOMPARE(widget.contrast(), 100); + + widget.setHue(100); + QCOMPARE(widget.hue(), 100); + + widget.setSaturation(100); + QCOMPARE(widget.saturation(), 100); +} + +void tst_QVideoWidget::nullOutputControl() +{ + QtTestVideoObject object(new QtTestVideoService(0, 0, 0, 0)); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QVERIFY(widget.sizeHint().isEmpty()); + + widget.setFullScreen(true); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), true); + + widget.setBrightness(100); + QCOMPARE(widget.brightness(), 100); + + widget.setContrast(100); + QCOMPARE(widget.contrast(), 100); + + widget.setHue(100); + QCOMPARE(widget.hue(), 100); + + widget.setSaturation(100); + QCOMPARE(widget.saturation(), 100); +} + +void tst_QVideoWidget::noOutputs() +{ + QtTestVideoObject object(0, 0, 0); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QVERIFY(widget.sizeHint().isEmpty()); + + widget.setFullScreen(true); + QCOMPARE(widget.isFullScreen(), true); + + widget.setBrightness(100); + QCOMPARE(widget.brightness(), 100); + + widget.setContrast(100); + QCOMPARE(widget.contrast(), 100); + + widget.setHue(100); + QCOMPARE(widget.hue(), 100); + + widget.setSaturation(100); + QCOMPARE(widget.saturation(), 100); +} + +void tst_QVideoWidget::serviceDestroyed() +{ + QtTestVideoObject object(new QtTestWindowControl, new QtTestWidgetControl, 0); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + widget.setBrightness(100); + widget.setContrast(100); + widget.setHue(100); + widget.setSaturation(100); + + delete object.testService; + object.testService = 0; + + QCOMPARE(widget.mediaObject(), static_cast<QMediaObject *>(&object)); + + QCOMPARE(widget.brightness(), 100); + QCOMPARE(widget.contrast(), 100); + QCOMPARE(widget.hue(), 100); + QCOMPARE(widget.saturation(), 100); + + widget.setFullScreen(true); + QCOMPARE(widget.isFullScreen(), true); +} + +void tst_QVideoWidget::objectDestroyed() +{ + QtTestVideoObject *object = new QtTestVideoObject( + new QtTestWindowControl, + new QtTestWidgetControl, + 0); + + QVideoWidget widget; + widget.setMediaObject(object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + widget.setBrightness(100); + widget.setContrast(100); + widget.setHue(100); + widget.setSaturation(100); + + // Delete the media object without deleting the service. + QtTestVideoService *service = object->testService; + object->testService = 0; + + delete object; + object = 0; + + QCOMPARE(widget.mediaObject(), static_cast<QMediaObject *>(object)); + + QCOMPARE(service->outputControl->output(), QVideoOutputControl::NoOutput); + + QCOMPARE(widget.brightness(), 100); + QCOMPARE(widget.contrast(), 100); + QCOMPARE(widget.hue(), 100); + QCOMPARE(widget.saturation(), 100); + + widget.setFullScreen(true); + QCOMPARE(widget.isFullScreen(), true); + + delete service; +} + +void tst_QVideoWidget::setMediaObject() +{ + QMediaObject *nullObject = 0; + QtTestVideoObject windowObject(new QtTestWindowControl, 0, 0); + QtTestVideoObject widgetObject(0, new QtTestWidgetControl, 0); + QtTestVideoObject rendererObject(0, 0, new QtTestRendererControl); + + QVideoWidget widget; + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QCOMPARE(widget.mediaObject(), nullObject); + QCOMPARE(windowObject.testService->outputControl->output(), QVideoOutputControl::NoOutput); + QCOMPARE(widgetObject.testService->outputControl->output(), QVideoOutputControl::NoOutput); + QCOMPARE(rendererObject.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + widget.setMediaObject(&windowObject); + QCOMPARE(widget.mediaObject(), static_cast<QMediaObject *>(&windowObject)); + QCOMPARE(windowObject.testService->outputControl->output(), QVideoOutputControl::WindowOutput); + QVERIFY(windowObject.testService->windowControl->winId() != 0); + + + widget.setMediaObject(&widgetObject); + QCOMPARE(widget.mediaObject(), static_cast<QMediaObject *>(&widgetObject)); + QCOMPARE(widgetObject.testService->outputControl->output(), QVideoOutputControl::WidgetOutput); + + QCoreApplication::processEvents(QEventLoop::AllEvents); + QCOMPARE(widgetObject.testService->widgetControl->videoWidget()->isVisible(), true); + + QCOMPARE(windowObject.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + widget.setMediaObject(&rendererObject); + QCOMPARE(widget.mediaObject(), static_cast<QMediaObject *>(&rendererObject)); + QCOMPARE(rendererObject.testService->outputControl->output(), QVideoOutputControl::RendererOutput); + QVERIFY(rendererObject.testService->rendererControl->surface() != 0); + + QCOMPARE(widgetObject.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + widget.setMediaObject(0); + QCOMPARE(widget.mediaObject(), nullObject); + + QCOMPARE(rendererObject.testService->outputControl->output(), QVideoOutputControl::NoOutput); +} + +void tst_QVideoWidget::showWindowControl() +{ + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + object.testService->windowControl->setNativeSize(QSize(240, 180)); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::WindowOutput); + QVERIFY(object.testService->windowControl->winId() != 0); + + QVERIFY(object.testService->windowControl->repaintCount() > 0); + + widget.resize(640, 480); + QCOMPARE(object.testService->windowControl->displayRect(), QRect(0, 0, 640, 480)); + + widget.move(10, 10); + QCOMPARE(object.testService->windowControl->displayRect(), QRect(0, 0, 640, 480)); + + widget.hide(); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::WindowOutput); +} + +void tst_QVideoWidget::showWidgetControl() +{ + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::WidgetOutput); + QCOMPARE(object.testService->widgetControl->videoWidget()->isVisible(), true); + + widget.resize(640, 480); + + widget.move(10, 10); + + widget.hide(); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::WidgetOutput); + QCOMPARE(object.testService->widgetControl->videoWidget()->isVisible(), false); +} + +void tst_QVideoWidget::showRendererControl() +{ + QtTestVideoObject object(0, 0, new QtTestRendererControl); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::NoOutput); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); + QVERIFY(object.testService->rendererControl->surface() != 0); + + widget.resize(640, 480); + + widget.move(10, 10); + + widget.hide(); + + QCOMPARE(object.testService->outputControl->output(), QVideoOutputControl::RendererOutput); +} + +void tst_QVideoWidget::aspectRatioWindowControl() +{ + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + object.testService->windowControl->setAspectRatioMode(QVideoWidget::IgnoreAspectRatio); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + // Test the aspect ratio defaults to keeping the aspect ratio. + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + + // Test the control has been informed of the aspect ratio change, post show. + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + QCOMPARE(object.testService->windowControl->aspectRatioMode(), QVideoWidget::KeepAspectRatio); + + // Test an aspect ratio change is enforced immediately while visible. + widget.setAspectRatioMode(QVideoWidget::IgnoreAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::IgnoreAspectRatio); + QCOMPARE(object.testService->windowControl->aspectRatioMode(), QVideoWidget::IgnoreAspectRatio); + + // Test an aspect ratio set while not visible is respected. + widget.hide(); + widget.setAspectRatioMode(QVideoWidget::KeepAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + widget.show(); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + QCOMPARE(object.testService->windowControl->aspectRatioMode(), QVideoWidget::KeepAspectRatio); +} + +void tst_QVideoWidget::aspectRatioWidgetControl() +{ + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + object.testService->widgetControl->setAspectRatioMode(QVideoWidget::IgnoreAspectRatio); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + // Test the aspect ratio defaults to keeping the aspect ratio. + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + + // Test the control has been informed of the aspect ratio change, post show. + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + QCOMPARE(object.testService->widgetControl->aspectRatioMode(), QVideoWidget::KeepAspectRatio); + + // Test an aspect ratio change is enforced immediately while visible. + widget.setAspectRatioMode(QVideoWidget::IgnoreAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::IgnoreAspectRatio); + QCOMPARE(object.testService->widgetControl->aspectRatioMode(), QVideoWidget::IgnoreAspectRatio); + + // Test an aspect ratio set while not visible is respected. + widget.hide(); + widget.setAspectRatioMode(QVideoWidget::KeepAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + widget.show(); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + QCOMPARE(object.testService->widgetControl->aspectRatioMode(), QVideoWidget::KeepAspectRatio); +} + +void tst_QVideoWidget::aspectRatioRendererControl() +{ + QtTestVideoObject object(0, 0, new QtTestRendererControl); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + // Test the aspect ratio defaults to keeping the aspect ratio. + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + + // Test the control has been informed of the aspect ratio change, post show. + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + + // Test an aspect ratio change is enforced immediately while visible. + widget.setAspectRatioMode(QVideoWidget::IgnoreAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::IgnoreAspectRatio); + + // Test an aspect ratio set while not visible is respected. + widget.hide(); + widget.setAspectRatioMode(QVideoWidget::KeepAspectRatio); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); + widget.show(); + QCOMPARE(widget.aspectRatioMode(), QVideoWidget::KeepAspectRatio); +} + +void tst_QVideoWidget::sizeHint_data() +{ + QTest::addColumn<QSize>("size"); + + QTest::newRow("720x576") + << QSize(720, 576); +} + +void tst_QVideoWidget::sizeHintWindowControl() +{ + QFETCH(QSize, size); + + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QVERIFY(widget.sizeHint().isEmpty()); + + object.testService->windowControl->setNativeSize(size); + QCOMPARE(widget.sizeHint(), size); +} + +void tst_QVideoWidget::sizeHintWidgetControl() +{ + QFETCH(QSize, size); + + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QVERIFY(widget.sizeHint().isEmpty()); + + object.testService->widgetControl->setSizeHint(size); + QCOMPARE(widget.sizeHint(), size); +} + +void tst_QVideoWidget::sizeHintRendererControl_data() +{ + QTest::addColumn<QSize>("frameSize"); + QTest::addColumn<QRect>("viewport"); + QTest::addColumn<QSize>("pixelAspectRatio"); + QTest::addColumn<QSize>("expectedSize"); + + QTest::newRow("640x480") + << QSize(640, 480) + << QRect(0, 0, 640, 480) + << QSize(1, 1) + << QSize(640, 480); + + QTest::newRow("800x600, (80,60, 640x480) viewport") + << QSize(800, 600) + << QRect(80, 60, 640, 480) + << QSize(1, 1) + << QSize(640, 480); + + QTest::newRow("800x600, (80,60, 640x480) viewport, 4:3") + << QSize(800, 600) + << QRect(80, 60, 640, 480) + << QSize(4, 3) + << QSize(853, 480); + +} + +void tst_QVideoWidget::sizeHintRendererControl() +{ + QFETCH(QSize, frameSize); + QFETCH(QRect, viewport); + QFETCH(QSize, pixelAspectRatio); + QFETCH(QSize, expectedSize); + + QtTestVideoObject object(0, 0, new QtTestRendererControl); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QVideoSurfaceFormat format(frameSize, QVideoFrame::Format_ARGB32); + format.setViewport(viewport); + format.setPixelAspectRatio(pixelAspectRatio); + + QVERIFY(object.testService->rendererControl->surface()->start(format)); + + QCOMPARE(widget.sizeHint(), expectedSize); +} + +#ifndef Q_WS_X11 + +void tst_QVideoWidget::fullScreenWindowControl() +{ + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + Qt::WindowFlags windowFlags = widget.windowFlags(); + + QSignalSpy spy(&widget, SIGNAL(fullScreenChanged(bool))); + + // Test showing full screen with setFullScreen(true). + widget.setFullScreen(true); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->windowControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toBool(), true); + + // Test returning to normal with setFullScreen(false). + widget.setFullScreen(false); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->windowControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toBool(), false); + QCOMPARE(widget.windowFlags(), windowFlags); + + // Test showing full screen with showFullScreen(). + widget.showFullScreen(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->windowControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 3); + QCOMPARE(spy.value(2).value(0).toBool(), true); + + // Test returning to normal with showNormal(). + widget.showNormal(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->windowControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + QCOMPARE(spy.value(3).value(0).toBool(), false); + QCOMPARE(widget.windowFlags(), windowFlags); + + // Test setFullScreen(false) and showNormal() do nothing when isFullScreen() == false. + widget.setFullScreen(false); + QCOMPARE(object.testService->windowControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + widget.showNormal(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->windowControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + + // Test setFullScreen(true) and showFullScreen() do nothing when isFullScreen() == true. + widget.showFullScreen(); + QTest::qWaitForWindowShown(&widget); + widget.setFullScreen(true); + QCOMPARE(object.testService->windowControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 5); + widget.showFullScreen(); + QCOMPARE(object.testService->windowControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 5); + + // Test if the window control exits full screen mode, the widget follows suit. + object.testService->windowControl->setFullScreen(false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 6); + QCOMPARE(spy.value(5).value(0).toBool(), false); + + // Test if the window control enters full screen mode, the widget does nothing. + object.testService->windowControl->setFullScreen(false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 6); +} + +void tst_QVideoWidget::fullScreenWidgetControl() +{ + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + Qt::WindowFlags windowFlags = widget.windowFlags(); + + QSignalSpy spy(&widget, SIGNAL(fullScreenChanged(bool))); + + // Test showing full screen with setFullScreen(true). + widget.setFullScreen(true); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->widgetControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toBool(), true); + + // Test returning to normal with setFullScreen(false). + widget.setFullScreen(false); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->widgetControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toBool(), false); + QCOMPARE(widget.windowFlags(), windowFlags); + + // Test showing full screen with showFullScreen(). + widget.showFullScreen(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->widgetControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 3); + QCOMPARE(spy.value(2).value(0).toBool(), true); + + // Test returning to normal with showNormal(). + widget.showNormal(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(object.testService->widgetControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + QCOMPARE(spy.value(3).value(0).toBool(), false); + QCOMPARE(widget.windowFlags(), windowFlags); + + // Test setFullScreen(false) and showNormal() do nothing when isFullScreen() == false. + widget.setFullScreen(false); + QCOMPARE(object.testService->widgetControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + widget.showNormal(); + QCOMPARE(object.testService->widgetControl->isFullScreen(), false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + + // Test setFullScreen(true) and showFullScreen() do nothing when isFullScreen() == true. + widget.showFullScreen(); + QTest::qWaitForWindowShown(&widget); + widget.setFullScreen(true); + QCOMPARE(object.testService->widgetControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 5); + widget.showFullScreen(); + QCOMPARE(object.testService->widgetControl->isFullScreen(), true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 5); + + // Test if the window control exits full screen mode, the widget follows suit. + object.testService->widgetControl->setFullScreen(false); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 6); + QCOMPARE(spy.value(5).value(0).toBool(), false); + + // Test if the window control enters full screen mode, the widget does nothing. + object.testService->widgetControl->setFullScreen(false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 6); +} + + +void tst_QVideoWidget::fullScreenRendererControl() +{ + QtTestVideoObject object(0, 0, new QtTestRendererControl); + QVideoWidget widget; + widget.setMediaObject(&object); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + Qt::WindowFlags windowFlags = widget.windowFlags(); + + QSignalSpy spy(&widget, SIGNAL(fullScreenChanged(bool))); + + // Test showing full screen with setFullScreen(true). + widget.setFullScreen(true); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toBool(), true); + + // Test returning to normal with setFullScreen(false). + widget.setFullScreen(false); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toBool(), false); + QCOMPARE(widget.windowFlags(), windowFlags); + + // Test showing full screen with showFullScreen(). + widget.showFullScreen(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 3); + QCOMPARE(spy.value(2).value(0).toBool(), true); + + // Test returning to normal with showNormal(). + widget.showNormal(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + QCOMPARE(spy.value(3).value(0).toBool(), false); + QCOMPARE(widget.windowFlags(), windowFlags); + + // Test setFullScreen(false) and showNormal() do nothing when isFullScreen() == false. + widget.setFullScreen(false); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + widget.showNormal(); + QCOMPARE(widget.isFullScreen(), false); + QCOMPARE(spy.count(), 4); + + // Test setFullScreen(true) and showFullScreen() do nothing when isFullScreen() == true. + widget.showFullScreen(); + QTest::qWaitForWindowShown(&widget); + widget.setFullScreen(true); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 5); + widget.showFullScreen(); + QCOMPARE(widget.isFullScreen(), true); + QCOMPARE(spy.count(), 5); +} + +#endif + +void tst_QVideoWidget::color_data() +{ + QTest::addColumn<int>("controlValue"); + QTest::addColumn<int>("value"); + QTest::addColumn<int>("expectedValue"); + + QTest::newRow("12") + << 0 + << 12 + << 12; + QTest::newRow("-56") + << 87 + << -56 + << -56; + QTest::newRow("100") + << 32 + << 100 + << 100; + QTest::newRow("1294") + << 0 + << 1294 + << 100; + QTest::newRow("-102") + << 34 + << -102 + << -100; +} + +void tst_QVideoWidget::brightnessWindowControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + object.testService->windowControl->setBrightness(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + // Test the video widget resets the controls starting brightness to the default. + QCOMPARE(widget.brightness(), 0); + + QSignalSpy spy(&widget, SIGNAL(brightnessChanged(int))); + + // Test the video widget sets the brightness value, bounded if necessary and emits a changed + // signal. + widget.setBrightness(value); + QCOMPARE(widget.brightness(), expectedValue); + QCOMPARE(object.testService->windowControl->brightness(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + // Test the changed signal isn't emitted if the value is unchanged. + widget.setBrightness(value); + QCOMPARE(widget.brightness(), expectedValue); + QCOMPARE(object.testService->windowControl->brightness(), expectedValue); + QCOMPARE(spy.count(), 1); + + // Test the changed signal is emitted if the brightness is changed internally. + object.testService->windowControl->setBrightness(controlValue); + QCOMPARE(widget.brightness(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); +} + +void tst_QVideoWidget::brightnessWidgetControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + object.testService->widgetControl->setBrightness(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QCOMPARE(widget.brightness(), 0); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QSignalSpy spy(&widget, SIGNAL(brightnessChanged(int))); + + widget.setBrightness(value); + QCOMPARE(widget.brightness(), expectedValue); + QCOMPARE(object.testService->widgetControl->brightness(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setBrightness(value); + QCOMPARE(widget.brightness(), expectedValue); + QCOMPARE(object.testService->widgetControl->brightness(), expectedValue); + QCOMPARE(spy.count(), 1); + + object.testService->widgetControl->setBrightness(controlValue); + QCOMPARE(widget.brightness(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); +} + +void tst_QVideoWidget::brightnessRendererControl() +{ + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, 0, new QtTestRendererControl); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QSignalSpy spy(&widget, SIGNAL(brightnessChanged(int))); + + widget.setBrightness(value); + QCOMPARE(widget.brightness(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setBrightness(value); + QCOMPARE(widget.brightness(), expectedValue); + QCOMPARE(spy.count(), 1); +} + +void tst_QVideoWidget::contrastWindowControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + object.testService->windowControl->setContrast(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QCOMPARE(widget.contrast(), 0); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.contrast(), 0); + + QSignalSpy spy(&widget, SIGNAL(contrastChanged(int))); + + widget.setContrast(value); + QCOMPARE(widget.contrast(), expectedValue); + QCOMPARE(object.testService->windowControl->contrast(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setContrast(value); + QCOMPARE(widget.contrast(), expectedValue); + QCOMPARE(object.testService->windowControl->contrast(), expectedValue); + QCOMPARE(spy.count(), 1); + + object.testService->windowControl->setContrast(controlValue); + QCOMPARE(widget.contrast(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); +} + +void tst_QVideoWidget::contrastWidgetControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + object.testService->widgetControl->setContrast(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + QCOMPARE(widget.contrast(), 0); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.contrast(), 0); + + QSignalSpy spy(&widget, SIGNAL(contrastChanged(int))); + + widget.setContrast(value); + QCOMPARE(widget.contrast(), expectedValue); + QCOMPARE(object.testService->widgetControl->contrast(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setContrast(value); + QCOMPARE(widget.contrast(), expectedValue); + QCOMPARE(object.testService->widgetControl->contrast(), expectedValue); + QCOMPARE(spy.count(), 1); + + object.testService->widgetControl->setContrast(controlValue); + QCOMPARE(widget.contrast(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); +} + +void tst_QVideoWidget::contrastRendererControl() +{ + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, 0, new QtTestRendererControl); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QSignalSpy spy(&widget, SIGNAL(contrastChanged(int))); + + widget.setContrast(value); + QCOMPARE(widget.contrast(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setContrast(value); + QCOMPARE(widget.contrast(), expectedValue); + QCOMPARE(spy.count(), 1); +} + +void tst_QVideoWidget::hueWindowControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + object.testService->windowControl->setHue(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + QCOMPARE(widget.hue(), 0); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.hue(), 0); + + QSignalSpy spy(&widget, SIGNAL(hueChanged(int))); + + widget.setHue(value); + QCOMPARE(widget.hue(), expectedValue); + QCOMPARE(object.testService->windowControl->hue(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setHue(value); + QCOMPARE(widget.hue(), expectedValue); + QCOMPARE(object.testService->windowControl->hue(), expectedValue); + QCOMPARE(spy.count(), 1); + + object.testService->windowControl->setHue(controlValue); + QCOMPARE(widget.hue(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); +} + +void tst_QVideoWidget::hueWidgetControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + object.testService->widgetControl->setHue(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + QCOMPARE(widget.hue(), 0); + + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.hue(), 0); + + QSignalSpy spy(&widget, SIGNAL(hueChanged(int))); + + widget.setHue(value); + QCOMPARE(widget.hue(), expectedValue); + QCOMPARE(object.testService->widgetControl->hue(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setHue(value); + QCOMPARE(widget.hue(), expectedValue); + QCOMPARE(object.testService->widgetControl->hue(), expectedValue); + QCOMPARE(spy.count(), 1); + + object.testService->widgetControl->setHue(controlValue); + QCOMPARE(widget.hue(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); +} + +void tst_QVideoWidget::hueRendererControl() +{ + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, 0, new QtTestRendererControl); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QSignalSpy spy(&widget, SIGNAL(hueChanged(int))); + + widget.setHue(value); + QCOMPARE(widget.hue(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setHue(value); + QCOMPARE(widget.hue(), expectedValue); + QCOMPARE(spy.count(), 1); +} + +void tst_QVideoWidget::saturationWindowControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(new QtTestWindowControl, 0, 0); + object.testService->windowControl->setSaturation(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + QCOMPARE(widget.saturation(), 0); + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.saturation(), 0); + + QSignalSpy spy(&widget, SIGNAL(saturationChanged(int))); + + widget.setSaturation(value); + QCOMPARE(widget.saturation(), expectedValue); + QCOMPARE(object.testService->windowControl->saturation(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setSaturation(value); + QCOMPARE(widget.saturation(), expectedValue); + QCOMPARE(object.testService->windowControl->saturation(), expectedValue); + QCOMPARE(spy.count(), 1); + + object.testService->windowControl->setSaturation(controlValue); + QCOMPARE(widget.saturation(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); +} + +void tst_QVideoWidget::saturationWidgetControl() +{ + QFETCH(int, controlValue); + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, new QtTestWidgetControl, 0); + object.testService->widgetControl->setSaturation(controlValue); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + + QCOMPARE(widget.saturation(), 0); + widget.show(); + QTest::qWaitForWindowShown(&widget); + QCOMPARE(widget.saturation(), 0); + + QSignalSpy spy(&widget, SIGNAL(saturationChanged(int))); + + widget.setSaturation(value); + QCOMPARE(widget.saturation(), expectedValue); + QCOMPARE(object.testService->widgetControl->saturation(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setSaturation(value); + QCOMPARE(widget.saturation(), expectedValue); + QCOMPARE(object.testService->widgetControl->saturation(), expectedValue); + QCOMPARE(spy.count(), 1); + + object.testService->widgetControl->setSaturation(controlValue); + QCOMPARE(widget.saturation(), controlValue); + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.value(1).value(0).toInt(), controlValue); + +} + +void tst_QVideoWidget::saturationRendererControl() +{ + QFETCH(int, value); + QFETCH(int, expectedValue); + + QtTestVideoObject object(0, 0, new QtTestRendererControl); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + QSignalSpy spy(&widget, SIGNAL(saturationChanged(int))); + + widget.setSaturation(value); + QCOMPARE(widget.saturation(), expectedValue); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.value(0).value(0).toInt(), expectedValue); + + widget.setSaturation(value); + QCOMPARE(widget.saturation(), expectedValue); + QCOMPARE(spy.count(), 1); +} + +static const uchar rgb32ImageData[] = +{ + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00 +}; + +void tst_QVideoWidget::paintRendererControl() +{ + QtTestVideoObject object(0, 0, new QtTestRendererControl); + + QVideoWidget widget; + widget.setMediaObject(&object); + widget.setWindowFlags(Qt::X11BypassWindowManagerHint); + widget.show(); + QTest::qWaitForWindowShown(&widget); + + QPainterVideoSurface *surface = qobject_cast<QPainterVideoSurface *>( + object.testService->rendererControl->surface()); + + QVideoSurfaceFormat format(QSize(2, 2), QVideoFrame::Format_RGB32); + + QVERIFY(surface->start(format)); + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), true); + + QCoreApplication::processEvents(QEventLoop::AllEvents); + + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), true); + + QVideoFrame frame(sizeof(rgb32ImageData), QSize(2, 2), 8, QVideoFrame::Format_RGB32); + + frame.map(QAbstractVideoBuffer::WriteOnly); + memcpy(frame.bits(), rgb32ImageData, frame.mappedBytes()); + frame.unmap(); + + QVERIFY(surface->present(frame)); + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), false); + + QCoreApplication::processEvents(QEventLoop::AllEvents); + + QCOMPARE(surface->isActive(), true); + QCOMPARE(surface->isReady(), true); +} + +QTEST_MAIN(tst_QVideoWidget) + +#include "tst_qvideowidget.moc" diff --git a/tests/benchmarks/corelib/tools/qvector/main.cpp b/tests/benchmarks/corelib/tools/qvector/main.cpp index 65e7609..6393eda 100644 --- a/tests/benchmarks/corelib/tools/qvector/main.cpp +++ b/tests/benchmarks/corelib/tools/qvector/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 15421eb..1824d20 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/binding/testtypes.cpp b/tests/benchmarks/declarative/binding/testtypes.cpp index 892738c..3a9f59b 100644 --- a/tests/benchmarks/declarative/binding/testtypes.cpp +++ b/tests/benchmarks/declarative/binding/testtypes.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/binding/testtypes.h b/tests/benchmarks/declarative/binding/testtypes.h index c0586b1..d4e0a1a 100644 --- a/tests/benchmarks/declarative/binding/testtypes.h +++ b/tests/benchmarks/declarative/binding/testtypes.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/binding/tst_binding.cpp b/tests/benchmarks/declarative/binding/tst_binding.cpp index 7b4875f..74a3407 100644 --- a/tests/benchmarks/declarative/binding/tst_binding.cpp +++ b/tests/benchmarks/declarative/binding/tst_binding.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp index ae50309..23c820c 100644 --- a/tests/benchmarks/declarative/creation/tst_creation.cpp +++ b/tests/benchmarks/declarative/creation/tst_creation.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/pointers/tst_pointers.cpp b/tests/benchmarks/declarative/pointers/tst_pointers.cpp index 55c2e89..4fead9a 100644 --- a/tests/benchmarks/declarative/pointers/tst_pointers.cpp +++ b/tests/benchmarks/declarative/pointers/tst_pointers.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp b/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp index 56d20c6..f0bc1f9 100644 --- a/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp +++ b/tests/benchmarks/declarative/qmlcomponent/testtypes.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/qmlcomponent/testtypes.h b/tests/benchmarks/declarative/qmlcomponent/testtypes.h index c0586b1..d4e0a1a 100644 --- a/tests/benchmarks/declarative/qmlcomponent/testtypes.h +++ b/tests/benchmarks/declarative/qmlcomponent/testtypes.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/qmlcomponent/tst_qmlcomponent.cpp b/tests/benchmarks/declarative/qmlcomponent/tst_qmlcomponent.cpp index f5a4540..647edbf 100644 --- a/tests/benchmarks/declarative/qmlcomponent/tst_qmlcomponent.cpp +++ b/tests/benchmarks/declarative/qmlcomponent/tst_qmlcomponent.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -23,7 +23,7 @@ ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.qml in this package. +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/tests/benchmarks/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp b/tests/benchmarks/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp index f6a6432..7d7d24e 100644 --- a/tests/benchmarks/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp +++ b/tests/benchmarks/declarative/qmlgraphicsimage/tst_qmlgraphicsimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp b/tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp index 8d0e549..4c002f8 100644 --- a/tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp +++ b/tests/benchmarks/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tests/benchmarks/declarative/script/tst_script.cpp b/tests/benchmarks/declarative/script/tst_script.cpp index 36a0833..dd21997 100644 --- a/tests/benchmarks/declarative/script/tst_script.cpp +++ b/tests/benchmarks/declarative/script/tst_script.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/assistant/lib/qclucenefieldnames.cpp b/tools/assistant/lib/qclucenefieldnames.cpp index 84e3a1a..1a94291 100644 --- a/tools/assistant/lib/qclucenefieldnames.cpp +++ b/tools/assistant/lib/qclucenefieldnames.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/assistant/tools/assistant/bookmarkitem.cpp b/tools/assistant/tools/assistant/bookmarkitem.cpp index 8036959..2e81e38 100644 --- a/tools/assistant/tools/assistant/bookmarkitem.cpp +++ b/tools/assistant/tools/assistant/bookmarkitem.cpp @@ -28,6 +28,13 @@ ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** +** +** +** +** +** +** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/tools/assistant/tools/assistant/bookmarkitem.h b/tools/assistant/tools/assistant/bookmarkitem.h index 7acaf86..924a762 100644 --- a/tools/assistant/tools/assistant/bookmarkitem.h +++ b/tools/assistant/tools/assistant/bookmarkitem.h @@ -28,9 +28,17 @@ ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** +** +** +** +** +** +** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ + #ifndef BOOKMARKITEM_H #define BOOKMARKITEM_H diff --git a/tools/assistant/tools/assistant/helpenginewrapper.cpp b/tools/assistant/tools/assistant/helpenginewrapper.cpp index a181c71..e21e95d 100644 --- a/tools/assistant/tools/assistant/helpenginewrapper.cpp +++ b/tools/assistant/tools/assistant/helpenginewrapper.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/assistant/tools/assistant/helpenginewrapper.h b/tools/assistant/tools/assistant/helpenginewrapper.h index 8d95273..c1041b6 100644 --- a/tools/assistant/tools/assistant/helpenginewrapper.h +++ b/tools/assistant/tools/assistant/helpenginewrapper.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/assistant/tools/assistant/xbelsupport.cpp b/tools/assistant/tools/assistant/xbelsupport.cpp index 7d5a08b..ce49230 100644 --- a/tools/assistant/tools/assistant/xbelsupport.cpp +++ b/tools/assistant/tools/assistant/xbelsupport.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/assistant/tools/shared/collectionconfiguration.cpp b/tools/assistant/tools/shared/collectionconfiguration.cpp index 896afaf..e3944b6 100644 --- a/tools/assistant/tools/shared/collectionconfiguration.cpp +++ b/tools/assistant/tools/shared/collectionconfiguration.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/assistant/tools/shared/collectionconfiguration.h b/tools/assistant/tools/shared/collectionconfiguration.h index d897adb..b7bf247 100644 --- a/tools/assistant/tools/shared/collectionconfiguration.h +++ b/tools/assistant/tools/shared/collectionconfiguration.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/designer/src/components/formeditor/formwindow.cpp b/tools/designer/src/components/formeditor/formwindow.cpp index 631ca7c..15775f6 100644 --- a/tools/designer/src/components/formeditor/formwindow.cpp +++ b/tools/designer/src/components/formeditor/formwindow.cpp @@ -1436,6 +1436,14 @@ struct ArrowKeyOperation { int arrowKey; }; +} // namespace + +QT_END_NAMESPACE +Q_DECLARE_METATYPE(qdesigner_internal::ArrowKeyOperation) +QT_BEGIN_NAMESPACE + +namespace qdesigner_internal { + QRect ArrowKeyOperation::apply(const QRect &rect) const { QRect r = rect; @@ -2964,4 +2972,3 @@ QUndoStack *FormWindow::commandHistory() const QT_END_NAMESPACE -Q_DECLARE_METATYPE(qdesigner_internal::ArrowKeyOperation) diff --git a/tools/linguist/lupdate/qml.cpp b/tools/linguist/lupdate/qml.cpp index 860d87c..cb35f47 100644 --- a/tools/linguist/lupdate/qml.cpp +++ b/tools/linguist/lupdate/qml.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qdoc3/codeparser.cpp b/tools/qdoc3/codeparser.cpp index 3ad3372..5ae63ac 100644 --- a/tools/qdoc3/codeparser.cpp +++ b/tools/qdoc3/codeparser.cpp @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE #define COMMAND_MAINCLASS Doc::alias(QLatin1String("mainclass")) #define COMMAND_NONREENTRANT Doc::alias(QLatin1String("nonreentrant")) #define COMMAND_OBSOLETE Doc::alias(QLatin1String("obsolete")) +#define COMMAND_PAGEKEYWORDS Doc::alias(QLatin1String("pagekeywords")) #define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary")) #define COMMAND_INPUBLICGROUP Doc::alias(QLatin1String("inpublicgroup")) #define COMMAND_REENTRANT Doc::alias(QLatin1String("reentrant")) @@ -170,6 +171,7 @@ QSet<QString> CodeParser::commonMetaCommands() << COMMAND_MAINCLASS << COMMAND_NONREENTRANT << COMMAND_OBSOLETE + << COMMAND_PAGEKEYWORDS << COMMAND_PRELIMINARY << COMMAND_INPUBLICGROUP << COMMAND_REENTRANT @@ -230,6 +232,9 @@ void CodeParser::processCommonMetaCommand(const Location &location, else if (command == COMMAND_SINCE) { node->setSince(arg); } + else if (command == COMMAND_PAGEKEYWORDS) { + node->addPageKeywords(arg); + } else if (command == COMMAND_SUBTITLE) { if (node->type() == Node::Fake) { FakeNode *fake = static_cast<FakeNode *>(node); diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp index f62ec24..acb1576 100644 --- a/tools/qdoc3/config.cpp +++ b/tools/qdoc3/config.cpp @@ -671,7 +671,9 @@ void Config::load(Location location, const QString& fileName) location.fatal(tr("Cannot open file '%1': %2").arg(fileName).arg(fin.errorString())); } - QString text = fin.readAll(); + QTextStream stream(&fin); + stream.setCodec("UTF-8"); + QString text = stream.readAll(); text += QLatin1String("\n\n"); text += QChar('\0'); fin.close(); diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 5e7e6f1..6f23469 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -140,8 +140,10 @@ class Config #define CONFIG_INDEXES "indexes" #define CONFIG_LANGUAGE "language" #define CONFIG_MACRO "macro" +#define CONFIG_NATURALLANGUAGE "naturallanguage" #define CONFIG_OBSOLETELINKS "obsoletelinks" #define CONFIG_OUTPUTDIR "outputdir" +#define CONFIG_OUTPUTENCODING "outputencoding" #define CONFIG_OUTPUTLANGUAGE "outputlanguage" #define CONFIG_OUTPUTFORMATS "outputformats" #define CONFIG_PROJECT "project" @@ -150,6 +152,7 @@ class Config #define CONFIG_SLOW "slow" #define CONFIG_SHOWINTERNAL "showinternal" #define CONFIG_SOURCEDIRS "sourcedirs" +#define CONFIG_SOURCEENCODING "sourceencoding" #define CONFIG_SOURCES "sources" #define CONFIG_SPURIOUS "spurious" #define CONFIG_STYLESHEETS "stylesheets" diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp index d9c767a..657cfbb 100644 --- a/tools/qdoc3/cppcodemarker.cpp +++ b/tools/qdoc3/cppcodemarker.cpp @@ -881,8 +881,7 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode, static QRegExp globalX("[\n{()=] *([a-zA-Z_][a-zA-Z_0-9]*)[ \n]*\\("); static QRegExp multiLineComment("/(?:( )?\\*(?:[^*]+|\\*(?! /))*\\*\\1/)"); multiLineComment.setMinimal(true); - static QRegExp singleLineCommentLine("(?:^|\n)(?:[^&]|&(?!quot;)|"(?:[^&\\\\]|&(?!quot;)|\\\\"|\\\\(?!"))*")*//(?!!)[^!\n]*"); - static QRegExp singleLineComment("//(?!!)[^!\n]*"); + static QRegExp singleLineComment("[^:]//(?!!)[^!\\n]*"); static QRegExp preprocessor("(?:^|\n)(#[ \t]*(?:include|if|elif|endif|error|pragma|define" "|warning)(?:(?:\\\\\n|\\n#)[^\n]*)*)"); static QRegExp literals(""(?:[^\\\\&]|\\\\[^\n]|&(?!quot;))*"" @@ -1057,8 +1056,7 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode, int mlpos; int slpos; int len; - int sllpos = singleLineCommentLine.indexIn(result, pos); - slpos = sllpos == -1 ? -1 : singleLineComment.indexIn(result, sllpos); + slpos = singleLineComment.indexIn(result, pos); mlpos = multiLineComment.indexIn(result, pos); if (slpos == -1 && mlpos == -1) @@ -1069,13 +1067,13 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode, len = multiLineComment.matchedLength(); } else if (mlpos == -1) { - pos = slpos; - len = singleLineComment.matchedLength(); + pos = slpos + 1; + len = singleLineComment.matchedLength() - 1; } else { if (slpos < mlpos) { - pos = slpos; - len = singleLineComment.matchedLength(); + pos = slpos + 1; + len = singleLineComment.matchedLength() - 1; } else { pos = mlpos; diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 7d08c77..c8655a4 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -281,8 +281,8 @@ void CppCodeParser::parseHeaderFile(const Location& location, const QString& filePath, Tree *tree) { - FILE *in = fopen(QFile::encodeName(filePath), "r"); - if (!in) { + QFile in(filePath); + if (!in.open(QIODevice::ReadOnly)) { location.error(tr("Cannot open C++ header file '%1'").arg(filePath)); return; } @@ -295,7 +295,7 @@ void CppCodeParser::parseHeaderFile(const Location& location, matchDeclList(tree->root()); if (!fileTokenizer.version().isEmpty()) tree->setVersion(fileTokenizer.version()); - fclose(in); + in.close(); if (fileLocation.fileName() == "qiterator.h") parseQiteratorDotH(location, filePath); @@ -312,8 +312,8 @@ void CppCodeParser::parseSourceFile(const Location& location, const QString& filePath, Tree *tree) { - FILE *in = fopen(QFile::encodeName(filePath), "r"); - if (!in) { + QFile in(filePath); + if (!in.open(QIODevice::ReadOnly)) { location.error(tr("Cannot open C++ source file '%1' (%2)").arg(filePath).arg(strerror(errno))); return; } @@ -325,7 +325,7 @@ void CppCodeParser::parseSourceFile(const Location& location, readToken(); usedNamespaces.clear(); matchDocsAndStuff(); - fclose(in); + in.close(); } /*! diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 17a6efd..ad4cdde 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -3056,7 +3056,8 @@ QString Doc::canonicalTitle(const QString &title) slurping = true; } else { - // !alnum && slurping -> nothin + result += title[i]; + lastAlnum = result.size(); } } result.truncate(lastAlnum); diff --git a/tools/qdoc3/doc/classic.css b/tools/qdoc3/doc/classic.css new file mode 100644 index 0000000..b8cae8e --- /dev/null +++ b/tools/qdoc3/doc/classic.css @@ -0,0 +1,284 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Arial, Geneva, Helvetica, sans-serif; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} + +h3.fn,span.fn +{ + background-color: #eee; + border-width: 1px; + border-style: solid; + border-color: #ddd; + font-weight: bold; + padding: 6px 0px 6px 10px; + margin: 42px 0px 0px 0px; +} + +hr { + border: 0; + color: #a0a0a0; + background-color: #ccc; + height: 1px; + width: 100%; + text-align: left; + margin: 34px 0px 34px 0px; +} + +table.valuelist { + border-width: 1px 1px 1px 1px; + border-style: solid; + border-color: #dddddd; + border-collapse: collapse; + background-color: #f0f0f0; +} + +table.indextable { + border-width: 1px 1px 1px 1px; + border-style: solid; + border-collapse: collapse; + background-color: #f0f0f0; + border-color:#555; + font-size: 100%; +} + +table td.largeindex { + border-width: 1px 1px 1px 1px; + border-collapse: collapse; + background-color: #f0f0f0; + border-color:#555; + font-size: 120%; +} + +table.valuelist th { + border-width: 1px 1px 1px 2px; + padding: 4px; + border-style: solid; + border-color: #666; + color:white; + background-color:#666; +} + +th.titleheader { + border-width: 1px 0px 1px 0px; + padding: 2px; + border-style: solid; + border-color: #666; + color:white; + background-color:#555; + background-image:url('images/gradient.png')}; + background-repeat: repeat-x; + font-size: 100%; +} + + +th.largeheader { + border-width: 1px 0px 1px 0px; + padding: 4px; + border-style: solid; + border-color: #444; + color:white; + background-color:#555555; + font-size: 120%; +} + +p { + + margin-left: 4px; + margin-top: 8px; + margin-bottom: 8px; +} + +a:link +{ + color: #0046ad; + text-decoration: none +} + +a:visited +{ + color: #672967; + text-decoration: none +} + +a.obsolete +{ + color: #661100; + text-decoration: none +} + +a.compat +{ + color: #661100; + text-decoration: none +} + +a.obsolete:visited +{ + color: #995500; + text-decoration: none +} + +a.compat:visited +{ + color: #995500; + text-decoration: none +} + +body +{ + background: #ffffff; + color: black +} + +table.generic, table.annotated +{ + border-width: 1px; + border-color:#bbb; + border-style:solid; + border-collapse:collapse; +} + +table td.memItemLeft { + width: 180px; + padding: 2px 0px 0px 8px; + margin: 4px; + border-width: 1px; + border-color: #E0E0E0; + border-style: none; + font-size: 100%; + white-space: nowrap +} + +table td.memItemRight { + padding: 2px 8px 0px 8px; + margin: 4px; + border-width: 1px; + border-color: #E0E0E0; + border-style: none; + font-size: 100%; +} + +table tr.odd { + background: #f0f0f0; + color: black; +} + +table tr.even { + background: #e4e4e4; + color: black; +} + +table.annotated th { + padding: 3px; + text-align: left +} + +table.annotated td { + padding: 3px; +} + +table tr pre +{ + padding-top: 0px; + padding-bottom: 0px; + padding-left: 0px; + padding-right: 0px; + border: none; + background: none +} + +tr.qt-style +{ + background: #96E066; + color: black +} + +body pre +{ + padding: 0.2em; + border: #e7e7e7 1px solid; + background: #f1f1f1; + color: black +} + +table tr.qt-code pre +{ + padding: 0.2em; + border: #e7e7e7 1px solid; + background: #f1f1f1; + color: black +} + +span.preprocessor, span.preprocessor a +{ + color: darkblue; +} + +span.comment +{ + color: darkred; + font-style: italic +} + +span.string,span.char +{ + color: darkgreen; +} + +.title +{ + text-align: center +} + +.subtitle +{ + font-size: 0.8em +} + +.small-subtitle +{ + font-size: 0.65em +} + +.qmlitem { + padding: 0; +} + +.qmlname { + white-space: nowrap; +} + +.qmltype { + text-align: center; + font-size: 160%; +} + +.qmlproto { + background-color: #eee; + border-width: 1px; + border-style: solid; + border-color: #ddd; + font-weight: bold; + padding: 6px 10px 6px 10px; + margin: 42px 0px 0px 0px; +} + +.qmlreadonly { + float: right; + color: red +} + +.qmldoc { +} + +*.qmlitem p { +} diff --git a/tools/qdoc3/doc/examples/layoutmanagement.qdocinc b/tools/qdoc3/doc/examples/layoutmanagement.qdocinc new file mode 100644 index 0000000..01f8acf --- /dev/null +++ b/tools/qdoc3/doc/examples/layoutmanagement.qdocinc @@ -0,0 +1,13 @@ +\section1 Layout Classes + +The Qt layout system provides a simple and powerful way of specifying +the layout of child widgets. + +By specifying the logical layout once, you get the following benefits: + +\list + \o Positioning of child widgets. + \o Sensible default sizes for windows. + \o Sensible minimum sizes for windows. + \o ... +\endlist diff --git a/tools/qdoc3/doc/examples/main.cpp b/tools/qdoc3/doc/examples/main.cpp new file mode 100644 index 0000000..e2cf6c5 --- /dev/null +++ b/tools/qdoc3/doc/examples/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include <QPushButton> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QPushButton *hello("Hello world!"); + hello.resize(100, 30); + + hello.show(); + return app.exec(); +} diff --git a/tools/qdoc3/doc/examples/minimum.qdocconf b/tools/qdoc3/doc/examples/minimum.qdocconf new file mode 100644 index 0000000..e5e9e67 --- /dev/null +++ b/tools/qdoc3/doc/examples/minimum.qdocconf @@ -0,0 +1,42 @@ +# QDoc is a tool that constantly evolves to suit our needs, +# and there are some compatibility issues between old and new +# practices. For that reason, any QDoc configuration file needs to +# include compat.qdocconf. + +#include(compat.qdocconf) + + +# The outputdir variable specifies the directory +# where QDoc will put the generated documentation. + +outputdir = html + + +# The headerdirs variable specifies the directories +# containing the header files associated +# with the .cpp source files used in the documentation. + +headerdirs = . + + +# The sourcedirs variable specifies the +# directories containing the .cpp or .qdoc +# files used in the documentation. + +#sourcedirs = . + + +# The exampledirs variable specifies the directories containing +# the source code of the example files. + +exampledirs = . + + +# The imagedirs variable specifies the +# directories containing the images used in the documentation. + +imagedirs = ./images + + + + diff --git a/tools/qdoc3/doc/examples/objectmodel.qdocinc b/tools/qdoc3/doc/examples/objectmodel.qdocinc new file mode 100644 index 0000000..02b5991 --- /dev/null +++ b/tools/qdoc3/doc/examples/objectmodel.qdocinc @@ -0,0 +1,11 @@ +\section1 Qt Object Model + +The standard C++ object model provides very efficient runtime support +for the object paradigm. But its static nature is inflexibile in +certain problem domains. Graphical user interface programming is a +domain that requires both runtime efficiency and a high level of +flexibility. Qt provides this, by combining the speed of C++ with the +flexibility of the Qt Object Model. + +... + diff --git a/tools/qdoc3/doc/examples/signalandslots.qdocinc b/tools/qdoc3/doc/examples/signalandslots.qdocinc new file mode 100644 index 0000000..cfae43a --- /dev/null +++ b/tools/qdoc3/doc/examples/signalandslots.qdocinc @@ -0,0 +1,9 @@ +\section1 Signals and Slots + +Signals and slots are used for communication between objects. The signals and +slots mechanism is a central feature of Qt and probably the part that differs +most from the features provided by other frameworks. + +\section2 Introduction + +In GUI programming, when we ... diff --git a/tools/qdoc3/doc/files/compat.qdocconf b/tools/qdoc3/doc/files/compat.qdocconf new file mode 100644 index 0000000..5745ed9 --- /dev/null +++ b/tools/qdoc3/doc/files/compat.qdocconf @@ -0,0 +1,31 @@ +alias.i = e +alias.include = input + +macro.0 = "\\\\0" +macro.b = "\\\\b" +macro.n = "\\\\n" +macro.r = "\\\\r" +macro.i = "\\o" +macro.i11 = "\\o{1,1}" +macro.i12 = "\\o{1,2}" +macro.i13 = "\\o{1,3}" +macro.i14 = "\\o{1,4}" +macro.i15 = "\\o{1,5}" +macro.i16 = "\\o{1,6}" +macro.i17 = "\\o{1,7}" +macro.i18 = "\\o{1,8}" +macro.i19 = "\\o{1,9}" +macro.i21 = "\\o{2,1}" +macro.i31 = "\\o{3,1}" +macro.i41 = "\\o{4,1}" +macro.i51 = "\\o{5,1}" +macro.i61 = "\\o{6,1}" +macro.i71 = "\\o{7,1}" +macro.i81 = "\\o{8,1}" +macro.i91 = "\\o{9,1}" +macro.img = "\\image" +macro.endquote = "\\endquotation" +macro.relatesto = "\\relates" + +spurious = "Missing comma in .*" \ + "Missing pattern .*" diff --git a/tools/qdoc3/doc/files/qt.qdocconf b/tools/qdoc3/doc/files/qt.qdocconf new file mode 100644 index 0000000..942d023 --- /dev/null +++ b/tools/qdoc3/doc/files/qt.qdocconf @@ -0,0 +1,115 @@ +include(compat.qdocconf) +include(macros.qdocconf) +include(qt-cpp-ignore.qdocconf) +include(qt-html-templates.qdocconf) +include(qt-defines.qdocconf) + +project = Qt +versionsym = +version = %VERSION% +description = Qt Reference Documentation +url = http://qt.nokia.com/doc/4.6 + +edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \ + QtXmlPatterns QtTest +edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \ + QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \ + QtDesigner QtAssistant QAxContainer Phonon \ + QAxServer QtUiTools QtTest QtDBus +edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest +edition.DesktopLight.groups = -graphicsview-api + +qhp.projects = Qt + +qhp.Qt.file = qt.qhp +qhp.Qt.namespace = com.trolltech.qt.460 +qhp.Qt.virtualFolder = qdoc +qhp.Qt.indexTitle = Qt Reference Documentation +qhp.Qt.indexRoot = + +# Files not referenced in any qdoc file (last four are needed by qtdemo) +# See also extraimages.HTML +qhp.Qt.extraFiles = classic.css \ + images/qt-logo.png \ + images/taskmenuextension-example.png \ + images/coloreditorfactoryimage.png \ + images/dynamiclayouts-example.png \ + images/stylesheet-coffee-plastique.png + +qhp.Qt.filterAttributes = qt 4.6.0 qtrefdoc +qhp.Qt.customFilters.Qt.name = Qt 4.6.0 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.0 +qhp.Qt.subprojects = classes overviews examples +qhp.Qt.subprojects.classes.title = Classes +qhp.Qt.subprojects.classes.indexTitle = Qt's Classes +qhp.Qt.subprojects.classes.selectors = class fake:headerfile +qhp.Qt.subprojects.classes.sortPages = true +qhp.Qt.subprojects.overviews.title = Overviews +qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs +qhp.Qt.subprojects.overviews.selectors = fake:page,group,module +qhp.Qt.subprojects.examples.title = Tutorials and Examples +qhp.Qt.subprojects.examples.indexTitle = Qt Examples +qhp.Qt.subprojects.examples.selectors = fake:example + +language = Cpp + +headerdirs = $QTDIR/src \ + $QTDIR/extensions/activeqt \ + $QTDIR/tools/assistant/lib \ + $QTDIR/tools/assistant/compat/lib \ + $QTDIR/tools/designer/src/uitools \ + $QTDIR/tools/designer/src/lib/extension \ + $QTDIR/tools/designer/src/lib/sdk \ + $QTDIR/tools/designer/src/lib/uilib \ + $QTDIR/tools/qtestlib/src \ + $QTDIR/tools/qdbus/src +sourcedirs = $QTDIR/src \ + $QTDIR/doc/src \ + $QTDIR/extensions/activeqt \ + $QTDIR/tools/assistant/lib \ + $QTDIR/tools/assistant/compat/lib \ + $QTDIR/tools/designer/src/uitools \ + $QTDIR/tools/designer/src/lib/extension \ + $QTDIR/tools/designer/src/lib/sdk \ + $QTDIR/tools/designer/src/lib/uilib \ + $QTDIR/tools/qtestlib/src \ + $QTDIR/tools/qdbus + +excludedirs = $QTDIR/src/3rdparty/clucene \ + $QTDIR/src/3rdparty/des \ + $QTDIR/src/3rdparty/freetype \ + $QTDIR/src/3rdparty/harfbuzz \ + $QTDIR/src/3rdparty/kdebase \ + $QTDIR/src/3rdparty/libjpeg \ + $QTDIR/src/3rdparty/libmng \ + $QTDIR/src/3rdparty/libpng \ + $QTDIR/src/3rdparty/libtiff \ + $QTDIR/src/3rdparty/md4 \ + $QTDIR/src/3rdparty/md5 \ + $QTDIR/src/3rdparty/patches \ + $QTDIR/src/3rdparty/sha1 \ + $QTDIR/src/3rdparty/sqlite \ + $QTDIR/src/3rdparty/webkit/JavaScriptCore \ + $QTDIR/src/3rdparty/webkit/WebCore \ + $QTDIR/src/3rdparty/wintab \ + $QTDIR/src/3rdparty/zlib \ + $QTDIR/doc/src/snippets \ + $QTDIR/src/3rdparty/phonon/gstreamer \ + $QTDIR/src/3rdparty/phonon/ds9 \ + $QTDIR/src/3rdparty/phonon/qt7 \ + $QTDIR/src/3rdparty/phonon/waveout + +sources.fileextensions = "*.cpp *.qdoc *.mm" +examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp" + +exampledirs = $QTDIR/doc/src \ + $QTDIR/examples \ + $QTDIR/examples/tutorials \ + $QTDIR \ + $QTDIR/qmake/examples \ + $QTDIR/src/3rdparty/webkit/WebKit/qt/docs +imagedirs = $QTDIR/doc/src/images \ + $QTDIR/examples +outputdir = $QTDIR/doc/html +tagfile = $QTDIR/doc/html/qt.tags +base = file:$QTDIR/doc/html diff --git a/tools/qdoc3/doc/images/happy.gif b/tools/qdoc3/doc/images/happy.gif Binary files differnew file mode 100644 index 0000000..a4597f6 --- /dev/null +++ b/tools/qdoc3/doc/images/happy.gif diff --git a/tools/qdoc3/doc/images/happyguy.jpg b/tools/qdoc3/doc/images/happyguy.jpg Binary files differnew file mode 100644 index 0000000..e860479 --- /dev/null +++ b/tools/qdoc3/doc/images/happyguy.jpg diff --git a/tools/qdoc3/doc/images/qt-logo.png b/tools/qdoc3/doc/images/qt-logo.png Binary files differnew file mode 100644 index 0000000..14ddf2a --- /dev/null +++ b/tools/qdoc3/doc/images/qt-logo.png diff --git a/tools/qdoc3/doc/images/training.jpg b/tools/qdoc3/doc/images/training.jpg Binary files differnew file mode 100644 index 0000000..c2ce5c3 --- /dev/null +++ b/tools/qdoc3/doc/images/training.jpg diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc new file mode 100644 index 0000000..e2f670c --- /dev/null +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -0,0 +1,8695 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page index.html + \nextpage QDoc Manual + + \title QDoc Manual - Table of Contents + + \list + \o \l{QDoc Manual} + \o \l{QDoc Commands} + \list + \o \l{Markup Commands} + \o \l{Text Formatting Commands} + \o \l{Document Structuring Commands} + \o \l{Verbatim Code Commands} + \o \l{Quoting External Code Commands} + \list + \o \l{Example File} + \endlist + \o \l{Linking Commands} + \o \l{Graphic Commands} + \o \l{Container Commands} + \o \l{Document Contents Commands} + \o \l{Miscellaneous Commands} + \list + \o \l{signalandslots.qdocinc} + \o \l{objectmodel.qdocinc} + \o \l{layoutmanagement.qdocinc} + \endlist + \o \l{Topical Commands} + \o \l{Contextual Commands} + \o \l{Navigation Commands} + \o \l{Status Commands} + \o \l{Thread Support Commands} + \o \l{Relating Commands} + \o \l{Grouping Commands} + \o \l{Title Commands} + \endlist + \o \l{QDoc Configuration} + \list + \o \l{General Variables} + \o \l{Creating Help Project Files} + \o \l{C++ Specific Variables} + \o \l{HTML Specific Variables} + \o \l{Supporting Derived Projects} + \o \l{QDoc Compatibility} + \o \l{qt.qdocconf} + \o \l{minimum.qdocconf} + \endlist + \o \l{QDoc Commands - Alphabetical List} + \endlist +*/ + +/*! + \page 01-qdoc-manual.html + \contentspage QDoc Manual - Table of Contents + \previouspage QDoc Manual - Table of Contents + \nextpage QDoc Commands + + \title QDoc Manual + + QDoc is the internal tool used by Qt Development Frameworks for generating + documentation. This document is a reference for QDoc command syntax and + configuration. + + \section1 Overview + + \list I + \o \section2 \l {QDoc Commands} + + \l {QDoc Commands - Alphabetical List}{A complete alphabetical + list}. + + There are two main categories of commands for QDoc: markup + commands and meta-commands. + + The markup commands indicate the generated documentation's + appearance and logical structure. The meta-commands provide + information about the document as well as the documented + item. The meta-commands can be further categorized as topical + commands and contextual commands. + + \list + \o \l {Markup Commands} + \list + \o \l {Text Formatting Commands}{Text Formatting} + \o \l {Document Structuring Commands}{Document Structuring} + \o \l {Verbatim Code Commands}{Verbatim Code} + \o \l {Quoting External Code Commands}{Quoting External Code} + \o \l {Linking Commands}{Linking} + \o \l {Graphic Commands}{Graphic} + \o \l {Container Commands}{Container} + \o \l {Document Contents Commands}{Document Contents} + \o \l {Miscellaneous Commands}{Miscellaneous} + \endlist + \o \l {Topical Commands} + \o \l {Contextual Commands} + \list + \o \l {Navigation Commands}{Navigation} + \o \l {Status Commands}{Status} + \o \l {Thread Support Commands}{Thread Support} + \o \l {Relating Commands}{Relating} + \o \l {Grouping Commands}{Grouping} + \o \l {Title Commands}{Title} + \endlist + \endlist + \endlist + + \list II + \o \section2 \l {QDoc Configuration} + + When running QDoc to generate the documentation, you must + specify a configuration file on the command line. The + configuration file is a list of entries of entries of the form + "variable = value". + + \list + \o \l {Configuration Variables} + \o \l {Configuration File Examples} + \endlist + + Some particular configuration variables allow you to use QDoc + to support Qt-based projects; i.e to make projects, such as Qt + Solutions, contain references to the online Qt documentation. + + \list + \o \l {Supporting Derived Projects} + \endlist + + QDoc is a tool that constantly evolves to suit our needs, for + that reason there are some compatibility issues between old and + new practices. + + \list + \o \l {QDoc Compatibility} + \endlist + \endlist +*/ + +/*! + \page 02-qdoc-commands.html + \previouspage QDoc Manual + \contentspage QDoc Manual - Table of Contents + \nextpage Markup Commands + + \title QDoc Commands + + There are two main categories of commands for QDoc: markup + commands and meta-commands. + + The markup commands indicate the generated documentation's visual + appearance and logical structure. The meta-commands provide + information about the documentation unit as well as the documented + item. The meta-commands can be further categorized as topical + commands and contextual commands. + + \section1 Alphabetical List + + A complete \l{QDoc Commands - Alphabetical List } + {alphabetical list of the QDoc commands}. + + \section1 Categories + + \list + \o \l {Markup Commands} + \o \l {Topical Commands} + \o \l {Contextual Commands} + \endlist +*/ + +/*! + \page 03-qdoc-commands-markup.html + \contentspage QDoc Manual - Table of Contents + \previouspage QDoc Commands + \nextpage Text Formatting Commands + + \title Markup Commands + + The markup commands indicate the generated documentation's visual + appearance and logical structure. + + \section1 Alphabetical List + + \l {04-qdoc-commands-textformatting.html#backslash}{\\\\}, + \l {04-qdoc-commands-textformatting.html#a}{\\a}, + \l {11-qdoc-commands-documentcontents.html#abstract}{\\abstract}, + \l {06-qdoc-commands-verbatimcode.html#badcode}{\\badcode}, + \l {04-qdoc-commands-textformatting.html#bold}{\\bold}, + \l {11-qdoc-commands-documentcontents.html#brief}{\\brief}, + \l {04-qdoc-commands-textformatting.html#c}{\\c}, + \l {09-qdoc-commands-graphic.html#caption}{\\caption}, + \l {05-qdoc-commands-documentstructuring.html#chapter}{\\chapter}, + \l {06-qdoc-commands-verbatimcode.html#code}{\\code}, + \l {07-0-qdoc-commands-quoting.html#codeline}{\\codeline}, + \l {07-0-qdoc-commands-quoting.html#dots}{\\dots}, + \l {12-0-qdoc-commands-miscellaneous.html#else}{\\else}, + \l {12-0-qdoc-commands-miscellaneous.html#endif}{\\endif}, + \l {12-0-qdoc-commands-miscellaneous.html#expire}{\\expire}, + \l {11-qdoc-commands-documentcontents.html#footnote}{\\footnote}, + \l {12-0-qdoc-commands-miscellaneous.html#generatelist}{\\generatelist}, + \l {10-qdoc-commands-container.html#header}{\\header}, + \l {04-qdoc-commands-textformatting.html#i}{\\i}, + \l {12-0-qdoc-commands-miscellaneous.html#if}{\\if}, + \l {09-qdoc-commands-graphic.html#image}{\\image}, + \l {12-0-qdoc-commands-miscellaneous.html#include}{\\include}, + \l {09-qdoc-commands-graphic.html#inlineimage}{\\inlineimage}, + \l {08-qdoc-commands-linking.html#keyword}{\\keyword}, + \l {08-qdoc-commands-linking.html#l}{\\l}, + \l {11-qdoc-commands-documentcontents.html#legalese}{\\legalese}, + \l {10-qdoc-commands-container.html#list}{\\list}, + \l {12-0-qdoc-commands-miscellaneous.html#meta}{\\meta}, + \l {06-qdoc-commands-verbatimcode.html#newcode}{\\newcode}, + \l {10-qdoc-commands-container.html#o}{\\o}, + \l {06-qdoc-commands-verbatimcode.html#oldcode}{\\oldcode}, + \l {12-0-qdoc-commands-miscellaneous.html#omit}{\\omit}, + \l {05-qdoc-commands-documentstructuring.html#part}{\\part}, + \l {07-0-qdoc-commands-quoting.html#printline}{\\printline}, + \l {07-0-qdoc-commands-quoting.html#printto}{\\printto}, + \l {07-0-qdoc-commands-quoting.html#printuntil}{\\printuntil}, + \l {11-qdoc-commands-documentcontents.html#quotation}{\\quotation}, + \l {07-0-qdoc-commands-quoting.html#quotefile}{\\quotefile}, + \l {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile}, + \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\raw}, + \l {10-qdoc-commands-container.html#row}{\\row}, + \l {08-qdoc-commands-linking.html#sa}{\\sa}, + \l {05-qdoc-commands-documentstructuring.html#sectionOne}{\\section1}, + \l {05-qdoc-commands-documentstructuring.html#sectionTwo}{\\section2}, + \l {05-qdoc-commands-documentstructuring.html#sectionThree}{\\section3}, + \l {05-qdoc-commands-documentstructuring.html#sectionFour}{\\section4}, + \l {07-0-qdoc-commands-quoting.html#skipline}{\\skipline}, + \l {07-0-qdoc-commands-quoting.html#skipto}{\\skipto}, + \l {07-0-qdoc-commands-quoting.html#skipuntil}{\\skipuntil}, + \l {07-0-qdoc-commands-quoting.html#snippet}{\\snippet}, + \l {04-qdoc-commands-textformatting.html#sub}{\\sub}, + \l {04-qdoc-commands-textformatting.html#sup}{\\sup}, + \l {10-qdoc-commands-container.html#table}{\\table}, + \l {11-qdoc-commands-documentcontents.html#tableofcontents} + {\\tableofcontents}, + \l {08-qdoc-commands-linking.html#target}{\\target}, + \l {04-qdoc-commands-textformatting.html#tt}{\\tt}, + \l {04-qdoc-commands-textformatting.html#underline}{\\underline}, + \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\unicode}, + \l {11-qdoc-commands-documentcontents.html#warning}{\\warning} + + \section1 Categories + \list + \o \l {Text Formatting Commands} + \o \l {Document Structuring Commands} + \o \l {Verbatim Code Commands} + \o \l {Quoting External Code Commands} + \o \l {Linking Commands} + \o \l {Graphic Commands} + \o \l {Container Commands} + \o \l {Document Contents Commands} + \o \l {Miscellaneous Commands} + \endlist + +*/ + +/*! + \page 04-qdoc-commands-textformatting.html + \contentspage QDoc Manual - Table of Contents + \previouspage Markup Commands + \nextpage Document Structuring Commands + + \title Text Formatting Commands + + The text formatting commands indicate how the regular text in the + documentation is rendered. + + \section1 Alphabetical List + + \l {04-qdoc-commands-textformatting.html#backslash}{\\\\}, + \l {04-qdoc-commands-textformatting.html#a}{\\a}, + \l {04-qdoc-commands-textformatting.html#bold}{\\bold}, + \l {04-qdoc-commands-textformatting.html#c}{\\c}, + \l {04-qdoc-commands-textformatting.html#i}{\\i}, + \l {04-qdoc-commands-textformatting.html#sub}{\\sub}, + \l {04-qdoc-commands-textformatting.html#sup}{\\sup}, + \l {04-qdoc-commands-textformatting.html#tt}{\\tt}, + \l {04-qdoc-commands-textformatting.html#underline}{\\underline} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + + \o \bold \\\\ \target backslash + \o \bold {The \\\\ command expands to a single backslash.} + + QDoc commands always start with a backslash alone. To + display an actual backslash in the text you need to type + two of the kind. If you want to display two backslashes, + you need to type four, and so forth. For example: + + \code + / *! + The \\\\ command is useful if you want a + backslash to appear verbatim, for example, + writing C:\\windows\\home\\. + * / + \endcode + + will be rendered as + + \quotation + The \\\\ command is useful if you want a + backslash to appear verbatim, for example, + writing C:\\windows\\home\\. + \endquotation + + However, if you want your text to appear in a typewriter + font as well, you can use the \l {c}{\\c} command instead, + which accepts and renders the backslash as any other + character. For example: + + \code + / *! + The \\c command is useful if you want a + backslash to appear verbatim, and the word + that contains it written in a typewriter font, + like this: \c {C:\windows\home\}. + * / + \endcode + + will be rendered as + + \quotation + The \\c command is useful if you want a + backslash to appear verbatim, and the word + that contains it written in a typewriter font, + like this: \c {C:\windows\home\}. + \endquotation + + \row + \o \bold \\a \target a + \o \bold {The \\a command indicates that the next word + is a parameter when documenting functions.} + + Warnings are emitted when function parameters are + undocumented or misspelled, so whenever you write + documentation for functions you should make sure you + mention all the parameters and precede each of these by the + \\a command. The parameter is then rendered in italic. For + example: + + \code + / *! + Constructs a line edit containing the text + \a contents. + + The \a parent parameter is sent to the + QWidget constructor. + * / + + QLineEdit::QLineEdit(const QString &contents, QWidget *parent) + :QWidget(parent) + { + ... + } + + \endcode + + will be rendered as + + \quotation + \bold {QLineEdit::QLineEdit ( const QString & + contents, QWidget *parent )} + + Constructs a line edit containing the text \a contents. + + The \a parent parameter is sent to the QWidget + constructor. + + \endquotation + + The \\a command follows the same conventions as the \l + {i}{\\i} command for \l {argument}{punctuation, parentheses + and use of braces} for the argument. However, a parameter + is always a single word, so braces are rarely + necessary. And for the same reason, parentheses seldom + occur. + + \row + \o \bold \\c \target c + \o \bold {The \\c command can be used to render variables, + user-defined classes and C++ keywords like \c int, + \c for, etc.} + + The command renders its argument using a typewriter font. For + example: + + \code + / *! + The \c AnalogClock class provides a clock widget with hour + and minute hands that is automatically updated every + few seconds. + * / + \endcode + + will be rendered as + + \quotation + The \c AnalogClock class provides a clock widget with hour + and minute hands that is automatically updated every + few seconds. + \endquotation + + The \\c command follows the same conventions as the \l + {i}{\\i} command for \l {argument}{punctuation, parentheses + and use of braces} for the argument. + + The \\c command accepts the special character \c \ within + its argument, i.e. it renders it as a normal character. So + if you want to use nested commands, you must use the \l + {tt}{teletype (\\tt)} command instead. + + See also \l {tt}{\\tt} and \l {code}{\\code}. + + \row + \o \bold \\tt \target tt + \o \bold {The \\tt command can be used to render variables, + user-defined classes and C++ keywords like \c int, \c + for, etc.} + + The \\tt command behaves just like the \l {c}{\\c} command, + except that \\tt parses QDoc commands (like \l {i}{\\i}, \l + {bold}{\\bold} and \l {underline}{\\underline}) contained + within its argument. + + The command renders its argument using a monospace + font. For example: + + \code + / *! + After \c setupUi() populates the main container with + child widgets it scans the main container's list of + slots for names with the form + \tt{on_\i{objectName}_\i{signalName}().} + * / + \endcode + + will be rendered as + + \quotation + After \c setupUi() populates the main container with + child widgets it scans the main container's list of + slots for names with the form + \tt{on_\i{objectName}_\i{signalName}().} + \endquotation + + The \\tt command follows the same conventions as the \l + {i}{\\i} command for \l {argument}{punctuation, parentheses + and use of braces} for the argument. + + See also \l {c}{\\c}. + + \row + \o \bold \\bold \target bold + \o \bold {The \\bold command renders its argument using + a bold font.} + + For example: + + \code + / *! + This is regular text; \bold {this text is + rendered using the \\bold command}. + * / + \endcode + + will be rendered as + + \quotation + This is regular text; \bold {this text is rendered using + the \\bold command}. + \endquotation + + The command follows the same conventions as the \l {i}{\\i} + command for \l {argument}{punctuation, parentheses and use + of braces} for the argument. + + \row + \o \bold \\i \target i + \o \bold {The \\i command renders its argument in italic.} + + \warning This is preliminary functionality. For + more information, see the \l + {26-qdoc-commands-compatibility.html#i-versus-e}{compatibility} + section. + + \target argument + Normally, a command argument ends at the next whitespace [1], + but braces can be used to group words [2]. For example: + + \code + / *! + Here, we render \i {a few words} in italic. + * / + \endcode + + will be rendered as + + \quotation + Here, we render \i {a few words} in italic. + \endquotation + + If you want to use other QDoc commands within an argument + that contains spaces, you always need to enclose the + argument with braces. But QDoc is smart enough to count + parentheses [3], so you don't need braces in cases like this: + + \code + / *! + An argument can sometimes contain whitespaces, + for example: \i QPushButton(tr("A Brand New Button")) + * / + \endcode + + will be rendered as + + \quotation + An argument can sometimes contain whitespaces, + for example: \i QPushButton(tr("A Brand New Button")) + \endquotation + + Finally, trailing punctuation is not included in an + argument [4], nor is 's [5] + + \raw HTML + <table align="center" cellpadding="2" + cellspacing="1" border="0"> + <tr valign="top" bgcolor="#a2c511"> + <th></th> + <th>QDoc Syntax</th> + <th>Generated Documentation</th> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td>1</td> + <td>A variation of a command button is a \i menu + button.</td> + <td>A variation of a command button is a <i>menu</i> + button.</td> + </tr> + + <tr valign="top" bgcolor="#c0c0c0"> + <td>2</td> + <td>The QPushButton widget provides a + \i {command button}.</td> + <td>The QPushButton widget provides a + <i>command button</i>.</td> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td>3</td> + <td>Another class of buttons are option buttons + \i (see QRadioButton).</td> + <td>Another class of buttons are option buttons + <i> (see QRadioButton)</i>.</td> + </tr> + + <tr valign="top" bgcolor="#c0c0c0"> + <td>4</td> + <td>A push button emits the signal \i clicked().</td> + <td>A push button emits the signal <i>clicked</i>().</td> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td>5</td> + <td>The \i QPushButton's checked property is + false by default.</td> + <td>The <i>QPushButton</i>'s checked property is + false by default.</td> + </tr> + + </table> + \endraw + + \row + \o \bold \\sub \target sub + \o \bold {The \\sub command renders its argument lower + than the baseline of the regular text, using a smaller font.} + + For example: + + \code + / *! + Definition (Range): Consider the sequence + {x\sub n}\sub {n > 1} . The set + + {x\sub 2, x\sub 3, x\sub 4, ...} = {x\sub n ; n = 2, 3, 4, ...} + + is called the range of the sequence. + * / + \endcode + + will be rendered as + + \quotation + Definition (Range): Consider the sequence + {x\sub n}\sub {n > 1} . The set + + {x\sub 2, x\sub 3, x\sub 4, ...} = {x\sub n ; n = 2, 3, 4, ...} + + is called the range of the sequence. + \endquotation + + The \\sub command follows the same conventions as the \l + {i}{\\i} command for \l {argument}{punctuation, parentheses + and use of braces} for the argument. + + \row + \o \bold \\sup \target sup + \o \bold {The \\sup command renders its argument higher than + the baseline of the regular text, using a smaller font.} + + For example: + + \code + / *! + The series + + 1 + a + a\sup 2 + a\sup 3 + a\sup 4 + ... + + is called the \i {geometric series}. + * / + \endcode + + will be rendered as + + \quotation + The series + + 1 + a + a\sup 2 + a\sup 3 + a\sup 4 + ... + + is called the \i {geometric series}. + \endquotation + + The \\sup command follows the same conventions as the \l + {i}{\\i} command for \l {argument}{punctuation, parentheses + and use of braces} for the argument. + + \row + \o \bold \\underline \target underline + \o \bold {The \\underline command renders its argument underlined.} + + For example: + + \code + / *! + The \underline {F}ile menu gives the users the possibility + to open, and edit, an existing file, save a new or modified + file, and exit the application. + * / + \endcode + + will be rendered as + + \quotation + The \underline {F}ile menu gives the users the possibility + to open, and edit, an existing file, save a new or modified + file, and exit the application. + \endquotation + + The \\underline command follows the same conventions as the + \l {i}{\\i} command for \l {argument}{punctuation, + parentheses and use of braces} for the argument. \endtable +*/ + +/*! + \page 05-qdoc-commands-documentstructuring.html + \previouspage Text Formatting Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Verbatim Code Commands + + \title Document Structuring Commands + + The document structuring commands divide the documentation into + sections. In total, there are six levels of sections in QDoc: \c + \part, \c \chapter, \c \section1, \c \section2, \c \section3 and + \c \section4. \c \section1 to \c \section4 correspond to the + traditional section, subsection, subsubsection and + subsubsubsection. + + \section1 Alphabetical List + + \l {05-qdoc-commands-documentstructuring.html#chapter}{\\chapter}, + \l {05-qdoc-commands-documentstructuring.html#part}{\\part}, + \l {05-qdoc-commands-documentstructuring.html#sectionOne}{\\section1}, + \l {05-qdoc-commands-documentstructuring.html#sectionTwo}{\\section2}, + \l {05-qdoc-commands-documentstructuring.html#sectionThree}{\\section3}, + \l {05-qdoc-commands-documentstructuring.html#sectionFour}{\\section4} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\part \target part + \o \bold {The \\part command is intended for use in + larger documents, and divides the document into parts.} + + In general a document structuring command considers + everything that follows it until the first line break as + its argument. The argument is rendered as the unit's + title. If the title needs to be spanned over several lines, + make sure that each line (except the last one) is ended + with a backslash. + + In total, there are six levels of sections in QDoc: \c + \part, \c \chapter, \c \section1, \c \section2, \c + \section3 and \c \section4. \c \section1 to \c \section4 + correspond to the traditional section, subsection, + subsubsection and subsubsubsection. + + There is a strict ordering of the section units: + + \code + part + | + chapter + | + section1 + | + section2 + | + section3 + | + section4 + \endcode + + For example, a \c section1 unit can only appear as the top + level section or inside a \c chapter unit. Skipping a + section unit, for example from \c part to \c section1, is + not allowed. + + You can \i begin with either of the three: \c part, \c + chapter or \c section1. For example: + + + \code + / *! + \part Basic Qt + + This is the first part. + + + \chapter Getting Started + + This is the first part's first chapter. + + + \section1 Hello Qt + + This is the first chapter's first section. + + + \section1 Making Connections + + This is the first chapter's second section. + + + \section1 Using the Reference Documentation + + This is the first chapter's third section. + + + \chapter Creating Dialogs + + This is the first part's second chapter. + + + \section1 Subclassing QDialog + + This is the second chapter's first section. + + ... + + + \part Intermediate Qt + + This is the second part. + + + \chapter Layout Management + + This is the second part's first chapter. + + + \section1 Basic Layouts + + This is the first chapter's first section. + + ... + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <a name="Basic Qt"> + <h1>Basic Qt</h1> + </a> + <p>This is the first part.</p> + + <a name="Getting started"> + <h2>Getting Started</h2> + </a> + This is the first part's first chapter.</p> + + <a name="Hello Qt"> + <h3>Hello Qt</h3> + </a> + <p>This is the first chapter's first section.</p> + + <a name="Making Connections"> + <h3>Making Connections</h3> + </a> + <p>This is the first chapter's second section.</p> + + <a name="Using the Reference Documentation"> + <h3>Using the Reference Documentation</h3> + </a> + <p>This is the first chapter's third section.</p> + + <a name="Creating Dialogs"> + <h2>Creating Dialogs</h2> + </a> + <p>This is the first part's second chapter.</p> + + <a name="Subclassing QDialog"> + <h3>Subclassing QDialog</h3> + </a> + <p>This is the second chapter's first section.</p> + + ... + + <a name="Intermediate Qt"> + <h1>Intermediate Qt</h1> + </a> + <p>This is the second part.</p> + + <a name="Layout Management"> + <h2>Layout Management</h2> + </a> + <p>This is the second part's first chapter.</p> + + <a name="Basic Layouts"> + <h3>Basic Layouts</h3> + </a> + <p>This is the first chapter's first section.</p> + + ... + + \endraw + \endquotation + + Each section level is a logical unit within the + document. Its title will appear on the table of contents + generated by the \l + {11-qdoc-commands-documentcontents.html#tableofcontents} + {\\tableofcontents} command. For example: + + \code + / *! + Contents: + + \tableofcontents + + ... + * / + \endcode + + will expand to + + \quotation + \raw HTML + <p>Contents:</p> + + <ul> + <li><a href="#Basic Qt">Basic Qt</a></li> + <ul> + <li><a href="#Getting Started">Getting Started</a></li> + <ul> + <li><a href="#Hello Qt">Hello Qt</a></li> + <li><a href="#Making Connections"> + Making Connections</a></li> + <li><a href="#Using the Reference Documentation"> + Using the Reference Documentation</a></li> + </ul> + <li><a href="#Creating Dialogs">Creating Dialogs</a></li> + <ul> + <li><a href="#Subclassing QDialog"> + Subclassing QDialog</a></li> + </ul> + </ul> + <li><a href="#Intermediate Qt">Intermediate Qt</a></li> + <ul> + <li><a href="#Layout Management"> + Layout Management</a></li> + <ul> + <li><a href="#Basic Layouts">Basic Layouts</a></li> + </ul> + </ul> + </ul> + + ... + \endraw + \endquotation + + \row + \o \bold \\chapter \target chapter + \o \bold {The \\chapter command is intended for use in + larger documents, and divides the document into chapters.} + + See \l{part}{\\part} for an explanation of the various + section units, command argument and rendering. + + \row + \o \bold \\section1 \target sectionOne + \o \bold {The \\section1 command starts a new section.} + + See \l{part}{\\part} for an explanation of the various + section units, command argument and rendering. + \row + \o \bold \\section2 \target sectionTwo + \o \bold {The \\section2 command starts a new section.} + + See \l{part}{\\part} for an explanation of the various + section units, command argument and rendering. + + \row + \o \bold \\section3 \target sectionThree + \o \bold {The \\section3 command starts a new section.} + + See \l{part}{\\part} for an explanation of the various + section units, command argument and rendering. + + \row + \o \bold \\section4 \target sectionFour + \o \bold {The \\section4 command starts a new section.} + + See \l{part}{\\part} for an explanation of the various + section units, command argument and rendering. + + \endtable +*/ + +/*! + \page 06-qdoc-commands-verbatimcode.html + \previouspage Document Structuring Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Quoting External Code Commands + + \title Verbatim Code Commands + + The following commands are used to render verbatim code within the + documentation. The code is rendered on a new line, using a + typewriter font and the standard indentation. + + \bold{Note:} Although all of these commands can be used to present + C++ code, the \l{07-0-qdoc-commands-quoting.html#snippet}{\\snippet} + and \l{07-0-qdoc-commands-quoting.html#codeline}{\\codeline} commands + should be used in preference to + the others when presenting valid code. This allows auxilliary tools + for Qt language bindings to substitute the relevant code snippets in + place of the C++ ones. + + \section1 Alphabetical List + + \l {06-qdoc-commands-verbatimcode.html#badcode}{\\badcode}, + \l {06-qdoc-commands-verbatimcode.html#code}{\\code}, + \l {06-qdoc-commands-verbatimcode.html#newcode}{\\newcode}, + \l {06-qdoc-commands-verbatimcode.html#oldcode}{\\oldcode} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\code \target code + \o \bold {The \\code command and the corresponding + \\endcode command delimit a piece of verbatim code.} + + Whereas the \l {c}{\\c} command can be used for short code + fragments within a sentence, the \\code command is for + longer code snippets and renders the code verbatim in a + separate paragraph using a typewriter font and the standard + indentation. + + When processing any of the \\code, \l {badcode}{\\badcode}, + \l {newcode}{\\newcode} and \l {oldcode}{\\oldcode} + commands, QDoc basically removes all indentation that is + common for the verbatim code blocks within a \c{/}\c{*!} ... + \c{*}\c{/} comment before it adds the standard + indentation. For that reason the recommended style is to + use 8 spaces for the verbatim code contained within these + commands (note that this doesn't apply to externally + quoted code using the \l {quotefromfile}{\\quotefromfile} + or \l {quotefile}{\\quotefile} command). + + For example: + + \code + / *! + \code + #include <QApplication> + #include <QPushButton> + + int main(int argc, char *argv[]) + { + ... + } + \ endcode + * / + \endcode + + will be rendered as + + \code + #include <QApplication> + #include <QPushButton> + + int main(int argc, char *argv[]) + { + ... + } + \endcode + + Other QDoc commands are disabled within + \\code... \\endcode, and the special character '\\' is + accepted and rendered like the rest of the code. + + You need to type the code manually between the \\code and + \\endcode commands. If you want to include code snippets + from a particular file, use the \l + {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile} + command instead. + + See also \l {c}{\\c}, \l + {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile}, + \l {badcode}{\\badcode}, \l {newcode}{\\newcode} and \l + {oldcode}{\\oldcode}. + + \row + \o \bold \\badcode \target badcode + \o \bold {The \\badcode command and the corresponding + \\endcode command delimit a piece of code that doesn't + compile or is wrong for some other reason.} + + The \\badcode command is similar the \l {code}{\\code} + command, but renders the code using a grey font instead of + black (the default). + + Like the \l {code}{\\code} command, it renders its code on + a new line in the documentation using a typewriter font and + the standard indentation. For example: + + \code + / *! + The statement below is rendered using the + regular \\code command: + + \code + statusbar()->message(tr("Host %1 found").arg(hostName)); + \ endcode + + While the following statement is rendered using + the \\badcode command: + + \badcode + statusbar()->message(tr("Host" + hostName + " found")); + \ endcode + * / + \endcode + + will be rendered as + + \quotation + The statement below is rendered using the + regular \\code command: + + \code + statusbar()->message(tr("Host %1 found").arg(hostName)); + \endcode + + While the following statement is rendered using + the \\badcode command: + + \badcode + statusbar()->message(tr("Host" + hostName + " found")); + \endcode + \endquotation + + Other QDoc commands are disabled within + \\badcode... \\endcode, and the special character '\\' is + accepted and rendered like the rest of the code. + + See also \l {code}{\\code}, \l {newcode}{\\newcode} and \l + {oldcode}{\\oldcode}. + + \row + \o \bold \\newcode \target newcode + \o \bold {The \\newcode command, and the associated \\oldcode + and \\endcode commands, indicate how to port a piece of + code to a new version of an API.} + + The \\newcode command, and its companion the \\oldcode + command, is a convenience combination of the \l + {code}{\\code} and \l {badcode}{\\badcode} commands: The + combination provides a text relating the two code snippets + to each other. The command requires a preceding \\oldcode + statement. + + Like the \l {code}{\\code} and \l {badcode}{\\badcode} + commands, the \\newcode command renders its code on a new + line in the documentation using a typewriter font and the + standard indentation. For example: + + \code + / *! + \oldcode + if (printer->setup(parent)) + ... + \newcode + QPrintDialog dialog(printer, parent); + if (dialog.exec()) + ... + \ endcode + * / + \endcode + + is rendered like this: + + \quotation + \oldcode + if (printer->setup(parent)) + ... + \newcode + QPrintDialog dialog(printer, parent); + if (dialog.exec()) + ... + \endcode + \endquotation + + Other QDoc commands are disabled within + \\oldcode ... \\endcode, and the '\\' character doesn't need + to be escaped. + + \row + \o \bold \\oldcode \target oldcode + \o \bold {The \\oldcode command requires a corresponding + \\newcode statement; otherwise QDoc fails to parse the command + and emits a warning.} + + See also \l {newcode}{\\newcode} and \l {badcode}{\\badcode}. + \endtable +*/ + +/*! + \page 07-0-qdoc-commands-quoting.html + \previouspage Verbatim Code Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Linking Commands + + \title Quoting External Code Commands + + The following commands enable quoting from files in the + documentation: You can make QDoc include the complete contents of + a file, or you can quote specific parts of the file and skip + others. The typical use of the latter is to quote a file chunk by + chunk. + + \bold{Note:} Although all of these commands can be used to present + C++ code, the \l{#snippet}{\\snippet} and \l{#codeline}{\\codeline} + commands should be used in preference to + the others when presenting valid code. This allows auxilliary tools + for Qt language bindings to substitute the relevant code snippets in + place of the C++ ones. + + \section1 Alphabetical List + + \l {07-0-qdoc-commands-quoting.html#codeline}{\\codeline}, + \l {07-0-qdoc-commands-quoting.html#dots}{\\dots}, + \l {07-0-qdoc-commands-quoting.html#printline}{\\printline}, + \l {07-0-qdoc-commands-quoting.html#printto}{\\printto}, + \l {07-0-qdoc-commands-quoting.html#printuntil}{\\printuntil}, + \l {07-0-qdoc-commands-quoting.html#quotefile}{\\quotefile}, + \l {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile}, + \l {07-0-qdoc-commands-quoting.html#skipline}{\\skipline}, + \l {07-0-qdoc-commands-quoting.html#skipto}{\\skipto}, + \l {07-0-qdoc-commands-quoting.html#skipuntil}{\\skipuntil}, + \l {07-0-qdoc-commands-quoting.html#snippet}{\\snippet} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\quotefile \target quotefile + \o \bold {The \\quotefile command expands to the complete + contents of the file given as argument.} + + The command considers the rest of the line as part of its + argument, make sure to follow the file name with a line + break. + + The file's contents is rendered in a separate paragraph, + using a typewriter font and the standard indentation. The + code is shown verbatim. + + For example: + + \code + / *! + This is a simple "Hello world" example: + + \quotefile examples/main.cpp + + It contains only the bare minimum you need + to get a Qt application up and running. + * / + \endcode + + will be rendered as + + \quotation + This is a simple "Hello world" example: + + \quotefile examples/main.cpp + + It contains only the bare minimum you need to get a Qt + application up and running. + \endquotation + + \warning If you use the \l {QDoc + Compatibility}{compat.qdocconf} file this command is called + \\include. + + See also \l {quotefromfile}{\\quotefromfile} and \l + {code}{\\code}. + + \row + \o \bold \\quotefromfile \target quotefromfile + \o \bold {The \\quotefromfile command opens the file + given as argument for quoting.} + + The command considers the rest of the line as part of its + argument, make sure to follow the file name with a line + break. + + The command is intended for use when quoting parts from + file with the walkthrough commands: \l + {printline}{\\printline}, \l {printto}{\\printto}, \l + {printuntil}{\\printuntil}, \l {skipline}{\\skipline}, \l + {skipto}{\\skipto}, \l {skipuntil}{\\skipuntil}. This + enables you to quote specific portions of a file. For + example: + + \code + / *! + The whole application is contained within + the \c main() function: + + \quotefromfile examples/main.cpp + + \skipto main + \printuntil app(argc, argv) + + First we create a QApplication object using + the \c argc and \c argv parameters. + + \skipto QPushButton + \printuntil resize + + Then we create a QPushButton, and give it a reasonable + size using the QWidget::resize() function. + + ... + * / + \endcode + + will be rendered as + + \quotation + The whole application is contained within + the \c main() function: + + \quotefromfile examples/main.cpp + + \skipto main + \printuntil app(argc, argv) + + First we create a QApplication object using the \c argc + and \c argv parameters. + + \skipto QPushButton + \printuntil resize + + Then we create a QPushButton, and give it a reasonable + size using the QWidget::resize() function. + + ... + \endquotation + + (\l {Example File}{The complete example file...}) + + QDoc remembers which file it's quoting, and the current + position within that file (see \l {file}{\\printline} for + more information). There is no need to "close" the file. + + Earlier we called this command \\quotefile. For more + information, see the \l + {26-qdoc-commands-compatibility.html#quotefromfile-versus-quotefile} + {compatibility} section. + + See also \l {quotefile}{\\quotefile}, \l {code}{\\code} and + \l {dots}{\\dots}. + + \row + \o \bold \\printline \target printline + \o \bold {The \\printline command expands to the line + from the current position to the next non-blank line of + the current souce file.} + + To ensure that the documentation always is synchronized + with the source file, a substring of the line must be + specified as an argument to the command. Note that the + command considers the rest of the line as part of its + argument, make sure to follow the substring with a line + break. + + The line from the source file is rendered as a separate + paragraph, using a typewriter font and the standard + indentation. The code is shown verbatim. + + For example: + + \code + / *! + There has to be exactly one QApplication object + in every GUI application that uses Qt. + + \quotefromfile examples/main.cpp + + \printline QApplication + + This line includes the QApplication class + definition. QApplication manages various + application-wide resources, such as the + default font and cursor. + + \printline QPushButton + + This line includes the QPushButton class + definition. The QPushButton widget provides a command + button. + + \printline main + + The main function... + * / + \endcode + + will be rendered as + + \quotation + There has to be exactly one QApplication object + in every GUI application that uses Qt. + + \quotefromfile examples/main.cpp + + \printline QApplication + + This line includes the QApplication class + definition. QApplication manages various + application-wide resources, such as the + default font and cursor. + + \printline QPushButton + + This line includes the QPushButton class + definition. The QPushButton widget provides a command + button. + + \printline main + + The main function... + \endquotation + + (\l {Example File}{The complete example file...}) + + \target file + + QDoc reads the file sequentially. To move the current + position forward you can use either of the \l + {skipline}{\\skip...} commands. To move the current + position backward, you can use the \l + {quotefromfile}{\\quotefromfile} command again. + + \target substring + + If the substring argument is surrounded by slashes it is + interpreted as a \l {regular expression}. + + For example: + + \code + / *! + \quotefromfile widgets/scribble/mainwindow.cpp + + \skipto closeEvent + \printuntil /^\}/ + + Close events are sent to widgets that the users want to + close, usually by clicking \c File|Exit or by clicking + the \c X title bar button. By reimplementing the event + handler, we can intercept attempts to close the + application. + * / + \endcode + + will be rendered as + + \quotation + \quotefromfile widgets/scribble/mainwindow.cpp + + \skipto closeEvent + \printuntil /^\}/ + + Close events are sent to widgets that the users want to + close, usually by clicking \c File|Exit or by clicking + the \c X title bar button. By reimplementing the event + handler, we can intercept attempts to close the + application. + \endquotation + + (\l {widgets/scribble}{The complete example file...}) + + The regular expression \c /^\}/ makes QDoc print until the + first '}' character occurring at the beginning of the line + without indentation. /.../ encloses the regular expression, + and '^' means the beginning of the line. The '}' character + must be escaped since it is a special character in regular + expressions. + + QDoc will emit a warning if the specified substring or + regular expression cannot be located, i.e. if the source + code has changed. + + See also \l {printto}{\\printto} and \l + {printuntil}{\\printuntil}. + + \row + \o \bold \\printto \target printto + \o \bold {The \\printto command expands to all the lines + from the current position up to and \i excluding the + next line containing a given substring.} + + The command considers the rest of the line as part of its + argument, make sure to follow the substring with a line + break. The command also follows the same conventions for \l + {file}{positioning} and \l {substring}{argument} as the \l + {printline}{\\printline} command. + + The lines from the source file are rendered in a separate + paragraph, using a typewriter font and the standard + indentation. The code is shown verbatim. + + For example: + + \code + / *! + The whole application is contained within the + \c main() function: + + \quotefromfile examples/main.cpp + \printto hello + + First we create a QApplication object using the \c argc and + \c argv parameters... + * / + \endcode + + will be rendered as + + \quotation + The whole application is contained within the + \c main() function: + + \quotefromfile examples/main.cpp + \skipto main + \printto hello + + First we create a QApplication object using the \c argc + and \c argv parameters... + \endquotation + + (\l {Example File}{The complete example file...}) + + See also \l {printline}{\\printline} and \l + {printuntil}{\\printuntil}. + + \row + \o \bold \\printuntil \target printuntil + \o \bold {The \\printuntil command expands to all the lines + from the current position up to and \i including the next line + containing a given substring.} + + The command considers the rest of the line as part of its + argument, make sure to follow the substring with a line + break. The command also follows the same conventions for \l + {file}{positioning} and \l {substring}{argument} as the \l + {printline}{\\printline} command. + + The lines from the source file are rendered in a separate + paragraph, using a typewriter font and the standard + indentation. The code is shown verbatim. + + For example: + + \code + / *! + The whole application is contained within the + \c main() function: + + \quotefromfile examples/main.cpp + \skipto main + \printuntil hello + + First we create a QApplication object using the + \c argc and \c argv parameters, then we create + a QPushButton. + * / + \endcode + + will be rendered as + + \quotation + The whole application is contained within the + \c main() function: + + \quotefromfile examples/main.cpp + \skipto main + \printuntil hello + + First we create a \l + {http://qt.nokia.com/doc/4.0/qapplication}{QApplication} + object using the \c argc and \c argv parameters, then we + create a \l + {http://qt.nokia.com/doc/4.0/qpushbutton}{QPushButton}. + \endquotation + + (\l {Example File}{The complete example file...}) + + See also \l {printline}{\\printline} and \l + {printto}{\\printto}. + + \row + \o \bold \\skipline \target skipline + \o \bold {The \\skipline command ignores the next non-blank + line in the current source file.} + + Doc reads the file sequentially, and the \\skipline command + is used to move the current position (omitting a line of + the source file). See the remark about \l {file}{file + positioning} above. + + The command considers the rest of the line as part of its + argument, make sure to follow the substring with a line + break. The command also follows the same conventions for \l + {substring}{argument} as the \l {printline}{\\printline} + command, and it is used in conjunction with the \l + {quotefromfile}{\\quotefromfile} command. For example: + + \code + / *! + QPushButton is a GUI push button that the user + can press and release. + + \quotefromfile examples/main.cpp + \skipline QApplication + \printline QPushButton + + This line includes the QPushButton class + definition. For each class that is part of the + public Qt API, there exists a header file of + the same name that contains its definition. + * / + \endcode + + will be rendered as + + \quotation + \l + QPushButton is a GUI push button that the user + can press and release. + + \quotefromfile examples/main.cpp + \skipline QApplication + \printline QPushButton + + This line includes the QPushButton class + definition. For each class that is part of the public + Qt API, there exists a header file of the same name + that contains its definition. + \endquotation + + (\l {Example File}{The complete example file...}) + + See also \l {skipto}{\\skipto}, \l + {skipuntil}{\\skipuntil} and \l {dots}{\\dots}. + + \row + \o \bold \\skipto \target skipto + \o \bold {The \\skipto command ignores all the lines from the + current position up to and \i excluding the next line + containing a given substring.} + + QDoc reads the file sequentially, and the \\skipto command + is used to move the current position (omitting one or + several lines of the source file). See the remark about \l + {file}{file positioning} above. + + The command considers the rest of the line as part of its + argument, make sure to follow the substring with a line + break. + + The command also follows the same conventions for \l + {substring}{argument} as the \l {printline}{\\printline} + command, and it is used in conjunction with the \l + {quotefromfile}{\\quotefromfile} command. For example: + + \code + / *! + The whole application is contained within + the \c main() function: + + \quotefromfile examples/main.cpp + \skipto main + \printuntil } + + First we create a QApplication object. There + has to be exactly one such object in + every GUI application that uses Qt. Then + we create a QPushButton, resize it to a reasonable + size... + * / + \endcode + + will be rendered as + + \quotation + The whole application is contained within + the \c main() function: + + \quotefromfile examples/main.cpp + \skipto main + \printuntil } + + First we create a QApplication object. There has to be + exactly one such object in every GUI application that + uses Qt. Then we create a QPushButton, resize it to a + reasonable size ... + \endquotation + + (\l {Example File}{The complete example file...}) + + See also \l {skipline}{\\skipline}, \l + {skipuntil}{\\skipuntil} and \l {dots}{\\dots}. + + \row + \o \bold \\skipuntil \target skipuntil + \o \bold {The \\skipuntil command ignores all the lines from + the current position up to and \i including the next line + containing a given substring.} + + QDoc reads the file sequentially, and the \\skipuntil + command is used to move the current position (omitting one + or several lines of the source file). See the remark about + \l {file}{file positioning} above. + + The command considers the rest of the line as part of its + argument, make sure to follow the substring with a line + break. + + The command also follows the same conventions for \l + {substring}{argument} as the \l {printline}{\\printline} + command, and it is used in conjunction with the \l + {quotefromfile}{\\quotefromfile} command. For example: + + \code + / *! + The first thing we did in the \c main() function + was to create a QApplication object \c app. + + \quotefromfile examples/main.cpp + \skipuntil show + \dots + \printuntil } + + In the end we must remember to make \c main() pass the + control to Qt. QCoreApplication::exec() will return when + the application exits... + * / + \endcode + + will be rendered as + + \quotation + The first thing we did in the \c main() function was to + create a QApplication object \c app. + + \quotefromfile examples/main.cpp + \skipuntil show + \dots + \printuntil } + + In the end we must remember to make \c main() pass the + control to Qt. QCoreApplication::exec() + will return when the application exits... + \endquotation + + (\l {Example File}{The complete example file...}) + + See also \l {skipline}{\\skipline}, \l {skipto}{\\skipto} + and \l {dots}{\\dots}. + + \row + \o \bold \\dots \target dots + \o \bold {The \\dots command indicates that parts of the + source file have been omitted when quoting a file.} + + The command is used in conjunction with the \l + {quotefromfile}{\\quotefromfile} command, and should be + stated on its own line. The dots are rendered on a new + line, using a typewriter font. For example: + + \code + / *! + \quotefromfile examples/main.cpp + \skipto main + \printuntil { + \dots + \skipuntil exec + \printline } + * / + \endcode + + will be rendered as + + \quotefromfile examples/main.cpp + \skipto main + \printuntil { + \dots + \skipuntil exec + \printline } + + (\l {Example File}{The complete example file...}) + + The default indentation is 4 spaces, but this can be + adjusted using the command's optional argument. For + example: + + \code + / *! + \dots 0 + \dots + \dots 8 + \dots 12 + \dots 16 + * / + \endcode + + will be rendered as + + \dots 0 + \dots + \dots 8 + \dots 12 + \dots 16 + + See also \l {skipline}{\\skipline}, \l + {skipto}{\\skipto} and \l {skipuntil}{\\skipuntil}. + + \row + \o \bold \\snippet \target snippet + \o \bold {The \\snippet command causes a code snippet to be included + verbatim as preformatted text, which may be syntax highlighted.} + + Each code snippet are referenced by the file that holds it and by + a unique identifier for that file. Snippet files are typically + stored in a \c{snippets} directory inside the documentation + directory (e.g., \c{$QTDIR/doc/src/snippets}). + + For example, the following documentation references a snippet in + a file residing in a subdirectory of the documentation directory: + + \code + \snippet snippets/textdocument-resources/main.cpp Adding a resource + \endcode + + The text following the file name is the unique identifier for the + snippet. This is used to delimit the quoted code in the relevant + snippet file as shown in the following example that corresponds to + the above \c{\\snippet} command: + + \dots + \code + QImage image(64, 64, QImage::Format_RGB32); + image.fill(qRgb(255, 160, 128)); + + //! [Adding a resource] + document->addResource(QTextDocument::ImageResource, + QUrl("mydata://image.png"), QVariant(image)); + //! [Adding a resource] + \endcode + \dots + \row + \o \bold \\codeline \target codeline + \o \bold{The \\codeline command inserts a blank line of preformatted + text. It is used to insert gaps between snippets without closing + the current preformatted text area and opening a new one.} + \endtable +*/ + +/*! + \page 07-1-example.html + \previouspage Quoting External Code Commands + \contentspage QDoc Manual - Table of Contents + + \title Example File + + \quotefile examples/main.cpp +*/ + +/*! + \page 08-qdoc-commands-linking.html + \previouspage Quoting External Code Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Graphic Commands + + \title Linking Commands + + The linking commands make it possible to create hyperlinks to + classes, functions, header files and examples. They also make it + possible to link to targets within a document, as well as to other + documents and URLs. + + \section1 Alphabetical List + + \l {08-qdoc-commands-linking.html#keyword}{\\keyword}, + \l {08-qdoc-commands-linking.html#l}{\\l}, + \l {08-qdoc-commands-linking.html#sa}{\\sa}, + \l {08-qdoc-commands-linking.html#target}{\\target} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\l \target l + \o \bold {The \\l command is used to create hyperlinks. } + + The command's general syntax is + + \code + \l {link target}{link text} + \endcode + + For example: + + \code + / *! + Read the \l {http://qt.nokia.com/doc/4.0/} + {Qt's Reference Documentation} carefully. + * / + \endcode + + will be rendered as + + \quotation + Read the \l {http://qt.nokia.com/doc/4.0/} + {Qt's Reference Documentation} carefully. + \endquotation + + If the link target is equivalent to the link text, the + second argument can be omitted. + + For example, if you have documentation like: + + \code + / *! + \target assertions + + Assertions make some statement about the text at the + point where they occur in the regexp but they do not + match any characters. + + ... + + Regexps are built up from expressions, quantifiers, and + \l {assertions}{assertions}. + * / + \endcode + + you can rewrite it as + + \code + / *! + \target assertions + + Assertions make some statement about the text at the + point where they occur in the regexp but they do not + match any characters. + + ... + + Regexps are built up from expressions, quantifiers, and + \l assertions. + * / + \endcode + + For the one-parameter version the braces can often + be omitted. See the \l {i}{\\i} command for the \l + {argument}{argument conventions}. + + The \\l command supports several kinds of links: + + \list + \o \c {\l QWidget} - a defined \l {class}{\\class} + \o \c {\l QWidget::sizeHint()} - a defined member + function (\l {fn}{\\fn}) + \o \c {\l <QtGlobal>} - a defined \l {headerfile}{\\headerfile} + \o \c {\l widgets/wiggly} - a defined + \l {example-command}{\\example} + \o \c {\l {QWidget Class Reference}} - a defined \l {title}{\\title} + \o \c {\l {Introduction}}- a defined \l{part}{\\part}, + \l{chapter}{\\chapter} or \l {sectionOne}{\\section...} + \o \c {\l fontmatching} - a defined \l {target}{\\target} + \o \c {\l {Shared Classes}} - a defined \l {keyword}{\\keyword} + \o \c {\l network.html} - a defined \l {page}{\\page} + \o \c {\l http://www.trolltech.com/} - a URL + \endlist + + QDoc also tries to make a link out of any words that don't + resemble any normal English words, for example Qt class + names or functions, like QWidget or QWidget::sizeHint(). In + these cases, the \\l command can actually be omitted, but + by using the command, you ensure that QDoc will emit a + warning if it cannot find the link target. In addition, if + you only want the function name to appear in the link, you + can use the following syntax: + + \list + \o \c {\l {QWidget::}{sizeHint()}} + \endlist + + See also \l {sa}{\\sa}, \l {target}{\\target} and \l + {keyword}{\\keyword}. + + \row + \o \bold \\sa \target sa + \o \bold {The \\sa command defines a list of links that will + be rendered in a separate "See also" section at the bottom + of the documentation.} + + The command takes a comma-separated list of links as its + argument. If the line ends with a comma, you can continue + on a second line. The general syntax is: + + \code + \sa {the first link}, {the second link}, + {the third link}, ... + \endcode + + QDoc will automatically try to generate "See also" links + interconnecting a property's various functions. For + example, an setVisible() function will automatically get a + link to visible() and vice versa. + + In general, QDoc will generate "See also" links that + interconnect the functions that access the same + property. It recognizes four different syntax versions: + + \list + \o \c property() + \o \c setProperty() + \o \c isProperty() + \o \c hasProperty() + \endlist + + The \\sa command supports the same kind + of links as the \l {l}{\\l} command. For example: + + \code + / *! + Appends the actions \a actions to this widget's + list of actions. + + \sa removeAction(), QMenu, addAction() + * / + void QWidget::addActions(QList<QAction *> actions) + { + ... + } + \endcode + + will be rendered as + + \quotation + \bold {void QWidget::addActions ( QList<QAction*> + \i actions )} + + Appends the actions \i actions to this widget's + list of actions. + + See also \l {QWidget::removeAction()}{removeAction()}, + \l QMenu, and \l {QWidget::addAction()}{addAction()}. + \endquotation + + See also \l {l}{\\l}, \l {target}{\\target} and \l + {keyword}{\\keyword}. + + \row + \o \bold \\target \target target + \o \bold {The \\target command defines an explicit point in the + documentation that you can later link to using the \l {l}{\\l} + and \l {sa}{\\sa} commands.} + + The command considers the rest of the line as part of its + argument, make sure to follow the target name with a line + break. + + For example: + + \code + / *! + \target capturing parentheses + \section1 Capturing Text + + Parentheses allow us to group elements together so that + we can quantify and capture them. + + ... + * / + \endcode + + can be referenced with + + \list + \o \c {\l {capturing parentheses}} + (from elsewhere in the same comment) + \o \c {\l qregexp.html#capturing-parentheses} + (from anywhere else) + \endlist + + within a documentation unit, and with + + \list + \o \c {\l http://www.trolltech.com/4.0/doc/html/qregexp.html#capturing-parentheses} + \endlist + + on a more global scale. + + If the target name does't contain any spaces, the brackets can + be omitted as well. + + See also \l {l}{\\l}, \l {sa}{\\sa} and \l + {keyword}{\\keyword}. + + \row + \o \bold \\keyword \target keyword + \o \bold {The \\keyword command defines an explicit point in the + documentation that you can later link to using the \l {l}{\\l} + and \l {sa}{\\sa} commands.} + + Keywords must be unique within the entire set of + documentation processed in on QDoc run. The command + considers the rest of the line as part of its argument, + make sure to follow the keyword with a line break. + + The \\keyword command is similar to \l {target}{\\target}, + but stronger. A keyword can be referenced from anywhere + using a simple syntax. For example: + + \code + / *! + \class QRegExp + \reentrant + \brief The QRegExp class provides pattern + matching using regular expressions. + \ingroup tools + \ingroup misc + \ingroup shared + \mainclass + + \keyword regular expression + + Regular expressions, or "regexps", provide a way to + find patterns within text. + + ... + * / + \endcode + + can be referenced like this + + \code + / *! + When a string is surrounded by slashes, it's + interpreted as a \l regular expression. + * / + \endcode + + which will be rendered as + + \quotation + When a string is surrounded by slashes, it's + interpreted as a \l {regular expression}. + \endquotation + + If the keyword does't contain any spaces, the brackets can + be omitted as well. + + See also \l {l}{\\l}, \l {sa}{\\sa} and \l + {target}{\\target}. + \endtable +*/ + +/*! + \page 09-qdoc-commands-graphic.html + \previouspage Linking Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Container Commands + + \title Graphic Commands + + The graphic commands makes it possible to include images in the + documentation. The images can be rendered as separate paragraphs, + or within running text. + + \section1 Alphabetical List + + \l {09-qdoc-commands-graphic.html#caption}{\\caption}, + \l {09-qdoc-commands-graphic.html#image}{\\image}, + \l {09-qdoc-commands-graphic.html#inlineimage}{\\inlineimage} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\image \target image + \o \bold {The \\image command expands to the image specified by its + argument, and renders it centered as a separate paragraph.} + + The \\image command replaces the old \\img command. For more + information, see the \l + {26-qdoc-commands-compatibility.html#image-versus-img} + {compatibility} section. + + The command takes two arguments. The first is the name of + the image file. The second argument is optional and is a + simple description of the image equivalent to the HTML + alt="" in an image tag. The description is used for + tooltips, and when a browser doesn't support images like + the Lynx text browser. + + The command considers the rest of the line after the file + name its second argument, make sure that you follow the + filename or description with a line break. Braces are only + necessary if the description spans several lines. + + For example: + + \code + / *! + Qt by Trolltech is a C++ toolkit for cross-platform GUI + application development. + + \image happyguy.jpg "Happy guy" + + Qt provides single-source portability across Microsoft + Windows, Mac OS X, Linux, and all major commercial Unix + variants. It is also available for embedded devices. + * / + \endcode + + will be rendered as + + \quotation + Qt by Trolltech is a C++ toolkit for cross-platform GUI + application development. + + \image happyguy.jpg image "Happy guy" + + Qt provides single-source portability across Microsoft + Windows, Mac OS X, Linux, and all major commercial Unix + variants. It is also available for embedded devices. + \endquotation + + See also \l {inlineimage}{\\inlineimage} and \l + {caption}{\\caption}. + + \row + \o \bold \\inlineimage \target inlineimage + \o \bold {The \\inlineimage command expands to the image + specified by its argument; the image is rendered inline + with the rest of the text.} + + The command takes two arguments. The first is the name of + the image file. The second argument is optional and is a + simple description of the image equivalent to the HTML + alt="" in an image tag. The description is used for + tooltips, and when a browser doesn't support images like + the Lynx text browser. + + The most common use of the \\inlineimage command is in + lists and tables. For example: + + \code + / *! + \list 1 + \o \inlineimage happy.gif Oh so happy! + \o \inlineimage happy.gif Oh so happy! + \o \inlineimage happy.gif Oh so happy! + \endlist + * / + \endcode + + will be rendered as + + \list 1 + \o \inlineimage happy.gif Oh so happy! + \o \inlineimage happy.gif Oh so happy! + \o \inlineimage happy.gif Oh so happy! + \endlist + + And + + \code + / *! + \table + \header + \o Trolltech + \o Trolltech + \row + \o \inlineimage happy.gif Oh so happy! + \o \inlineimage happy.gif Oh so happy! + \row + \o \inlineimage happy.gif Oh so happy! + \o \inlineimage happy.gif Oh so happy! + \endtable + * / + \endcode + + will be rendered as + + \raw HTML + <table align="center" cellpadding="2" + cellspacing="1" border="0"> + <tr valign="top" bgcolor="#a2c511"> + <th>Trolltech</th> + <th>Trolltech</th> + </tr> + + <tr valign="top" bgcolor="#f0f0f0"> + <td><img src="images/happy.gif" alt="Oh so happy!" /> + </td> + <td><img src="images/happy.gif" alt="Oh so happy!" /> + </td> + </tr> + + <tr valign="top" bgcolor="#f0f0f0"> + <td><img src="images/happy.gif" alt="Oh so happy!"/> + </td> + <td><img src="images/happy.gif" alt="Oh so happy!" /> + </td> + </tr> + + </table> + \endraw + + The command can also be used to insert an image + inline with the regular text. For example: + + \code + / *! + \inlineimage training.jpg Training by Trolltech + The Qt Programming course is offered as a + five day Open Enrollment Course. The classes + are open to the public.While the course is open + to anyone who wants to learn, attendees should + have significant experience in C++ development + to derive maximum benefit from the course. + * / + \endcode + + will be rendered as + + \quotation + \inlineimage training.jpg Training by Trolltech + The Qt Programming course is offered as a + five day Open Enrollment Course. The classes + are open to the public.While the course is open + to anyone who wants to learn, attendees should + have significant experience in C++ development + to derive maximum benefit from the course. + \endquotation + + See also \l {image}{\\image} and \l {caption}{\\caption}. + + \row + \o \bold \\caption \target caption + \o \bold {The \\caption command provides a caption for an image.} + + The command follows the same conventions for parentheses and use + of braces for its \l argument as the \l {i}{\\i} command. + + \warning This is preliminary functionality. The + command is not fully implemented. + + See also \l {image}{\\image} and \l + {inlineimage}{\\inlineimage} + + \endtable +*/ + +/*! + \page 10-qdoc-commands-container.html + \previouspage Graphic Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Document Contents Commands + + \title Container Commands + + The container commands create tables and lists with associated + items and contents. A list is rendered left aligned as a separate + paragraph. A table is rendered centered as a separate paragraph, + and its width depends on its content. + + \section1 Alphabetical List + + \l {10-qdoc-commands-container.html#header}{\\header}, + \l {10-qdoc-commands-container.html#list}{\\list}, + \l {10-qdoc-commands-container.html#o}{\\o}, + \l {10-qdoc-commands-container.html#omitvalue}{\\omitvalue}, + \l {10-qdoc-commands-container.html#row}{\\row}, + \l {10-qdoc-commands-container.html#table}{\\table}, + \l {10-qdoc-commands-container.html#value}{\\value} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\table \target table + \o \bold {The \\table command and the corresponding \\endtable + command delimit the contents of a table.} + + The command accepts a single argument specifying the + table's width in percentage: + + \code + / *! + \table 100 % + + ... + + \endtable + * / + \endcode + + The code above ensures that the table will fill all + available space. If the table's width is smaller than 100 %, + the table will be centered in the generated documentation. + + A table can contain headers, rows and columns. A row starts + with a \l {row}{\\row} command and consists of cells, which + starts with a \l {o}{\\o} command. There is also a \l + {header}{\\header} command which is a special kind of row + with a special formatting. For example: + + \code + / *! + \table + \header + \o Qt Core Feature + \o Brief Description + \row + \o \l {Signal and Slots} + \o Signals and slots are used for communication + between objects. + \row + \o \l {Layout Management} + \o The Qt layout system provides a simple + and powerful way of specifying the layout + of child widgets. + \row + \o \l {Drag and Drop} + \o Drag and drop provides a simple visual + mechanism which users can use to transfer + information between and within applications. + \endtable + * / + \endcode + + will be rendered as + + \raw HTML + <table align="center" cellpadding="2" + cellspacing="1" border="0"> + <tr valign="top" bgcolor="#a2c511"> + <th>Qt Core Feature</th> + <th>Brief Description</th> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href="http://qt.nokia.com/doc/4.0/signalsandslots.html"> + Signals and Slots</a> + </td> + <td>Signals and slots are used for communication + between objects.</td> + </tr> + + <tr valign="top" bgcolor="#c0c0c0"> + <td> + <a href=http://qt.nokia.com/doc/4.0/layout.html"> + Layout Management</a></td> + <td>The Qt layout system provides a simple + and powerful way of specifying the layout + of child widgets.</td> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href=http://qt.nokia.com/doc/4.0/dnd.html"> + Drag and Drop</a></td> + <td>Drag and drop provides a simple visual + mechanism which users can use to transfer + information between and within applications.</td> + </tr> + + </table> + \endraw + + You can also make cells span several rows and columns. For + example: + + \code + / *! + \table + \header + \o {3,1} This header cell spans three columns + but only one row. + \row + \o {2, 1} This table cell spans two columns + but only one row + \o {1, 2} This table cell spans only one column, + but two rows. + \row + \o A regular table cell + \o A regular table cell + \endtable + * / + \endcode + + will be rendered as + + \raw HTML + <table align="center" cellpadding="2" cellspacing="1" + border="0"> + + <tr valign="top" bgcolor="#a2c511"> + <th colspan="3" rowspan=" 1"> + This header cell spans three columns but only one row + </th> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td colspan="2" rowspan=" 1"> + This table cell spans two columns but only one row + </td> + <td rowspan=" 2"> + This table cell spans only one column, but two rows. + </td> + </tr> + + <tr valign="top" bgcolor="#c0c0c0"> + <td>A regular table cell</td> + <td>A regular table cell</td> + </tr> + + </table> + \endraw + + See also \l {header}{\\header}, \l {row}{\\row} and \l {o}{\\o}. + + \row + \o \bold \\header \target header + \o \bold {The \\header command indicates that the following + table cells are the current table's column headers.} + + The command can only be used within the \l{table} + {\\table...\\endtable} commands. A header can contain + several cells. A cell is created with the \l {o}{\\o} + command. + + A header cell's text is centered within the table cell and + rendered using a bold font. For example: + + \code + / *! + \table + \header + \o Qt Core Feature + \o Brief Description + \row + \o \l {Signal and Slots} + \o Signals and slots are used for communication + between objects. + \endtable + * / + \endcode + + will be rendered as + + \raw HTML + <table align="center" cellpadding="2" + cellspacing="1" border="0"> + <tr valign="top" bgcolor="#a2c511"> + <th>Qt Core Feature</th> + <th>Brief Description</th> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href="http://qt.nokia.com/doc/4.0/signalsandslots.html"> + Signals and Slots</a> + </td> + <td>Signals and slots are used for communication + between objects.</td> + </tr> + </table> + \endraw + + See also \l {table}{\\table}, \l {row}{\\row} and \l {o}{\\o}. + + \row + \o \bold \\row \target row + \o \bold {The \\row command indicates that the following table + cells belong to the same row in the current table.} + + The command can only be used within the \l{table} + {\\table...\\endtable} commands. A row can contain + several cells. A cell is created with the \l {o}{\\o} + command. + + The background cell color of each row alternate between two + shades of grey, making it easier to distinguish the rows + from each other. The cells' contents is left aligned. + + For example: + + \code + / *! + \table + \header + \o Qt Core Feature + \o Brief Description + \row + \o \l {Signal and Slots} + \o Signals and slots are used for communication + between objects. + \row + \o \l {Layout Management} + \o The Qt layout system provides a simple + and powerful way of specifying the layout + of child widgets. + \row + \o \l {Drag and Drop} + \o Drag and drop provides a simple visual + mechanism which users can use to transfer + information between and within applications. + \endtable + * / + \endcode + + will be rendered as + + \raw HTML + <table align="center" cellpadding="2" + cellspacing="1" border="0"> + <tr valign="top" bgcolor="#a2c511"> + <th>Qt Core Feature</th> + <th>Brief Description</th> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href="http://qt.nokia.com/doc/4.0/signalsandslots.html"> + Signals and Slots</a> + </td> + <td>Signals and slots are used for communication + between objects.</td> + </tr> + + <tr valign="top" bgcolor="#c0c0c0"> + <td> + <a href=http://qt.nokia.com/doc/4.0/layout.html"> + Layout Management</a></td> + <td>The Qt layout system provides a simple + and powerful way of specifying the layout + of child widgets.</td> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href=http://qt.nokia.com/doc/4.0/dnd.html"> + Drag and Drop</a></td> + <td>Drag and drop provides a simple visual + mechanism which users can use to transfer + information between and within applications.</td> + </tr> + + </table> + \endraw + + See also \l {table}{\\table}, \l {header}{\\header} and \l + {o}{\\o}. + + \row + \o \bold \\value \target value + \o \bold {The \\value command starts the documentation of a C++ enum + item}. + + The command's first argument is the enum item. Then follows + its associated description. The description argument ends + at the next blank line or \\value. The arguments are + rendered within a table. + + The documentation will be located in the associated class, + header file or namespace documentation. See the \l + {enum}{\\enum} documentation for an example. + + See also \l {enum}{\\enum} and \l {omitvalue}{\\omitvalue}. + + \row + \o \bold \\omitvalue \target omitvalue + \o \bold {The \\omitvalue command excludes a C++ enum item + from the documentation}. + + The command's only argument is the name of the enum item + that will be omitted. See the \l {enum}{\\enum} + documentation for an example. + + See also \l {enum}{\\enum} and \l {value}{\\value}. + + \row + \o \bold \\list \target list + \o \bold {The \\list command and the corresponding \\endlist + command delimit a list of items.} + + You need to create each list item explicitly using the \l + {o}{\\o} command. A list can contain one or more items; it + can also be nested. For example: + + \code + / *! + \list + \o Qt Reference Documentation: Getting Started + \list + \o How to Learn Qt + \o Installation + \list + \o Qt/X11 + \o Qt/Windows + \o Qt/Mac + \o Qt/Embedded + \endlist + \o Tutorial and Examples + \endlist + \endlist + * / + \endcode + + will be rendered as + + \list + \o Qt Reference Documentation: Getting Started + \list + \o How to Learn Qt + \o Installation + \list + \o Qt/X11 + \o Qt/Windows + \o Qt/Mac + \o Qt/Embedded + \endlist + \o Tutorial and Examples + \endlist + \endlist + + The \\list command takes an optional argument providing + alternative appearances for the list items. For example: + + \code + / *! + \list + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + \endlist + * / + \endcode + + will render the list items with bullets (the default): + + \list + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + \endlist + + If you provide 'A' as an argument to the \\list command, + the bullets are replaced with characters following in + alphabetical order: + + \list A + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + \endlist + + If you replace 'A' with '1', the list items are rendered + with numbers following in ascending order: + + \list 1 + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + + \endlist + + If you provide 'i' as the argument, the default bullets are + replaced with roman numerals: + + \list i + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + \endlist + + Or finally, you can make the list items appear with roman + numbers following in ascending order if you provide 'I' as + the optional argument: + + \list I + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + \endlist + + You can also make the listing start at any character or + number by simply provide the number or character you want + to start at. For example: + + \code + / *! + \list G + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + \endlist + * / + \endcode + + will be rendered as + + \list G + \o How to Learn Qt + \o Installation + \o Tutorial and Examples + \endlist + + See also \l {o}{\\o}. + + \row + \o \bold \\o \target o + \o \bold {The \\o command announce a table or list item.} + + Earlier we used the \l {i}{\\i} command for this purpose. For more + information see the \l + {26-qdoc-commands-compatibility.html#o-versus-i}{compatibility} + section. + + The command can only be used within the \l{table} + {\\table...\\endtable} or \l{list}{\\list... \\endlist} + commands. + + It considers everything until the next occurrence + of the \\o command, or the currently applicable \l + {table}{\\endtable} or \l {list}{\\endlist} command, as its + argument. For examples, see \l {table}{\\table} and \l + {list}{\\list}. + + If the command is used within a table, you can in addition + specify how many rows or columns the item should span. For + example: + + \code + / *! + \table + \header + \o {3,1} This header cell spans three columns + but only one row. + \row + \o {2, 1} This table item spans two columns + but only one row + \o {1, 2} This table item spans only one column, + but two rows. + \row + \o A regular table item + \o A regular table item + \endtable + * / + \endcode + + will be rendered as + + \raw HTML + <table align="center" cellpadding="2" cellspacing="1" + border="0"> + + <tr valign="top" bgcolor="#a2c511"> + <th colspan="3" rowspan=" 1"> + This header cell spans three columns but only one row + </th> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td colspan="2" rowspan=" 1"> + This table item spans two columns but only one row + </td> + <td rowspan=" 2"> + This table item spans only one column, but two rows. + </td> + </tr> + + <tr valign="top" bgcolor="#c0c0c0"> + <td>A regular table item</td> + <td>A regular table item</td> + </tr> + + </table> + \endraw + + If not specified, the item will span one column and one row. + + See also \l {table}{\\table}, \l {header}{\\header}, + \l {list}{\\list} and \l {o}{\\o}. + \endtable +*/ + +/*! + \page 11-qdoc-commands-documentcontents.html + \previouspage Container Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Miscellaneous Commands + + \title Document Contents Commands + + The document contents commands identify parts of the documentation, + i.e. parts with a special rendering, conceptual meaning or + function. + + \section1 Alphabetical List + + \l {11-qdoc-commands-documentcontents.html#abstract}{\\abstract}, + \l {11-qdoc-commands-documentcontents.html#brief}{\\brief}, + \l {11-qdoc-commands-documentcontents.html#footnote}{\\footnote}, + \l {11-qdoc-commands-documentcontents.html#legalese}{\\legalese}, + \l {11-qdoc-commands-documentcontents.html#tableofcontents} + {\\tableofcontents}, + \l {11-qdoc-commands-documentcontents.html#quotation}{\\quotation}, + \l {11-qdoc-commands-documentcontents.html#warning}{\\warning} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\abstract \target abstract + \o \bold {The \\abstract command and the corresponding \\endabstract + command delimit a document's abstract section.} + + The abstract section is rendered as an indented italicized + paragraph. + + \warning This is preliminary funcionality. The + command is not fully implemented. Currently, the abstract + section is rendered as a regular HTML paragraph. For + example: + + \code + / *! + \abstract + Qt by Trolltech is a C++ toolkit for cross-platform + GUI application development. Qt provides + single-source portability across Microsoft Windows, + Mac OS X, Linux, and all major commercial Unix + variants. It is also available for embedded + devices. + \endabstract + * / + \endcode + + will be rendered as + + \abstract + Qt by Trolltech is a C++ toolkit for cross-platform GUI + application development. Qt provides single-source + portability across Microsoft Windows, Mac OS X, Linux, + and all major commercial Unix variants. It is also + available for embedded devices. + \endabstract + + \row + \o \bold \\quotation \target quotation + \o \bold { The \\quotation command and the corresponding + \\endquotation command delimit a quotation remark.} + + This command replaces the old \\quote command. For more + information see the \l + {26-qdoc-commands-compatibility.html#quotation-versus-quote} + {compatibility} section. + + The remark is rendered as a separate centered + paragraph. For example: + + \code + / *! + While the prospect of a significantly broader market is + good news for Firstlogic, the notion also posed some + challenges. Dave Dobson, director of technology for the La + Crosse, Wisconsin-based company, said: + + + \quotation + As our solutions were being adopted into new + environments, we saw an escalating need for easier + integration with a wider range of enterprise + applications. + \endquotation + * / + \endcode + + will be rendered as + + While the prospect of a significantly broader market is + good news for Firstlogic, the notion also posed some + challenges. Dave Dobson, director of technology for the La + Crosse, Wisconsin-based company, said: + + \quotation + As our solutions were being adopted into new + environments, we saw an escalating need for easier + integration with a wider range of enterprise + applications. + \endquotation + + \row + \o \bold \\footnote \target footnote + \o \bold {The \\footnote command and the corresponding + \\endfootnote command delimit a footnote.} + + The footnote follows the standard conventions, rendered at the + bottom of the page. + + \warning This is preliminary funcionality. The + command is not fully implemented. + + For example: + + \code + / *! + In Qt 4 we have tried to simplify the constructors of + QObject/QWidget subclasses. This makes subclassing + easier, at the same time as it helps make the Qt + library more efficient. + + \footnote + Constructors no longer take a "const char *name" + parameter. If you want to specify a name for a QObject, + you must call QObject::setObjectName() after + construction. The object name is now a QString. + \endfootnote + + QWidget's WFlags data type has been split in two: + Qt::WindowFlags specifies low-level window flags (the + type of window and the frame style), whereas + Qt::WidgetAttribute specifies various higher-level + attributes about the widget (e.g., + WA_StaticContents). + * / + \endcode + + will be rendered as + + \quotation + In Qt 4 we have tried to simplify the constructors of + QObject/QWidget subclasses. This makes subclassing + easier, at the same time as it helps make the Qt + library more efficient. + + \footnote + Constructors no longer take a "const char *name" + parameter. If you want to specify a name for a QObject, + you must call QObject::setObjectName() after + construction. The object name is now a QString. + \endfootnote + + QWidget's WFlags data type has been split in two: + Qt::WindowFlags specifies low-level window flags (the + type of window and the frame style), whereas + Qt::WidgetAttribute specifies various higher-level + attributes about the widget (e.g., + WA_StaticContents). + \endquotation + + \row + \o \bold \\tableofcontents \target tableofcontents + \o \bold {The \\tableofcontents command generates a + table displaying the titles of the current documentation + unit's parts, chapters, sections, etc.} + + The command accepts a single optional argument: + + \code + \tableofcontents sectionN + \endcode + + where \c sectionN is the deepest section to include (by + default all sections are included). + + For example, it the documentation unit's structure looks + something like this: + + \quotation + \raw HTML + <a name="Basic Qt"> + <h1>Basic Qt</h1> + </a> + <p>This is the first part.</p> + + <a name="Getting started"> + <h2>Getting Started</h2> + </a> + This is the first part's first chapter.</p> + + <a name="Hello Qt"> + <h3>Hello Qt</h3> + </a> + <p>This is the first chapter's first section.</p> + + <a name="Making Connections"> + <h3>Making Connections</h3> + </a> + <p>This is the first chapter's second section.</p> + + <a name="Using the Reference Documentation"> + <h3>Using the Reference Documentation</h3> + </a> + <p>This is the first chapter's third section.</p> + + <a name="Creating Dialogs"> + <h2>Creating Dialogs</h2> + </a> + <p>This is the first part's second chapter.</p> + + <a name="Subclassing QDialog"> + <h3>Subclassing QDialog</h3> + </a> + <p>This is the second chapter's first section.</p> + + ... + + <a name="Intermediate Qt"> + <h1>Intermediate Qt</h1> + </a> + <p>This is the second part.</p> + + <a name="Layout Management"> + <h2>Layout Management</h2> + </a> + <p>This is the second part's first chapter.</p> + + <a name="Basic Layouts"> + <h3>Basic Layouts</h3> + </a> + <p>This is the first chapter's first section.</p> + + ... + + \endraw + \endquotation + + Then + + \code + / *! + Contents: + + \tableofcontents + + ... + * / + \endcode + + will expand to + + \quotation + \raw HTML + <p>Contents:</p> + + <ul> + <li><a href="#Basic Qt">Basic Qt</a></li> + <ul> + <li><a href="#Getting Started">Getting Started</a></li> + <ul> + <li><a href="#Hello Qt">Hello Qt</a></li> + <li><a href="#Making Connections"> + Making Connections</a></li> + <li><a href="#Using the Reference Documentation"> + Using the Reference Documentation</a></li> + </ul> + <li><a href="#Creating Dialogs">Creating Dialogs</a></li> + <ul> + <li><a href="#Subclassing QDialog"> + Subclassing QDialog</a></li> + </ul> + </ul> + <li><a href="#Intermediate Qt">Intermediate Qt</a></li> + <ul> + <li><a href="#Layout Management">Layout Management</a></li> + <ul> + <li><a href="#Basic Layouts">Basic Layouts</a></li> + </ul> + </ul> + </ul> + + ... + \endraw + \endquotation + + Each table entry becomes a link to the corresponding part, + chapter or section. + + \row + \o \bold \\brief \target brief + \o \bold {The \\brief command introduces a one-sentence + description of a class, namespace, header file, property + or variable.} + + The brief text is used to introduce the documentation of + the associated object, and in lists generated using the \l + {generatelist}{\\generatelist} command. + + The \\brief command can be used in two significant + different ways: \l {brief class}{One for classes, + namespaces and header files}, and \l {brief property}{one + for properties and variables}. + + \target brief property + + When the \\brief command is used to describe a property or + a variable, the brief text must only be a sentence fragment + and start with "whether" (for boolean properties and + variables) or "the" (for any other property or variable). + + For example the boolean QWidget::isWindow property: + + \code + / *! + \property QWidget::isActiveWindow + \brief whether this widget's window is the active window + + The active window is the window that contains the widget that + has keyboard focus. + + When popup windows are visible, this property is true + for both the active window \e and for the popup. + + \sa activateWindow(), QApplication::activeWindow() + * / + \endcode + + and the QWidget::geometry property + + \code + / *! + \property QWidget::geometry + \brief the geometry of the widget relative to its parent and + excluding the window frame + + When changing the geometry, the widget, if visible, + receives a move event (moveEvent()) and/or a resize + event (resizeEvent()) immediately. + + ... + + \sa frameGeometry(), rect(), ... + * / + \endcode + + The latter will be rendered as + + \quotation + \raw HTML + <h3>geometry : + <a href="http://qt.nokia.com/doc/4.0/qrect.html">QRect</a> + </h3> + \endraw + + This property holds the geometry of the widget relative + to its parent and excluding the window frame. + + ... + + Access functions: + \list + \o \bold {const QRect & geometry () const} + \o \bold {void setGeometry ( int x, int y, int w, int h )} + \o \bold {void setGeometry ( const QRect & )} + \endlist + + See also \l + {QWidget::frameGeometry()}{frameGeometry()}, \l + {QWidget::rect()}{rect()}, ... + \endquotation + + \target brief class + + When the \\brief command is used to describe a class, the + brief text should be a complete sentence and must start + like this: + + \code + The <classname> class is|provides|contains|specifies... + \endcode + + and likewise when the command is used for namespaces or + header files. + + \warning The brief statement is used as the first + paragraph of the detailed description. Do not repeat the + sentence. + + For example: + + \code + / *! + \class PreviewWindow + \brief The PreviewWindow class is a custom widget + displaying the names of its currently set + window flags in a read-only text editor. + + The PreviewWindow class inherits QWidget. The widget + displays the names of its window flags set with the + setWindowFlags() function. It is also provided with a + QPushButton that closes the window. + + ... + + \sa QWidget + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1>PreviewWindow Class Reference</h1> + \endraw + + The PreviewWindow class is a custom widget displaying + the names of its currently set window flags in a + read-only text editor. \l {preview window}{More...} + + \raw HTML + <h3>Properties</h3> + \endraw + + \list + \o 52 properties inherited from QWidget + \o 1 property inherited from QObject + \endlist + + \raw HTML + <h3>Public Functions</h3> + \endraw + + \list + \o \l {constructor}{PreviewWindow}(QWidget *parent = 0) + \o void \l {function}{setWindowFlags}(Qt::WindowFlags flags) + \endlist + + \list + \o 183 public functions inherited from QWidget + \o 28 public functions inherited from QObject + \endlist + + \raw HTML + <h3>Public Slots</h3> + \endraw + + \list + \o 17 public slots inherited from QWidget + \o 1 public slot inherited from QObject + \endlist + + \raw HTML + <h3>Additional Inherited Members</h3> + \endraw + + \list + \o 1 signal inherited from QWidget + \o 1 signal inherited from QObject + \o 4 static public members inherited from QWidget + \o 4 static public members inherited from QObject + \o 39 protected functions inherited from QWidget + \o 7 protected functions inherited from QObject + \endlist + + \target preview window + + \raw HTML + <hr /> + <h2>Detailed Description</h2> + \endraw + The PreviewWindow class is a custom widget displaying + the names of its currently set window flags in a + read-only text editor. + + The PreviewWindow class inherits QWidget. The widget + displays the names of its window flags set with the \l + {function}{setWindowFlags()} function. It is also + provided with a QPushButton that closes the window. + + ... + + See also QWidget. + + \raw HTML + <hr /> + <h2>Member Function Documentation</h2> + \endraw + + \target constructor + \raw HTML + <h3>PreviewWindow(QWidget *parent = 0)</h3> + \endraw + + Constructs a preview window widget with \i parent. + + \target function + \raw HTML + <h3>setWindowFlags(Qt::WindowFlags flags)</h3> + \endraw + + Sets the widgets flags using the + QWidget::setWindowFlags() function. + + Then runs through the available window flags, + creating a text that contains the names of the flags + that matches the flags parameter, displaying + the text in the widgets text editor. + \endquotation + + Using \\brief with a namespace can for example look like this: + + \code + / *! + \namespace Qt + + \brief The Qt namespace contains miscellaneous identifiers + used throughout the Qt library. + * / + \endcode + + and finally using \\brief with a header file can look + something like this: + + \code + / *! + \headerfile <QtGlobal> + \title Global Qt Declarations + + \brief The <QtGlobal> header file provides basic + declarations and is included by all other Qt headers. + + \sa <QtAlgorithms> + * / + \endcode + + See also \l{property}{\\property}, \l{class}{\\class}, + \l{namespace}{\\namespace} and \l{headerfile}{\\headerfile}. + + \row + \o \bold \\legalese \target legalese + \o \bold {The \\legalese command, and the corresponding \\endlegalese + command, delimit a licence agreement.} + + If the \\endlegalese command is omitted, QDoc will still + process the \\legalese command but considers the rest of + the documentation page as the license agreement. + + Ideally, the license documentation is located where the + licensed code is used. + + Later the documentation identified by the \\legalese + command can be accumulated into a list using the \l + {generatelist}{\\generatelist} command with the \c legalese + argument. This is useful to generate an overview of all the + licenses associated with the source code. + + For example: + + \code + \ * ! + ... + + On X11, Qt also supports drops via the Motif Drag \& + Drop Protocol. The implementation incorporates some + code that was originally written by Daniel Dardailler, + and adapted for Qt by Matt Koss \<koss@napri.sk\> and + Trolltech. Here is the original copyright notice: + + \legalese + \code + + Copyright 1996 Daniel Dardailler. + + Permission to use, copy, modify, distribute, and sell + this software for any purpose is hereby granted without + fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this + permission notice appear in supporting documentation, + and that the name of Daniel Dardailler not be used in + advertising or publicity pertaining to distribution of + the software without specific, written prior + permission. Daniel Dardailler makes no representations + about the suitability of this software for any + purpose. It is provided "as is" without express or + implied warranty. + + Modifications Copyright 1999 Matt Koss, under the same + license as above. + + \ endcode + \endlegalese + * / + \endcode + + will be rendered as + + \quotation + ... + + On X11, Qt also supports drops via the Motif Drag \& + Drop Protocol. The implementation incorporates some + code that was originally written by Daniel Dardailler, + and adapted for Qt by Matt Koss \<koss@napri.sk\> and + Trolltech. Here is the original copyright notice: + + \legalese + \code + + Copyright 1996 Daniel Dardailler. + + Permission to use, copy, modify, distribute, and sell + this software for any purpose is hereby granted without + fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this + permission notice appear in supporting documentation, + and that the name of Daniel Dardailler not be used in + advertising or publicity pertaining to distribution of + the software without specific, written prior + permission. Daniel Dardailler makes no representations + about the suitability of this software for any + purpose. It is provided "as is" without express or + implied warranty. + + Modifications Copyright 1999 Matt Koss, under the same + license as above. + + \endcode + \endlegalese + \endquotation + + \row + \o \bold \\warning \target warning + \o \bold {The \\warning command renders a "Warning:" prefix to + the command's argument.} + + For example: + + \code + / *! + Qt::HANDLE is a platform-specific handle type + for system objects. This is equivalent to + \c{void *} on Windows and Mac OS X, and to + \c{unsigned long} on X11. + + \warning Using this type is not portable. + * / + \endcode + + will be rendered as + + \quotation + Qt::HANDLE is a platform-specific handle type + for system objects. This is equivalent to + \c{void *} on Windows and Mac OS X, and to + \c{unsigned long} on X11. + + \warning Using this type is not portable. + \endquotation + \endtable +*/ + +/*! + \page 12-0-qdoc-commands-miscellaneous.html + \previouspage Document Contents Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Topical Commands + + \title Miscellaneous Commands + + These commands provide miscellaneous functions + connected to the visual appearance of the documentation, and to the + process of generating the documentation. + + \section1 Alphabetical List + + \l {12-0-qdoc-commands-miscellaneous.html#else}{\\else}, + \l {12-0-qdoc-commands-miscellaneous.html#endif}{\\endif}, + \l {12-0-qdoc-commands-miscellaneous.html#expire}{\\expire}, + \l {12-0-qdoc-commands-miscellaneous.html#generatelist}{\\generatelist}, + \l {12-0-qdoc-commands-miscellaneous.html#if}{\\if}, + \l {12-0-qdoc-commands-miscellaneous.html#include}{\\include}, + \l {12-0-qdoc-commands-miscellaneous.html#meta}{\\meta}, + \l {12-0-qdoc-commands-miscellaneous.html#omit}{\\omit}, + \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\raw}, + \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\unicode} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\expire \target expire + \o \bold {The \\expire command allows you to define an expiration + date for your documentation.} + + When using the \\expire command, QDoc will emit a warning + when the current date is larger than the specified + date. The command accepts one argument; the argument's + format is yyyy-mm-dd. For example: + + \code + / *! + \page porting.html + + \title Porting to Qt 3.x + + \expire 2004-12-31 + + This document describes porting applications from Qt + 2.x to Qt 3.x. + + The Qt 3.x series is not binary compatible with the + 2.x series. + ... + * / + \endcode + + If you run QDoc on 4 July 2005, it will emit the warning + + \quotation + porting.qdoc:6: Documentation expired 185 days ago + \endquotation + + \row + \o \bold \\generatelist \target generatelist + \o \bold {The \\generatelist command expands to a list of + various documentation or links to documentation.} + + For example in the Qt Reference Documentation: + + \code + / *! + \page classes.html + \title All Qt Classes (main index) + + For a shorter list that only includes the most + frequently used classes, see \l{Qt's Main Classes}. For + a list of Qt 3 support classes, see \l{Qt3Support + Classes}. + + \generatelist classes + * / + \endcode + + is used to generate \l {All Qt Classes (main index)}. + + The command accepts the following arguments: + + \target table example + + \list + \o \c annotatedclasses + + The \c annotatedclasses argument provides a table + containing the names of all the classes, and a + description of each class. Each class name is a link to + the class's reference documentation. + + For example: + + \quotation + \raw HTML + <table align="center" cellpadding="2" + cellspacing="1" border="0"> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href="http://qt.nokia.com/doc/4.0/qdial.html"> + QDial</a> + </td> + <td>Rounded range control (like a speedometer + or potentiometer)</td> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href="http://qt.nokia.com/doc/4.0/qdialog.html"> + QDialog</a> + </td> + <td>The base class of dialog windows</td> + </tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td> + <a href="http://qt.nokia.com/doc/4.0/qdir.html"> + QDir</a> + </td> + <td>Access to directory structures and their + contents</td> + </tr> + </table> + \endraw + \endquotation + + A class is identified within the documentation by the + the \l {class}{\\class} command, and the descriptions + are based on the argument of the \l {brief}{\\brief} + commands in the class documentation. + + \target list example + + \o \c classes + + The \c classes argument provides a complete alphabetical + list of the classes. Each class name is a link to the + class's reference documentation. + + For example: + + \quotation + \raw HTML + <p><table width="100%"> + + <tr> + <td align="right"><b>A </b></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractbutton.html">QAbstractButton</a></td> + + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractextensionmanager.html">QAbstractExtensionManager</a></td> + + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractitemmodel.html">QAbstractItemModel</a></td> + </tr> + + <tr> + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstracteventdispatcher.html">QAbstractEventDispatcher</a></td> + + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractformbuilder.html">QAbstractFormBuilder</a></td> + + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractitemview.html">QAbstractItemView</a></td> + </tr> + + <tr> + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractextensionfactory.html">QAbstractExtensionFactory</a></td> + + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractitemdelegate.html">QAbstractItemDelegate</a></td> + + <td align="right"></td> + <td><a href="http://qt.nokia.com/doc/4.0/qabstractlistmodel.html">QAbstractListModel</a></td> + </tr> + </table></p> + \endraw + \endquotation + + A class is identified within the documentation by the + the \l {class}{\\class} command. + + \o \c classesbymodule + + This particular argument requests an additional argument, + i.e. a specification of the module. + + For example: + + \code + / *! + \page qtgui.html + \contentspage Qt Classes by Module + \previouspage QtCore Classes + \nextpage QtNetwork Classes + + \title QtGui Classes + + \keyword QtGui + + \generatelist {classesbymodule QtGui} + * / + \endcode + + Together, these arguments provide a table containing the + classes considered members of the specified module, + accompanied with a brief description. Each class name is + a link to the class's reference documentation. + + The generated table is rendered similarily to the one + generated when using the \l {table example}{\c + annotatedclasses} argument. + + For the basic classes in Qt, a class's module is + determined by its location, i.e. its directory. However, + for extensions, like ActiveQt and Qt Designer, a class + is related to a module with the \l + {inmodule}{\\inmodule} command. + + \o \c classesbyedition + + This particular argument requests an additional argument, + i.e. a specification of the edition. + + For example: + + \code + / *! + \page console-edition-classes.html + \title Qt Console Edition Classes + + \generatelist{classesbyedition Console} + * / + \endcode + + Together, these arguments provide a table containing the + classes considered members of the specified edition, + accompanied with a brief description. Each class name is + a link to the class's reference documentation. + + The edition a given class can be found in is determined by + the module it belongs to. + + \o \c compatclasses + + The \c compatclasses argument provides a complete and + alphabetical list of the support classes. A support + class is identified within the documentation by the \l + {compat}{\\compat} command. Each class name is a link to + the class's reference documentation. The list is + rendered similarily to the list generated by the \l + {list example}{\c classes} argument. + + \warning The \c classesbymodule argument will at some + point replace the this argument. + + \o \c functionindex + + The \c functionindex argument provides a complete + alphabetical list of all the documented member + functions. + + For example: + + \quotation + \raw HTML + <p><center><font size="+1"><b><a href="#a">A</a> <a href="#b">B</a> <a href="#c">C</a> <a href="#d">D</a> <a href="#e">E</a> <a href="#f">F</a> <a href="#g">G</a> <a href="#h">H</a> <a href="#i">I</a> <a href="#j">J</a> <a href="#k">K</a> <a href="#l">L</a> <a href="#m">M</a> <a href="#n">N</a> <a href="#o">O</a> <a href="#p">P</a> <a href="#q">Q</a> <a href="#r">R</a> <a href="#s">S</a> <a href="#t">T</a> <a href="#u">U</a> <a href="#v">V</a> <a href="#w">W</a> <a href="#x">X</a> <a href="#y">Y</a> <a href="#z">Z</a> </b></font></center></p> + + <p>DTDHandler: <a href="http://qt.nokia.com/doc/4.0/qxmlreader.html#DTDHandler">QXmlReader</a></p> + + <p>QAXCLASS: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXCLASS">global</a></p> + + <p>QAXFACTORY_BEGIN: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXFACTORY_BEGIN">global</a></p> + + <p>QAXFACTORY_DEFAULT: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXFACTORY_DEFAULT">global</a></p> + + <p>QAXFACTORY_END: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXFACTORY_END">global</a></p> + + \endraw + + ... + \endquotation + + \o \c legalese + + The \c legalese argument provides a complete list of all + the licenses. The licenses are identified within the + documentation using the \l {legalese}{\\legalese} + command. + + For example: + + \quotation + \raw HTML + <hr /> + <p> + Copyright (c) 1989 The Regents of the + University of California. All rights reserved. + </p> + + <p> + Redistribution and use in source and binary + forms are permitted provided that the above + copyright notice and this paragraph are + duplicated in all such forms and that any + documentation, advertising materials, and other + materials related to such distribution and use + acknowledge that the software was developed by + the University of California, Berkeley... + </p> + + <ul> + <li> + <a href="http://qt.nokia.com/doc/4.0/qdate.html#weekNumber">QDate::weekNumber()</a> + </li> + </ul> + + <hr /> + <p> + Copyright (c) 1991 by AT&T. + </p> + + <p> + Permission to use, copy, modify, and distribute + this software for any purpose without fee is + hereby granted, provided that this entire notice + is included in all copies of any software which + is or includes a copy or modification of this + software and in all copies of the supporting + documentation for such software... + </p> + + <ul> + <li> + <a href="http://qt.nokia.com/doc/4.0/qlocale.html">QLocale</a> + </li> + </ul> + <hr /> + \endraw + ... + \endquotation + + \o \c mainclasses + + The \c mainclasses argument provides a complete + alphabetical list of the main classes. Each class name + is a link to the class's reference documentation. A + class is related to the group of main classes by using + the \l {mainclass}{\\mainclass} command. + + The list is rendered similarily to the list generated by + the \l {list example}{\c classes} argument. + + \o \c overviews + + The \c overviews argument provides a complete + alphabetical overview of the documentation. Each list + entry is a link to the respective documentation page. + + The list includes pages declared using commands like \l + {page}{\\page} and \l {group}{\\group}. The list omits + examples and classes, and only lists the first page of + documentation that contains two or more pages using + commands like \l {nextpage}{\\nextpage}. + + For example: + + \quotation + \raw HTML + <ul> + + <li> + <a href="http://qt.nokia.com/doc/4.0/qtalgorithms.html"> + <QtAlgorithms> - Generic Algorithms + </a> + </li> + + <li> + <a href="http://qt.nokia.com/doc/4.0/qtglobal.html"> + <QtGlobal> - Global Qt Declarations + </a> + </li> + + <li> + <a href="http://qt.nokia.com/doc/4.0/qaxserver-demo-simple.html"> + A standard ActiveX and the "simple" ActiveQt widget + </a> + </li> + + <li> + <a href="http://qt.nokia.com/doc/4.0/aboutqt.html"> + About Qt + </a> + </li> + + <li> + <a href="http://qt.nokia.com/doc/4.0/trolltech.html"> + About Trolltech + </a> + </li> + + <li> + <a href="http://qt.nokia.com/doc/4.0/abstractwidgets.html"> + Abstract Widget Classes + </a> + </li> + + <li> + <a href="http://qt.nokia.com/doc/4.0/accessibility.html"> + Accessibility Classes + </a> + </li> + ... + </ul> + \endraw + \endquotation + + \o \c related + + The \c related argument is used in combination with the + \l {group}{\\group} command to list all the overviews + related to the given group. Each list entry is a link to + the respective documentation page. + + \o \c relatedinline + + The \c related argument is used in combination with the + \l {group}{\\group} command to collect all documentation + related to the given group. The various documentation + snippets are copied directly into the group page. + + \o \c service + + The \c service argument provides a complete alphabetical + list of the services. Each service name is a link to the + service's reference documentation. + + A service is identified within the documentation by the + \l {service}{\\service} command. + + \endlist + + + \row + \o \bold \\if \target if + \o \bold {The \\if command and the corresponding \\endif command + enclose parts of a QDoc comment that only will be included if + the condition specified by the command's argument is true.} + + The command reads the rest of the line and parses it as an + C++ #if statement. For example: + + \code + / *! + \if defined(opensourceedition) + + \bold{Note:} This edition is for the development of + \l{Qt Open Source Edition}{Free and Open Source} + software only; see \l{Qt Commercial Editions}. + + \endif + * / + \endcode + + This QDoc comment will only be rendered if the \c + opensourceedition preprocessor symbol is defined, and + specified in the \l {definesvariable}{defines} variable in + the configuration file to make QDoc process + the code within #ifdef and #endif: + + \code + defines = opensourceedition + \endcode + + You can also define the preprocessor symbol manually on the + command line. For more information see the documentation of + the \l {definesvariable}{defines} variable. + + See also \l{endif}{\\endif}, \l{else}{\\else}, \l + {definesvariable}{defines} and \l falsehoods. + + \row + \o \bold \\endif \target endif + \o \bold {The \\endif command and the corresponding \\if command + enclose parts of a QDoc comment that will be included if + the condition specified by the \l {if}{\\if} command's + argument is true.} + + For more information, see the documentation of the \l + {if}{\\if} command. + + See also \l{if}{\\if}, \l{else}{\\else}, \l + {definesvariable}{defines} and \l falsehoods. + + \row + \o \bold \\else \target else + \o \bold {The \\else command specifies an alternative if the + condition in the \l {if}{\\if} command is false.} + + The \\else command can only be used within \l + {if}{\\if...\\endif} commands, but is useful when there is + only two alternatives. For example: + + \code + / *! + The Qt 3 support library is provided to keep old + source code working. + + In addition to the \c Qt3Support classes, Qt 4 provides + compatibility functions when it's possible for an old + API to cohabit with the new one. + + \if !defined(QT3_SUPPORT) + \if defined(QT3_SUPPORTWARNINGS) + The compiler emits a warning when a + compatibility function is called. (This works + only with GCC 3.2+ and MSVC 7.) + \else + To use the Qt 3 support library, you need to + have the line QT += qt3support in your .pro + file (qmake automatically define the + QT3_SUPPORT symbol, turning on compatibility + function support). + + You can also define the symbol manually (e.g., + if you don't want to link against the \c + Qt3Support library), or you can define \c + QT3_SUPPORT_WARNINGS instead, telling the + compiler to emit a warning when a compatibility + function is called. (This works only with GCC + 3.2+ and MSVC 7.) + \endif + \endif + * / + \endcode + + If the \c QT3_SUPPORT is defined, the comment will be rendered + as + + \quotation + The Qt 3 support library is provided to keep old source + code working. + + In addition to the Qt3Support classes, Qt 4 provides + compatibility functions when it's possible for an old + API to cohabit with the new one. + \endquotation + + If \c QT3_SUPPORT isn't defined but \c QT3_SUPPORT_WARNINGS + is, the comment will be rendered as + + \quotation + The Qt 3 support library is provided to keep old source + code working. + + In addition to the Qt3Support classes, Qt 4 provides + compatibility functions when it's possible for an old + API to cohabit with the new one. + + The compiler emits a warning when a compatibility + function is called. (This works only with GCC 3.2+ and + MSVC 7.) + \endquotation + + If none of the symbols are defined, the comment will be + rendered as + + \quotation + The Qt 3 support library is provided to keep old + source code working. + + In addition to the \c Qt3Support classes, Qt 4 provides + compatibility functions when it's possible for an old + API to cohabit with the new one. + + To use the Qt 3 support library, you need to have the + line QT += qt3support in your .pro file (qmake + automatically define the QT3_SUPPORT symbol, turning on + compatibility function support). + + You can also define the symbol manually (e.g., if you + don't want to link against the \c Qt3Support library), + or you can define \c QT3_SUPPORT_WARNINGS instead, + telling the compiler to emit a warning when a + compatibility function is called. (This works only with + GCC 3.2+ and MSVC 7.) + \endquotation + + See also \l{if}{\\if}, \l{endif}{\\endif}, \l + {definesvariable}{defines} and \l falsehoods. + + \row + \o \bold \\include \target include + \o \bold {The \\include command expands to the contents of the + file specified by the command's argument.} + + \warning This is preliminary functionality. For more + information, see the \l + {26-qdoc-commands-compatibility.html#include-versus-input} + {compatibility} section. + + The command takes a file name as an argument, and is + useful when some piece of the documentation is used + repeatedly: Move the repetetive text into a separate file, + and use the \\include command whenever you want to insert + the separate documentation. + + The contents of such a file should follow QDoc syntax, + excluding the enclosing \c{/}\c{*!} ... \c{*}\c{/} marks. + To ensure that QDoc won't attempt to read the file as a + stand-alone piece of documentation, we recommend that you + use the \c .qdocinc extension. + + For example: + + \code + / *! + \page corefeatures.html + \title Core Features + + \include examples/signalandslots.qdocinc + \include examples/objectmodel.qdocinc + \include examples/layoutmanagement.qdocinc + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1>Core Features</h1> + \endraw + + \include examples/signalandslots.qdocinc + \include examples/objectmodel.qdocinc + \include examples/layoutmanagement.qdocinc + \endquotation + + Here is the actual \c .qdocinc files: \l + signalandslots.qdocinc, \l objectmodel.qdocinc, \l + layoutmanagement.qdocinc + + \row + \o \bold \\meta \target meta + \o \bold {The \\meta command is the QDoc equivalent to the HTML + \c meta tag.} + + The command accepts two arguments: The first argument (the + following word) is equivalent to the HTML meta tag's \i + name variable, and the second argument (the rest of the + line) is equivalent to the tag's \i contents variable. + + For example: + + \code + / *! + \meta author Summerfield + + \section1 Automatic Dialogs + + \abstract + This article shows how to maintain sets of + "attributes" (QVariant values), and how to allow + users to view and edit them using dialogs that are + created dynamically based on the attributes and + their types. + \endabstract + + The Attributes class described in this article holds a + set of QVariants, and can create a dialog to present + the QVariants to the user in an appropriate way. + + ... + * / + \endcode + + will be included in the generated HTML page as + + \code + <head> + ... + <meta name="author" content="Summerfield" /> + ... + </head> + \endcode + + \row + \o \bold \\omit \target omit + \o \bold {The \\omit command and the correspondning \\endomit + command delimit parts of the documentation that + you want QDoc to skip.} + + For example: + + \code + / *! + \table + \row + \o Basic Widgets + \o Basic GUI widgets such as buttons, comboboxes + and scrollbars. + + \omit + \row + \o Component Model + \o Interfaces and helper classes for the Qt + Component Model. + \endomit + + \row + \o Database Classes + \o Database related classes, e.g. for SQL databases. + \endtable + * / + \endcode + + will be rendered as + + \raw HTML + <table align="center" cellpadding="2" + cellspacing="1" border="0"> + + <tr valign="top" bgcolor="#d0d0d0"> + <td>Basic Widgets</td> + <td>Basic GUI widgets such as buttons, comboboxes + and scrollbars.</td> + </tr> + + <tr valign="top" bgcolor="#c0c0c0"> + <td>Database Classes</td> + <td>Database related classes, e.g. for SQL databases.</td> + </tr> + </table> + \endraw + + + \row + \o \bold \\raw \target raw + \o \bold {The \\raw command and the corresponding + \\endraw command delimit a block of raw mark-up language code.} + + The command takes an argument specifying the code's format; + currently the only supported format is HTML. + + The \\raw command is useful if you want some special HTML + effects in your documentation. For example: + + \code + / *! + Qt has some predefined QColor objects. For example: + + \raw HTML + <style type="text/css" id="colorstyles"> + #blue { background-color: #0000ff; color: #ffffff } + #darkBlue { background-color: #000080; color: #ffffff } + #cyan { background-color: #00ffff; color: #000000 } + </style> + + <p> + <tt id="blue">Blue(#0000ff)</tt>, + <tt id="darkBlue">dark blue(#000080)</tt> and + <tt id="cyan">cyan(#00ffff)</tt>. + \endraw + * / + \endcode + + will be rendered as + + \quotation + Qt has some predefined QColor objects. For example: + + \raw HTML + <style type="text/css" id="colorstyles"> + #blue { background-color: #0000ff; color: #ffffff } + #darkBlue { background-color: #000080; color: #ffffff } + #cyan { background-color: #00ffff; color: #000000 } + </style> + + <p> + <tt id="blue">Blue(#0000ff)</tt>, + <tt id="darkBlue">dark blue(#000080)</tt> and + <tt id="cyan">cyan(#00ffff)</tt>. + \endraw + \endquotation + + \row + \o \bold \\unicode \target unicode + \o \bold {The \\unicode command allows you to insert an + arbitrary Unicode character in the document.} + + The command takes an argument specifying the character as + an integer. By default, base 10 is assumed, unless a '0x' + or '0' prefix is specified (for base 16 and 8, + respectively). For example: + + \code + O G\unicode{0xEA}nio e as Rosas + + \unicode 0xC0 table en famille avec 15 \unicode 0x20AC par jour + + \unicode 0x3A3 \i{a}\sub{\i{i}} + \endcode + + will be rendered as + + \quotation + O G\unicode{0xEA}nio e as Rosas + + \unicode 0xC0 table en famille avec 15 \unicode 0x20AC par jour + + \unicode 0x3A3 \i{a}\sub{\i{i}} + \endquotation + + The \\raw command follows the same conventions as the \l + {i}{\\i} command for \l {argument}{punctuation and use of + braces} for the argument. + \endtable +*/ + +/*! + \page 12-1-signalandslots.html + \previouspage Miscellaneous Commands + \contentspage QDoc Manual - Table of Contents + + \title signalandslots.qdocinc + + \quotefile examples/signalandslots.qdocinc +*/ + +/*! + \page 12-2-objectmodel.html + \previouspage Miscellaneous Commands + \contentspage QDoc Manual - Table of Contents + + \title objectmodel.qdocinc + + \quotefile examples/objectmodel.qdocinc +*/ + +/*! + \page 12-3-layoutmanagement.html + \previouspage Miscellaneous Commands + \contentspage QDoc Manual - Table of Contents + + \title layoutmanagement.qdocinc + + \quotefile examples/layoutmanagement.qdocinc +*/ + +/*! + \page 13-qdoc-commands-topical.html + \previouspage Miscellaneous Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Contextual Commands + + \title Topical Commands + + The topical commands tell QDoc what is being documented + (i.e. existing units like classes, functions and examples), and + some of the commands allows you to create extra pages. + + \section1 Alphabetical List + + \l {13-qdoc-commands-topical.html#class}{\\class}, + \l {13-qdoc-commands-topical.html#enum}{\\enum}, + \l {13-qdoc-commands-topical.html#example-command}{\\example}, + \l {13-qdoc-commands-topical.html#externalpage}{\\externalpage}, + \l {13-qdoc-commands-topical.html#fn}{\\fn}, + \l {13-qdoc-commands-topical.html#group}{\\group}, + \l {13-qdoc-commands-topical.html#headerfile}{\\headerfile}, + \l {13-qdoc-commands-topical.html#macro}{\\macro}, + \l {13-qdoc-commands-topical.html#module}{\\module}, + \l {13-qdoc-commands-topical.html#namespace}{\\namespace}, + \l {13-qdoc-commands-topical.html#page}{\\page}, + \l {13-qdoc-commands-topical.html#property}{\\property}, + \l {13-qdoc-commands-topical.html#service}{\\service}, + \l {13-qdoc-commands-topical.html#typedef}{\\typedef}, + \l {13-qdoc-commands-topical.html#variable}{\\variable}, + + \section1 General Description + + When QDoc is processing a comment, it will try to connect the + documentation to the source code. For that reason it will first + look for the topical commands. If there is no such command, it + will try to tie the documentation to the immediately following + code. If there is no topical command, and the documentation cannot + be tied to following code, the documentation is simply lost. + + \target topical argument + + The documented unit's name is passed as the unique argument for + all the topical commands. The argument's naming convention is the + documented unit's complete name. For example: + + \code + \enum QComboBox::InsertPolicy + \endcode + + Functions is a special case, the argument's naming convention for + the \l {fn}{\\fn} command is that of the function's definition + outside the class definition. For example: + + \code + \fn void PreviewWindow::setWindowFlags() + \endcode + + A topical command can appear anywhere in a comment, but must stand + alone on its own line. If the argument spans several lines, make + sure that each line (except the last one) is ended with a + backslash. In addition QDoc counts parentheses, which means that + if it encounters a '(' it considers everything until the closing + ')' as its argument. + + If a topical command is repeated with different arguments, the + same documentation will appear for both the units. For example: + + \code + / *! + \fn void PreviewWindow::setWindowFlags() + \fn void ControllerWindow::setWindowFlags() + + Sets the widgets flags using the QWidget::setWindowFlags() + function. + + Then runs through the available window flags, creating a text + that contains the names of the flags that matches the flags + parameter, displaying the text in the widgets text editor. + * / + \endcode + + The \c PreviewWindow::setWindowFlags() and \c + ControllerWindow::setWindowFlags() functions will get the same + documentation. + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\class \target class + \o \bold {The \\class command tells QDoc that a class is + part of the public API, and lets you enter a detailed + description.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument, and supports + nested classes, for example: + + \code + / *! + \class QMap::iterator + + \brief The QMap::iterator class provides an STL-style + non-const iterator for QMap and QMultiMap. + + QMap features both \l{STL-style iterators} and + \l{Java-style iterators}. The STL-style iterators ... + * / + \endcode + + The generated HTML documentation for the specified class is + put in \c <lower-case>classname.html. For example, the + documentation for the \c PreviewWindow class is located in + \c previewwindow.html. + + \target framework + + In addition to render the detailed description, the \\class + comand will generate the documentation framework, i.e. a + list of the class's types, properties, functions, signals + and slots with empty documentation. + + The command is typically accompanied with a \l + {brief}{\\brief} command, a \l {mainclass}{\\mainclass} + command, an \l {ingroup}{\\ingroup} command and a \l + {sa}{\\sa} command. For example: + + \code + / *! + \class PreviewWindow + \brief The PreviewWindow class is a custom widget + displaying the names of its currently set + window flags in a read-only text editor. + + \mainclass + \ingroup miscellaneous + + The PreviewWindow class inherits QWidget. The widget + displays the names of its window flags set with the \l + {function}{setWindowFlags()} function. It is also + provided with a QPushButton that closes the window. + + ... + + \sa QWidget + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1>PreviewWindow Class Reference</h1> + \endraw + + The PreviewWindow class is a custom widget displaying + the names of its currently set window flags in a + read-only text editor. \l {preview window}{More...} + + \raw HTML + <h3>Properties</h3> + \endraw + + \list + \o 52 properties inherited from QWidget + \o 1 property inherited from QObject + \endlist + + \raw HTML + <h3>Public Functions</h3> + \endraw + + \list + \o \l {constructor}{PreviewWindow}(QWidget *parent = 0) + \o void \l {function}{setWindowFlags}(Qt::WindowFlags flags) + \endlist + + \list + \o 183 public functions inherited from QWidget + \o 28 public functions inherited from QObject + \endlist + + \raw HTML + <h3>Public Slots</h3> + \endraw + + \list + \o 17 public slots inherited from QWidget + \o 1 public slot inherited from QObject + \endlist + + \raw HTML + <h3>Additional Inherited Members</h3> + \endraw + + \list + \o 1 signal inherited from QWidget + \o 1 signal inherited from QObject + \o 4 static public members inherited from QWidget + \o 4 static public members inherited from QObject + \o 39 protected functions inherited from QWidget + \o 7 protected functions inherited from QObject + \endlist + + \target preview window + + \raw HTML + <hr /> + <h2>Detailed Description</h2> + \endraw + + The PreviewWindow class is a custom widget displaying + the names of its currently set window flags in a + read-only text editor. + + The PreviewWindow class inherits QWidget. The widget + displays the names of its window flags set with the \l + {function}{setWindowFlags()} function. It is also + provided with a QPushButton that closes the window. + + ... + + See also QWidget. + + \raw HTML + <hr /> + <h2>Member Function Documentation</h2> + \endraw + + \target constructor + \raw HTML + <h3>PreviewWindow(QWidget *parent = 0)</h3> + \endraw + + Constructs a preview window widget with \i parent. + + \target function + \raw HTML + <h3>setWindowFlags(Qt::WindowFlags flags)</h3> + \endraw + + Sets the widgets flags using the + QWidget::setWindowFlags() function. + + Then runs through the available window flags, + creating a text that contains the names of the flags + that matches the flags parameter, displaying + the text in the widgets text editor. + \endquotation + + \row + \o \bold \\enum \target enum + \o \bold {The \\enum command allows you to document a C++ enum.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + The enum items are documented using the \l {value}{\\value} + command. If an item isn't documented, QDoc will emit a + warning. This can be avoided using the \l + {omitvalue}{\\omitvalue} command excluding an item from the + documentation. The enum documentation will be located in + the associated class, header file or namespace + documentation. + + For example: + + \code + enum Corner { + TopLeftCorner = 0x00000, + TopRightCorner = 0x00001, + BottomLeftCorner = 0x00002, + BottomRightCorner = 0x00003 + #if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN) + ,TopLeft = TopLeftCorner, + TopRight = TopRightCorner, + BottomLeft = BottomLeftCorner, + BottomRight = BottomRightCorner + #endif + }; + \endcode + + In case of the Qt::Corner enum, + + \code + / *! + \enum Qt::Corner + + This enum type specifies a corner in a rectangle: + + \value TopLeftCorner + The top-left corner of the rectangle. + \value TopRightCorner + The top-right corner of the rectangle. + \value BottomLeftCorner + The bottom-left corner of the rectangle. + \value BottomRightCorner + The bottom-right corner of the rectangle. + + \omitvalue TopLeft + \omitvalue TopRight + \omitvalue BottomLeft + \omitvalue BottomRight + * / + \endcode + + this associated QDoc comment will be rendered as + + \quotation + \raw HTML + <h3 class="fn"><a name="Corner-enum"></a>enum Qt::Corner</h3> + + <p>This enum type specifies a corner in a rectangle:</p> + + <table border="1" cellpadding="2" cellspacing="1" width="100%"> + <tr> + <th width="25%">Constant</th> + <th width="15%">Value</th> + <th width="60%">Description</th> + </tr> + + <tr> + <td valign="top"><tt>Qt::TopLeftCorner</tt></td> + <td align="center" valign="top"><tt>0x00000</tt></td> + <td valign="top">The top-left corner of the rectangle.</td> + </tr> + + <tr> + <td valign="top"><tt>Qt::TopRightCorner</tt></td> + <td align="center" valign="top"><tt>0x00001</tt></td> + <td valign="top">The top-right corner of the rectangle.</td> + </tr> + + <tr> + <td valign="top"><tt>Qt::BottomLeftCorner</tt></td> + <td align="center" valign="top"><tt>0x00002</tt></td> + <td valign="top">The bottom-left corner of the rectangle.</td> + </tr> + + <tr> + <td valign="top"><tt>Qt::BottomRightCorner</tt></td> + <td align="center" valign="top"><tt>0x00003</tt></td> + <td valign="top">The bottom-right corner of the rectangle.</td> + </tr> + + </table> + \endraw + \endquotation + + in qt.html. + + See also \l {value}{\\value} and \l {omitvalue}{\\omitvalue}. + + \row + \o \bold \\example \target example-command + \o \bold {The \\example command allows you to document an + example.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. In particular + the command's argument is the example's path relative to + the paths listed in the \l exampledirs configuration + variable. + + The documentation will be located in \i + {path-to-example}.html, and QDoc will add a list of all the + example files at the top of this documentation page. + + For example, if \l exampledirs contain \c + $QTDIR/examples/widgets/imageviewer, then + + \code + / *! + \example widgets/imageviewer + \title ImageViewer Example + \subtitle + + The example shows how to combine QLabel and QScrollArea + to display an image. + + ... + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <center><h1>Image Viewer Example</h1></center> + \endraw + + Files: + \list + \o \l{http://qt.nokia.com/doc/4.0/widgets-imageviewer-imageviewer-cpp.html} + {widgets/imageviewer/imageviewer.cpp} + \o \l{http://qt.nokia.com/doc/4.0/widgets-imageviewer-imageviewer-h.html} + {widgets/imageviewer/imageviewer.h} + \o \l{http://qt.nokia.com/doc/4.0/widgets-imageviewer-main-cpp.html} + {widgets/imageviewer/main.cpp} + \endlist + + The example shows how to combine QLabel and QScrollArea + to display an image. + + ... + \endquotation + + in widgets-imageviewer.html. + + \row + \o \bold \\fn \target fn + \o \bold {The \\fn command allows you to document a function.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. In particular + it is important that the return type of the function, + whether it is \c const or not and the complete set of + arguments with type are included in the argument. If the + referenced function doesn't exist, QDoc will emit a + warning. + + Also, the \\fn command is QDoc's default command, i.e. when + no topical command can be found within a QDoc comment, QDoc + tries to tie the documentation to the following code as if + it was function documentation. + + This means that the command normally isn't necessary since + the recommended style is to write the function + documentation directly before the function implementation + in the \c .cpp file. In fact, it should only be used for + inline functions implemented in the \c .h file. + + For example: + + \code + / *! + \fn bool QToolBar::isAreaAllowed(Qt::ToolBarArea area) const + + Returns true if this toolbar is dockable in the given + \a area; otherwise returns false. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>bool QToolBar::isAreaAllowed(Qt::ToolBarArea area) const + </h3> + \endraw + + Returns true if this toolbar is dockable in the given + \a area; otherwise returns false. + \endquotation + + See also \l {overload}{\\overload}. + + \row + \o \bold \\group \target group + \o \bold {The \\group command creates a separate page that + lists the classes belonging to the group specified by the + command's argument.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. The \\group + command is typically followed by a \l {title}{\\title} + command and a short introduction to the group. The + generated HTML documentation for the specified group is put + in <lower-case>\i{group}.html. + + A class can be related to a group by using the \l + {ingroup}{\\ingroup} command. In addition, overviews can be + related to a group using the same command, but these must + be listed explicitly using the \l + {generatelist}{\\generatelist} command (see example below). + + Each class is listed with a link to the class reference + page and a brief description based on the classes' \l + {brief}{\\brief} texts. For example: + + \code + / *! + \group io + + \title Input/Output and Networking + + These classes are used to handle input and output to + and from external devices, processes, files etc. as + well as manipulating files and directories. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + + <h1>Input/Output and Networking</h1> + + <p>These classes are used to handle input and output + to and from external devices, processes, files etc. as + well as manipulating files and directories.</p> + + <p> + <table width="100%"> + <tr valign="top" bgcolor="#e0e0e0"> + <td><b> + <a href="http://qt.nokia.com/doc/4.0/qabstractsocket.html">QAbstractSocket</a> + </b></td> + <td> + The base functionality common to all socket types + </td></tr> + + <tr valign="top" bgcolor="#e0e0e0"> + <td><b> + <a href="http://qt.nokia.com/doc/4.0/qbuffer.html">QBuffer</a> + </b></td> + <td> + QIODevice interface for a QByteArray + </td></tr> + + <tr valign="top" bgcolor="#e0e0e0"> + <td><b> + <a href="http://qt.nokia.com/doc/4.0/qclipboard.html">QClipboard</a> + </b></td> + <td> + Access to the window system clipboard + </td></tr> + </table> + \endraw + \endquotation + + in io.html. + + Note that overviews related to the given group, must be + listed explicitly using the \l + {generatelist}{\\generatelist} command with the \c related + argument. For example: + + \code + / *! + \group architecture + + \title Architecture + + These documents describe aspects of Qt's architecture + and design, including overviews of core Qt features and + technologies. + + \generatelist{related} + * / + \endcode + + See also \l {ingroup}{\\ingroup} and \l + {generatelist}{\\generatelist}. + + \row + \o \bold \\headerfile \target headerfile + \o \bold {The \\headerfile command allows you to document + global functions, types and macros declared in a header file.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument, and the + generated HTML documentation for the specified header file + is put in <lower-case>\i{headerfilename}.html. + + A function, type or macro can be associated with a + headerfile using the \l {relates}{\\relates} command. + + If the referenced header file doesn't exist, the + \\headerfile command will still create a documentation page + for a header file with the referenced file's name. + + For example: + + \code + / *! + \headerfile <QtAlgorithms> + + \title Generic Algorithms + + \brief The <QtAlgorithms> header file provides + generic template-based algorithms. + + Qt provides a number of global template functions in \c + <QtAlgorithms> that work on containers and perform + well-know algorithms. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <center><h1><QtAlgorithms> - + Generic Algorithms</h1></center> + <p>The <QtAlgorithms> header file provides generic + template-based algorithms. + <a href="13-qdoc-commands-topical.html#header">More...</a> + </p> + + <h3>Functions</h3> + <ul> + <li>RandomAccessIterator + <a href="http://qt.nokia.com/doc/4.0/qlineedit.html#EchoMode-enum">qBinaryFind</a></b> + (RandomAccessIterator begin, RandomAccessIterator end, + const T & value)</li> + <li>...</li></ul> + <hr /> + \endraw + + \target header + + \raw HTML + <h2>Detailed Description</h2> + <p>The <QtAlgorithms> header file provides generic + template-based algorithms. </p> + \endraw + + Qt provides a number of global template functions in \c + <QtAlgorithms> that work on containers and perform + well-know algorithms. + + ... + \endquotation + + in qtalgorithms.html. + + \row + \o \bold \\macro \target macro + \o \bold {The \\macro command allows you to document a C++ macro.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + QDoc recognizes three different macro syntax: function-like + macros like Q_ASSERT(), declaration-style macros like + Q_PROPERTY() and macros without parentheses like Q_OBJECT. + + The \\macro command must be followed by a \l + {relates}{\\relates} command which attaches the + documentation to that of a related class, header file. or + namespace. Otherwise the documentation will be lost. + + For example: + + \code + / *! + \macro void Q_ASSERT(bool test) + \relates <QtGlobal> + + Prints a warning message containing the source code + file name and line number if \a test is false. + + ... + + \sa Q_ASSERT_X(), qFatal(), {Debugging Techniques} + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>void Q_ASSERT ( bool <i>test</i> )</h3> + \endraw + + Prints a warning message containing the source code + file name and line number if \a test is false. + + ... + + See also Q_ASSERT_X(), qFatal() and \l {Debugging + Techniques}. + \endquotation + + in qtglobal.html. And + + \code + / *! + \macro Q_PROPERTY(...) + \relates QObject + + This macro declares a QObject property. The syntax is: + + ... + + \sa {Qt's Property System} + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>Q_PROPERTY ( ... )</h3> + \endraw + + This macro declares a QObject property. The syntax is: + + ... + + See also \l {Qt's Property System}. + \endquotation + + in qobject.html. And + + \code + / *! + \macro Q_OBJECT + \relates QObject + + The Q_OBJECT macro must appear in the private section + of a class definition that declares its own signals and + slots or that uses other services provided by Qt's + meta-object system. + + ... + + \sa {Meta-Object System}, {Signals and Slots}, {Qt's + Property System} + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>Q_OBJECT</h3> + \endraw + + The Q_OBJECT macro must appear in the private section + of a class definition that declares its own signals and + slots or that uses other services provided by Qt's + meta-object system. + + ... + + See also \l {Meta-Object System}, \l {Signals and + Slots} and \l {Qt's Property System}. + \endquotation + + in qobject.html. + + \row + \o \bold \\module \target module + \o \bold {The \\module creates a separate page that lists the + classes belonging to the module specified by the command's + argument.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + A class can be related to a module using the \l + {inmodule}{\\inmodule} command. + + The \\module command is typically followed by the \l + {title}{\\title} and \l {brief}{\\brief} commands. Each + class is listed with a link to the class reference page and + a brief description based on the classes' \l + {brief}{\\brief} texts. + + For example: + + \code + / *! + \module QtNetwork + + \title QtNetwork Module + + \brief The QtNetwork module offers classes that allow + you to write TCP/IP clients and servers. + + The network module provides classes to make network + programming easier and portable. It offers both + high-level classes such as QHttp and QFtp that + implement specific application-level protocols, and + lower-level classes such as QTcpSocket, QTcpServer, and + QUdpSocket. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1><center>QtNetwork Module</center></h1> + \endraw + + The QtNetwork module offers classes that allow you to + write TCP/IP clients and servers.\l {module + details}{More...} + + \raw HTML + <p> + <table width="100%"> + <tr valign="top" bgcolor="#d0d0d0"> + <td><b> + <a href="http://qt.nokia.com/doc/4.0/qabstractsocket.html">QAbstractSocket</a> + </b></td> + <td> + The base functionality common to all socket types + </td></tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td><b> + <a href="http://qt.nokia.com/doc/4.0/qftp.html">QFtp</a> + </b></td> + <td> + Implementation of the FTP protocol + </td></tr> + + <tr valign="top" bgcolor="#d0d0d0"> + <td>...</td> + <td>...</td> + </tr> + </table> + + <p><hr /></p> + \endraw + + \target module details + + \raw HTML + <h2>Detailed Description</h2> + + <p> + The QtNetwork module offers classes that allow you to + write TCP/IP clients and servers. + </p> + + <p> + The network module provides classes to make network + programming easier and portable. It offers both + high-level classes such as QHttp and QFtp that + implement specific application-level protocols, and + lower-level classes such as QTcpSocket, QTcpServer, and + QUdpSocket. + </p> + \endraw + + ... + + \endquotation + + in qtnetwork.html. + + See also \l {inmodule}{\\inmodule} + + \row + \o \bold \\namespace \target namespace + \o \bold {The \\namespace command allows you to document a C++ + namespace.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + QDoc will generate the same additional links and + documentation for all the members of the namespace as it + does for \l {framework}{classes}. The documentation for + the specified namespace is put in <lower-case>\i + {namespace}.html. + + For example: + + \code + / *! + \namespace Qt + + \brief The Qt namespace contains miscellaneous + identifiers used throughout the Qt library. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <center><h1>Qt Namespace Reference</h1></center> + <p>The Qt namespace contains miscellaneous + identifiers used throughout the Qt library. + <a href="13-qdoc-commands-topical.html#name">More...</a> + </p> + + <pre>#include <Qt></pre> + <ul> + <li> + <a href="http://qt.nokia.com/doc/4.0/qt-qt3.html"> + Qt 3 support members</a></li> + </ul> + + + <h3>Types</h3> + <ul> + <li>flags + <a href="http://qt.nokia.com/doc/4.0/qt.html#AlignmentFlag-enum">Alignment</a></b></li> + <li>...</li></ul> + <hr /> + \endraw + + \target name + + \raw HTML + <h2>Detailed Description</h2> + <p>The Qt namespace contains miscellaneous identifiers + used throughout the Qt library.</p> + \endraw + + ... + \endquotation + + in qt.html. + + \row + \o \bold \\page \target page + \o \bold {The \\page command allows you to create a stand-alone + documentation page.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + The page's title can be set using the \l {title}{\\title} + command. For example: + + \code + / *! + \page aboutqt.html + + \title About Qt + + Qt by Trolltech is a C++ toolkit for cross-platform GUI + application development. Qt provides single-source + portability across Microsoft Windows, Mac OS X, Linux, + and all major commercial Unix variants. (A version of + Qt 4 for embedded Linux will be available in + August/September 2005.) + + Qt provides application developers with all the + functionality needed to build applications with + state-of-the-art graphical user interfaces. Qt is fully + object-oriented, easily extensible, and allows true + component programming. + + ... + * / + \endcode + + will be rendered in its own HTML file: \l{About Qt}. + + \row + \o \bold {\\externalpage} \target externalpage + \o \bold {The \\externalpage command gives a title to + an external URL.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + For example: + + \code + / *! + \externalpage http://www.trolltech.com/products/embedded/index.html + \title Qtopia Core + * / + \endcode + + The QDoc comment above allows you to link to the Qtopia + Core webpage by simply linking to the given title. For + example: + + \code + / *! + The broad scope of the \l {Qtopia Core} API enables it to + be used across a wide variety of development projects. + * / + \endcode + + will be rendered as + + \quotation + The broad scope of the \l + {http://www.trolltech.com/products/embedded/index.html}{Qtopia + Core} API enables it to be used across a wide variety + of development projects. + \endquotation + + To achieve the same result without using the + \\externalpage command, you would have to hard code the + adress into your documentation: + + \code + / *! + The broad scope of the \l + {http://www.trolltech.com/products/embedded/index.html}{Qtopia + Core} API enables it to be used across a wide variety + of development projects. + * / + \endcode + + The \\externalpage command makes it easier to maintain the + documentation. If the adress changes, you only need to change the + argument of the \\externalpage command. + + \row + \o \bold \\property \target property + \o \bold {The \\property command allows you to document a Qt + property.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + A property is defined using the Q_PROPERTY() macro. The + macro takes as arguments the property's name and its set, + reset and get functions. For example: + + \code + Q_PROPERTY(QString state READ state WRITE setState) + \endcode + + The set, reset and get functions don't need to be + documented, documenting the property is sufficient. QDoc + will generate a list of the access function that will + appear in the property documentation which in turn will be + located in the documentation of the class that defines the + property. + + The \\property command is typically accompanied with a \l + {brief}{\\brief} command. In the case of a property, the + \l {brief}{\\brief} command's argument is a sentence + fragment that will be included in a one-sentence + description of the property generated by QDoc. The command + follows the same rules for the \l {brief + property}{description} as the \l {variable}{\\variable} + command. + + For example: + + \code + / *! + \property QPushButton::flat + \brief whether the border is disabled + + This property's default is false. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>flat : bool</h3> + \endraw + + This property holds whether the border is disabled. + + This property's default is false. + + Access functions: + + \list + \o \bold { bool isFlat () const} + \o \bold { void setFlat ( bool )} + \endlist + + \endquotation + + in qpushbutton.html. And + + \code + / *! + \property QWidget::width + \brief the width of the widget excluding any window frame + + See the \l {Window Geometry} documentation for an + overview of window geometry. + + \sa geometry, height, size + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>width : const int</h3> + \endraw + + This property holds the width of the widget excluding + any window frame. + + See the \l {Window Geometry} documentation for an + overview of window geometry. + + Access functions: + + \list + \o \bold { int width () const} + \endlist + + See also \l{QWidget::geometry}{geometry}, + \l{QWidget::height}{height}, and \l{QWidget::size}{size}. + \endquotation + + in qwidget.html. + + \row + \o \bold \\service \target service + + \o \bold {The \\service command tells QDoc that a class is a + service class and specifies its alias, i.e. the associated + service's name.} + + The command takes two arguments, the service class's name + and the associated alias. For example: + + \code + / *! + \service TimeService Time + ... + * / + class TimeService : public QCopObjectService + { + ... + } + \endcode + + See also \l {class}{\\class} and \l + {generatelist}{\\generatelist}. + + \row + \o \bold \\typedef \target typedef + \o \bold {The \\typedef command allows you to document a C++ type + definition.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + The documentation will be located in the associated class, + header file or namespace documentation. When documenting a + global type definition, the \\typedef command must be + accompanied with a \l {relates}{\\relates} command. For + example: + + \code + / *! + \typedef QObjectList + \relates QObject + + Synonym for QList<QObject>. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>typedef QObjectList</h3> + \endraw + + Synonym for QList<QObject>. + \endquotation + + in qobject.html. Another, although more rare, example is + + \code + / *! + \typedef QMsgHandler + \relates QtGlobal + + This is a typedef for a pointer to a function with the + following signature: + + \code + void myMsgHandler(QtMsgType, const char *); + \ endcode + + \sa QtMsgType, qInstallMsgHandler() + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>typedef QtMsgHandler</h3> + \endraw + + This is a typedef for a pointer to a function with the + following signature: + + \raw HTML + <tt> + <pre> void myMsgHandler(QtMsgType, const char *);</pre> + </tt> + \endraw + + See also QtMsgType and qInstallMsgHandler(). + + \endquotation + + in qtglobal.html. Other type definitions are located in the + documentation of the class that defines it, for example: + + \code + / *! + \typedef QLinkedList::Iterator + + Qt-style synonym for QList::iterator. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>typedef QLinkedList::Iterator</h3> + \endraw + + Qt-style synonym for QList::iterator. + \endquotation + + in qlinkedlist.html. + + \row + \o \bold \\variable \target variable + \o \bold {The \\variable command allows you to document a + member variable or a constant.} + + The command follows \l {topical argument}{the general + topical command convention} for the argument. + + The \\variable command is typically followed by a \l + {brief}{\\brief} command; QDoc will generate the + documentation for the variable based on the brief + description. The command follows the same rules for the \l + {brief property}{description} as the \l + {property}{\\property} command. + + The documentation will be located in the in the associated + class, header file or namespace documentation. + + In case of a member variable: + + \code + / *! + \variable QStyleOption::palette + \brief the palette that should be used when painting + the control + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3> + <a href="http://qt.nokia.com/doc/4.0/qpalette.html"> + QPalette + </a> + QStyleOption::palette + </h3> + \endraw + + This variable holds the palette that should be used + when painting the control. + \endquotation + + in qstyleoption.html. + + But you can also use the \\variable command to document + constants like for example the \c Type and \c UserType + constants in the QTreeWidgetItem class: + + \code + enum { Type = 0, UserType = 1000 }; + \endcode + + Then + + \code + / *! + \variable QTreeWidgetItem::Type + + The default type for tree widget items. + + \sa UserType, type() + * / + \endcode + + and + + \code + / *! + \variable QTreeWidgetItem::UserType + + The minimum value for custom types. Values below + UserType are reserved by Qt. + + \sa Type, type() + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3> + const int QTreeWidgetItem::Type + </h3> + \endraw + + The default type for tree widget items. + + See also \l {QTreeWidgetItem::UserType}{UserType} and + \l {QTreeWidgetItem::type()}{type()}. + + \raw HTML + <h3> + const int QTreeWidgetItem::UserType + </h3> + \endraw + + The minimum value for custom types. Values below + UserType are reserved by Qt. + + See also \l {QTreeWidgetItem::Type}{Type} and + \l{QTreeWidgetItem::type()}{type()}. + + \endquotation + + in qtreewidget.html. + \endtable +*/ + +/*! + \page 14-qdoc-commands-contextualcommands.html + \previouspage Topical Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Navigation Commands + + \title Contextual Commands + + The contextual commands provide QDoc with information, that it + wouldn't figure out otherwise, about the documented object. For + example whether a class is thread-safe or not. + + These commands can appear anywhere within a QDoc comment. + + \section1 Alphabetical List + + \l {16-qdoc-commands-status.html#compat}{\\compat}, + \l {15-qdoc-commands-navigation.html#contentspage}{\\contentspage}, + \l {15-qdoc-commands-navigation.html#indexpage}{\\indexpage}, + \l {19-qdoc-commands-grouping.html#ingroup}{\\ingroup}, + \l {19-qdoc-commands-grouping.html#inmodule}{\\inmodule}, + \l {16-qdoc-commands-status.html#internal}{\\internal}, + \l {19-qdoc-commands-grouping.html#mainclass}{\\mainclass}, + \l {15-qdoc-commands-navigation.html#nextpage}{\\nextpage}, + \l {17-qdoc-commands-thread.html#nonreentrant}{\\nonreentrant}, + \l {16-qdoc-commands-status.html#obsolete}{\\obsolete}, + \l {18-qdoc-commands-relating.html#overload}{\\overload}, + \l {16-qdoc-commands-status.html#preliminary}{\\preliminary}, + \l {15-qdoc-commands-navigation.html#previouspage}{\\previouspage}, + \l {17-qdoc-commands-thread.html#reentrant}{\\reentrant}, + \l {18-qdoc-commands-relating.html#reimp}{\\reimp}, + \l {18-qdoc-commands-relating.html#relates}{\\relates}, + \l {15-qdoc-commands-navigation.html#startpage}{\\startpage}, + \l {17-qdoc-commands-thread.html#threadsafe}{\\threadsafe}, + \l {20-qdoc-commands-title.html#title}{\\title} + + \section1 Categories + \list + \o \l {Navigation Commands} + \o \l {Status Commands} + \o \l {Thread Support Commands} + \o \l {Relating Commands} + \o \l {Grouping Commands} + \o \l {Title Commands} + \endlist +*/ + +/*! + \page 15-qdoc-commands-navigation.html + \previouspage Contextual Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Status Commands + + \title Navigation Commands + + The navigation commands allow you to link the pages of a multipage + document together. They provide the components of a navigation bar + at the top and bottom of the document. They also provide browser + and search engine support. + + \section1 Alphabetical List + + \l {15-qdoc-commands-navigation.html#contentspage}{\\contentspage}, + \l {15-qdoc-commands-navigation.html#indexpage}{\\indexpage}, + \l {15-qdoc-commands-navigation.html#nextpage}{\\nextpage}, + \l {15-qdoc-commands-navigation.html#previouspage}{\\previouspage}, + \l {15-qdoc-commands-navigation.html#startpage}{\\startpage} + + \section1 General Description + + The QDoc comments below shows a typical example using the + navigation commands. + + \code + / *! + \page basicqt.html + \contentspage {Basic Qt}{Contents} + \nextpage Getting Started + + \indexpage Index + \startpage Basic Qt + + \title Basic Qt + + The Qt toolkit is a C++ class library and a set of tools for + building multiplatform GUI programs using a "write once, + compile anywhere approach". + + Table of contents: + + \list + \o \l {Getting Started} + \o \l {Creating Dialogs} + \o \l {Creating Main Windows} + \endlist + * / + + / *! + \page gettingstarted.html + \previouspage Basic Qt + \contentspage {Basic Qt}{Contents} + \nextpage Creating Dialogs + + \indexpage Index + \startpage Basic Qt + + \title Getting Started + + This chapter shows how to combine basic C++ with the + functionality provided by Qt to create a few small graphical + interface (GUI) applications. + * / + + / *! + \page creatingdialogs.html + \previouspage Getting Started + \contentspage {Basic Qt}{Contents} + + \indexpage Index + \startpage Basic Qt + + \title Creating Dialogs + + This chapter will teach you how to create dialog boxes using Qt. + * / + + / *! + \page index.html + + \indexpage Index + \startpage Basic Qt + + \title Index + + \list + \o \l {Basic Qt} + \o \l {Creating Dialogs} + \o \l {Getting Started} + \endlist + * / + \endcode + + The second page of this multipage document, "Getting Started", + will be rendered as + + \quotation + \raw HTML + <table border="0" cellpadding="0" cellspacing="5" width="100%"> + + <tr> + <p> + [Previous: <a href="15-qdoc-commands-navigation.html#deadlink"> + Basic Qt</a>] + [<a href="15-qdoc-commands-navigation.html#deadlink">Contents</a>] + [Next: <a href="15-qdoc-commands-navigation.html#deadlink"> + Creating Dialogs</a>] + </p> + + <h1 align="center">Getting Started<br /></h1> + + <p> + This chapter shows how to combine basic C++ with the + functionality provided by Qt to create a few small graphical + interface (GUI) applications. + </p> + + <p> + [Previous: <a href="15-qdoc-commands-navigation.html#deadlink"> + Basic Qt</a>] + [<a href="15-qdoc-commands-navigation.html#deadlink">Contents</a>] + [Next: <a href="15-qdoc-commands-navigation.html#deadlink"> + Creating Dialogs</a>] + </p> + + </table> + \endraw + \endquotation + + in creatingdialogs.html. + + In addition, the \l {indexpage}{\\indexpage} and \l + {startpage}{\\startpage} commands specifies links to the page's + index page and start page. These links are used by browsers and + search engines. + + The index page is typically an alphabetical list of the document's + titles and topics, while the start page is the page considered by + the author to be the starting point of a multipage document. + + The links are included in the generated HTML source code but has + no visual effect on the documentation: + + \code + <head> + ... + <link rel="index" href="index.html" /> + <link rel="start" href="basicqt.html" /> + ... + </head> + \endcode + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\previouspage \target previouspage + \o \bold {The \\previouspage command links the current page + to the previous one in an ordered series of documents}. + + The command has two arguments, each enclosed by curly + braces: The first is the link target, i.e. the title of the + previous page, the second is the link text. If the page's + title is equivalent to the link text, the second argument + can be omitted. + + The command must stand alone on its own line. + + In the end, the link is rendered at the top and bottom of + the current page. For an example, see the \l {General + Description} section. + + \row + \o \bold \\nextpage \target nextpage + \o \bold {The \\nextpage command links the current + page to the next page in an ordered series of documents}. + + The command follows the same syntax and argument convention + as the \l {previouspage}{\\previouspage} command. + + For an example, see the \l {General Description} section. + + \row + \o \bold \\startpage \target startpage + \o \bold {The \\startpage command specifies the first document + in a collection of documents.} + + The command must stand alone on its own line, and its + unique argument is the title of the first document. + + QDoc will generate a link to the specified document which + is included in the HTML file but has no visual effect on + the documentation. The generated link type tells browsers + and search engines which document is considered by the + author to be the starting point of the collection. + + For an example, see the \l {General Description} section. + + \row + \o \bold \\contentspage \target contentspage + \o \bold {The \\contentspage command links the current + page to a contents page}. + + The command follows the same syntax and argument convention + as the \l {previouspage}{\\previouspage} command. + + For an example, see the \l {General Description} section. + + \row + \o \bold \\indexpage \target indexpage + \o \bold {The \\indexpage command specifies a document providing + an index for the current document}. + + The command must stand alone on its own line, and its + unique argument is the title of the index document. + + QDoc will generate a link to the specified document which + is included in the HTML file but has no visual effect on + the documentation. The generated link type tells browsers + and search engines which document is considered by the + author to be the index page for the current document. + + For an example, see the \l {General Description} section. + + \endtable +*/ + +/*! + \page 16-qdoc-commands-status.html + \previouspage Navigation Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Thread Support Commands + + \title Status Commands + + The usage commands can indicate whether a documented object is + under development, becoming obsolete, provided for compatibility + reasons or simply not part of the public interface. They can + describe the history of minor versions. And they can also describe + a documented object's ability to handle multithreaded programming. + + \section1 Alphabetical List + + \l {16-qdoc-commands-status.html#compat}{\\compat}, + \l {16-qdoc-commands-status.html#internal}{\\internal}, + \l {16-qdoc-commands-status.html#obsolete}{\\obsolete}, + \l {16-qdoc-commands-status.html#preliminary}{\\preliminary}, + \l {16-qdoc-commands-status.html#since}{\\since} + + \section1 Command Description + + \table + \header + \o Command + \o Description + + \row + \o \bold \\preliminary \target preliminary + \o \bold {The \\preliminary command indicates that the + referenced function is under development.} + + The command must stand on its own line. + + The \\preliminary command expands to a notification in the + function documentation, and marks the function as + preliminary when it appears in lists. For example: + + \code + / *! + \preliminary + + Returns information about the joining properties of the + character (needed for certain languages such as + Arabic). + * / + QChar::Joining QChar::joining() const + { + return ::joining(*this); + } + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3> + <a href="http://qt.nokia.com/doc/4.0/qchar.html#Joining-enum">Joining</a> + QChar::joining () const</h3> + \endraw + + \bold {This function is under development and + is subject to change.} + + Returns information about the joining properties of the + character (needed for certain languages such as + Arabic). + \endquotation + + And the function's entry in QChar's list of functions will + be rendered as + + \quotation + \list + \o ... + \o Joining + \l {http://qt.nokia.com/doc/4.0/qchar.html#Joining-enum} + {joining}() + const \c (preliminary) + \o ... + \endlist + \endquotation + + \row + \o \bold \\obsolete \target obsolete + \o \bold {The \\obsolete command indicates that the referenced + function no longer should be used in new code; + there is no guarantee for how long it will remain in + the library.} + + The command must stand on its own line. + + When generating the reference documentation for a class, + QDoc will create and link to a separate page documenting + its obsolete functions. Usually an equivalent function is + provided as an alternative. + + For example: + + \code + / *! + \fn MyClass::MyObsoleteFunction + \obsolete + + Use MyNewFunction() instead. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1>Obsolete Members for MyClass</h1> + \endraw + + \bold {The following class members are obsolete.} They + are provided to keep old source code working. We + strongly advise against using them in new code. + + ... + + \list + \o void MyObsoleteFunction() \c (obsolete) + \o ... + \endlist + + \raw HTML + <hr /> + <h2>Member Function Documentation</h2> + <h3>void MyObsoleteFunction ()</h3> + <p>Use MyNewFunction() instead.</p> + \endraw + + ... + \endquotation + + in myclass-obsolete.html + + + \row + \o \bold \\compat \target compat + \o \bold {The \\compat command indicates that the referenced class + or function is part of the support library provided to keep + old source code working.} + + The command must stand on its own line. + + Usually an equivalent function or class is provided as an + alternative. + + If the command is used within the documentation of a class, + the command expands to a warning that the referenced class + is part of the support library. The warning is located on + top of the associated documentation. For example: + + \code + / *! + \class MyQt3SupportClass + \compat + * / + \endcode + + will be rendered as + + \quotation + \bold {This class is part of the Qt 3 support + library.} It is provided to keep old source code + working. We strongly advise against using it in new + code. See the \l + {http://qt.nokia.com/doc/4.0/porting4.html}{Porting + Guide} for more information. + \endquotation + + on the top of the MyQt3SupportClass class reference. + + If the command is used when documenting a function, QDoc + will create and link to a separate page documenting Qt 3 + support members when generating the reference documentation + for the associated class. For example: + + \code + / *! + \fn MyClass::MyQt3SupportMemberFunction + \compat + + Use MyNewFunction() instead. + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1>Qt 3 Support Members for MyClass</h1> + \endraw + + \bold {The following class members are part of the Qt + 3 support layer.} They are provided to help you port + old code to Qt 4. We advise against using them in new + code. + + ... + + \list + \o void MyQt3SupportMemberFunction() + \o ... + \endlist + + \raw HTML + <hr /> + <h2>Member Function Documentation</h2> + <h3>void MyQt3SupportMemberFunction ()</h3> + <p>Use MyNewFunction() instead.</p> + \endraw + + ... + \endquotation + + in myclass-qt3.html + + + \row + \o \bold \\internal \target internal + \o \bold {The \\internal command indicates that the referenced + function is not part of the public interface.} + + The command must stand on its own line. + + QDoc ignores the documentation as well as the documented + item, when generating the associated class reference + documenation. For example: + + \code + / *! + \internal + + Tries to find the decimal separator. If it can't find + it and the thousand delimiter is != '.' it will try to + find a '.'; + * / + int QDoubleSpinBoxPrivate::findDelimiter + (const QString &str, int index) const + { + int dotindex = str.indexOf(delimiter, index); + if (dotindex == -1 && thousand != dot && delimiter != dot) + dotindex = str.indexOf(dot, index); + return dotindex; + } + \endcode + + in qspinbox.cpp, will not be rendered at all. + + \row + \o \bold \\since \target since + \o \bold {The \\since command tells in which minor release + the associated functionality was added.} + + For example: + + \code + / *! + \since 4.1 + + Returns an icon for \a standardIcon. + + ... + + \sa standardIconImplementation(), standardPixmap() + * / + QIcon QStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const + { + } + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3>QIcon QStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const</h3> + \endraw + + This function was introduced in Qt version 4.1 + + Returns an icon for \a standardIcon. + + ... + + See also \l + {QStyle::standardIconImplementation()}{standardIconImplementation()} + and \l {QStyle::standardPixmap()}{standardPixmap()}. + \endquotation + + QDoc generates the "Qt" reference from the \l + {25-qdoc-configuration-derivedprojects.html#project}{\c + project} configuration variable. For that reason this + reference will change according to the current + documentation project. + + See also \l + {25-qdoc-configuration-derivedprojects.html#project}{\c + project}. + + \endtable +*/ + +/*! + \page 17-qdoc-commands-thread.html + \previouspage Status Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Relating Commands + + \title Thread Support Commands + + The thread support commands specify the level of support for + multithreaded programming of a class or function. + + \section1 Alphabetical List + + \l {17-qdoc-commands-thread.html#nonreentrant}{\\nonreentrant}, + \l {17-qdoc-commands-thread.html#reentrant}{\\reentrant}, + \l {17-qdoc-commands-thread.html#threadsafe}{\\threadsafe} + + \section1 General Description + + There are three levels of support for multithreaded programming of + a class or function: \c threadsafe, \c reentrant and \c + nonreentrant. + + The default is \c nonreentrant which means that the associated + class or function cannot be called by multiple threads. \c + Reentrant and \c threadsafe are levels primarily used for classes. + + \c Reentrant means that all the functions in the referenced class + can be called simultaneously by multiple threads, provided that + each invocation of the functions reference unique data. While \c + threadsafe means that all the functions in the referenced class + can be called simultaneously by multiple threads even when each + invocation references shared data. + + When a class is declared \c reentrant or \c threadsafe, using the + \l {reentrant}{\\reentrant} and \l {threadsafe}{\\threadsafe} + commands respectively, functions in the referenced class can be + declared \c nonreentrant, using the \l + {nonreentrant}{\\nonreentrant} command, excluding the functions + from the general view. + + For example: + + \code + / *! + \class QLocale + \brief The QLocale class converts between numbers and their + string representations in various languages. + + \reentrant + \ingroup i18n + \ingroup text + \mainclass + + QLocale is initialized with a language/country pair in its + constructor and offers number-to-string and string-to-number + conversion functions similar to those in QString. + + ... + * / + + / *! + \nonreentrant + + Sets the global default locale to \a locale. These values are + used when a QLocale object is constructed with no + arguments. If this function is not called, the system's locale + is used. + + \warning In a multithreaded application, the default locale + should be set at application startup, before any non-GUI + threads are created. + + \sa system() c() + * / + void QLocale::setDefault(const QLocale &locale) + { + default_d = locale.d; + } + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1><center>QLocale Class Reference</center></h1> + \endraw + + The QLocale class converts between numbers and their string + representations in various languages. More... + + \code + #include <QLocale> + \endcode + + \bold {Note:} All the functions in this class are \l + {threads.html#reentrant}{reentrant}, except \l + {QLocale::setDefault()}{setDefault()}. + + ... + + \raw HTML + <hr /> + <h2>Member Type Documentation</h2> + \endraw + + ... + + \raw HTML + <h3>void QLocale::setDefault ( const QLocale & locale ) </h3> + \endraw + + Sets the global default locale to locale. These values are + used when a QLocale object is constructed with no + arguments. If this function is not called, the system's locale + is used. + + \warning In a multithreaded application, the default locale + should be set at application startup, before any non-GUI + threads are created. + + \warning This function is not reentrant. + + See also \l {QLocale::system()}{system()} and \l + {QLocale::c()}{c()}. + + ... + \endquotation + + As shown above, QDoc generates a notification when a class is + declared reentrant, and lists the exceptions (the declared + nonreentrant functions). A link to the general documentation on \l + {threads.html#reentrant}{reentrancy and thread-safety} is + included. In addition a warning, "\bold Warning: This function is + not reentrant.", is generated in the nonreentrant functions' + documentation. + + QDoc will generate the same notification and warnings when a class + is declared threadsafe. + + For more information see the general documentation on \l + {threads.html#reentrant}{reentrancy and thread-safety}. + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\threadsafe \target threadsafe + \o \bold {The \\threadsafe command indicates that the + associated class or function can be called simultaneously by + multiple threads even when each invocation references + shared data.} + + The command must stand on its own line. + + The generated documentation resulting from using the + \\threadsafe command is similar to the result of using the + \l {reentrant}{\\reentrant} command. For an example, see + the \l {General Description} section. + + See also \l{reentrant}{\\reentrant} and + \l{nonreentrant}{\\nonreentrant}. + + \row + \o \bold \\reentrant \target reentrant + \o \bold {The \\reentrant command indicates that the associated + class or function can be called simultaneously + by multiple threads, provided that each invocation of the + functions reference unique data.} + + The command must stand on its own line. + + For an example, see the \l {General Description} section. + + See also \l{nonreentrant}{\\nonreentrant} and + \l{threadsafe}{\\threadsafe}. + + \row + \o \bold \\nonreentrant \target nonreentrant + \o \bold {The \\nonreentrant command indicates that the + associated class or function cannot be called by + multiple threads.} + + The command must stand on its own line. + + For an example, see the \l {General Description} section. + + See also \l{reentrant}{\\reentrant} and + \l{threadsafe}{\\threadsafe}. + + \endtable +*/ + +/*! + \page 18-qdoc-commands-relating.html + \previouspage Thread Support Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Grouping Commands + + \title Relating Commands + + The relation commands discribe how the documented object relates + to its context: Whether it is an overloaded function, a + reimplemented function or a global function related to a specified + class or header file. + + \section1 Alphabetical List + + \l {18-qdoc-commands-relating.html#overload}{\\overload}, + \l {18-qdoc-commands-relating.html#reimp}{\\reimp}, + \l {18-qdoc-commands-relating.html#relates}{\\relates}, + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\overload \target overload + \o \bold {The \\overload command indicates that the + function is a secondary overload of its name.} + + The command must stand on its own line. + + For any overloaded function (except constructors), QDoc + expects one primary version of the function and all the + the overloads marked with the \bold{\\overload command}. + The primary version should be fully documented. Each + overload can have whatever extra documentation you want + to add for just that overload. + + From Qt 4.5, you can include the function name plus '()' + as a parameter to the \bold{\\overload} command, which + will include a standard \i{This function overloads...} + line of text with a link to the documentation for the + primary version of the function. + + For example: + + \code + / *! + \overload addAction() + + This convenience function creates a new action with an + \a icon and some \a text. The function adds the newly + created action to the menu's list of actions, and + returns it. + + \sa QWidget::addAction() + * / + QAction *QMenu::addAction(const QIcon &icon, const QString &text) + { + QAction *ret = new QAction(icon, text, this); + addAction(ret); + return ret; + } + \endcode + + will be rendered as + + \quotation + \raw HTML + <h3><a href="http://qt.nokia.com/doc/4.0/qaction.html">QAction</a> + * QMenu::addAction ( const QIcon & <i>icon</i>, + const QString & <i>text</i> ) + </h3> + \endraw + + This function overloads \l {http://qt.nokia.com/doc/4.0/qwidget.html#addAction}{addAction()} + + This convenience function creates a new action with an + \i icon and some \i text. The function adds the newly + created action to the menu's list of actions, and + returns it. + + See also + \l {http://qt.nokia.com/doc/4.0/qwidget.html#addAction} + {QWidget::addAction}(). + \endquotation + + If you don't include the function name with the + \bold{\\overlaod} command, then instead of the "This + function overloads..." line with the link to the + documentation for the primary version, you get the old + standard line: + + \quotation + This is an overloaded member function, provided for + convenience. + \endquotation. + + \row + \o \bold \\reimp \target reimp + \o \bold {The \\reimp command indicates that the + referenced function is a reimplementation of a virtual function, + where the reimplementation has no effect on the interface.} + + The command must stand on its own line. + + QDoc will omit the reimplemented function from the class + reference. For example: + + \code + / *! + \reimp + * / + void QToolButton::nextCheckState() + { + Q_D(QToolButton); + if (!d->defaultAction) + QAbstractButton::nextCheckState(); + else + d->defaultAction->trigger(); + } + \endcode + + will not be rendered at all; only a link to the inherited + QAbstractButton::nextCheckState() will appear in the + documentation. + + \row + \o \bold \\relates \target relates + \o \bold {The \\relates command attaches the documentation of + a global function to that of a related class or header file.} + + The command's argument is a class name, an the command (and + its argument) must stand on its own line. + + \code + / *! + \relates QChar + + Reads a char from the stream \a in into char \a chr. + + \sa {Format of the QDataStream operators} + * / + QDataStream &operator>>(QDataStream &in, QChar &chr) + { + quint16 u; + in >> u; + chr.unicode() = ushort(u); + return in; + } + \endcode + + will be rendered with the QChar documentation. + + \endtable +*/ + +/*! + \page 19-qdoc-commands-grouping.html + \previouspage Relating Commands + \contentspage QDoc Manual - Table of Contents + \nextpage Title Commands + + \title Grouping Commands + + The grouping commands relate classes to defined groups and + modules. The groups are used when generating lists of related + classes in the documentation, while the modules are elements of + Qt's structure. + + \section1 Alphabetical List + + \l {19-qdoc-commands-grouping.html#ingroup}{\\ingroup}, + \l {19-qdoc-commands-grouping.html#inmodule}{\\inmodule}, + \l {19-qdoc-commands-grouping.html#mainclass}{\\mainclass}, + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\mainclass \target mainclass + \o \bold {The \\mainclass command relates the documented class to + a group called mainclasses.} + + The command must stand on its own line. + + For example: + + \code + / *! + \class QWidget qwidget.h + \brief The QWidget class is the base class of + all user interface objects. + + \mainclass + + ... + * / + \endcode + + will ensure that the QWidget class is included in the \c + mainclasses group, which means, for example, that the class + will appear on the list created by calling the \l + {generatelist}{\\generatelist} command with the \c + mainclasses argument: + + \l http://qt.nokia.com/doc/4.0/mainclasses.html + + See also \l {generatelist}{\\generatelist}. + + \row + \o \bold \\ingroup \target ingroup + + \o \bold {The \\ingroup command indicates that the given + overview or documented class belongs to a certain group of + related docmentation.} + + A class or overview may belong to many groups. + + The \\ingroup command's argument is a group name, but note + that the command considers the rest of the line as part of + its argument. Make sure that the group name is followed by + a linebreak. For example: + + \code + / *! + \class QDir + \brief The QDir class provides access to directory + structures and their contents. + + \ingroup io + ... + * / + \endcode + + will ensure that the QDir class is included in the \c io + group, which means, for example, that QDir will appear on + the list created by calling the \l {group}{\\group} command + with the \c io argument. + + Note that to list overviews that are related to a given + group, you must generate the list exlicitly by using the \l + {generatelist}{\\generatelist} command with the \c related + argument. + + See also \l {group}{\\group}. + \row + \o \bold \\inmodule \target inmodule + \o \bold {The \\inmodule command relates the documented class + to the module specified by the command's argument.} + + For the basic classes in Qt, a class's module is determined + by its location, i.e. its directory. However, for + extensions, like ActiveQt and Qt Designer, a class needs to + be related to a module explicitly. + + The command's argument is a module name, but note that the + command considers the rest of the line as part of its + argument. Make sure that the module name is followed by a + linebreak. For example: + + \code + /*! + \class QDesignerTaskMenuExtension + \inmodule QtDesigner + * / + \endcode + + will ensure that the QDesignerTaskMenuExtension class is + included in the \c QtDesigner module, which means, for + example, that the class will appear on the list created by + calling the \l {generatelist}{\\generatelist} command with + the \c {{classesbymodule QtDesigner}} argument. + + See also \l {module}{\\module} and \l + {generatelist}{\\generatelist}. + \endtable +*/ + +/*! + \page 20-qdoc-commands-title.html + \previouspage Grouping Commands + \contentspage QDoc Manual - Table of Contents + \nextpage QDoc Configuration + + \title Title Commands + + In general a title command considers everything that follows it + until the first line break as its argument. If the title needs to + be spanned over several lines, make sure to end each line (except + the last one) with a backslash. + + \section1 Alphabetical List + + \l {20-qdoc-commands-title.html#title}{\\title}, + \l {20-qdoc-commands-title.html#subtitle}{\\subtitle} + + \section1 Command Descriptions + + \table + \header + \o Command + \o Description + + \row + \o \bold \\title \target title + \o \bold {The \\title command sets the title for a + documentation page, or allows you to override it.} + + For example: + + \code + / *! + \page signalandslots.html + + \title Signals and Slots + + Signals and slots are used for communication between + objects. The signals and slots mechanism is a central + feature of Qt and probably the part that differs most + from the features provided by other frameworks. + + ... + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1><center>Signal and Slots</center></h1> + \endraw + + Signals and slots are used for communication between + objects. The signals and slots mechanism is a central + feature of Qt and probably the part that differs most + from the features provided by other frameworks. + + ... + \endquotation + See also \l {subtitle}{\\subtitle}. + + \row + \o \bold \\subtitle \target subtitle + \o \bold {The \\subtitle command sets a subtitle for a + documentation page.} + + For example: + + \code + / *! + \page qtopiacore-overview.html + + \title Qtopia Core + \subtitle Qt for Embedded Linux + + Qt/Embedded, the embedded Linux port of Qt, is a + complete and self-contained C++ GUI and platform + development tool for Linux-based embedded development. + + ... + * / + \endcode + + will be rendered as + + \quotation + \raw HTML + <h1><center>Qtopia Core</center></h1> + <h2><center>Qt for Embedded Linux</center></h2> + \endraw + + Qt/Embedded, the embedded Linux port of Qt, is a + complete and self-contained C++ GUI and platform + development tool for Linux-based embedded development. + + ... + \endquotation + + See also \l {title}{\\title}. + \endtable +*/ + +/*! + \page 21-0-qdoc-configuration.html + \previouspage Title Commands + \contentspage QDoc Manual - Table of Contents + \nextpage General Variables + + \title QDoc Configuration + + \tableofcontents + + \list + \o \l {Supporting Derived Projects} + \o \l {QDoc Compatibility} + \endlist + + When running QDoc to generate the documentation, you must specify + a configuration file on the command line: + + \quotation + \bold {/currentdirectory$ qdoc3 my-documentation.qdocconf} + \endquotation + + \section1 General Description + + The configuration file is a list of entries of entries of the form + \i {"variable = value"}. Using the configuration variables, you + can define where QDoc should find the various source files, images + and examples, where to put generated documentation etc. The + configuration file can also contain directives like \c + include. For an example, see the \l minimum.qdocconf file. + + In addition, you can use some particular configuration variables + to make QDoc support derived projects, i.e make the projects, for + example Qt Solutions, contain links to the online Qt + documentation. These variables are documented in the \l + {Supporting Derived projects} section. In this section you can + also find out how to use these variables to support your derived + projects. + + If some of the variable keys have the same values, they can be set + at the same time. For example: + + \code + {header, source}dirs = kernel + \endcode + + is equivalent to + + \code + headerdirs = kernel + sourcedirs = kernel + \endcode + + A variable's value can be set using either '=' or '+='. The + difference is that '=' overrides any previously set value, while + '+=' only adds the value to the previously set ones. + + In general, some of the variables accepts a list of strings as + their value, while others only accept a single string. If you + provide a variable of the latter type with several strings they + will simply be concatenated. The quotes around the value string + are optional. But applying them allows you to use special + characters like '=' and ' \" ' within the string. For example: + + \code + HTML.postheader = "<a href=\"index.html\">Home</a>" + \endcode + + If an entry spans many lines, use a backslash at the end of every + line but the last: + + \code + sourcedirs = kernel \ + tools \ + widgets + \endcode + + \section1 Configuration Variables + + \section2 Alphabetical List + + \l {22-qdoc-configuration-generalvariables.html#alias}{alias}, + \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoredirectives} + {Cpp.ignoredirectives}, + \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoretoken} + {Cpp.ignoretokens}, + \l {22-qdoc-configuration-generalvariables.html#definesvariable}{defines}, + \l {22-qdoc-configuration-generalvariables.html#edition}{edition}, + \l {22-qdoc-configuration-generalvariables.html#exampledirs}{exampledirs}, + \l {22-qdoc-configuration-generalvariables.html#examples}{examples}, + \l {22-qdoc-configuration-generalvariables.html#examples.fileextensions} + {examples.fileextensions}, + \l {22-qdoc-configuration-generalvariables.html#extraimages}{extraimages}, + \l {22-qdoc-configuration-generalvariables.html#falsehoods}{falsehoods}, + \l {22-qdoc-configuration-generalvariables.html#headerdirs}{headerdirs}, + \l {22-qdoc-configuration-generalvariables.html#headers}{headers}, + \l {22-qdoc-configuration-generalvariables.html#headers.fileextensions} + {headers.fileextensions}, + \l {24-qdoc-configuration-htmlvariables.html#HTML.footer}{HTML.footer}, + \l {24-qdoc-configuration-htmlvariables.html#HTML.postheader} + {HTML.postheader}, + \l {24-qdoc-configuration-htmlvariables.html#HTML.style}{HTML.style}, + \l {22-qdoc-configuration-generalvariables.html#imagedirs}{imagedirs}, + \l {22-qdoc-configuration-generalvariables.html#images}{images}, + \l {22-qdoc-configuration-generalvariables.html#images.fileextensions} + {images.fileextensions}, + \l {22-qdoc-configuration-generalvariables.html#language}{language}, + \l {22-qdoc-configuration-generalvariables.html#macro}{macro}, + \l {22-qdoc-configuration-generalvariables.html#outputdir}{outputdir}, + \l {22-qdoc-configuration-generalvariables.html#outputformats} + {outputformats}, + \l {22-qdoc-configuration-generalvariables.html#slow}{slow}, + \l {22-qdoc-configuration-generalvariables.html#sourcedirs}{sourcedirs}, + \l {22-qdoc-configuration-generalvariables.html#sources}{sources}, + \l {22-qdoc-configuration-generalvariables.html#sources.fileextensions} + {sources.fileextensions}, + \l {22-qdoc-configuration-generalvariables.html#spurious}{spurious}, + \l {22-qdoc-configuration-generalvariables.html#tabsize}{tabsize}, + \l {22-qdoc-configuration-generalvariables.html#version}{version}, + \l {22-qdoc-configuration-generalvariables.html#versionsym}{versionsym} + + \section2 Categories + + \list + \o \l {General Variables} + \o \l {C++ Specific Variables} + \o \l {HTML Specific Variables} + \endlist + + \section1 Configuration File Examples + + \list + \o A minimum configuration file: \l minimum.qdocconf + \o The Qt configuration file: \l qt.qdocconf + \endlist +*/ + +/*! + \page 21-1-minimum-qdocconf.html + \previouspage QDoc Configuration + \contentspage QDoc Manual - Table of Contents + + \title minimum.qdocconf + + \quotefile examples/minimum.qdocconf +*/ + +/*! + \page 21-2-qt-qdocconf.html + \previouspage QDoc Configuration + \contentspage QDoc Manual - Table of Contents + + \title qt.qdocconf + + \quotefile files/qt.qdocconf +*/ + +/*! + \page 22-qdoc-configuration-generalvariables.html + \previouspage QDoc Configuration + \contentspage QDoc Manual - Table of Contents + \nextpage Creating Help Project Files + + \title General Variables + + With the general QDoc configuration variables, you can define + where QDoc will find the various source files it needs to generate + the documentation, as well as the directory to put the generated + documentation. You can also do some minor manipulation of QDoc + itself, controlling its output and processing behavior. + + \section1 Alphabetical List + + \l {22-qdoc-configuration-generalvariables.html#alias}{alias}, + \l {22-qdoc-configuration-generalvariables.html#codeindent}{codeindent}, + \l {22-qdoc-configuration-generalvariables.html#definesvariable}{defines}, + \l {22-qdoc-configuration-generalvariables.html#edition}{edition}, + \l {22-qdoc-configuration-generalvariables.html#exampledirs}{exampledirs}, + \l {22-qdoc-configuration-generalvariables.html#examples}{examples}, + \l {22-qdoc-configuration-generalvariables.html#examples.fileextensions} + {examples.fileextensions}, + \l {22-qdoc-configuration-generalvariables.html#extraimages}{extraimages}, + \l {22-qdoc-configuration-generalvariables.html#falsehoods}{falsehoods}, + \l {22-qdoc-configuration-generalvariables.html#generateindex}{generateindex}, + \l {22-qdoc-configuration-generalvariables.html#headerdirs}{headerdirs}, + \l {22-qdoc-configuration-generalvariables.html#headers}{headers}, + \l {22-qdoc-configuration-generalvariables.html#headers.fileextensions} + {headers.fileextensions}, + \l {22-qdoc-configuration-generalvariables.html#imagedirs}{imagedirs}, + \l {22-qdoc-configuration-generalvariables.html#images}{images}, + \l {22-qdoc-configuration-generalvariables.html#images.fileextensions} + {images.fileextensions}, + \l {22-qdoc-configuration-generalvariables.html#language}{language}, + \l {22-qdoc-configuration-generalvariables.html#macro}{macro}, + \l {22-qdoc-configuration-generalvariables.html#outputdir}{outputdir}, + \l {22-qdoc-configuration-generalvariables.html#outputformats} + {outputformats}, + \l {22-qdoc-configuration-generalvariables.html#slow}{slow}, + \l {22-qdoc-configuration-generalvariables.html#sourcedirs}{sourcedirs}, + \l {22-qdoc-configuration-generalvariables.html#sources}{sources}, + \l {22-qdoc-configuration-generalvariables.html#sources.fileextensions} + {sources.fileextensions}, + \l {22-qdoc-configuration-generalvariables.html#spurious}{spurious}, + \l {22-qdoc-configuration-generalvariables.html#tabsize}{tabsize}, + \l {22-qdoc-configuration-generalvariables.html#tagfile}{tagfile}, + \l {22-qdoc-configuration-generalvariables.html#version}{version}, + \l {22-qdoc-configuration-generalvariables.html#versionsym}{versionsym} + + \section1 Variable Descriptions + + \table + + \header + \o Variable + \o Description + + \row + \o \bold alias \target alias + \o \bold {The \c alias variable renames a QDoc command.} + + The general syntax is \tt {alias.\i{original-command-name} + = \i temporary-command-name}. + + For example: + + \code + alias.i = e + \endcode + + renames the built-in command \\i (italics) to \\e. + + The \c alias variable is often used for compatibility + reasons; for more information see the \l {QDoc + Compatibility}{compatibility section}. + + See also \l macro. + + \row + \o \bold codeindent \target codeindent + \o \bold {The \c codeindent variable specifies the level of + indentation that QDoc uses when writing code snippets.} + + QDoc originally used a hard-coded value of four spaces for + code indentation to ensure that code snippets could be easily + distinguished from surrounding text. Since we can use + \l{HTML Specific Variables#HTML.stylesheets}{stylesheets} to + adjust the appearance of certain types of HTML elements, this + level of indentation is not always required. + + \row + \o \bold defines \target definesvariable + \o \bold {The \c defines variable specifies the C++ preprocessor + symbols that QDoc will recognize and respond to.} + + When a preprocessor symbol is specified using the \c + defines variable, you can also use the \l {if}{\\if} + command to enclose documentation that only will be included + if the preprocessor symbol is defined. + + The values of the variable are regular expressions (see + QRegExp for details). By default, no symbol is defined, + meaning that code protected with #ifdef...#endif will be + ignored. + + For example: + + \code + defines = Q_QDOC \ + QT_.*_SUPPORT \ + QT_.*_LIB \ + QT_COMPAT \ + QT3_SUPPORT \ + Q_WS_.* \ + Q_OS_.* \ + Q_BYTE_ORDER \ + __cplusplus + \endcode + + ensures that QDoc will process the code that requires these + symbols to be defined. For example: + + \code + #ifdef Q_WS_WIN + HDC getDC() const; + void releaseDC(HDC) const; + #endif + \endcode + + Since the Q_WS_.* regular expression (specified using the + \c defines variable) matches Q_WS_WIN, QDoc will process + the code within #ifdef and #endif in our example. + + You can also define preprocessor symbols manually on the + command line using the -D option. For example: + + \code + currentdirectory$ qdoc3 -Dconsoleedition qt.qdocconf + \endcode + + In this case the -D option ensures that the \c + consoleedition preprocessor symbol is defined when QDoc + processes the source files defined in the qt.qdocconf file. + + See also \l falsehoods and \l {if}{\\if}. + + \row + \o \bold edition \target edition + \o \bold {The \c edition variable specifies which modules are + included in each edition of a package, and provides QDoc + with information to provide class lists for each edition.} + + This feature is mostly used when providing documentation + for Qt packages. + + The \c edition variable is always used with a particular + edition name to define the modules for that edition: + + \code + edition.Console = QtCore QtNetwork QtSql QtXml + edition.Desktop = QtCore QtGui QtNetwork QtOpenGL QtSql QtXml \ + QtDesigner QtAssistant Qt3Support QAxContainer \ + QAxServer + edition.DesktopLight = QtCore QtGui Qt3SupportLight + \endcode + + In the above examples, the \c Console edition only includes + the contents of four modules. Only the classes from these + modules will be used when the + \l{Miscellaneous Commands#generatelist}{generatelist} command + is used to generate a list of classes for this edition: + + \code + \generatelist{classesbyedition Console} + \endcode + + \row + \o \bold exampledirs \target exampledirs + \o \bold {The \c exampledirs variable specifies the directories + containing the source code of the example files.} + + The \l {examples}{\c examples} and \c exampledirs variables + are used by the \l {quotefromfile}{\\quotefromfile}, \l + {quotefile}{\\quotefile} and \l {example}{\\example} + commands. If both the \l {examples}{\c examples} and \c + exampledirs variables are defined, QDoc will search in + both, first in \l {examples}{\c examples} then in \c + exampledirs. + + QDoc will search through the directories in the specified + order, and accept the first matching file it finds. It will + only search in the specified directories, \i not in + subdirectories. + + For example: + + \code + exampledirs = $QTDIR/doc/src \ + $QTDIR/examples \ + $QTDIR \ + $QTDIR/qmake/examples + + examples = $QTDIR/examples/widgets/analogclock/analogclock.cpp + \endcode + + When processing + + \code + \quotefromfile widgets/calculator/calculator.cpp + \endcode + + QDoc will then see if there exists a file called \c + calculator.cpp listed as a value in the \l {examples}{\c + examples} variable. If it doesn't, it will search in the \c + exampledirs variable, and first see if there exists a file + called + + \code + $QTDIR/doc/src/widgets/calculator/calculator.cpp + \endcode + + If it doesn't, QDoc will continue looking for a file + called + + \code + $QTDIR/examples/widgets/calculator/calculator.cpp + \endcode + + and so forth. + + See also \l examples. + + \row + \o \bold examples \target examples + \o \bold {The \c examples variable allows you to specify individual + example files in addition to those located in the directories + specified by the \l {exampledirs}{\c exampledirs} variable.} + + The \c examples and \l {exampledirs}{\c exampledirs} + variables are used by the \l + {quotefromfile}{\\quotefromfile}, \l + {quotefile}{\\quotefile} and \l {example}{\\example} + commands. If both the \c examples and \l {exampledirs}{\c + exampledirs} variables are defined, QDoc will search in + both, first in \c examples then in \l {exampledirs}{\c + exampledirs}. + + QDoc will search through the values listed for the \c + examples variable, in the specified order, and accept + the first one it finds. + + For an extensive example, see the \l {exampledirs}{\c + exampledirs} command. But note that if you know the file is + listed in the \c examples variable, you don't need to + specify its path: + + \code + \quotefromfile calculator.cpp + \endcode + + See also \l exampledirs. + + \row + \o \bold examples.fileextensions \target examples.fileextensions + \o \bold {The \c examples.fileextensions variable specifies the + file extensions that qdoc will look for when collecting example + files for display in the documentation.} + + The default extensions are *.cpp, *.h, *.js, *.xq, *.svg, *.xml + and *.ui. However, if + + The extensions are given as standard wildcard expressions. + You can add a file extension to the filter using '+='. For + example: + + \code + examples.fileextensions += *.qrc + \endcode + + See also \l{headers.fileextensions}. + + \row + \o \bold extraimages \target extraimages + \o \bold {The \c extraimages variable tells QDoc to incorporate + specific images in the generated documentation.} + + QDoc will not recognize images used within HTML (or any + other markup language). If we want the images to be copied + from the directories specified by \l {imagedirs}{\c + imagedirs} (the images in question must be located in these + directories) to the output directory, we must specify the + images using the \c extraimages variable. + + The general syntax is \tt {extraimages.\i{format} = \i + image}. The file extension is optional. + + For example, in \l qt.qdocconf we use a couple of images + within the HTML.postheader variable which value is pure + HTML. For that reason, these images are specified using the + \c extraimages variable: + + \code + extraimages.HTML = qt-logo + \endcode + + See also \l images and \l imagedirs. + + \row + \o \bold falsehoods \target falsehoods + \o \bold {The \c falsehoods variable defines the truth value of + specified preprocessor symbols as false.} + + If this variable is not set for a preprocessor symbol, QDoc + assumes its truth value is true. The exception is '0', + which value always is false. + + QDoc will recognize, and is able to evaluate, the following + preprocessor syntax: + + \code + #ifdef NOTYET + ... + #endif + + #if defined (NOTYET) + ... + #end if + \endcode + + However, faced with unknown syntax like + + \code + #if NOTYET + ... + #endif + \endcode + + QDoc will evaluate it as true by default, \i unless the + preprocessor symbol is specified within the \c falsehoods + variable entry: + + \code + falsehoods = NOTYET + \endcode + + See also \l defines. + + \row + \o \bold generateindex \target generateindex + \o \bold{The \c generateindex variable contains a boolean value that + specifies whether to generate an index file when HTML documentation + is generated.} + + By default, an index file is always generated with HTML documentation, + so this variable is typically only used when disabling this feature + (by setting the value to \c false) or when enabling index generation + for the WebXML output (by setting the value to \c true). + \row + \o \bold headerdirs \target headerdirs + \o \bold {The \c headerdirs variable specifies the directories + containing the header files associated with the \c .cpp source + files used in the documentation.} + + For example: + + \code + headerdirs = $QTDIR/src \ + $QTDIR/extensions/activeqt \ + $QTDIR/extensions/motif \ + $QTDIR/tools/designer/src/lib/extension \ + $QTDIR/tools/designer/src/lib/sdk \ + $QTDIR/tools/designer/src/lib/uilib + \endcode + + When executed, the first QDoc will do is to read through + the headers specified in the \l {headers}{\c headers} + variable, and the ones located in the directories specified + in the \c headerdir variable (including all + subdirectories), building an internal structure of the + classes and their functions. + + Then it will read through the sources specified in the \l + {sources}{\c sources}, and the ones located in the + directories specified in the \l {sourcedirs}{\c sourcedirs} + varible (including all subdirectories), merging the + documentation with the structure it retrieved from the + header files. + + If both the \c headers and \c headerdirs variables are + defined, QDoc will read through both, first \l {headers}{\c + headers} then \c headerdirs. + + In the specified directories, QDoc will only read the files + with the fileextensions specified in the \l + {headers.fileextensions}{\c headers.fileextensions} + variable. The default extensions are *.ch, *.h, *.h++, + *.hh, *.hpp and *.hxx". The files specified by \l + {headers}{\c headers} will be read independent of their + fileextensions. + + See also \l headers and \l headers.fileextensions. + + \row + \o \bold headers \target headers + \o \bold {The \c headers variable allows you to specify individual + header files in addition to those located in the directories + specified by the \l {headerdirs}{\c headerdirs} variable.} + + For example: + + \code + headers = $QTDIR/src/gui/widgets/qlineedit.h \ + $QTDIR/src/gui/widgets/qpushbutton.h + \endcode + + When processing the \c headers variable, QDoc behaves in the + same way as it does when processing the \l {headerdirs}{\c + headerdirs} variable. For more information, see the \l + {headerdirs}{\c headerdirs} variable. + + See also \l headerdirs. + + \row + \o \bold headers.fileextensions \target headers.fileextensions + \o \bold {The \c headers.fileextensions variable specify the + extension used by the headers.} + + When processing the header files specified in the \l + {headerdirs}{\c headerdirs} variable, QDoc will only read + the files with the fileextensions specified in the \c + headers.fileextensions variable. In this way QDoc avoid + spending time reading irrelevant files. + + The default extensions are *.ch, *.h, *.h++, *.hh, *.hpp + and *.hxx. + + The extensions are given as standard wildcard expressions. + You can add a file extension to the filter using '+='. For + example: + + \code + header.fileextensions += *.H + \endcode + + \warning The above assignment may not work as described. + + See also \l headerdirs. + + \row + \o \bold imagedirs \target imagedirs + \o \bold {The \c imagedirs variable specifies the directories + containing the images used in the documentation.} + + The \l {images}{\c images} and \c imagedirs variables are + used by the \l {image}{\\image} and \l + {inlineimage}{\\inlineimage} commands. If both the \l + {images}{\c images} and \c imagedirs variables are defined, + QDoc will search in both, first in \l {images}{\c images} + then in \c imagedirs. + + QDoc will search through the directories in the specified + order, and accept the first matching file it finds. It will + only search in the specified directories, \i not in + subdirectories. + + For example: + + \code + imagedirs = $QTDIR/doc/src/images \ + $QTDIR/examples + + images = $QTDIR/doc/src/images/calculator-example.png + \endcode + + When processing + + \code + \image calculator-example.png + \endcode + + QDoc will then see if there exists a file called + calculator-example.png listed as a value in the \c images + variable. If it doesn't, it will search in the \c imagedirs + variable, and first see if there exists a file called + + \code + $QTDIR/doc/src/images/calculator-example.png + \endcode + + If it doesn't, QDoc will look for a file called + + \code + $QTDIR/examples/calculator-example.png + \endcode + + You can filter the images in an image directory using the + \l {images.fileextensions}{\c images.fileextensions} + variable. The general idea behind the \l + {images.fileextensions}{\c images.fileextensions} variable + is to enable different image format for different output + format. + + \warning The \l {images.fileextensions}{\c + images.fileextensions} variable's functionality is + preliminay since QDoc at this point only support HTML. + + See also \l images and \l images.fileextensions. + + \row + \o \bold images \target images + \o \bold {The \c images variable allows you to specify individual + image files in addition to those located in the directories + specified by the \l {imagedirs}{\c imagedirs} variable.} + + For example: + + \code + images = $QTDIR/doc/src/images/calculator-example.png + \endcode + + When processing the \c images variable, QDoc behaves in the + same way as it does when processing the \l {imagedirs}{\c + imagedirs} variable. For more information, see the \l + {imagedirs}{\c imagedirs} variable. + + See also \l imagedirs and \l images.fileextensions. + + \row + \o \bold images.fileextensions \target images.fileextensions + \o \bold {The images.fileextensions variable filters the files within + an image directory.} + + The variable's values (the extensions) are given as + standard wildcard expressions. The general syntax is: \tt + {images.fileextensions.\i{format} = *.\i{extension}}. + + The idea is to enable different image format for different + output format. For example: + + \code + images.fileextensions.HTML = *.png + images.fileextensions.LOUT = *.eps + \endcode + + Then, when processing the \l {image}{\\image} and \l + {inlineimage}{\\inlineimage} commands, QDoc will only + search for files with extensions specified in the output + format's associated image extension variable. + + \warning This is preliminary functionality since QDoc at + this point only support HTML. + + The default extensions for HTML are *.png, *.jpg, *.jpeg + and *.gif. + + You can add a file extension to the filter using '+='. For + example: + + \code + images.fileextensions.HTML += *.eps + \endcode + + See also \l imagedirs and \l images. + + \row + \o \bold language \target language + \o \bold {The \c language variable specifies the language of the + source code that is used in the documentation.} + + Currently, C++ is the only language that QDoc + understands. It is also the default language, and doesn't + really need to be specified. But for example in \l + qt.qdocconf: + + \code + language = Cpp + \endcode + + identifies the language of the Qt source code as C++. + + \row + \o \bold macro \target macro + \o \bold {The \c macro variable can be used to create your + own QDoc commands.} + + The general syntax is \tt {macro.\i{command} = + "\i{definition}}". The definition can be described using + QDoc syntax. In addition it is possible to provide an HTML + definition by appending .HTML to the variable. + + For example in \l qt.qdocconf: + + \code + macro.gui = "\\bold" + macro.raisedaster.HTML = "<sup>*</sup>" + \endcode + + makes sure that the \\gui command renders its argument using a + bold font, and that \\raisedaster renders a '*'. + + \row + \o \bold outputdir \target outputdir + \o \bold {The \c outputdir variable specifies the directory + where QDoc will put the generated documentation.} + + In qt.qdocconf: + + \code + outputdir = $QTDIR/doc/html + \endcode + + locates the generated Qt reference documentation in + $QTDIR/doc/html. For example, the documentation of the + QWidget class is located in + + \code + $QTDIR/doc/html/qwidget.html + \endcode + + The associated images will be put in an \c images subdirectory. + + \warning When running QDoc multiple times using the same output + directory, all files from the previous run will be lost. + + \row + \o \bold outputformats \target outputformats + \o \bold {The \c outputformats variable specifies the format of + the generated documentation.} + + Currently, QDoc only supports the HTML format. It is also + the default format, and doesn't need to be specified. + + \row + \o \bold qhp \target qhp + \o \bold{The \c qhp variable is used to define the information to be + written out to Qt Help Project (\c{qhp}) files.} + + See the \l{Creating Help Project Files} chapter for information + about this process. + + \row + \o \bold slow \target slow + \o \bold {The \c slow variable specifies whether QDoc should do + time-consuming processing, such as syntax highlighting.} + + By default, this setting is false. + + Example: + + \code + slow = true + \endcode + + Another way to turn on "slowness" is to invoke QDoc with the + \c -slow command-line option. + + \row + \o \bold sourcedirs \target sourcedirs + \o \bold {The \c sourcedirs variable specifies the directories + containing the \c .cpp or \c .qdoc files used in + the documentation.} + + For example in \l qt.qdocconf + + \code + sourcedirs = $QTDIR/src \ + $QTDIR/doc/src \ + $QTDIR/extensions/activeqt \ + $QTDIR/extensions/motif \ + $QTDIR/tools/designer/src/lib/extension \ + $QTDIR/tools/designer/src/lib/sdk \ + $QTDIR/tools/designer/src/lib/uilib + \endcode + + When executed, the first QDoc will do is to read through + the headers specified in the \l {header}{\c header} + variable, and the ones located in the directories specified + in the \c headerdir variable (including all + subdirectories), building an internal structure of the + classes and their functions. + + Then it will read through the sources specified in the \l + {sources}{\c sources}, and the ones located in the + directories specified in the \l {sourcedirs}{\c sourcedirs} + varible (including all subdirectories), merging the + documentation with the structure it retrieved from the + header files. + + If both the \c sources and \c sourcedirs variables are + defined, QDoc will read through both, first \l {sources}{\c + sources} then \c sourcedirs. + + In the specified directories, QDoc will only read the files + with the fileextensions specified in the \l + {sources.fileextensions}{\c sources.fileextensions} + variable. The default extensions are *.c++, *.cc, *.cpp and + *.cxx. The files specified by \l {sources}{\c sources} will + be read independent of their fileextensions. + + See also \l sources and \l sources.fileextensions. + + \row + \o \bold sources \target sources + \o \bold {The \c sources variable allows you to specify + individual source files in addition to those located in the + directories specified by the \l {sourcedir}{\c sourcedir} + variable.} + + For example: + + \code + sources = $QTDIR/src/gui/widgets/qlineedit.cpp \ + $QTDIR/src/gui/widgets/qpushbutton.cpp + \endcode + + When processing the \c sources variable, QDoc behaves in the + same way as it does when processing the \l {sourcedirs}{\c + sourcedirs} variable. For more information, see the \l + {sourcedirs}{\c sourcedirs} variable. + + See also \l sourcedirs. + + \row + \o \bold sources.fileextensions \target sources.fileextensions + \o \bold {The \c sources.fileextensions variable filters the + files within a source directory.} + + When processing the source files specified in the \l + {sourcedirs}{\c sourcedirs} variable, QDoc will only read + the files with the fileextensions specified in the \c + sources.fileextensions variable. In this way QDoc avoid + spending time reading irrelevant files. + + The default extensions are *.c++, *.cc, *.cpp and *.cxx. + + The extensions are given as standard wildcard expressions. + You can add a file extension to the filter using '+='. For + example: + + \code + sources.fileextensions += *.CC + \endcode + + \warning The above assignment may not work as described. + + See also \l sourcedirs and \l sources. + + \row + \o \bold spurious \target spurious + \o \bold {The \c spurious variable excludes specified + QDoc warnings from the output.} + + The warnings are specified using standard wildcard + expressions. For example: + + \code + spurious = "Cannot find .*" \ + "Missing .*" + \endcode + + makes sure that warnings matching either of these + expressions, will not be part of the output when running + QDoc. For example would the following warning be omitted + from the output: + + \code + qt-4.0/src/opengl/qgl_mac.cpp:156: Missing parameter name + \endcode + + \row + \o \bold tabsize \target tabsize + \o \bold {The \c tabsize variable defines the size of a tab + character.} + + For example: + + \code + tabsize = 4 + \endcode + + will give the tab character the size of 4 spaces. + + The default value of the variable is 8, and doesn't need to + be specified. + + \row + \o \bold tagfile \target tagfile + \o \bold{The \c tagfile variable specifies the Doxygen tag file to be written + when HTML is generated.} + \row + \o \bold version \target version + \o \bold {The \c version variable specifies the version number of the + documented software.} + + For example: + + \code + version = 4.0.1 + \endcode + + When a version number is specified (using the \tt{\l + version} or \tt {\l versionsym} variables in a \c .qdocconf + file), it is accessible through the corresponding \\version + command for use in the documentation. + + \warning The \\version command's functionality is not + fully implemented; currently it only works within raw HTML + code. + + See also \l versionsym. + + \row + \o \bold versionsym \target versionsym + \o \bold {The \c versionsym variable specifies a C++ + preprocessor symbol that defines the version number + of the documented software.} + + For example in \l qt.qdocconf: + + \code + versionsym = QT_VERSION_STR + \endcode + + QT_VERSION_STR is defined in qglobal.h as follows + + \code + #define QT_VERSION_STR "4.0.1" + \endcode + + When a version number is specified (using the \tt{\l + version} or \tt {\l versionsym} variables in a \c .qdocconf + file), it is accessible through the corresponding \\version + command for use in the documentation. + + \warning The \\version command's functionality is not fully + implemented; currently it only works within raw HTML code. + + See also \l {version}{\\version}. + + \endtable +*/ + +/*! + \page 22-creating-help-project-files.html + \previouspage General Variables + \contentspage QDoc Manual - Table of Contents + \nextpage C++ Specific Variables + + \title Creating Help Project Files + + \section1 Overview + + Starting with Qt 4.4, Qt Assistant uses a different system for managing + Qt documentation that requires QDoc to generate inventories of files in a + format that is similar to the old style DCF format, but with additional + features. + + Instead of hard-coding information about the documentation sets for Qt, + QDoc allows configuration variables to be used to specify which pages are + to be used in each documentation set it generates. These are specified as + subvariables of the \c qch variable with each set declared using a unique + identifier as a subvariable. + + For example, the configuration file for the Qt documentation defines a + \c Qt documentation set by specifying information about the set as + subvariables with the \c{qhp.Qt} prefix: + + \code + qhp.Qt.file = qt.qhp + qhp.Qt.namespace = com.trolltech.qt.440 + qhp.Qt.virtualFolder = qdoc + qhp.Qt.indexTitle = Qt Reference Documentation + qhp.Qt.indexRoot = + qhp.Qt.extraFiles = classic.css images/qt-logo.png + qhp.Qt.filterAttributes = qt 4.4.0 qtrefdoc + qhp.Qt.customFilters.Qt.name = Qt 4.4.0 + qhp.Qt.customFilters.Qt.filterAttributes = qt 4.4.0 + qhp.Qt.subprojects = classes overviews examples + qhp.Qt.subprojects.classes.title = Classes + qhp.Qt.subprojects.classes.indexTitle = Qt's Classes + qhp.Qt.subprojects.classes.selectors = class + qhp.Qt.subprojects.overviews.title = Overviews + qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs + qhp.Qt.subprojects.overviews.selectors = fake:page,group,module + qhp.Qt.subprojects.examples.title = Tutorials and Examples + qhp.Qt.subprojects.examples.indexTitle = Qt Examples + qhp.Qt.subprojects.examples.selectors = fake:example + \endcode +*/ + +/*! + \page 23-qdoc-configuration-cppvariables.html + \previouspage Creating Help Project Files + \contentspage QDoc Manual - Table of Contents + \nextpage HTML Specific Variables + + \title C++ Specific Variables + + The C++ specific configuration variables are provided to avoid + erroneous documentation due to non-standard C++ constructs. + + \section1 Alphabetical List + + \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoredirectives} + {Cpp.ignoredirectives}, + \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoretoken} + {Cpp.ignoretokens} + + \section1 Variable Descriptions + + \table + + \header + \o Variable + \o Description + + \row + \o \bold Cpp.ignoredirectives \target Cpp.ignoredirectives + \o \bold {The \c Cpp.ignoredirectives variable makes QDoc ignore + the specified non-standard constructs, within C++ source code.} + + If not specified by the \tt {\l Cpp.ignoretokens} or \tt + {\l Cpp.ignoredirectives} variables, non-standard + constructs (typically macros) can result in erroneous + documentation. + + In \l qt.qdocconf: + + \code + Cpp.ignoredirectives = Q_DECLARE_INTERFACE \ + Q_DECLARE_OPERATORS_FOR_FLAGS \ + Q_DECLARE_PRIVATE \ + Q_DECLARE_PUBLIC \ + Q_DISABLE_COPY \ + Q_DUMMY_COMPARISON_OPERATOR \ + Q_ENUMS \ + Q_FLAGS \ + Q_INTERFACES \ + __attribute__ + \endcode + + makes sure that when processing the code below, for + example, QDoc will simply ignore the 'Q_ENUMS' and + 'Q_FLAGS' expressions: + + \code + class Q_CORE_EXPORT Qt { + Q_OBJECT + Q_ENUMS(Orientation TextFormat BackgroundMode + DateFormat ScrollBarPolicy FocusPolicy + ContextMenuPolicy CaseSensitivity + LayoutDirection ArrowType) + Q_ENUMS(ToolButtonStyle) + Q_FLAGS(Alignment) + Q_FLAGS(Orientations) + Q_FLAGS(DockWidgetAreas) + + public: + ... + }; + \endcode + + The Q_OBJECT macro, however, is an exception: QDoc + recognizes this particular non-standard construct, so there + is no need specifying it using the \tt {\l + Cpp.ignoredirectives} variable. + + Regarding the Q_CORE_EXPORT macro; see the documentation of + the \tt {\l Cpp.ignoretokens} variable. + + See also \l Cpp.ignoretokens. + + \row + \o \bold Cpp.ignoretokens \target Cpp.ignoretokens + \o \bold {The \c Cpp.ignoretokens variable makes QDoc ignore + the specified non-standard constructs, within C++ source code.} + + If not specified by the \tt {\l Cpp.ignoretokens} or \tt + {\l Cpp.ignoredirectives} variables, non-standard + constructs (typically macros) can result in erroneous + documentation. + + In \l qt.qdocconf: + + \code + Cpp.ignoretokens = QAXFACTORY_EXPORT \ + QM_EXPORT_CANVAS \ + ... + Q_COMPAT_EXPORT \ + Q_CORE_EXPORT \ + Q_EXPLICIT \ + Q_EXPORT \ + ... + Q_TYPENAME \ + Q_XML_EXPORT + \endcode + + makes sure that when processing the code below, for + example, QDoc will simply ignore the 'Q_CORE_EXPORT' + expression: + + \code + class Q_CORE_EXPORT Qt { + Q_OBJECT + Q_ENUMS(Orientation TextFormat BackgroundMode + DateFormat ScrollBarPolicy FocusPolicy + ContextMenuPolicy CaseSensitivity + LayoutDirection ArrowType) + Q_ENUMS(ToolButtonStyle) + Q_FLAGS(Alignment) + Q_FLAGS(Orientations) + Q_FLAGS(DockWidgetAreas) + + public: + ... + }; + \endcode + + Regarding the Q_OBJECT, Q_ENUMS and Q_FLAGS macros; see the + documentation of the \tt {\l Cpp.ignoredirectives} + variable. + + See also \l Cpp.ignoredirectives. + + \endtable +*/ + + +/*! + \page 24-qdoc-configuration-htmlvariables.html + \previouspage C++ Specific Variables + \contentspage QDoc Manual - Table of Contents + \nextpage Supporting Derived Projects + + \title HTML Specific Variables + + The HTML specific configuration variables define the generated + documentation's style, or define the contents of the + documentation's footer or postheader. The format of the variable + values are raw HTML. + + \section1 Alphabetical List + + \l {24-qdoc-configuration-htmlvariables.html#HTML.footer}{HTML.footer}, + \l {24-qdoc-configuration-htmlvariables.html#HTML.postheader} + {HTML.postheader}, + \l {24-qdoc-configuration-htmlvariables.html#HTML.style}{HTML.style}, + \l {24-qdoc-configuration-htmlvariables.html#HTML.stylesheets}{HTML.stylesheets} + + + \section1 Variable Descriptions + + \table + + \header + \o Variable + \o Description + + \row + \o \bold HTML.footer \target HTML.footer + \o \bold {The \c HTML.footer variable defines the content + of the generated HTML documentation's footer.} + + The footer is rendered at the bottom of the generated + documentation page. + + The variable's value is given as raw HTML code enclosed by + quotation marks. Note that if the value spans several + lines, each line needs to be enclosed by quotation marks. + + For example in \l qt.qdocconf: + + \code + HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ + ... + "</tr></table></div></address>" + \endcode + + The complete variable entry in \l qt.qdocconf provides the + standard footer of the \l + {http://qt.nokia.com/doc/4.0/index.html}{Qt Reference + Documentation}. + + \row + \o \bold HTML.postheader \target HTML.postheader + \o \bold {The \c HTML.postheader variable defines the content + of the generated HTML documentation's postheader.} + + The header is rendered at the top of the generated + documentation page. + + The variable's value is given as raw HTML enclosed by + quotation marks. Note that if the value spans several + lines, each line needs to be enclosed by quotation marks. + + For example in \l qt.qdocconf: + + \code + HTML.postheader = "<table border=\"0\"..." \ + ... + "<img src=\"images/trolltech-logo.png\" \ + "align=\"right\" width=\"203\" height=\"32\""\ + "border=\"0\" />" \ + "</td></tr>" \ + "</table>" + \endcode + + The complete variable entry in \l qt.qdocconf provides the + standard header of the \l + {http://qt.nokia.com/doc/4.0/index.html}{Qt Reference + Documentation}. + + \row + \o \bold HTML.style \target HTML.style + \o \bold {The HTML.style variable defines the style for + the generated HTML documentation.} + + The variable's value is given as raw HTML enclosed by + quotation marks. Note that if the value spans several + lines, each line needs to be enclosed by quotation marks. + + For example in \l qt.qdocconf: + + \code + HTML.style = "h3.fn,span.fn" \ + "{ margin-left: 1cm; text-indent: -1cm; }\n" \ + "a:link { color: #004faf; text-decoration: none }\n" \ + "a:visited" \ + "{ color: #672967; text-decoration: none }\n" \ + "td.postheader { font-family: sans-serif }\n" \ + "tr.address { font-family: sans-serif }\n" \ + "body { background: #ffffff; color: black; }" + \endcode + + provides the HTML style for the \l + {http://qt.nokia.com/doc/4.0/index.html}{Qt Reference + Documentation}. + + \row + \o \bold HTML.stylesheets \target HTML.stylesheets + \o \bold {The HTML.stylesheets variable defines a list of stylesheets + to use for the generated HTML documentation.} + + Using separate stylesheets for the documentation makes it easier to + customize and experiment with the style used once the contents has + been generated. Typically, it is only necessary to define a single + stylesheet for any set of documentation; for example: + + \code + HTML.stylesheets = classic.css + \endcode + + QDoc expects to find stylesheets in the directory containing the + \l qt.qdocconf file, and it will copy those specified to the output + directory alongside the HTML pages. + \endtable +*/ + +/*! + \page 25-qdoc-configuration-derivedprojects.html + \previouspage HTML Specific Variables + \contentspage QDoc Manual - Table of Contents + \nextpage QDoc Compatibility + + \title Supporting Derived Projects + + \tableofcontents + + Some particular configuration variables allow you to use QDoc to + support Qt-based projects; i.e to make projects, such as Qt Solutions, + contain references to the online Qt documentation. This + means that QDoc will be able to create links to the class reference + documentation, without any explicit linking command. + + \section1 The Configuration Variables + + \section2 Alphabetical List + + \l{25-qdoc-configuration-derivedprojects.html#description}{description}, + \l{25-qdoc-configuration-derivedprojects.html#indexes}{indexes}, + \l{25-qdoc-configuration-derivedprojects.html#project}{project}, + \l{25-qdoc-configuration-derivedprojects.html#url}{url} + + \section2 Variable Descriptions + + \table + \header + \o Variable + \o Description + \row + \o \bold description \target description + \o \bold {The description variable holds a short description of + the associated project.} + + See also \l project. + + \row + \o \bold indexes \target indexes + \o \bold {The \c indexes variable lists the index files + that will be used to generate references.} + + For example. to make a derived Qt project contain links to + the Qt Reference documentation, you need to specify the + associated index file: + + \code + indexes = $QTDIR/doc/html/qt.index + \endcode + + See also \l project and \l url. + + \row + \o \bold project \target project + \o \bold {The \c project variable provides a name for the project + associated with the \c .qdocconf file.} + + The project's name is used to form a file name for the + associated project's \i index file. For example: + + \code + project = QtMotif + \endcode + + This will cause an index file called \c qtmotif.index to be + created. + + See also \l description and \l indexes. + \row + \o \bold url \target url + \o \bold {The \c url variable holds the base URL for the + reference documentation associated with the current project.} + + The URL is stored in the generated index file for the + project. When we use the index on its own, QDoc will use + this as the base URL when constructing links to classes, + functions, and other things listed in the index. + + For example: + + \code + project = Qt + description = Qt Reference Documentation + url = http://qt.nokia.com/doc/4.0 + + ... + \endcode + + This makes sure that whenever \c qt.index is used to generate + references to for example Qt classes, the base URL is + \c http://qt.nokia.com/doc/4.0. + + See also \l indexes. + + \endtable + + \target howto + \section1 How to Support Derived Projects + + This feature makes use of the comprehensive indexes generated by + QDoc when it creates the Qt reference documentation. + + For example, \l qt.qdocconf (the configuration file for Qt) + contains the following variable definitions: + + \code + project = Qt + description = Qt Reference Documentation + url = http://qt.nokia.com/doc/4.0 + + ... + \endcode + + The \l project variable name is used to form a file name for the + index file; in this case the \c qt.index file is created. The \l + url is stored in the index file. Later, when we use the index on + its own, QDoc will use this as the base URL when constructing + links to classes, functions, and other things listed in the index. + + In a mini-project, you can use an index file by defining an \l + indexes configuration variable in your \c .qdocconf file. + + For example, you can create a \c qtmotif.qdocconf file to help you + check the QtMotif documentation (which is part of Qt Solutions): + + \code + include($QTDIR/tools/qdoc3/test/compat.qdocconf) + + project = QtMotif + description = QtMotif Class Documentation + url = http://www.trolltech.com/products/solutions/catalog/4/Migration/qtmotifextension + + indexes = $QTDIR/doc/html/qt.index + + outputdir = html + + headerdirs = src + sourcedirs = src \ + examples + sources.fileextensions = "*.cpp *.qdoc *.doc" + + exampledirs = examples + \endcode + + The code above requires that you run QDoc from the directory that + contains this file. You need to include the compat.qdocconf + file for compatibility reasons; this is further explained in the + \l {QDoc Compatibility} section. + + \bold {To resolve the actual links to Qt classes, the + mini-project's \c .qdocconf file needs to assign a value to the \l + indexes variable; \c $QTDIR/doc/html/qt.index makes sure that you + always use the updated index file for the Qt documentation.} + + The only disadvantages with this approach are the extra file that + QDoc has to generate and the time it takes to do so. Reading the + index back again later isn't instantaneous either, but it's + quicker than processing all the Qt classes each time you need to + write a new document. +*/ + +/*! + \page 26-qdoc-commands-compatibility.html + \previouspage Supporting Derived Projects + \contentspage QDoc Manual - Table of Contents + \nextpage QDoc Commands - Alphabetical List + + \title QDoc Compatibility + + \tableofcontents + + \section1 General Description + + \target reason + + QDoc is a tool that constantly evolves to suit our needs, for that + reason there are some compatibility issues in the transition + between old and new practices. + + To make the transition as smooth and rapid as possible, the + general idea is to adopt the new commands and usage in new + documentation. While waiting for the occurrences of the old + practices to be eliminated from the old parts of the + documentation, you can map the new commands and usage to the old + ones using a compat.qdocconf file. + + A compat.qdocconf file is a separate \c .qdocconf file which you + can include in your main configuration file. It typically contains + the mapping between old and new commands using the \l alias and \l + {22-qdoc-configuration-generalvariables.html#macro}{macro} + configuration variables. + + \section1 Qt Compatibility + + In Qt's documentation there still exist occurrences of old + commands, and the Qt \l {qt.qdocconf}{configuration file} needs to + include the compat.qdocconf file tailored for Qt. For more + detailed information about the commands creating compatibility + issues, see the \l {Command Comments}{command comments}. + + \section2 Qt's current compat.qdocconf file + + \quotefile files/compat.qdocconf + + \section2 Command Comments + + \table + \header + \o New Command + \o Old Command + \o Description + + \row + \o \\i \target i-versus-e + \o \\e + \o Earlier we + used the \\i command to indicate a list or table item, and + the \\e command for rendering in italic. Now we want the + \\i command to render in italic discarding the + \\e command name. + + \bold {We still need to use the \\e command to render in + italic in new documentation for \l {reason}{compatibility + reasons}}. + + \row + \o \\include \target include-versus-input + \o \\input + \o The \\include command was previously used to quote the + complete contents of a source file, now we want to use the + command to include separate documentation. + That is the functionality of the old \\input command + which name we want to discard. + + \bold {We still need to use the \\input command to include + plain text in new documentation for \l + {reason}{compatibility reasons}}. + + \row + \o \\quotefile \target quotefile-versus-include + \o \\include + \o Earlier, we have used the \\quotefile command to + quote from file, i.e. quote parts from file, and the + \\include command to quote the entire file. Since we now want + \\include to include separate documentation, we change the use of + \\quotefile to quote a complete source file. + + \bold {We still need to use the \\include command to quote + the entire contents of a source file in new documentation + for \l {reason}{compatibility reasons}}. + + \row + \o \\quotefromfile \target quotefromfile-versus-quotefile + \o \\quotefile + \o Earlier, we have used the \\quotefile command to + quote from file, i.e. quote parts from file. Since we now want + that command to quote an entire file, we introduce the new + \\quotefromfile command to quote from file. + + \bold {Use \l {quotefromfile}{\\quotefromfile} to quote + parts from a source file in new documentation}. + + \row + \o \\o \target o-versus-i + \o \\i + \o Earlier we used the \\i command to indicate list items + and table items. Since we now want the \\i command to render + in italic instead, we introduce the new \\o command for + this purpose. + + \bold {Use \l {o}{\\o} to indicate list and table items in + new documentation}. + + \row + \o \\quotation \target quotation-versus-quote + \o \\quote + \o These commands are equivalent, and represent a simple name + change. + + \bold {Use \l {quotation}{\\quotation} in new + documentation}. + + \row + \o \\image \target image-versus-img + \o \\img + \o These commands are equivalent, and represent a simple name + change. + + \bold {Use \l {image}{\\image} in new documentation}. + + \endtable +*/ + +/*! + \page 27-qdoc-commmands-alphabetical.html + \previouspage QDoc Compatibility + \contentspage QDoc Manual - Table of Contents + + \title QDoc Commands - Alphabetical List + + \list + + \o \l {04-qdoc-commands-textformatting.html#a}{\\a} + \o \l {11-qdoc-commands-documentcontents.html#abstract}{\\abstract} + \o \l {06-qdoc-commands-verbatimcode.html#badcode}{\\badcode} + \o \l {04-qdoc-commands-textformatting.html#bold}{\\bold} + \o \l {11-qdoc-commands-documentcontents.html#brief}{\\brief} + \o \l {04-qdoc-commands-textformatting.html#c}{\\c} + \o \l {09-qdoc-commands-graphic.html#caption}{\\caption} + \o \l {05-qdoc-commands-documentstructuring.html#chapter}{\\chapter} + \o \l {13-qdoc-commands-topical.html#class}{\\class} + \o \l {06-qdoc-commands-verbatimcode.html#code}{\\code} + \o \l {07-0-qdoc-commands-quoting.html#codeline}{\\codeline}, + \o \l {16-qdoc-commands-status.html#compat}{\\compat} + \o \l {15-qdoc-commands-navigation.html#contentspage}{\\contentspage} + \o \l {07-0-qdoc-commands-quoting.html#dots}{\\dots} + \o \l {12-0-qdoc-commands-miscellaneous.html#else}{\\else} + \o \l {12-0-qdoc-commands-miscellaneous.html#endif}{\\endif} + \o \l {13-qdoc-commands-topical.html#enum}{\\enum} + \o \l {13-qdoc-commands-topical.html#example-command}{\\example} + \o \l {12-0-qdoc-commands-miscellaneous.html#expire}{\\expire} + \o \l {13-qdoc-commands-topical.html#externalpage}{\\externalpage} + \o \l {13-qdoc-commands-topical.html#fn}{\\fn} + \o \l {11-qdoc-commands-documentcontents.html#footnote}{\\footnote} + \o \l {12-0-qdoc-commands-miscellaneous.html#generatelist}{\\generatelist} + \o \l {13-qdoc-commands-topical.html#group}{\\group} + \o \l {10-qdoc-commands-container.html#header}{\\header} + \o \l {13-qdoc-commands-topical.html#headerfile}{\\headerfile} + \o \l {04-qdoc-commands-textformatting.html#i}{\\i} + \o \l {12-0-qdoc-commands-miscellaneous.html#if}{\\if} + \o \l {09-qdoc-commands-graphic.html#image}{\\image} + \o \l {12-0-qdoc-commands-miscellaneous.html#include}{\\include} + \o \l {15-qdoc-commands-navigation.html#indexpage}{\\indexpage} + \o \l {19-qdoc-commands-grouping.html#ingroup}{\\ingroup} + \o \l {19-qdoc-commands-grouping.html#inmodule}{\\inmodule} + \o \l {09-qdoc-commands-graphic.html#inlineimage}{\\inlineimage} + \o \l {16-qdoc-commands-status.html#internal}{\\internal} + \o \l {08-qdoc-commands-linking.html#keyword}{\\keyword} + \o \l {08-qdoc-commands-linking.html#l}{\\l} + \o \l {11-qdoc-commands-documentcontents.html#legalese}{\\legalese} + \o \l {10-qdoc-commands-container.html#list}{\\list} + \o \l {13-qdoc-commands-topical.html#macro}{\\macro} + \o \l {19-qdoc-commands-grouping.html#mainclass}{\\mainclass} + \o \l {12-0-qdoc-commands-miscellaneous.html#meta}{\\meta} + \o \l {13-qdoc-commands-topical.html#module}{\\module} + \o \l {13-qdoc-commands-topical.html#namespace}{\\namespace} + \o \l {15-qdoc-commands-navigation.html#nextpage}{\\nextpage} + \o \l {06-qdoc-commands-verbatimcode.html#newcode}{\\newcode} + \o \l {17-qdoc-commands-thread.html#nonreentrant}{\\nonreentrant} + \o \l {10-qdoc-commands-container.html#o}{\\o} + \o \l {16-qdoc-commands-status.html#obsolete}{\\obsolete} + \o \l {06-qdoc-commands-verbatimcode.html#oldcode}{\\oldcode} + \o \l {12-0-qdoc-commands-miscellaneous.html#omit}{\\omit} + \o \l {10-qdoc-commands-container.html#omitvalue}{\\omitvalue} + \o \l {18-qdoc-commands-relating.html#overload}{\\overload} + \o \l {13-qdoc-commands-topical.html#page}{\\page} + \o \l {05-qdoc-commands-documentstructuring.html#part}{\\part} + \o \l {16-qdoc-commands-status.html#preliminary}{\\preliminary} + \o \l {15-qdoc-commands-navigation.html#previouspage}{\\previouspage} + \o \l {07-0-qdoc-commands-quoting.html#printline}{\\printline} + \o \l {07-0-qdoc-commands-quoting.html#printto}{\\printto} + \o \l {07-0-qdoc-commands-quoting.html#printuntil}{\\printuntil} + \o \l {13-qdoc-commands-topical.html#property}{\\property} + \o \l {11-qdoc-commands-documentcontents.html#quotation}{\\quotation} + \o \l {07-0-qdoc-commands-quoting.html#quotefile}{\\quotefile} + \o \l {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile} + \o \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\raw} + \o \l {17-qdoc-commands-thread.html#reentrant}{\\reentrant} + \o \l {18-qdoc-commands-relating.html#reimp}{\\reimp} + \o \l {18-qdoc-commands-relating.html#relates}{\\relates} + \o \l {10-qdoc-commands-container.html#row}{\\row} + \o \l {08-qdoc-commands-linking.html#sa}{\\sa} + \o \l {05-qdoc-commands-documentstructuring.html#sectionOne}{\\section1} + \o \l {05-qdoc-commands-documentstructuring.html#sectionTwo}{\\section2} + \o \l {05-qdoc-commands-documentstructuring.html#sectionThree}{\\section3} + \o \l {05-qdoc-commands-documentstructuring.html#sectionFour}{\\section4} + \o \l {13-qdoc-commands-topical.html#service}{\\service} + \o \l {16-qdoc-commands-status.html#since}{\\since} + \o \l {07-0-qdoc-commands-quoting.html#skipline}{\\skipline} + \o \l {07-0-qdoc-commands-quoting.html#skipto}{\\skipto} + \o \l {07-0-qdoc-commands-quoting.html#skipuntil}{\\skipuntil} + \o \l {07-0-qdoc-commands-quoting.html#snippet}{\\snippet}, + \o \l {15-qdoc-commands-navigation.html#startpage}{\\startpage} + \o \l {04-qdoc-commands-textformatting.html#sub}{\\sub} + \o \l {20-qdoc-commands-title.html#subtitle}{\\subtitle} + \o \l {04-qdoc-commands-textformatting.html#sup}{\\sup} + \o \l {10-qdoc-commands-container.html#table}{\\table} + \o \l {11-qdoc-commands-documentcontents.html#tableofcontents} + {\\tableofcontents} + \o \l {08-qdoc-commands-linking.html#target}{\\target} + \o \l {17-qdoc-commands-thread.html#threadsafe}{\\threadsafe} + \o \l {20-qdoc-commands-title.html#title}{\\title} + \o \l {04-qdoc-commands-textformatting.html#tt}{\\tt} + \o \l {13-qdoc-commands-topical.html#typedef}{\\typedef} + \o \l {04-qdoc-commands-textformatting.html#underline}{\\underline} + \o \l {13-qdoc-commands-topical.html#variable}{\\variable} + \o \l {10-qdoc-commands-container.html#value}{\\value} + \o \l {11-qdoc-commands-documentcontents.html#warning}{\\warning} + \endlist +*/ + +/*! + \externalpage http://qt.nokia.com/about + \title About Qt +*/ diff --git a/tools/qdoc3/doc/qdoc-manual.qdocconf b/tools/qdoc3/doc/qdoc-manual.qdocconf new file mode 100644 index 0000000..26fd09c --- /dev/null +++ b/tools/qdoc3/doc/qdoc-manual.qdocconf @@ -0,0 +1,49 @@ +project = QDoc +description = QDoc3 Manual + +indexes = $QTDIR/doc/html/qt.index + +outputdir = html + +sources = qdoc-manual.qdoc +sourcedirs = $PWD + +exampledirs += $PWD \ + $QTDIR/examples + +imagedirs += images + +extraimages.HTML = qt-logo + +HTML.stylesheets = classic.css + +HTML.style = "h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; }\n" \ + "a:link { color: #004faf; text-decoration: none }\n" \ + "a:visited { color: #672967; text-decoration: none }\n" \ + "td.postheader { font-family: sans-serif }\n" \ + "tr.address { font-family: sans-serif }\n" \ + "body { background: #ffffff; color: black; }" + +HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"5\" width=\"100%\">\n" \ + "<tr>\n" \ + "<td align=\"left\" valign=\"top\" width=\"32\">" \ + "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \ + "</td>\n" \ + "<td class=\"postheader\" valign=\"center\">" \ + "<a href=\"01-qdoc-manual.html\">" \ + "<font color=\"#004faf\">Home: QDoc Manual</font></a> ·" \ + "<a href=\"http://qt.nokia.com/doc/4.7\">" \ + "<font color=\"#004faf\"> Qt Reference Documentation</font></a>" \ + "</td>\n" \ + "</tr></table>" + +HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ + "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ + "<td width=\"40%\" align=\"left\">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \ + "<td width=\"20%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \ + "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \ + "</tr></table></div></address>" + +spurious += "Missing '\\}'" +spurious += "Cannot use .*" +spurious += "Unexpected .*" diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 15386f1..e341a03 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -54,10 +54,12 @@ #include <qdebug.h> #include <qlist.h> #include <qiterator.h> +#include <qtextcodec.h> QT_BEGIN_NAMESPACE #define COMMAND_VERSION Doc::alias("version") +int HtmlGenerator::id = 0; QString HtmlGenerator::sinceTitles[] = { @@ -266,6 +268,15 @@ void HtmlGenerator::initializeGenerator(const Config &config) projectUrl = config.getString(CONFIG_URL); + outputEncoding = config.getString(CONFIG_OUTPUTENCODING); + if (outputEncoding.isEmpty()) + outputEncoding = QLatin1String("ISO-8859-1"); + outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit()); + + naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE); + if (naturalLanguage.isEmpty()) + naturalLanguage = QLatin1String("en"); + QSet<QString> editionNames = config.subVars(CONFIG_EDITION); QSet<QString>::ConstIterator edition = editionNames.begin(); while (edition != editionNames.end()) { @@ -389,9 +400,9 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) "qmake Manual", dcfQmakeRoot); - generateIndex(project.toLower().simplified().replace(" ", "-"), - projectUrl, - projectDescription); + QString fileBase = project.toLower().simplified().replace(" ", "-"); + generateIndex(fileBase, projectUrl, projectDescription); + generatePageIndex(outputDir() + "/" + fileBase + ".pageindex", marker); helpProjectWriter->generate(myTree); } @@ -431,11 +442,11 @@ int HtmlGenerator::generateAtom(const Atom *atom, endLink(); } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } break; case Atom::BaseName: @@ -483,7 +494,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::C: out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]; if (inLink) { - out() << protect(plainCode(atom->string())); + out() << protectEnc(plainCode(atom->string())); } else { out() << highlightedCode(atom->string(), marker, relative); @@ -516,7 +527,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, // fallthrough case Atom::CodeBad: out() << "<pre><font color=\"#404040\">" - << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string())))) + << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string())))) << "</font></pre>\n"; break; case Atom::FootnoteLeft: @@ -768,7 +779,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, out() << "<a name=\"" << Doc::canonicalTitle((*s).name) << "\"></a>\n"; - out() << "<h3>" << protect((*s).name) << "</h3>\n"; + out() << "<h3>" << protectEnc((*s).name) << "</h3>\n"; if (idx == Class) generateCompactList(0, marker, ncmap.value(), QString("Q")); else if (idx == MemberFunction) { @@ -792,7 +803,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, << linkForNode(pmap.key(), 0) << "\">"; QStringList pieces = fullName(pmap.key(), 0, marker).split("::"); - out() << protect(pieces.last()); + out() << protectEnc(pieces.last()); out() << "</a>" << ":</p>\n"; generateSection(nlist, 0, marker, CodeMarker::Summary); @@ -820,12 +831,12 @@ int HtmlGenerator::generateAtom(const Atom *atom, out() << "<p align=\"center\">"; if (fileName.isEmpty()) { out() << "<font color=\"red\">[Missing image " - << protect(atom->string()) << "]</font>"; + << protectEnc(atom->string()) << "]</font>"; } else { - out() << "<img src=\"" << protect(fileName) << "\""; + out() << "<img src=\"" << protectEnc(fileName) << "\""; if (!text.isEmpty()) - out() << " alt=\"" << protect(text) << "\""; + out() << " alt=\"" << protectEnc(text) << "\""; out() << " />"; helpProjectWriter->addExtraFile(fileName); } @@ -923,7 +934,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, // ### Trenton out() << "<tr><td valign=\"top\"><tt>" - << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(), + << protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(), relative))) << "</tt></td><td align=\"center\" valign=\"top\">"; @@ -936,7 +947,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, if (itemValue.isEmpty()) out() << "?"; else - out() << "<tt>" << protect(itemValue) << "</tt>"; + out() << "<tt>" << protectEnc(itemValue) << "</tt>"; skipAhead = 1; } @@ -1052,7 +1063,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, generateLink(atom, relative, marker); } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } break; case Atom::TableLeft: @@ -1166,7 +1177,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, out() << "<font color=\"red\"><b><Missing HTML></b></font>"; break; case Atom::UnknownCommand: - out() << "<font color=\"red\"><b><code>\\" << protect(atom->string()) + out() << "<font color=\"red\"><b><code>\\" << protectEnc(atom->string()) << "</code></b></font>"; break; #ifdef QDOC_QML @@ -1295,7 +1306,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, out() << "<a name=\"" << registerRef((*s).name.toLower()) << "\"></a>\n"; - out() << "<h2>" << protect((*s).name) << "</h2>\n"; + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; generateSection(s->members, inner, marker, CodeMarker::Summary); } if (!s->reimpMembers.isEmpty()) { @@ -1304,7 +1315,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, out() << "<a name=\"" << registerRef(name.toLower()) << "\"></a>\n"; - out() << "<h2>" << protect(name) << "</h2>\n"; + out() << "<h2>" << protectEnc(name) << "</h2>\n"; generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary); } @@ -1343,7 +1354,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, s = sections.begin(); while (s != sections.end()) { out() << "<hr />\n"; - out() << "<h2>" << protect((*s).name) << "</h2>\n"; + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; NodeList::ConstIterator m = (*s).members.begin(); while (m != (*s).members.end()) { @@ -1518,7 +1529,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) s = sections.begin(); while (s != sections.end()) { out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n"; - out() << "<h2>" << protect((*s).name) << "</h2>\n"; + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; generateQmlSummary(*s,fake,marker); ++s; } @@ -1534,7 +1545,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) sections = marker->qmlSections(qml_cn,CodeMarker::Detailed); s = sections.begin(); while (s != sections.end()) { - out() << "<h2>" << protect((*s).name) << "</h2>\n"; + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; NodeList::ConstIterator m = (*s).members.begin(); while (m != (*s).members.end()) { generateDetailedQmlMember(*m, fake, marker); @@ -1554,7 +1565,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) s = sections.begin(); while (s != sections.end()) { out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n"; - out() << "<h2>" << protect((*s).name) << "</h2>\n"; + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; generateSectionList(*s, fake, marker, CodeMarker::Summary); ++s; } @@ -1583,7 +1594,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) s = sections.begin(); while (s != sections.end()) { out() << "<hr />\n"; - out() << "<h2>" << protect((*s).name) << "</h2>\n"; + out() << "<h2>" << protectEnc((*s).name) << "</h2>\n"; NodeList::ConstIterator m = (*s).members.begin(); while (m != (*s).members.end()) { @@ -1619,7 +1630,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) } } -QString HtmlGenerator::fileExtension(const Node * /* node */) +QString HtmlGenerator::fileExtension(const Node * /* node */) const { return "html"; } @@ -1629,11 +1640,11 @@ void HtmlGenerator::generateHeader(const QString& title, CodeMarker *marker, bool mainPage) { - out() << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"; + out() << QString("<?xml version=\"1.0\" encoding=\"%1\"?>\n").arg(outputEncoding); out() << "<!DOCTYPE html\n" - " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n" - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"; + " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"; + out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage); QString shortVersion; if ((project != "Qtopia") && (project != "Qt Extended")) { @@ -1653,7 +1664,9 @@ void HtmlGenerator::generateHeader(const QString& title, } out() << "<head>\n" - " <title>" << shortVersion << protect(title) << "</title>\n"; + " <title>" << shortVersion << protectEnc(title) << "</title>\n"; + out() << QString("<meta http-equiv=\"Content-type\" content=\"text/html; charset=%1\" />").arg(outputEncoding); + if (!style.isEmpty()) out() << " <style type=\"text/css\">" << style << "</style>\n"; @@ -1662,8 +1675,8 @@ void HtmlGenerator::generateHeader(const QString& title, QMapIterator<QString, QString> i(metaMap); while (i.hasNext()) { i.next(); - out() << " <meta name=\"" << protect(i.key()) << "\" contents=\"" - << protect(i.value()) << "\" />\n"; + out() << " <meta name=\"" << protectEnc(i.key()) << "\" contents=\"" + << protectEnc(i.value()) << "\" />\n"; } } @@ -1687,9 +1700,9 @@ void HtmlGenerator::generateHeader(const QString& title, navigationLinks += "[Previous: <a href=\"" + anchorPair.first + "\">"; if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protect(anchorPair.second); + navigationLinks += protectEnc(anchorPair.second); else - navigationLinks += protect(linkPair.second); + navigationLinks += protectEnc(linkPair.second); navigationLinks += "</a>]\n"; } if (node->links().contains(Node::ContentsLink)) { @@ -1705,9 +1718,9 @@ void HtmlGenerator::generateHeader(const QString& title, navigationLinks += "[<a href=\"" + anchorPair.first + "\">"; if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protect(anchorPair.second); + navigationLinks += protectEnc(anchorPair.second); else - navigationLinks += protect(linkPair.second); + navigationLinks += protectEnc(linkPair.second); navigationLinks += "</a>]\n"; } if (node->links().contains(Node::NextLink)) { @@ -1723,9 +1736,9 @@ void HtmlGenerator::generateHeader(const QString& title, navigationLinks += "[Next: <a href=\"" + anchorPair.first + "\">"; if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty()) - navigationLinks += protect(anchorPair.second); + navigationLinks += protectEnc(anchorPair.second); else - navigationLinks += protect(linkPair.second); + navigationLinks += protectEnc(linkPair.second); navigationLinks += "</a>]\n"; } if (node->links().contains(Node::IndexLink)) { @@ -1776,7 +1789,7 @@ void HtmlGenerator::generateTitle(const QString& title, const Node *relative, CodeMarker *marker) { - out() << "<h1 class=\"title\">" << protect(title); + out() << "<h1 class=\"title\">" << protectEnc(title); if (!subTitle.isEmpty()) { out() << "<br />"; if (subTitleSize == SmallSubTitle) @@ -2014,18 +2027,18 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, out() << "<p><ul><li><a href=\"" << linkForNode(inner, 0) << "\">" - << protect(inner->name()) + << protectEnc(inner->name()) << " class reference</a></li></ul></p>\n"; for (i = 0; i < sections.size(); ++i) { - out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n"; + out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n"; generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary); } sections = marker->sections(inner, CodeMarker::Detailed, status); for (i = 0; i < sections.size(); ++i) { out() << "<hr />\n"; - out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n"; + out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n"; NodeList::ConstIterator m = sections.at(i).members.begin(); while (m != sections.at(i).members.end()) { @@ -2118,7 +2131,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, } else { out() << "<td>"; - out() << protect(node->doc().briefText().toString()); + out() << protectEnc(node->doc().briefText().toString()); out() << "</td>"; } out() << "</tr>\n"; @@ -2320,7 +2333,7 @@ void HtmlGenerator::generateCompactList(const Node *relative, << linkForNode(it.value(), relative) << "\">"; QStringList pieces = fullName(it.value(), relative, marker).split("::"); - out() << protect(pieces.last()); + out() << protectEnc(pieces.last()); out() << "</a>"; if (pieces.size() > 1) { out() << " ("; @@ -2362,7 +2375,7 @@ void HtmlGenerator::generateFunctionIndex(const Node *relative, #else out() << "<p>"; #endif - out() << protect(f.key()) << ":"; + out() << protectEnc(f.key()) << ":"; currentLetter = f.key()[0].unicode(); while (islower(currentLetter) && currentLetter >= nextLetter) { @@ -2416,7 +2429,7 @@ void HtmlGenerator::generateLegaleseList(const Node *relative, QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2455,7 +2468,7 @@ void HtmlGenerator::generateQmlItem(const Node *node, QString marked = marker->markedUpQmlItem(node,summary); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -2561,7 +2574,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m const FakeNode *groupNode = groupTitlesMap[groupTitle]; out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg( linkForNode(groupNode, relative)).arg( - protect(groupNode->fullTitle())); + protectEnc(groupNode->fullTitle())); if (fakeNodeMap[groupNode].count() == 0) continue; @@ -2573,7 +2586,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m if (title.startsWith("The ")) title.remove(0, 4); out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">" - << protect(title) << "</a></li>\n"; + << protectEnc(title) << "</a></li>\n"; } out() << "</ul>\n"; } @@ -2587,7 +2600,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m if (title.startsWith("The ")) title.remove(0, 4); out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">" - << protect(title) << "</a></li>\n"; + << protectEnc(title) << "</a></li>\n"; } out() << "</ul>\n"; } @@ -2750,7 +2763,7 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section, } out() << " inherited from <a href=\"" << fileName((*p).first) << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">" - << protect(marker->plainFullName((*p).first, relative)) + << protectEnc(marker->plainFullName((*p).first, relative)) << "</a></li>\n"; ++p; } @@ -2765,7 +2778,7 @@ void HtmlGenerator::generateSynopsis(const Node *node, QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -3034,7 +3047,7 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section, } out() << " inherited from <a href=\"" << fileName((*p).first) << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">" - << protect(marker->plainFullName((*p).first, relative)) + << protectEnc(marker->plainFullName((*p).first, relative)) << "</a></li>\n"; ++p; } @@ -3048,7 +3061,7 @@ void HtmlGenerator::generateSynopsis(const Node *node, QString marked = marker->markedUpSynopsis(node, relative, style); QRegExp templateTag("(<[^@>]*>)"); if (marked.indexOf(templateTag) != -1) { - QString contents = protect(marked.mid(templateTag.pos(1), + QString contents = protectEnc(marked.mid(templateTag.pos(1), templateTag.cap(1).length())); marked.replace(templateTag.pos(1), templateTag.cap(1).length(), contents); @@ -3246,7 +3259,7 @@ void HtmlGenerator::generateLink(const Atom* atom, if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) { // hack for C++: move () outside of link int k = funcLeftParen.pos(1); - out() << protect(atom->string().left(k)); + out() << protectEnc(atom->string().left(k)); if (link.isEmpty()) { if (showBrokenLinks) out() << "</i>"; @@ -3254,7 +3267,7 @@ void HtmlGenerator::generateLink(const Atom* atom, out() << "</a>"; } inLink = false; - out() << protect(atom->string().mid(k)); + out() << protectEnc(atom->string().mid(k)); } else if (marker->recognizeLanguage("Java")) { // hack for Java: remove () and use <tt> when appropriate bool func = atom->string().endsWith("()"); @@ -3262,13 +3275,13 @@ void HtmlGenerator::generateLink(const Atom* atom, if (tt) out() << "<tt>"; if (func) { - out() << protect(atom->string().left(atom->string().length() - 2)); + out() << protectEnc(atom->string().left(atom->string().length() - 2)); } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } out() << "</tt>"; } else { - out() << protect(atom->string()); + out() << protectEnc(atom->string()); } } @@ -3342,7 +3355,12 @@ QString HtmlGenerator::registerRef(const QString& ref) return clean; } -QString HtmlGenerator::protect(const QString& string) +QString HtmlGenerator::protectEnc(const QString &string) +{ + return protect(string, outputEncoding); +} + +QString HtmlGenerator::protect(const QString &string, const QString &outputEncoding) { #define APPEND(x) \ if (html.isEmpty()) { \ @@ -3365,7 +3383,7 @@ QString HtmlGenerator::protect(const QString& string) APPEND(">"); } else if (ch == QLatin1Char('"')) { APPEND("""); - } else if (ch.unicode() > 0x007F + } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F) || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/')) || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) { // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator @@ -3495,7 +3513,7 @@ QString HtmlGenerator::refForNode(const Node *node) ref = node->name() + "-var"; break; case Node::Target: - return protect(node->name()); + return protectEnc(node->name()); } return registerRef(ref); } @@ -3569,7 +3587,7 @@ void HtmlGenerator::generateFullName(const Node *apparentNode, } } out() << "\">"; - out() << protect(fullName(apparentNode, relative, marker)); + out() << protectEnc(fullName(apparentNode, relative, marker)); out() << "</a>"; } @@ -3630,12 +3648,12 @@ void HtmlGenerator::generateDetailedMember(const Node *node, else if (node->type() == Node::Enum) { const EnumNode *enume = static_cast<const EnumNode *>(node); if (enume->flagsType()) { - out() << "<p>The " << protect(enume->flagsType()->name()) + out() << "<p>The " << protectEnc(enume->flagsType()->name()) << " type is a typedef for " << "<a href=\"qflags.html\">QFlags</a><" - << protect(enume->name()) + << protectEnc(enume->name()) << ">. It stores an OR combination of " - << protect(enume->name()) + << protectEnc(enume->name()) << " values.</p>\n"; } } @@ -4352,4 +4370,128 @@ void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn, } } +/*! + Generate the <page> element for the given \a node using the \a writer. + Return true if a <page> element was written; otherwise return false. + */ +bool HtmlGenerator::generatePageElement(QXmlStreamWriter& writer, + const Node* node, + CodeMarker* marker) const +{ + if (node->pageType() == Node::NoPageType) + return false; + if (node->name().isEmpty()) + return true; + if (node->access() == Node::Private) + return false; + if (!node->isInnerNode()) + return false; + + QString title; + QString rawTitle; + QString fullTitle; + const InnerNode* inner = static_cast<const InnerNode*>(node); + + writer.writeStartElement("page"); + QXmlStreamAttributes attributes; + QString t; + t.setNum(id++); + switch (node->type()) { + case Node::Fake: + { + const FakeNode* fake = static_cast<const FakeNode*>(node); + title = fake->fullTitle(); + break; + } + case Node::Class: + { + title = node->name() + " Class Reference"; + break; + } + case Node::Namespace: + { + rawTitle = marker->plainName(inner); + fullTitle = marker->plainFullName(inner); + title = rawTitle + " Namespace Reference"; + break; + } + default: + title = node->name(); + break; + } + writer.writeAttribute("id",t); + writer.writeStartElement("pageWords"); + writer.writeCharacters(title); + if (!inner->pageKeywords().isEmpty()) { + const QStringList& w = inner->pageKeywords(); + for (int i = 0; i < w.size(); ++i) { + writer.writeCharacters(" "); + writer.writeCharacters(w.at(i).toLocal8Bit().constData()); + } + } + writer.writeEndElement(); + writer.writeStartElement("pageTitle"); + writer.writeCharacters(title); + writer.writeEndElement(); + writer.writeStartElement("pageUrl"); + writer.writeCharacters(PageGenerator::fileName(node)); + writer.writeEndElement(); + writer.writeStartElement("pageType"); + switch (node->pageType()) { + case Node::ApiPage: + writer.writeCharacters("APIPage"); + break; + case Node::ArticlePage: + writer.writeCharacters("Article"); + break; + case Node::ExamplePage: + writer.writeCharacters("Example"); + break; + default: + break; + } + writer.writeEndElement(); + writer.writeEndElement(); + return true; +} + +/*! + Traverse the tree recursively and generate the <keyword> + elements. + */ +void HtmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const +{ + if (generatePageElement(writer, node, marker)) { + + if (node->isInnerNode()) { + const InnerNode *inner = static_cast<const InnerNode *>(node); + + // Recurse to write an element for this child node and all its children. + foreach (const Node *child, inner->childNodes()) + generatePageElements(writer, child, marker); + } + } +} + +/*! + Outputs the file containing the index used for searching the html docs. + */ +void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const +{ + QFile file(fileName); + if (!file.open(QFile::WriteOnly | QFile::Text)) + return ; + + QXmlStreamWriter writer(&file); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement("qtPageIndex"); + + generatePageElements(writer, myTree->root(), marker); + + writer.writeEndElement(); // qtPageIndex + writer.writeEndDocument(); + file.close(); +} + #endif diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index 19a7c78..369d6c3 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -50,6 +50,7 @@ #include <qmap.h> #include <qregexp.h> +#include <QXmlStreamWriter> #include "codemarker.h" #include "config.h" @@ -104,7 +105,8 @@ class HtmlGenerator : public PageGenerator virtual QString format(); virtual void generateTree(const Tree *tree, CodeMarker *marker); - static QString protect(const QString& string); + QString protectEnc(const QString &string); + static QString protect(const QString &string, const QString &encoding = "ISO-8859-1"); static QString cleanRef(const QString& ref); static QString sinceTitle(int i) { return sinceTitles[i]; } @@ -115,7 +117,7 @@ class HtmlGenerator : public PageGenerator CodeMarker *marker); virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker); - virtual QString fileExtension(const Node *node); + virtual QString fileExtension(const Node *node) const; virtual QString refForNode(const Node *node); virtual QString linkForNode(const Node *node, const Node *relative); virtual QString refForAtom(Atom *atom, const Node *node); @@ -261,6 +263,14 @@ class HtmlGenerator : public PageGenerator const Node *relative, CodeMarker *marker); void endLink(); + bool generatePageElement(QXmlStreamWriter& writer, + const Node* node, + CodeMarker* marker) const; + void generatePageElements(QXmlStreamWriter& writer, + const Node* node, + CodeMarker* marker) const; + void generatePageIndex(const QString& fileName, + CodeMarker* marker) const; #if 0 NavigationBar currentNavigationBar; @@ -315,6 +325,7 @@ class HtmlGenerator : public PageGenerator NewSinceMaps newSinceMaps; static QString sinceTitles[]; NewClassMaps newClassMaps; + static int id; }; #define HTMLGENERATOR_ADDRESS "address" diff --git a/tools/qdoc3/javadocgenerator.cpp b/tools/qdoc3/javadocgenerator.cpp index 001bd27..eb9c1c9 100644 --- a/tools/qdoc3/javadocgenerator.cpp +++ b/tools/qdoc3/javadocgenerator.cpp @@ -145,7 +145,7 @@ void JavadocGenerator::generateTree(const Tree *tree, CodeMarker *marker) HtmlGenerator::generateTree(tree, marker); } -QString JavadocGenerator::fileExtension(const Node *node) +QString JavadocGenerator::fileExtension(const Node *node) const { if (node->type() == Node::Fake) { return "html"; diff --git a/tools/qdoc3/javadocgenerator.h b/tools/qdoc3/javadocgenerator.h index 73452cf..b485502 100644 --- a/tools/qdoc3/javadocgenerator.h +++ b/tools/qdoc3/javadocgenerator.h @@ -61,7 +61,7 @@ public: QString imageFileName(const Node *relative, const QString &fileBase); protected: - QString fileExtension(const Node *node); + QString fileExtension(const Node *node) const; void startText( const Node *relative, CodeMarker *marker ); void endText( const Node *relative, CodeMarker *marker ); int generateAtom( const Atom *atom, const Node *relative, CodeMarker *marker ); diff --git a/tools/qdoc3/linguistgenerator.cpp b/tools/qdoc3/linguistgenerator.cpp index d1bd22d..702f0fb 100644 --- a/tools/qdoc3/linguistgenerator.cpp +++ b/tools/qdoc3/linguistgenerator.cpp @@ -82,14 +82,14 @@ QString LinguistGenerator::format() return "Linguist"; } -QString LinguistGenerator::fileExtension(const Node * /* node */) +QString LinguistGenerator::fileExtension(const Node * /* node */) const { return "ts"; } void LinguistGenerator::generateClassLikeNode(const InnerNode *inner, CodeMarker *marker) { - out().setCodec("utf-8"); + out().setCodec("UTF-8"); QDomDocument document("TS"); QDomElement documentElement = document.createElement("TS"); @@ -100,7 +100,7 @@ void LinguistGenerator::generateClassLikeNode(const InnerNode *inner, CodeMarker documentElement.appendChild(element); QDomProcessingInstruction process = document.createProcessingInstruction( - "xml", QString("version=\"1.0\" encoding=\"%1\"").arg("utf-8")); + "xml", QString("version=\"1.0\" encoding=\"%1\"").arg("UTF-8")); document.appendChild(process); document.appendChild(documentElement); diff --git a/tools/qdoc3/linguistgenerator.h b/tools/qdoc3/linguistgenerator.h index f7f0606..979db02 100644 --- a/tools/qdoc3/linguistgenerator.h +++ b/tools/qdoc3/linguistgenerator.h @@ -70,7 +70,7 @@ protected: virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); virtual void generateFakeNode( const FakeNode *fake, CodeMarker *marker ); - virtual QString fileExtension(const Node *node); + virtual QString fileExtension(const Node *node) const; QList<QDomElement> generateIndexSections(QDomDocument &document, const Node *node, CodeMarker *marker); diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp index 3d0106d..57823fb 100644 --- a/tools/qdoc3/main.cpp +++ b/tools/qdoc3/main.cpp @@ -337,8 +337,9 @@ static void processQdocconfFile(const QString &fileName) Generate the XML tag file, if it was requested. */ QString tagFile = config.getString(CONFIG_TAGFILE); - if (!tagFile.isEmpty()) + if (!tagFile.isEmpty()) { tree->generateTagFile(tagFile); + } tree->setVersion(""); Generator::terminate(); diff --git a/tools/qdoc3/mangenerator.cpp b/tools/qdoc3/mangenerator.cpp index c3b7780..1e85b73 100644 --- a/tools/qdoc3/mangenerator.cpp +++ b/tools/qdoc3/mangenerator.cpp @@ -187,7 +187,7 @@ void ManGenerator::generateFakeNode( const FakeNode *fake, CodeMarker *marker ) generateFooter(); } -QString ManGenerator::fileExtension(const Node * /* node */) +QString ManGenerator::fileExtension(const Node * /* node */) const { return "3qt"; } diff --git a/tools/qdoc3/mangenerator.h b/tools/qdoc3/mangenerator.h index 284517e..0fca342 100644 --- a/tools/qdoc3/mangenerator.h +++ b/tools/qdoc3/mangenerator.h @@ -63,7 +63,7 @@ protected: CodeMarker *marker ); virtual void generateClassLikeNode(const InnerNode *node, CodeMarker *marker); virtual void generateFakeNode( const FakeNode *fake, CodeMarker *marker ); - virtual QString fileExtension(const Node *node); + virtual QString fileExtension(const Node *node) const; private: void generateHeader( const QString& name ); diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 9357671..ec574f8 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -92,8 +92,9 @@ void Node::setDoc(const Doc& doc, bool replace) Node::Node(Type type, InnerNode *parent, const QString& name) : typ(type), acc(Public), - sta(Commendable), saf(UnspecifiedSafeness), + pageTyp(NoPageType), + sta(Commendable), par(parent), rel(0), nam(name) @@ -103,6 +104,7 @@ Node::Node(Type type, InnerNode *parent, const QString& name) } /*! + Returns the node's URL. */ QString Node::url() const { @@ -110,13 +112,25 @@ QString Node::url() const } /*! + Sets the node's URL to \a url */ void Node::setUrl(const QString &url) { u = url; } +void Node::setPageType(const QString& t) +{ + if ((t == "API") || (t == "api")) + pageTyp = ApiPage; + else if (t == "article") + pageTyp = ArticlePage; + else if (t == "example") + pageTyp = ExamplePage; +} + /*! + Sets the pointer to the node that this node relates to. */ void Node::setRelates(InnerNode *pseudoParent) { @@ -401,7 +415,7 @@ void InnerNode::deleteChildren() } /*! - Returns true. + Returns true because this is an inner node. */ bool InnerNode::isInnerNode() const { @@ -455,6 +469,9 @@ const EnumNode *InnerNode::findEnumNodeForValue(const QString &enumValue) const } /*! + Returnds the sequence number of the function node \a func + in the list of overloaded functions for a class, such that + all the functions have the same name as the \a func. */ int InnerNode::overloadNumber(const FunctionNode *func) const { @@ -468,6 +485,8 @@ int InnerNode::overloadNumber(const FunctionNode *func) const } /*! + Returns the number of member functions of a class such that + the functions are all named \a funcName. */ int InnerNode::numOverloads(const QString& funcName) const { @@ -480,6 +499,8 @@ int InnerNode::numOverloads(const QString& funcName) const } /*! + Returns a node list containing all the member functions of + some class such that the functions overload the name \a funcName. */ NodeList InnerNode::overloads(const QString &funcName) const { @@ -499,6 +520,8 @@ NodeList InnerNode::overloads(const QString &funcName) const InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name) : Node(type, parent, name) { + if (type == Class) + setPageType(ApiPage); } /*! @@ -682,6 +705,8 @@ bool LeafNode::isInnerNode() const } /*! + Constructs a leaf node named \a name of the specified + \a type. The new leaf node becomes a child of \a parent. */ LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name) : Node(type, parent, name) @@ -693,10 +718,12 @@ LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name) */ /*! + Constructs a namespace node. */ NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name) : InnerNode(Namespace, parent, name) { + setPageType(ApiPage); } /*! @@ -704,11 +731,13 @@ NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name) */ /*! + Constructs a class node. A class node will generate an API page. */ ClassNode::ClassNode(InnerNode *parent, const QString& name) : InnerNode(Class, parent, name) { hidden = false; + setPageType(ApiPage); } /*! @@ -765,11 +794,28 @@ void ClassNode::fixBaseClasses() /*! The type of a FakeNode is Fake, and it has a \a subtype, - which specifies the type of FakeNode. + which specifies the type of FakeNode. The page type for + the page index is set here. */ FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype) : InnerNode(Fake, parent, name), sub(subtype) { + switch (subtype) { + case Module: + case Page: + case Group: + setPageType(ArticlePage); + break; + case QmlClass: + case QmlBasicType: + setPageType(ApiPage); + break; + case Example: + setPageType(ExamplePage); + break; + default: + break; + } } /*! diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index 077aeb8..021a052 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -137,6 +137,13 @@ class Node AppendixLink */ }; + enum PageType { + NoPageType, + ApiPage, + ArticlePage, + ExamplePage + }; + virtual ~Node(); void setAccess(Access access) { acc = access; } @@ -150,6 +157,8 @@ class Node void setLink(LinkType linkType, const QString &link, const QString &desc); void setUrl(const QString &url); void setTemplateStuff(const QString &templateStuff) { tpl = templateStuff; } + void setPageType(PageType t) { pageTyp = t; } + void setPageType(const QString& t); virtual bool isInnerNode() const = 0; virtual bool isReimp() const { return false; } @@ -173,6 +182,8 @@ class Node ThreadSafeness inheritedThreadSafeness() const; QString since() const { return sinc; } QString templateStuff() const { return tpl; } + PageType pageType() const { return pageTyp; } + virtual void addPageKeywords(const QString& ) { } void clearRelated() { rel = 0; } @@ -186,13 +197,15 @@ class Node #ifdef Q_WS_WIN Type typ; Access acc; - Status sta; ThreadSafeness saf; + PageType pageTyp; + Status sta; #else Type typ : 4; Access acc : 2; - Status sta : 3; ThreadSafeness saf : 2; + PageType pageTyp : 4; + Status sta : 3; #endif InnerNode *par; InnerNode *rel; @@ -244,6 +257,8 @@ class InnerNode : public Node QStringList primaryKeys(); QStringList secondaryKeys(); + const QStringList& pageKeywords() const { return pageKeywds; } + virtual void addPageKeywords(const QString& t) { pageKeywds << t; } protected: InnerNode(Type type, InnerNode *parent, const QString& name); @@ -256,6 +271,7 @@ class InnerNode : public Node void removeChild(Node *child); void removeRelated(Node *pseudoChild); + QStringList pageKeywds; QStringList inc; NodeList children; NodeList enumChildren; diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp index 07edcc4..2cad9ed 100644 --- a/tools/qdoc3/pagegenerator.cpp +++ b/tools/qdoc3/pagegenerator.cpp @@ -77,7 +77,7 @@ void PageGenerator::generateTree(const Tree *tree, CodeMarker *marker) generateInnerNode(tree->root(), marker); } -QString PageGenerator::fileBase(const Node *node) +QString PageGenerator::fileBase(const Node *node) const { if (node->relates()) node = node->relates(); @@ -153,7 +153,7 @@ QString PageGenerator::fileBase(const Node *node) return res; } -QString PageGenerator::fileName(const Node *node) +QString PageGenerator::fileName(const Node *node) const { if (!node->url().isEmpty()) return node->url(); @@ -177,7 +177,7 @@ void PageGenerator::beginSubPage(const Location& location, location.fatal(tr("Cannot open output file '%1'") .arg(outFile->fileName())); QTextStream *out = new QTextStream(outFile); - out->setCodec("ISO-8859-1"); + out->setCodec(outputCodec); outStreamStack.push(out); } diff --git a/tools/qdoc3/pagegenerator.h b/tools/qdoc3/pagegenerator.h index db24edd..7ab7e5e 100644 --- a/tools/qdoc3/pagegenerator.h +++ b/tools/qdoc3/pagegenerator.h @@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE +class QTextCodec; + class ClassNode; class InnerNode; class NamespaceNode; @@ -67,15 +69,19 @@ class PageGenerator : public Generator virtual void generateTree(const Tree *tree, CodeMarker *marker); protected: - virtual QString fileBase(const Node *node); - virtual QString fileExtension(const Node *node) = 0; - QString fileName(const Node *node); + virtual QString fileBase(const Node *node) const; + virtual QString fileExtension(const Node *node) const = 0; + QString fileName(const Node *node) const; QString outFileName(); void beginSubPage(const Location& location, const QString& fileName); void endSubPage(); virtual void generateInnerNode(const InnerNode *node, CodeMarker *marker); QTextStream& out(); + QString naturalLanguage; + QString outputEncoding; + QTextCodec *outputCodec; + private: QStack<QTextStream *> outStreamStack; }; diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro index 441bf39..7705692 100644 --- a/tools/qdoc3/qdoc3.pro +++ b/tools/qdoc3/qdoc3.pro @@ -105,5 +105,26 @@ SOURCES += apigenerator.cpp \ webxmlgenerator.cpp \ yyindent.cpp +### Documentation for qdoc3 ### + +win32:!win32-g++ { + unixstyle = false +} else :win32-g++:isEmpty(QMAKE_SH) { + unixstyle = false +} else { + unixstyle = true +} + +$$unixstyle { + QDOC = cd $$PWD/doc && $$[QT_INSTALL_BINS]/qdoc3 +} else { + QDOC = cd $$PWD/doc && $$[QT_INSTALL_BINS]/qdoc3.exe + QDOC = $$replace(QDOC, "/", "\\") +} + +docs.commands = $$QDOC qdoc-manual.qdocconf + +QMAKE_EXTRA_TARGETS += docs + target.path = $$[QT_INSTALL_BINS] INSTALLS += target diff --git a/tools/qdoc3/qsakernelparser.cpp b/tools/qdoc3/qsakernelparser.cpp index 9320a17..8f12eda 100644 --- a/tools/qdoc3/qsakernelparser.cpp +++ b/tools/qdoc3/qsakernelparser.cpp @@ -70,8 +70,8 @@ void QsaKernelParser::parseSourceFile( const Location& location, const QString& filePath, Tree * /* tree */ ) { - FILE *in = fopen( QFile::encodeName(filePath), "r" ); - if ( in == 0 ) { + QFile in(filePath); + if (!in.open(QIODevice::ReadOnly)) { location.error( tr("Cannot open QSA kernel file '%1'").arg(filePath) ); return; } @@ -171,7 +171,7 @@ void QsaKernelParser::parseSourceFile( const Location& location, readToken(); } } - fclose( in ); + in.close(); } void QsaKernelParser::doneParsingSourceFiles( Tree * /* tree */ ) diff --git a/tools/qdoc3/qscodeparser.cpp b/tools/qdoc3/qscodeparser.cpp index 8b3bc98..3b8bc1a 100644 --- a/tools/qdoc3/qscodeparser.cpp +++ b/tools/qdoc3/qscodeparser.cpp @@ -151,8 +151,8 @@ void QsCodeParser::parseHeaderFile(const Location& location, { qsTre = tree; - FILE *in = fopen(QFile::encodeName(filePath), "r"); - if (in == 0) { + QFile in(filePath); + if (!in.open(QIODevice::ReadOnly)) { location.error(tr("Cannot open Qt Script class list '%1'") .arg(filePath)); return; @@ -175,7 +175,7 @@ void QsCodeParser::parseHeaderFile(const Location& location, } tok = fileTokenizer.getToken(); } - fclose(in); + in.close(); } void QsCodeParser::parseSourceFile(const Location& location, diff --git a/tools/qdoc3/test/qt-api-only_zh_CN.qdocconf b/tools/qdoc3/test/qt-api-only_zh_CN.qdocconf new file mode 100644 index 0000000..c722ee8 --- /dev/null +++ b/tools/qdoc3/test/qt-api-only_zh_CN.qdocconf @@ -0,0 +1,30 @@ +include(qt-build-docs_zh_CN.qdocconf) + +# Ensures that the generated index contains a URL that can be used by the +# tools documentation (assistant.qdocconf, designer.qdocconf, linguist.qdocconf, +# qmake.qdocconf). + +url = ./ + +# Ensures that the documentation for the tools is not included in the generated +# .qhp file. + +qhp.Qt.excluded += $QT_SOURCE_TREE/doc/src/development/assistant-manual.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \ + $QT_SOURCE_TREE/doc/src/development/designer-manual.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/calculatorform.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/customwidgetplugin.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/taskmenuextension.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/containerextension.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/worldtimeclockbuilder.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/worldtimeclockplugin.qdoc \ + $QT_SOURCE_TREE/doc/src/internationalization/linguist-manual.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/hellotr.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/arrowpad.qdoc \ + $QT_SOURCE_TREE/doc/src/examples/trollprint.qdoc \ + $QT_SOURCE_TREE/doc/src/development/qmake-manual.qdoc + +outputdir = $QT_BUILD_TREE/doc-build/html-qt_zh_CN +tagfile = $QT_BUILD_TREE/doc-build/html-qt_zh_CN/qt.tags +base = file:$QT_BUILD_TREE/doc-build/html-qt_zh_CN diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index 6cc27b6..555e826 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -8,9 +8,13 @@ project = Qt description = Qt Reference Documentation url = http://qt.nokia.com/doc/4.7 -edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \ - QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \ - QtDesigner QtAssistant QAxContainer Phonon \ +sourceencoding = UTF-8 +outputencoding = UTF-8 +naturallanguage = en_US + +edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript \ + QtScriptTools QtSql QtSvg QtWebKit QtXml QtXmlPatterns \ + Qt3Support QtHelp QtDesigner QtAssistant QAxContainer Phonon \ QAxServer QtUiTools QtTest QtDBus edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest @@ -90,11 +94,13 @@ excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \ $QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \ $QT_SOURCE_TREE/src/3rdparty/wintab \ $QT_SOURCE_TREE/src/3rdparty/zlib \ - $QT_SOURCE_TREE/doc/src/snippets \ $QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \ $QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \ $QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \ - $QT_SOURCE_TREE/src/3rdparty/phonon/waveout + $QT_SOURCE_TREE/src/3rdparty/phonon/mmf \ + $QT_SOURCE_TREE/src/3rdparty/phonon/waveout \ + $QT_SOURCE_TREE/doc/src/snippets \ + $QT_SOURCE_TREE/doc/src/zh_CN sources.fileextensions = "*.cpp *.qdoc *.mm" examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml" diff --git a/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf new file mode 100644 index 0000000..18b72a1 --- /dev/null +++ b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf @@ -0,0 +1,92 @@ +include(compat.qdocconf) +include(macros.qdocconf) +include(qt-cpp-ignore.qdocconf) +include(qt-html-templates_zh_CN.qdocconf) +include(qt-defines.qdocconf) + +project = Qt +description = Qt Reference Documentation +url = http://qt.nokia.com/doc/zh_CN/4.7 + +sourceencoding = UTF-8 +outputencoding = UTF-8 +naturallanguage = zh-Hans + +indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index + +edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript \ + QtScriptTools QtSql QtSvg QtWebKit QtXml QtXmlPatterns \ + Qt3Support QtHelp QtDesigner QtAssistant QAxContainer Phonon \ + QAxServer QtUiTools QtTest QtDBus + +edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest +edition.DesktopLight.groups = -graphicsview-api + +qhp.projects = Qt + +qhp.Qt.file = qt.qhp +qhp.Qt.namespace = com.trolltech.qt.470 +qhp.Qt.virtualFolder = qdoc +qhp.Qt.title = 教程 +qhp.Qt.indexTitle = 教程 +qhp.Qt.selectors = fake:example + +qhp.Qt.filterAttributes = qt 4.7.0 qtrefdoc zh_CN +qhp.Qt.customFilters.Qt.name = Qt 4.7.0 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.0 + +# Files not referenced in any qdoc file (last four are needed by qtdemo) +# See also extraimages.HTML +qhp.Qt.extraFiles = classic.css \ + images/qt-logo.png \ + images/taskmenuextension-example.png \ + images/coloreditorfactoryimage.png \ + images/dynamiclayouts-example.png \ + images/stylesheet-coffee-plastique.png + +language = Cpp + +sourcedirs = $QT_SOURCE_TREE/doc/src/zh_CN + +excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \ + $QT_SOURCE_TREE/src/3rdparty/des \ + $QT_SOURCE_TREE/src/3rdparty/freetype \ + $QT_SOURCE_TREE/src/3rdparty/harfbuzz \ + $QT_SOURCE_TREE/src/3rdparty/kdebase \ + $QT_SOURCE_TREE/src/3rdparty/libjpeg \ + $QT_SOURCE_TREE/src/3rdparty/libmng \ + $QT_SOURCE_TREE/src/3rdparty/libpng \ + $QT_SOURCE_TREE/src/3rdparty/libtiff \ + $QT_SOURCE_TREE/src/3rdparty/md4 \ + $QT_SOURCE_TREE/src/3rdparty/md5 \ + $QT_SOURCE_TREE/src/3rdparty/patches \ + $QT_SOURCE_TREE/src/3rdparty/sha1 \ + $QT_SOURCE_TREE/src/3rdparty/sqlite \ + $QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore \ + $QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \ + $QT_SOURCE_TREE/src/3rdparty/wintab \ + $QT_SOURCE_TREE/src/3rdparty/zlib \ + $QT_SOURCE_TREE/doc/src/snippets \ + $QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \ + $QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/mmf \ + $QT_SOURCE_TREE/src/3rdparty/phonon/waveout + +sources.fileextensions = "*.cpp *.qdoc *.mm" +examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp" +examples.imageextensions = "*.png" + +exampledirs = $QT_SOURCE_TREE/doc/src \ + $QT_SOURCE_TREE/examples \ + $QT_SOURCE_TREE/examples/tutorials \ + $QT_SOURCE_TREE \ + $QT_SOURCE_TREE/qmake/examples \ + $QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/docs +imagedirs = $QT_SOURCE_TREE/doc/src/images \ + $QT_SOURCE_TREE/examples +outputdir = $QT_BUILD_TREE/doc/html_zh_CN +tagfile = $QT_BUILD_TREE/doc/html_zh_CN/qt.tags +base = file:$QT_BUILD_TREE/doc/html_zh_CN + +HTML.generatemacrefs = "true" diff --git a/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf b/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf new file mode 100644 index 0000000..5fb68cf --- /dev/null +++ b/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf @@ -0,0 +1,25 @@ +HTML.stylesheets = classic.css +HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \ + "<tr>\n" \ + "<td align=\"left\" valign=\"top\" width=\"32\">" \ + "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \ + "</td>\n" \ + "<td width=\"1\"> </td>" \ + "<td class=\"postheader\" valign=\"center\">" \ + "<a href=\"http://qt.nokia.com/doc/4.7/index.html\">" \ + "<font color=\"#004faf\">主页</font></a> ·" \ + " <a href=\"http://qt.nokia.com/doc/4.7/classes.html\">" \ + "<font color=\"#004faf\">所有类</font></a> ·" \ + " <a href=\"http://qt.nokia.com/doc/4.7/functions.html\">" \ + "<font color=\"#004faf\">所有函数</font></a> ·" \ + " <a href=\"http://qt.nokia.com/doc/4.7/overviews.html\">" \ + "<font color=\"#004faf\">简介</font></a>" \ + "</td>" \ + "</tr></table>" + +HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ + "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ + "<td width=\"40%\" align=\"left\">版权所有 © 2010 诺基亚公司和/或其子公司</td>\n" \ + "<td width=\"20%\" align=\"center\"><a href=\"trademarks.html\">商标</a></td>\n" \ + "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \ + "</tr></table></div></address>" diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf index b65ac56..f7757fb 100644 --- a/tools/qdoc3/test/qt.qdocconf +++ b/tools/qdoc3/test/qt.qdocconf @@ -10,9 +10,13 @@ version = %VERSION% description = Qt Reference Documentation url = http://qt.nokia.com/doc/4.7 +sourceencoding = UTF-8 +outputencoding = UTF-8 +naturallanguage = en_US + edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript \ QtScriptTools QtSql QtSvg QtWebKit QtXml QtXmlPatterns \ - Qt3Support QtHelp QtDesigner QAxContainer Phonon \ + Qt3Support QtHelp QtDesigner QtAssistant QAxContainer Phonon \ QAxServer QtUiTools QtTest QtDBus edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest edition.DesktopLight.groups = -graphicsview-api @@ -91,12 +95,13 @@ excludedirs = $QTDIR/src/3rdparty/clucene \ $QTDIR/src/3rdparty/webkit/WebCore \ $QTDIR/src/3rdparty/wintab \ $QTDIR/src/3rdparty/zlib \ - $QTDIR/doc/src/snippets \ $QTDIR/src/3rdparty/phonon/gstreamer \ $QTDIR/src/3rdparty/phonon/ds9 \ $QTDIR/src/3rdparty/phonon/qt7 \ $QTDIR/src/3rdparty/phonon/mmf \ - $QTDIR/src/3rdparty/phonon/waveout + $QTDIR/src/3rdparty/phonon/waveout \ + $QTDIR/doc/src/snippets \ + $QTDIR/doc/src/zh_CN sources.fileextensions = "*.cpp *.qdoc *.mm" examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml" diff --git a/tools/qdoc3/tokenizer.cpp b/tools/qdoc3/tokenizer.cpp index b391759..7c10de6 100644 --- a/tools/qdoc3/tokenizer.cpp +++ b/tools/qdoc3/tokenizer.cpp @@ -47,6 +47,7 @@ #include <qhash.h> #include <qregexp.h> #include <qstring.h> +#include <qtextcodec.h> #include <ctype.h> #include <string.h> @@ -97,6 +98,8 @@ static QRegExp *definedX = 0; static QRegExp *defines = 0; static QRegExp *falsehoods = 0; +static QTextCodec *sourceCodec = 0; + /* This function is a perfect hash function for the 37 keywords of C99 (with a hash table size of 512). It should perform well on our @@ -118,13 +121,10 @@ static void insertKwordIntoHash(const char *s, int number) kwordHashTable[k] = number; } -Tokenizer::Tokenizer(const Location& loc, FILE *in) +Tokenizer::Tokenizer(const Location& loc, QFile &in) { init(); - QFile file; - file.open(in, QIODevice::ReadOnly); - yyIn = file.readAll(); - file.close(); + yyIn = in.readAll(); yyPos = 0; start(loc); } @@ -483,6 +483,11 @@ void Tokenizer::initialize(const Config &config) { QString versionSym = config.getString(CONFIG_VERSIONSYM); + QString sourceEncoding = config.getString(CONFIG_SOURCEENCODING); + if (sourceEncoding.isEmpty()) + sourceEncoding = QLatin1String("ISO-8859-1"); + sourceCodec = QTextCodec::codecForName(sourceEncoding.toLocal8Bit()); + comment = new QRegExp("/(?:\\*.*\\*/|/.*\n|/[^\n]*$)"); comment->setMinimal(true); versionX = new QRegExp("$cannot possibly match^"); @@ -750,4 +755,14 @@ bool Tokenizer::isTrue(const QString &condition) return !falsehoods->exactMatch(t); } +QString Tokenizer::lexeme() const +{ + return sourceCodec->toUnicode(yyLex); +} + +QString Tokenizer::previousLexeme() const +{ + return sourceCodec->toUnicode(yyPrevLex); +} + QT_END_NAMESPACE diff --git a/tools/qdoc3/tokenizer.h b/tools/qdoc3/tokenizer.h index 519cffb..f55d2ef 100644 --- a/tools/qdoc3/tokenizer.h +++ b/tools/qdoc3/tokenizer.h @@ -46,11 +46,10 @@ #ifndef TOKENIZER_H #define TOKENIZER_H +#include <qfile.h> #include <qstack.h> #include <qstring.h> -#include <stdio.h> - #include "location.h" QT_BEGIN_NAMESPACE @@ -99,7 +98,7 @@ class Tokenizer { public: Tokenizer(const Location& loc, const QByteArray &in); - Tokenizer(const Location& loc, FILE *in); + Tokenizer(const Location& loc, QFile &file); ~Tokenizer(); @@ -108,8 +107,8 @@ class Tokenizer bool parsingFnOrMacro() const { return parsingMacro; } const Location &location() const { return yyTokLoc; } - QString previousLexeme() const { return QString(yyPrevLex); } - QString lexeme() const { return QString(yyLex); } + QString previousLexeme() const; + QString lexeme() const; QString version() const { return yyVersion; } int braceDepth() const { return yyBraceDepth; } int parenDepth() const { return yyParenDepth; } diff --git a/tools/qdoc3/webxmlgenerator.cpp b/tools/qdoc3/webxmlgenerator.cpp index a3c92ce..205bc8c 100644 --- a/tools/qdoc3/webxmlgenerator.cpp +++ b/tools/qdoc3/webxmlgenerator.cpp @@ -90,7 +90,7 @@ QString WebXMLGenerator::format() return "WebXML"; } -QString WebXMLGenerator::fileExtension(const Node * /* node */) +QString WebXMLGenerator::fileExtension(const Node * /* node */) const { return "xml"; } diff --git a/tools/qdoc3/webxmlgenerator.h b/tools/qdoc3/webxmlgenerator.h index 3145d50..cadf176 100644 --- a/tools/qdoc3/webxmlgenerator.h +++ b/tools/qdoc3/webxmlgenerator.h @@ -69,7 +69,7 @@ protected: const Node *relative, CodeMarker *marker ); virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker); - virtual QString fileExtension(const Node *node); + virtual QString fileExtension(const Node *node) const; virtual const Atom *addAtomElements(QXmlStreamWriter &writer, const Atom *atom, const Node *relative, CodeMarker *marker); diff --git a/tools/qmldebugger/standalone/canvasframerate.cpp b/tools/qmldebugger/standalone/canvasframerate.cpp index d956029..1bf7bf6 100644 --- a/tools/qmldebugger/standalone/canvasframerate.cpp +++ b/tools/qmldebugger/standalone/canvasframerate.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/canvasframerate.h b/tools/qmldebugger/standalone/canvasframerate.h index f8eec59..b31d607 100644 --- a/tools/qmldebugger/standalone/canvasframerate.h +++ b/tools/qmldebugger/standalone/canvasframerate.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/engine.cpp b/tools/qmldebugger/standalone/engine.cpp index 6cfd82b..894f97d 100644 --- a/tools/qmldebugger/standalone/engine.cpp +++ b/tools/qmldebugger/standalone/engine.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/engine.h b/tools/qmldebugger/standalone/engine.h index f4c4275..ee706624 100644 --- a/tools/qmldebugger/standalone/engine.h +++ b/tools/qmldebugger/standalone/engine.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/expressionquerywidget.cpp b/tools/qmldebugger/standalone/expressionquerywidget.cpp index cd59871..a068982 100644 --- a/tools/qmldebugger/standalone/expressionquerywidget.cpp +++ b/tools/qmldebugger/standalone/expressionquerywidget.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/expressionquerywidget.h b/tools/qmldebugger/standalone/expressionquerywidget.h index 8c224f8..5bba5c3 100644 --- a/tools/qmldebugger/standalone/expressionquerywidget.h +++ b/tools/qmldebugger/standalone/expressionquerywidget.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/main.cpp b/tools/qmldebugger/standalone/main.cpp index 715837e..9c075a1 100644 --- a/tools/qmldebugger/standalone/main.cpp +++ b/tools/qmldebugger/standalone/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/objectpropertiesview.cpp b/tools/qmldebugger/standalone/objectpropertiesview.cpp index 3a8d8c8..b6089c3 100644 --- a/tools/qmldebugger/standalone/objectpropertiesview.cpp +++ b/tools/qmldebugger/standalone/objectpropertiesview.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/objectpropertiesview.h b/tools/qmldebugger/standalone/objectpropertiesview.h index 43413dc..e524033 100644 --- a/tools/qmldebugger/standalone/objectpropertiesview.h +++ b/tools/qmldebugger/standalone/objectpropertiesview.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/objecttree.cpp b/tools/qmldebugger/standalone/objecttree.cpp index cf467f2..11857a6 100644 --- a/tools/qmldebugger/standalone/objecttree.cpp +++ b/tools/qmldebugger/standalone/objecttree.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/objecttree.h b/tools/qmldebugger/standalone/objecttree.h index c8d625c..31c257f 100644 --- a/tools/qmldebugger/standalone/objecttree.h +++ b/tools/qmldebugger/standalone/objecttree.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/qmldebugger.cpp b/tools/qmldebugger/standalone/qmldebugger.cpp index 4d86377..d713ce8 100644 --- a/tools/qmldebugger/standalone/qmldebugger.cpp +++ b/tools/qmldebugger/standalone/qmldebugger.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/qmldebugger.h b/tools/qmldebugger/standalone/qmldebugger.h index da95ef9..894cf0f 100644 --- a/tools/qmldebugger/standalone/qmldebugger.h +++ b/tools/qmldebugger/standalone/qmldebugger.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/watchtable.cpp b/tools/qmldebugger/standalone/watchtable.cpp index 6f9f99a..9d79a63 100644 --- a/tools/qmldebugger/standalone/watchtable.cpp +++ b/tools/qmldebugger/standalone/watchtable.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmldebugger/standalone/watchtable.h b/tools/qmldebugger/standalone/watchtable.h index fd12d3d..3dbba63 100644 --- a/tools/qmldebugger/standalone/watchtable.h +++ b/tools/qmldebugger/standalone/watchtable.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/deviceorientation.cpp b/tools/qmlviewer/deviceorientation.cpp index c507479..75ea48e 100644 --- a/tools/qmlviewer/deviceorientation.cpp +++ b/tools/qmlviewer/deviceorientation.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/deviceorientation.h b/tools/qmlviewer/deviceorientation.h index fa7758f..a2ed6ec 100644 --- a/tools/qmlviewer/deviceorientation.h +++ b/tools/qmlviewer/deviceorientation.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/deviceorientation_maemo.cpp b/tools/qmlviewer/deviceorientation_maemo.cpp index 9df9af4..fa2c6e5 100644 --- a/tools/qmlviewer/deviceorientation_maemo.cpp +++ b/tools/qmlviewer/deviceorientation_maemo.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp index b7a3f1a..18213ef 100644 --- a/tools/qmlviewer/main.cpp +++ b/tools/qmlviewer/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/proxysettings.cpp b/tools/qmlviewer/proxysettings.cpp index 52fa74f..b6caf6c 100644 --- a/tools/qmlviewer/proxysettings.cpp +++ b/tools/qmlviewer/proxysettings.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/proxysettings.h b/tools/qmlviewer/proxysettings.h index b2f3e25..41bd7dc 100644 --- a/tools/qmlviewer/proxysettings.h +++ b/tools/qmlviewer/proxysettings.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/qfxtester.cpp b/tools/qmlviewer/qfxtester.cpp index bd96545..1d5175d 100644 --- a/tools/qmlviewer/qfxtester.cpp +++ b/tools/qmlviewer/qfxtester.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/qfxtester.h b/tools/qmlviewer/qfxtester.h index 303ac3a..0e7108e 100644 --- a/tools/qmlviewer/qfxtester.h +++ b/tools/qmlviewer/qfxtester.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/qmlfolderlistmodel.cpp b/tools/qmlviewer/qmlfolderlistmodel.cpp index 35c672d..52caf13 100644 --- a/tools/qmlviewer/qmlfolderlistmodel.cpp +++ b/tools/qmlviewer/qmlfolderlistmodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/qmlfolderlistmodel.h b/tools/qmlviewer/qmlfolderlistmodel.h index 7357954..2063896 100644 --- a/tools/qmlviewer/qmlfolderlistmodel.h +++ b/tools/qmlviewer/qmlfolderlistmodel.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index 1566473..f4f04be 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -40,6 +40,10 @@ ****************************************************************************/ #include <qmlview.h> + +#ifdef hz +#undef hz +#endif #include "ui_recopts.h" #include "qmlviewer.h" diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h index 6b05584..958210e 100644 --- a/tools/qmlviewer/qmlviewer.h +++ b/tools/qmlviewer/qmlviewer.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** |