src/multimedia/qmediaimageviewer.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qmediaimageviewer.h"
       
    43 
       
    44 #include "qmediaobject_p.h"
       
    45 #include "qmediaimageviewerservice_p.h"
       
    46 
       
    47 #include <qmediaplaylist.h>
       
    48 #include <qmediaplaylistsourcecontrol.h>
       
    49 #include <qmediacontent.h>
       
    50 #include <qmediaresource.h>
       
    51 
       
    52 #include <QtCore/qcoreevent.h>
       
    53 #include <QtCore/qtextstream.h>
       
    54 #include <QtCore/qdatetime.h>
       
    55 
       
    56 QT_BEGIN_NAMESPACE
       
    57 
       
    58 class QMediaImageViewerPrivate : public QMediaObjectPrivate
       
    59 {
       
    60     Q_DECLARE_NON_CONST_PUBLIC(QMediaImageViewer)
       
    61 public:
       
    62     QMediaImageViewerPrivate():
       
    63         viewerControl(0), playlist(0),
       
    64         state(QMediaImageViewer::StoppedState), timeout(3000), pauseTime(0)
       
    65     {
       
    66     }
       
    67 
       
    68     void _q_mediaStatusChanged(QMediaImageViewer::MediaStatus status);
       
    69     void _q_playlistMediaChanged(const QMediaContent &content);
       
    70     void _q_playlistDestroyed();
       
    71 
       
    72     QMediaImageViewerControl *viewerControl;
       
    73     QMediaPlaylist *playlist;
       
    74     QMediaImageViewer::State state;
       
    75     int timeout;
       
    76     int pauseTime;
       
    77     QTime time;
       
    78     QBasicTimer timer;
       
    79     QMediaContent media;
       
    80 };
       
    81 
       
    82 void QMediaImageViewerPrivate::_q_mediaStatusChanged(QMediaImageViewer::MediaStatus status)
       
    83 {
       
    84     switch (status) {
       
    85     case QMediaImageViewer::NoMedia:
       
    86     case QMediaImageViewer::LoadingMedia:
       
    87         emit q_func()->mediaStatusChanged(status);
       
    88         break;
       
    89     case QMediaImageViewer::LoadedMedia:
       
    90         if (state == QMediaImageViewer::PlayingState) {
       
    91             time.start();
       
    92             timer.start(qMax(0, timeout), q_func());
       
    93             q_func()->addPropertyWatch("elapsedTime");
       
    94         }
       
    95         emit q_func()->mediaStatusChanged(status);
       
    96         emit q_func()->elapsedTimeChanged(0);
       
    97         break;
       
    98     case QMediaImageViewer::InvalidMedia:
       
    99         emit q_func()->mediaStatusChanged(status);
       
   100 
       
   101         if (state == QMediaImageViewer::PlayingState) {
       
   102             playlist->next();
       
   103             if (playlist->currentIndex() < 0)
       
   104                 emit q_func()->stateChanged(state = QMediaImageViewer::StoppedState);
       
   105         }
       
   106         break;
       
   107     }
       
   108 }
       
   109 
       
   110 void QMediaImageViewerPrivate::_q_playlistMediaChanged(const QMediaContent &content)
       
   111 {
       
   112     media = content;
       
   113     pauseTime = 0;
       
   114 
       
   115     viewerControl->showMedia(media);
       
   116 
       
   117     emit q_func()->mediaChanged(media);
       
   118 }
       
   119 
       
   120 void QMediaImageViewerPrivate::_q_playlistDestroyed()
       
   121 {
       
   122     playlist = 0;
       
   123     timer.stop();
       
   124 
       
   125     if (state != QMediaImageViewer::StoppedState)
       
   126         emit q_func()->stateChanged(state = QMediaImageViewer::StoppedState);
       
   127 
       
   128     q_func()->setMedia(QMediaContent());
       
   129 }
       
   130 
       
   131 /*!
       
   132     \class QMediaImageViewer
       
   133     \brief The QMediaImageViewer class provides a means of viewing image media.
       
   134     \ingroup multimedia
       
   135     \preliminary
       
   136 
       
   137     QMediaImageViewer is used together with a media display object such as
       
   138     QVideoWidget to present an image.  A display object is attached to the
       
   139     image viewer by means of the bind function.
       
   140 
       
   141     \code
       
   142     viewer = new QMediaImageViewer(this);
       
   143 
       
   144     display = new QVideoWidget;
       
   145     viewer->bind(display);
       
   146     display->show();
       
   147     \endcode
       
   148 
       
   149     QMediaImageViewer can be paired with a QMediaPlaylist to create a slide
       
   150     show of images. Constructing a QMediaPlaylist with a pointer to an
       
   151     instance of QMediaImageViewer will attach it to the image viewer;
       
   152     changing the playlist's selection will then change the media displayed
       
   153     by the image viewer.  With a playlist attached QMediaImageViewer's
       
   154     play(), pause(), and stop() slots can be control the progression of the
       
   155     playlist.  The \l timeout property determines how long an image is
       
   156     displayed for before progressing to the next in the playlist, and the
       
   157     \l elapsedTime property holds how the duration the current image has
       
   158     been displayed for.
       
   159 
       
   160     \code
       
   161     playlist = new QMediaPlaylist(this);
       
   162     playlist->setMediaObject(viewer);
       
   163     playlist->setPlaybackMode(QMediaPlaylist::Loop);
       
   164     playlist->addMedia(image1);
       
   165     playlist->addMedia(image2);
       
   166     playlist->addMedia(image3);
       
   167 
       
   168     viewer->setTimeout(5000);
       
   169     viewer->play();
       
   170     \endcode
       
   171 */
       
   172 
       
   173 /*!
       
   174     \enum QMediaImageViewer::State
       
   175 
       
   176     Enumerates the possible control states an image viewer may be in.  The
       
   177     control state of an image viewer determines whether the image viewer is
       
   178     automatically progressing through images in an attached playlist.
       
   179 
       
   180     \value StoppedState The image viewer is stopped, and will not automatically move to the next
       
   181     image.  The \l elapsedTime is fixed at 0.
       
   182     \value PlayingState The slide show is playing, and will move to the next image when the
       
   183     \l elapsedTime reaches the \l timeout.  The \l elapsedTime is being incremented.
       
   184     \value PausedState The image viewer is paused, and will not automatically move the to next
       
   185     image.  The \l elapsedTime is fixed at the time the image viewer was paused.
       
   186 */
       
   187 
       
   188 /*!
       
   189     \enum QMediaImageViewer::MediaStatus
       
   190 
       
   191     Enumerates the status of an image viewer's current media.
       
   192 
       
   193     \value NoMedia  There is no current media.
       
   194     \value LoadingMedia The image viewer is loading the current media.
       
   195     \value LoadedMedia The image viewer has loaded the current media.
       
   196     \value InvalidMedia The current media cannot be loaded.
       
   197 */
       
   198 
       
   199 /*!
       
   200     Constructs a new image viewer with the given \a parent.
       
   201 */
       
   202 QMediaImageViewer::QMediaImageViewer(QObject *parent)
       
   203     : QMediaObject(*new QMediaImageViewerPrivate, parent, new QMediaImageViewerService)
       
   204 {
       
   205     Q_D(QMediaImageViewer);
       
   206 
       
   207     d->viewerControl = qobject_cast<QMediaImageViewerControl*>(
       
   208             d->service->requestControl(QMediaImageViewerControl_iid));
       
   209 
       
   210     connect(d->viewerControl, SIGNAL(mediaStatusChanged(QMediaImageViewer::MediaStatus)),
       
   211             this, SLOT(_q_mediaStatusChanged(QMediaImageViewer::MediaStatus)));
       
   212 }
       
   213 
       
   214 /*!
       
   215     Destroys an image viewer.
       
   216 */
       
   217 QMediaImageViewer::~QMediaImageViewer()
       
   218 {
       
   219     Q_D(QMediaImageViewer);
       
   220 
       
   221     delete d->service;
       
   222 }
       
   223 
       
   224 /*!
       
   225     \property QMediaImageViewer::state
       
   226     \brief the playlist control state of a slide show.
       
   227 */
       
   228 
       
   229 QMediaImageViewer::State QMediaImageViewer::state() const
       
   230 {
       
   231     return d_func()->state;
       
   232 }
       
   233 
       
   234 /*!
       
   235     \fn QMediaImageViewer::stateChanged(QMediaImageViewer::State state)
       
   236 
       
   237     Signals that the playlist control \a state of an image viewer has changed.
       
   238 */
       
   239 
       
   240 /*!
       
   241     \property QMediaImageViewer::mediaStatus
       
   242     \brief the status of the current media.
       
   243 */
       
   244 
       
   245 QMediaImageViewer::MediaStatus QMediaImageViewer::mediaStatus() const
       
   246 {
       
   247     return d_func()->viewerControl->mediaStatus();
       
   248 }
       
   249 
       
   250 /*!
       
   251     \fn QMediaImageViewer::mediaStatusChanged(QMediaImageViewer::MediaStatus status)
       
   252 
       
   253     Signals the the \a status of the current media has changed.
       
   254 */
       
   255 
       
   256 /*!
       
   257     \property QMediaImageViewer::media
       
   258     \brief the media an image viewer is presenting.
       
   259 */
       
   260 
       
   261 QMediaContent QMediaImageViewer::media() const
       
   262 {
       
   263     Q_D(const QMediaImageViewer);
       
   264 
       
   265     return d->media;
       
   266 }
       
   267 
       
   268 void QMediaImageViewer::setMedia(const QMediaContent &media)
       
   269 {
       
   270     Q_D(QMediaImageViewer);
       
   271 
       
   272     if (d->playlist && d->playlist->currentMedia() != media) {
       
   273         disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
       
   274                    this, SLOT(_q_playlistMediaChanged(QMediaContent)));
       
   275         disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   276 
       
   277         d->playlist = 0;
       
   278     }
       
   279 
       
   280     d->media = media;
       
   281 
       
   282     if (d->timer.isActive()) {
       
   283         d->pauseTime = 0;
       
   284         d->timer.stop();
       
   285         removePropertyWatch("elapsedTime");
       
   286         emit elapsedTimeChanged(0);
       
   287     }
       
   288 
       
   289     if (d->state != QMediaImageViewer::StoppedState)
       
   290         emit stateChanged(d->state = QMediaImageViewer::StoppedState);
       
   291 
       
   292     d->viewerControl->showMedia(d->media);
       
   293 
       
   294     emit mediaChanged(d->media);
       
   295 }
       
   296 
       
   297 /*!
       
   298   Use \a playlist as the source of images to be displayed in the viewer.
       
   299 */
       
   300 void QMediaImageViewer::setPlaylist(QMediaPlaylist *playlist)
       
   301 {
       
   302     Q_D(QMediaImageViewer);
       
   303 
       
   304     if (d->playlist) {
       
   305         disconnect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
       
   306                    this, SLOT(_q_playlistMediaChanged(QMediaContent)));
       
   307         disconnect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   308 
       
   309         QMediaObject::unbind(playlist);
       
   310     }
       
   311 
       
   312     d->playlist = playlist;
       
   313 
       
   314     if (d->playlist) {
       
   315         connect(d->playlist, SIGNAL(currentMediaChanged(QMediaContent)),
       
   316                 this, SLOT(_q_playlistMediaChanged(QMediaContent)));
       
   317         connect(d->playlist, SIGNAL(destroyed()), this, SLOT(_q_playlistDestroyed()));
       
   318 
       
   319         QMediaObject::bind(d->playlist);
       
   320 
       
   321         setMedia(d->playlist->currentMedia());
       
   322     } else {
       
   323         setMedia(QMediaContent());
       
   324     }
       
   325 }
       
   326 
       
   327 /*!
       
   328   Returns the current playlist, or 0 if none.
       
   329 */
       
   330 QMediaPlaylist *QMediaImageViewer::playlist() const
       
   331 {
       
   332     return d_func()->playlist;
       
   333 }
       
   334 
       
   335 /*!
       
   336     \fn QMediaImageViewer::mediaChanged(const QMediaContent &media)
       
   337 
       
   338     Signals that the \a media an image viewer is presenting has changed.
       
   339 */
       
   340 
       
   341 /*!
       
   342     \property QMediaImageViewer::timeout
       
   343     \brief the amount of time in milliseconds an image is displayed for before moving to the next
       
   344     image.
       
   345 
       
   346     The timeout only applies if the image viewer has a playlist attached and is in the PlayingState.
       
   347 */
       
   348 
       
   349 int QMediaImageViewer::timeout() const
       
   350 {
       
   351     return d_func()->timeout;
       
   352 }
       
   353 
       
   354 void QMediaImageViewer::setTimeout(int timeout)
       
   355 {
       
   356     Q_D(QMediaImageViewer);
       
   357 
       
   358     d->timeout = qMax(0, timeout);
       
   359 
       
   360     if (d->timer.isActive())
       
   361         d->timer.start(qMax(0, d->timeout - d->pauseTime - d->time.elapsed()), this);
       
   362 }
       
   363 
       
   364 /*!
       
   365     \property QMediaImageViewer::elapsedTime
       
   366     \brief the amount of time in milliseconds that has elapsed since the current image was loaded.
       
   367 
       
   368     The elapsed time only increases while the image viewer is in the PlayingState.  If stopped the
       
   369     elapsed time will be reset to 0.
       
   370 */
       
   371 
       
   372 int QMediaImageViewer::elapsedTime() const
       
   373 {
       
   374     Q_D(const QMediaImageViewer);
       
   375 
       
   376     int elapsedTime = d->pauseTime;
       
   377 
       
   378     if (d->timer.isActive())
       
   379         elapsedTime += d->time.elapsed();
       
   380 
       
   381     return elapsedTime;
       
   382 }
       
   383 
       
   384 /*!
       
   385     \fn QMediaImageViewer::elapsedTimeChanged(int time)
       
   386 
       
   387     Signals that the amount of \a time in milliseconds since the current
       
   388     image was loaded has changed.
       
   389 
       
   390     This signal is emitted at a regular interval when the image viewer is
       
   391     in the PlayingState and an image is loaded.  The notification interval
       
   392     is controlled by the QMediaObject::notifyInterval property.
       
   393 
       
   394     \sa timeout, QMediaObject::notifyInterval
       
   395 */
       
   396 
       
   397 /*!
       
   398     \internal
       
   399 */
       
   400 bool QMediaImageViewer::bind(QObject *object)
       
   401 {
       
   402     if (QMediaPlaylist *playlist = qobject_cast<QMediaPlaylist *>(object)) {
       
   403         setPlaylist(playlist);
       
   404 
       
   405         return true;
       
   406     } else {
       
   407         return QMediaObject::bind(object);
       
   408     }
       
   409 }
       
   410 
       
   411 /*!
       
   412      \internal
       
   413  */
       
   414 void QMediaImageViewer::unbind(QObject *object)
       
   415 {
       
   416     if (object == d_func()->playlist)
       
   417         setPlaylist(0);
       
   418     else
       
   419         QMediaObject::unbind(object);
       
   420 }
       
   421 
       
   422 /*!
       
   423     Starts a slide show.
       
   424 
       
   425     If the playlist has no current media this will start at the beginning of the playlist, otherwise
       
   426     it will resume from the current media.
       
   427 
       
   428     If no playlist is attached to an image viewer this will do nothing.
       
   429 */
       
   430 void QMediaImageViewer::play()
       
   431 {
       
   432     Q_D(QMediaImageViewer);
       
   433 
       
   434     if (d->playlist && d->playlist->mediaCount() > 0 && d->state != PlayingState) {
       
   435         d->state = PlayingState;
       
   436 
       
   437         switch (d->viewerControl->mediaStatus()) {
       
   438         case NoMedia:
       
   439         case InvalidMedia:
       
   440             d->playlist->next();
       
   441             if (d->playlist->currentIndex() < 0)
       
   442                 d->state = StoppedState;
       
   443             break;
       
   444         case LoadingMedia:
       
   445             break;
       
   446         case LoadedMedia:
       
   447             d->time.start();
       
   448             d->timer.start(qMax(0, d->timeout - d->pauseTime), this);
       
   449             break;
       
   450         }
       
   451 
       
   452         if (d->state == PlayingState)
       
   453             emit stateChanged(d->state);
       
   454     }
       
   455 }
       
   456 
       
   457 /*!
       
   458     Pauses a slide show.
       
   459 
       
   460     The current media and elapsed time are retained.  If resumed, the current image will be
       
   461     displayed for the remainder of the time out period before the next image is loaded.
       
   462 */
       
   463 void QMediaImageViewer::pause()
       
   464 {
       
   465     Q_D(QMediaImageViewer);
       
   466 
       
   467     if (d->state == PlayingState) {
       
   468         if (d->viewerControl->mediaStatus() == LoadedMedia) {
       
   469             d->pauseTime += d->timeout - d->time.elapsed();
       
   470             d->timer.stop();
       
   471             removePropertyWatch("elapsedTime");
       
   472         }
       
   473 
       
   474         emit stateChanged(d->state = PausedState);
       
   475         emit elapsedTimeChanged(d->pauseTime);
       
   476     }
       
   477 }
       
   478 
       
   479 /*!
       
   480     Stops a slide show.
       
   481 
       
   482     The current media is retained, but the elapsed time is discarded.  If resumed, the current
       
   483     image will be displayed for the full time out period before the next image is loaded.
       
   484 */
       
   485 void QMediaImageViewer::stop()
       
   486 {
       
   487     Q_D(QMediaImageViewer);
       
   488 
       
   489     switch (d->state) {
       
   490     case PlayingState:
       
   491         d->timer.stop();
       
   492         removePropertyWatch("elapsedTime");
       
   493         // fall through.
       
   494     case PausedState:
       
   495         d->pauseTime = 0;
       
   496         d->state = QMediaImageViewer::StoppedState;
       
   497 
       
   498         emit stateChanged(d->state);
       
   499         emit elapsedTimeChanged(0);
       
   500         break;
       
   501     case StoppedState:
       
   502         break;
       
   503     }
       
   504 }
       
   505 
       
   506 /*!
       
   507     \reimp
       
   508 
       
   509     \internal
       
   510 */
       
   511 void QMediaImageViewer::timerEvent(QTimerEvent *event)
       
   512 {
       
   513     Q_D(QMediaImageViewer);
       
   514 
       
   515     if (event->timerId() == d->timer.timerId()) {
       
   516         d->timer.stop();
       
   517         removePropertyWatch("elapsedTime");
       
   518         emit elapsedTimeChanged(d->pauseTime = d->timeout);
       
   519 
       
   520         d->playlist->next();
       
   521 
       
   522         if (d->playlist->currentIndex() < 0) {
       
   523             d->pauseTime = 0;
       
   524             emit stateChanged(d->state = StoppedState);
       
   525             emit elapsedTimeChanged(0);
       
   526         }
       
   527     } else {
       
   528         QMediaObject::timerEvent(event);
       
   529     }
       
   530 }
       
   531 
       
   532 #include "moc_qmediaimageviewer.cpp"
       
   533 QT_END_NAMESPACE
       
   534