Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/modules/gui/qt/playlist/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 25 kB image not shown  

Quelle  playlist_controller.cpp   Sprache: C

 

/*****************************************************************************
 * Copyright (C) 2019 VLC authors and VideoLAN
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * ( at your option ) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "playlist_controller.hpp"
#include "playlist_controller_p.hpp"
#include <vlc_player.h>
#include <vlc_url.h>
#include "util/shared_input_item.hpp"
#include <algorithm>
#include <QVariant>
#include <QDesktopServices>

namespace vlc {
  namespace playlist {

static QVector<PlaylistItem> toVec(vlc_playlist_item_t *const items[],
                                   size_t len)
{
    QVector<PlaylistItem> vec;
    for (size_t i = 0; i < len; ++i)
        vec.push_back(items[i]);
    return vec;
}

template <typename RAW, typename WRAPPER>
static QVector<RAW> toRaw(const QVector<WRAPPER> &items)
{
    QVector<RAW> vec;
    int count = items.size();
    vec.reserve(count);
    for (int i = 0; i < count; ++i)
        vec.push_back(items[i].raw());
    return vec;
}

QVector<Media> toMediaList(const QVariantList &sources)
{
    QVector<Media> mediaList;
    std::transform(sources.begin(), sources.end(),
                   std::back_inserter(mediaList), [](const QVariant& value) {
        const auto typeId = value.typeId();
        if ((typeId == QMetaType::QUrl) || (typeId == QMetaType::QString))
        {
            std::optional<QString> input;
            QUrl mrl;
            if (typeId == QMetaType::QString)
            {
                input = value.value<QString>().trimmed(); // akin to `UrlValidator::fixup()`
                mrl = *input; // plain text to QUrl, tolerant mode
            }
            else if (typeId == QMetaType::QUrl)
            {
                mrl = value.value<QUrl>(); // use the provided QUrl as is
            }
            else
                Q_UNREACHABLE();

            if (!mrl.isValid())
                return Media(); // the input is broken (beyond repair of tolerant mode if plain text)

            if ((typeId == QMetaType::QString) && mrl.scheme().isEmpty())
            {
                // Assume input is a path (only if the input is plain text):
                assert(input);
                mrl = QString::fromUtf8(vlc::wrap_cptr(vlc_path2uri(input->toUtf8().cbegin(), nullptr)).get()); // tolerant mode

                if (!mrl.isValid())
                    return Media();
            }

            if (mrl.scheme().isEmpty()) // akin to `UrlValidator::validate()`
                return Media();

            return Media(mrl.toString(QUrl::FullyEncoded), mrl.fileName());
        }
        else if (value.canConvert<SharedInputItem>())
        {
            return Media(value.value<SharedInputItem>().get());
        }
        else if (value.canConvert<PlaylistItem>())
        {
            return Media(value.value<PlaylistItem>().inputItem());
        }
        return Media{};
    });

    // Clear invalid media:
    mediaList.removeAll(Media());

    return mediaList;
}


extern "C" { // for C callbacks

static void
on_playlist_items_reset(vlc_playlist_t *playlist,
                        vlc_playlist_item_t *const items[],
                        size_t len, void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    auto vec = toVec(items, len);
    size_t totalCount = vlc_playlist_Count(playlist);

    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        PlaylistController* q = that->q_func();
        bool empty = vec.size() == 0;
        if (that->m_empty != empty)
        {
            that->m_empty = empty;
            emit q->isEmptyChanged(empty);
        }
        emit q->itemsReset(vec);

        if (totalCount != that->m_count)
        {
            that->m_count = totalCount;
            emit q->countChanged(totalCount);
        }
    });
}

static void
on_playlist_items_added(vlc_playlist_t *playlist, size_t index,
                        vlc_playlist_item_t *const items[], size_t len,
                        void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    auto vec = toVec(items, len);
    size_t totalCount = vlc_playlist_Count(playlist);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        PlaylistController* q = that->q_func();
        if (that->m_empty && vec.size() > 0)
        {
            that->m_empty = false;
            emit q->isEmptyChanged(that->m_empty);
        }
        emit q->itemsAdded(index, vec);

        if (totalCount != that->m_count)
        {
            that->m_count = totalCount;
            emit q->countChanged(totalCount);
        }
    });
}

static void
on_playlist_items_moved(vlc_playlist_t *playlist, size_t index, size_t count,
                        size_t target, void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        emit that->q_func()->itemsMoved(index, count, target);
    });
}

static void
on_playlist_items_removed(vlc_playlist_t *playlist, size_t index, size_t count,
                          void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    size_t totalCount = vlc_playlist_Count(playlist);
    bool empty = (totalCount == 0);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        PlaylistController* q = that->q_func();
        if (that->m_empty != empty)
        {
            that->m_empty = empty;
            emit q->isEmptyChanged(empty);
        }
        emit q->itemsRemoved(index, count);
        if (totalCount != that->m_count)
        {
            that->m_count = totalCount;
            emit q->countChanged(totalCount);
        }
    });
}

static void
on_playlist_items_updated(vlc_playlist_t *playlist, size_t index,
                          vlc_playlist_item_t *const items[], size_t len,
                          void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    auto vec = toVec(items, len);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        emit that->q_func()->itemsUpdated(index, vec);
        if (that->m_currentIndex != -1) {
            size_t currentIndex = static_cast<size_t>(that->m_currentIndex);
            if (currentIndex >= index && currentIndex < index + len)
            {
                const auto newCurrentItem = vec[currentIndex - index];
                const auto currentItem = that->m_currentItem.raw();
                // Even if vlc_playlist_item_t is the same, assign unconditionally to
                // update the data:
                that->m_currentItem = newCurrentItem;
                if (currentItem != newCurrentItem.raw())
                    emit that->q_func()->currentItemChanged();
            }
        }
    });
}

static void
on_playlist_playback_repeat_changed(vlc_playlist_t *playlist,
                                    enum vlc_playlist_playback_repeat repeat,
                                    void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        PlaylistController::PlaybackRepeat repeatMode = static_cast<PlaylistController::PlaybackRepeat>(repeat);
        if (that->m_repeat != repeatMode )
        {
            that->m_repeat = repeatMode;
            emit that->q_func()->repeatModeChanged(repeatMode);
        }
    });
}

static void
on_playlist_playback_order_changed(vlc_playlist_t *playlist,
                                   enum vlc_playlist_playback_order order,
                                   void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        bool isRandom = order == VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM;
        if (that->m_random != isRandom)
        {
            that->m_random = isRandom;
            emit that->q_func()->randomChanged(isRandom);
        }
    });
}

static void
on_playlist_current_index_changed(vlc_playlist_t *playlist, ssize_t index,
                                 void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);


    vlc_playlist_item_t* playlistItem = nullptr;
    if (index >= 0)
        playlistItem = vlc_playlist_Get(playlist, index);
    PlaylistItem newItem{ playlistItem };

    that->callAsync([=](){
        PlaylistController* q = that->q_func();

        if (that->m_playlist != playlist)
            return;
        if (that->m_currentIndex != index)
        {
            that->m_currentIndex = index;
            emit q->currentIndexChanged(that->m_currentIndex);
        }

        // Unlike items updated callback, we should not need to unconditionally
        // set the current item to update data because this is only a current
        // index changed callback.
        if (that->m_currentItem.raw() != newItem.raw())
        {
            that->m_currentItem = newItem;
            emit q->currentItemChanged();
        }
    });
}

static void
on_playlist_has_prev_changed(vlc_playlist_t *playlist, bool has_prev,
                             void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        if (that->m_hasPrev != has_prev)
        {
            that->m_hasPrev = has_prev;
            emit that->q_func()->hasPrevChanged(has_prev);
        }
    });
}

static void
on_playlist_has_next_changed(vlc_playlist_t *playlist, bool has_next,
                             void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    that->callAsync([=](){
        if (that->m_playlist != playlist)
            return;
        if (that->m_hasNext != has_next)
        {
            that->m_hasNext = has_next;
            emit that->q_func()->hasNextChanged(has_next);
        }
    });
}

static void
on_media_stopped_action_changed(vlc_playlist_t *playlist,
                          enum vlc_playlist_media_stopped_action new_action,
                          void *userdata)
{
    PlaylistControllerPrivate *that = static_cast<PlaylistControllerPrivate *>(userdata);
    that->callAsync([=](){
        auto action = static_cast<PlaylistController::MediaStopAction>(new_action);
        if (that->m_playlist != playlist)
            return;
        if (that->m_mediaStopAction == action)
            return;
        that->m_mediaStopAction = action;
        emit that->q_func()->mediaStopActionChanged(action);
    });
}

} // extern "C"

static const struct vlc_playlist_callbacks playlist_callbacks = []{
    struct vlc_playlist_callbacks cbs {};
    cbs.on_items_reset = on_playlist_items_reset;
    cbs.on_items_added = on_playlist_items_added;
    cbs.on_items_moved = on_playlist_items_moved;
    cbs.on_items_removed = on_playlist_items_removed;
    cbs.on_items_updated = on_playlist_items_updated;
    cbs.on_playback_repeat_changed = on_playlist_playback_repeat_changed;
    cbs.on_playback_order_changed= on_playlist_playback_order_changed;
    cbs.on_current_index_changed = on_playlist_current_index_changed;
    cbs.on_has_next_changed = on_playlist_has_next_changed;
    cbs.on_has_prev_changed = on_playlist_has_prev_changed;
    cbs.on_media_stopped_action_changed = on_media_stopped_action_changed;
    return cbs;
}();


//private API

PlaylistControllerPrivate::PlaylistControllerPrivate(PlaylistController* playlistController, vlc_playlist_t *playlist)
    : q_ptr(playlistController)
    , m_playlist(playlist)
{
    fillSortKeyTitleList();
}

PlaylistControllerPrivate::~PlaylistControllerPrivate()
{
    if (m_playlist && m_listener)
    {
        vlc_playlist_locker lock(m_playlist);
        vlc_playlist_RemoveListener(m_playlist, m_listener);
    }
}

//public API

PlaylistController::PlaylistController(vlc_playlist_t *playlist, QObject *parent)
    : QObject(parent)
    , d_ptr( new PlaylistControllerPrivate(this, playlist) )
{
    Q_D(PlaylistController);
    assert(playlist);

    connect(this, &PlaylistController::itemsMoved, this, &PlaylistController::resetSortKey);
    connect(this, &PlaylistController::itemsAdded, this, &PlaylistController::resetSortKey);
    connect(this, &PlaylistController::isEmptyChanged, [this](bool isEmpty) {if (isEmpty) emit resetSortKey();});

    {
        vlc_playlist_locker locker(d->m_playlist);
        d->m_listener = vlc_playlist_AddListener(d->m_playlist, &playlist_callbacks, d, true);
    }
    /*
     * Queue a playlistInitialized to be sent after the initial state callbacks
     * vlc_playlist_AddListener will synchronously call each callback in
     * playlist_callbacks, which will in turn queue an async call on the Qt
     * main thread
     */

    d->callAsync([this, d](){
        d->m_initialized = true;
        emit initializedChanged();
    });
}

PlaylistController::~PlaylistController()
{
}

PlaylistItem PlaylistController::getCurrentItem() const
{
    Q_D(const PlaylistController);
    return d->m_currentItem;
}

void PlaylistController::append(const QVariantList& sourceList, bool startPlaying)
{
    append(toMediaList(sourceList), startPlaying);
}

void PlaylistController::append(const QVariant &source, bool startPlaying)
{
    append(QVariantList{source}, startPlaying);
}

void PlaylistController::insert(unsigned index, const QVariantList& sourceList, bool startPlaying)
{
    insert(index, toMediaList(sourceList), startPlaying);
}

void
PlaylistController::append(const QVector<Media> &media, bool startPlaying)
{
    Q_D(PlaylistController);

    if (Q_UNLIKELY(media.isEmpty()))
        return;

    vlc_playlist_locker locker(d->m_playlist);

    auto rawMedia = toRaw<input_item_t *>(media);
    /* We can't append an empty media. */
    assert(rawMedia.size() > 0);

    int ret = vlc_playlist_Append(d->m_playlist,
                                  rawMedia.constData(), rawMedia.size());
    if (ret != VLC_SUCCESS)
        throw std::bad_alloc();
    if (startPlaying)
    {
        ssize_t playIndex = (ssize_t)vlc_playlist_Count( d->m_playlist ) - rawMedia.size();
        ret = vlc_playlist_GoTo(d->m_playlist, playIndex);
        if (ret != VLC_SUCCESS)
            return;
        vlc_playlist_Start(d->m_playlist);
    }
}

void
PlaylistController::insert(size_t index, const QVector<Media> &media, bool startPlaying)
{
    Q_D(PlaylistController);

    if (Q_UNLIKELY(media.isEmpty()))
        return;

    vlc_playlist_locker locker(d->m_playlist);

    auto rawMedia = toRaw<input_item_t *>(media);
    /* We can't insert an empty media. */
    assert(rawMedia.size() > 0);

    int ret = vlc_playlist_RequestInsert(d->m_playlist, index,
                                         rawMedia.constData(), rawMedia.size());
    if (ret != VLC_SUCCESS)
        throw std::bad_alloc();
    if (startPlaying)
    {
        ret = vlc_playlist_GoTo(d->m_playlist, index);
        if (ret != VLC_SUCCESS)
            return;
        vlc_playlist_Start(d->m_playlist);
    }
}

void
PlaylistController::move(const QVector<PlaylistItem> &items, size_t target,
               ssize_t indexHint)
{
    Q_D(PlaylistController);
    vlc_playlist_locker locker(d->m_playlist);

    auto rawItems = toRaw<vlc_playlist_item_t *>(items);
    int ret = vlc_playlist_RequestMove(d->m_playlist, rawItems.constData(),
                                       rawItems.size(), target, indexHint);
    if (ret != VLC_SUCCESS)
        throw std::bad_alloc();
}

void
PlaylistController::remove(const QVector<PlaylistItem> &items, ssize_t indexHint)
{
    Q_D(PlaylistController);
    vlc_playlist_locker locker(d->m_playlist);
    auto rawItems = toRaw<vlc_playlist_item_t *>(items);
    int ret = vlc_playlist_RequestRemove(d->m_playlist, rawItems.constData(),
                                         rawItems.size(), indexHint);
    if (ret != VLC_SUCCESS)
        throw std::bad_alloc();
}

void
PlaylistController::shuffle()
{
    Q_D(PlaylistController);
    vlc_playlist_locker locker(d->m_playlist);
    vlc_playlist_Shuffle(d->m_playlist);
}

void
PlaylistController::sort(const QVector<vlc_playlist_sort_criterion> &criteria)
{
    Q_D(PlaylistController);
    vlc_playlist_locker locker(d->m_playlist);
    vlc_playlist_Sort(d->m_playlist, criteria.constData(), criteria.size());
}

void PlaylistController::sort(PlaylistController::SortKey key, PlaylistController::SortOrder order)
{
    if(key != SortKey::SORT_KEY_NONE)
        setSortKey(key);
    setSortOrder(order);

    sort();
}

void PlaylistController::sort(PlaylistController::SortKey key)
{
    if (key == SortKey::SORT_KEY_NONE)
        return;

    if (getSortKey() != key)
    {
        setSortOrder(SortOrder::SORT_ORDER_ASC);
        setSortKey(key);
    }
    else
    {
        switchSortOrder();
    }

    sort();
}

void PlaylistController::sort(void)
{
    Q_D(PlaylistController);

    if (d->m_sortKey == SortKey::SORT_KEY_NONE)
        return;

    vlc_playlist_sort_criterion crit = {
        static_cast<vlc_playlist_sort_key>(d->m_sortKey),
        static_cast<vlc_playlist_sort_order>(d->m_sortOrder)
    };
    QVector<vlc_playlist_sort_criterion> criteria { crit };
    sort( criteria );
}

void PlaylistController::explore(const PlaylistItem& pItem)
{
    vlc_playlist_item_t * const playlistItem = pItem.raw();
    if( playlistItem )
    {
        input_item_t * const p_input = vlc_playlist_item_GetMedia(playlistItem);
        auto uri = vlc::wrap_cptr( input_item_GetURI(p_input) );

        if( uri && uri.get()[0] != '\0')
        {
            auto path = vlc::wrap_cptr( vlc_uri2path( uri.get() ) );

            if( !path )
                return;

            QString containingDir = QFileInfo( path.get() ).absolutePath();
            if( !QFileInfo( containingDir ).isDir() )
                return;

            QUrl file = QUrl::fromLocalFile( containingDir );
            if( !file.isLocalFile() )
                return;

            QDesktopServices::openUrl( file );
        }
    }
}

int PlaylistController::serialize(const QString &fileName)
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{d->m_playlist};
    return vlc_playlist_Export(d->m_playlist, qtu(fileName), "export-m3u8");
}

int PlaylistController::currentIndex() const
{
    Q_D(const PlaylistController);
    return d->m_currentIndex;
}

void PlaylistController::play()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_Start( d->m_playlist );
}

void PlaylistController::pause()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_Pause( d->m_playlist );
}

void PlaylistController::stop()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_Stop( d->m_playlist );
}

void PlaylistController::next()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_Next( d->m_playlist );
}

void PlaylistController::prev()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_Prev( d->m_playlist );
}

void PlaylistController::prevOrReset()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    bool seek = false;
    vlc_player_t* player = vlc_playlist_GetPlayer( d->m_playlist );
    Q_ASSERT(player);
    if( !vlc_player_IsStarted(player) || vlc_player_GetTime(player) < VLC_TICK_FROM_MS(10) )
    {
        int ret = vlc_playlist_Prev( d->m_playlist );
        if (ret == VLC_SUCCESS)
            vlc_playlist_Start( d->m_playlist );
    }
    else
        seek = true;
    if (seek)
        vlc_player_JumpPos( player, 0.f );
}

void PlaylistController::togglePlayPause()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_player_t* player = vlc_playlist_GetPlayer( d->m_playlist );
    if ( vlc_player_IsStarted(player) )
        vlc_player_TogglePause( player );
    else
        vlc_playlist_Start( d->m_playlist );
}

void PlaylistController::toggleRandom()
{
    Q_D(PlaylistController);
    vlc_playlist_playback_order new_order;
    vlc_playlist_locker lock{ d->m_playlist };
    if ( d->m_random )
        new_order = VLC_PLAYLIST_PLAYBACK_ORDER_NORMAL;
    else
        new_order = VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM;
    vlc_playlist_SetPlaybackOrder( d->m_playlist, new_order );
    config_PutInt( "random", new_order );
}

void PlaylistController::toggleRepeatMode()
{
    Q_D(PlaylistController);
    vlc_playlist_playback_repeat new_repeat;
    /* Toggle Normal -> Loop -> Repeat -> Normal ... */
    switch ( d->m_repeat ) {
    case PlaybackRepeat::PLAYBACK_REPEAT_NONE:
        new_repeat = VLC_PLAYLIST_PLAYBACK_REPEAT_ALL;
        break;
    case PlaybackRepeat::PLAYBACK_REPEAT_ALL:
        new_repeat = VLC_PLAYLIST_PLAYBACK_REPEAT_CURRENT;
        break;
    case PlaybackRepeat::PLAYBACK_REPEAT_CURRENT:
    default:
        new_repeat = VLC_PLAYLIST_PLAYBACK_REPEAT_NONE;
        break;
    }
    {
        vlc_playlist_locker lock{ d->m_playlist };
        vlc_playlist_SetPlaybackRepeat( d->m_playlist, new_repeat );
    }
    config_PutInt( "repeat", new_repeat );
}

void PlaylistController::clear()
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_Clear( d->m_playlist );
}

void PlaylistController::goTo(uint index, bool startPlaying)
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    size_t count = vlc_playlist_Count( d->m_playlist );
    if (count == 0 || index > count-1)
        return;
    vlc_playlist_GoTo( d->m_playlist, index );
    if (startPlaying)
        vlc_playlist_Start( d->m_playlist );
}

bool PlaylistController::isRandom() const
{
    Q_D(const PlaylistController);
    return d->m_random;
}

void PlaylistController::setRandom(bool random)
{
    Q_D(const PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_SetPlaybackOrder( d->m_playlist, random ? VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM : VLC_PLAYLIST_PLAYBACK_ORDER_NORMAL );
}

Playlist PlaylistController::getPlaylist() const
{
    Q_D(const PlaylistController);
    return Playlist(d->m_playlist);
}

void PlaylistController::resetSortKey()
{
    Q_D(PlaylistController);
    d->m_sortKey = SortKey::SORT_KEY_NONE;
    emit sortKeyChanged();
}

PlaylistController::PlaybackRepeat PlaylistController::getRepeatMode() const
{
    Q_D(const PlaylistController);
    return d->m_repeat;
}

void PlaylistController::setRepeatMode(PlaylistController::PlaybackRepeat mode)
{
    Q_D(const PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_SetPlaybackRepeat( d->m_playlist, static_cast<vlc_playlist_playback_repeat>(mode) );
}

PlaylistController::MediaStopAction PlaylistController::getMediaStopAction() const
{
    Q_D(const PlaylistController);
    return d->m_mediaStopAction;
}

void PlaylistController::setMediaStopAction(PlaylistController::MediaStopAction action)
{
    Q_D(PlaylistController);
    vlc_playlist_locker lock{ d->m_playlist };
    vlc_playlist_SetMediaStoppedAction(d->m_playlist, static_cast<vlc_playlist_media_stopped_action>(action) );
}

bool PlaylistController::isEmpty() const
{
    Q_D(const PlaylistController);
    return d->m_empty;
}

int PlaylistController::count() const
{
    Q_D(const PlaylistController);
    assert(d->m_count <= (size_t)INT_MAX);
    return d->m_count;
}

void PlaylistController::setSortKey(SortKey sortKey)
{
    Q_D(PlaylistController);

    if (sortKey == d->m_sortKey)
        return;

    d->m_sortKey = sortKey;
    emit sortKeyChanged();
}

void PlaylistController::setSortOrder(SortOrder sortOrder)
{
    Q_D(PlaylistController);

    SortOrder order = d->m_sortOrder;
    if(sortOrder == order)
        return;

    d->m_sortOrder = sortOrder;
    emit sortOrderChanged();
}

void PlaylistController::switchSortOrder()
{
    Q_D(PlaylistController);

    SortOrder order = d->m_sortOrder;
    if (order == SortOrder::SORT_ORDER_ASC)
        order = SortOrder::SORT_ORDER_DESC;
    else if (order == SortOrder::SORT_ORDER_DESC)
        order = SortOrder::SORT_ORDER_ASC;
    else
        return;

    d->m_sortOrder = order;
    emit sortOrderChanged();
}

PlaylistController::SortKey PlaylistController::getSortKey() const
{
    Q_D(const PlaylistController);
    return d->m_sortKey;
}

PlaylistController::SortOrder PlaylistController::getSortOrder() const
{
    Q_D(const PlaylistController);
    return d->m_sortOrder;
}

bool PlaylistController::hasNext() const
{
    Q_D(const PlaylistController);
    return d->m_hasNext;
}

bool PlaylistController::hasPrev() const
{
    Q_D(const PlaylistController);
    return d->m_hasPrev;
}

QVariantList PlaylistController::getSortKeyTitleList() const
{
    Q_D(const PlaylistController);

    return d->sortKeyTitleList;
}

bool PlaylistController::isInitialized() const
{
    Q_D(const PlaylistController);
    return d->m_initialized;
}

  } // namespace playlist
} // namespace vlc

Messung
CHZG
85999994

¤ Dauer der Verarbeitung: 0.11 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.