Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  custom_menus.cpp   Sprache: C

 

/*****************************************************************************
 * custom_menus.cpp : Qt custom menus classes
 *****************************************************************************
 * Copyright © 2006-2018 VideoLAN authors
 *                  2018 VideoLabs
 *
 * 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 <vlc_common.h>
#include <vlc_renderer_discovery.h>

#include "custom_menus.hpp"
#include "util/renderer_manager.hpp"

// MediaLibrary includes
#include "medialibrary/mlbookmarkmodel.hpp"

// Dialogs includes
#include "dialogs/dialogs_provider.hpp"

// Menus includes
#include "menus/menus.hpp"
#include "player/player_controller.hpp"

// Qt includes
#include <QMenu>
#include <QAction>
#include <QActionGroup>
#include <QWidgetAction>
#include <QVBoxLayout>
#include <QLabel>
#include <QProgressBar>
#include <QMetaObject>
#include <QMetaProperty>
#include <QMetaMethod>

#include "util/vlcaccess_image_provider.hpp"

RendererMenu::RendererMenu( QMenu* parent, qt_intf_t* intf, PlayerController* player )
    : QMenu( parent)
    , p_intf( intf )
    , m_renderManager(player->getRendererManager())
{
    setTitle( qtr("&Renderer") );

    QAction *action = new QAction( qtr("<Local>"), this );
    action->setCheckable(true);
    action->setChecked(!m_renderManager->useRenderer());
    connect(action, &QAction::triggered, this, [this](bool checked){
        if (checked) {
            m_renderManager->disableRenderer();
        }
    });
    addAction( action );
    connect(m_renderManager,  &RendererManager::useRendererChanged, action,
            [action, this](){
                action->setChecked(!m_renderManager->useRenderer());
    });

    QAction* separator = addSeparator();

    ListMenuHelper* helper = new ListMenuHelper(this, m_renderManager, separator, this);
    connect(helper, &ListMenuHelper::select, this, [this](int row, bool checked){
        m_renderManager->setData(m_renderManager->index(row), checked, Qt::CheckStateRole);
    });

    QActionGroup* actionGroup = helper->getActionGroup();
    actionGroup->setExclusionPolicy(QActionGroup::ExclusionPolicy::Exclusive);
    //the <Local> node is part of the group
    actionGroup->addAction(action);

    QWidget *statusWidget = new QWidget();
    statusWidget->setLayout( new QVBoxLayout );
    m_statusLabel = new QLabel();
    statusWidget->layout()->addWidget( m_statusLabel );
    m_statusProgressBar = new QProgressBar();
    m_statusProgressBar->setMaximumHeight( 10 );
    m_statusProgressBar->setStyleSheet( QString(R"RAW(
        QProgressBar:horizontal {
            border: none;
            background: transparent;
            padding: 1px;
        }
        QProgressBar::chunk:horizontal {
            background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5,
                        stop: 0 white, stop: 0.4 orange, stop: 0.6 orange, stop: 1 white);
        })RAW") );
    m_statusProgressBar->setRange( 0, 0 );
    m_statusProgressBar->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Maximum );
    statusWidget->layout()->addWidget( m_statusProgressBar );

    QWidgetAction *qwa = new QWidgetAction( this );
    qwa->setDefaultWidget( statusWidget );
    qwa->setDisabled( true );
    addAction( qwa );
    m_statusAction = qwa;

    connect( this, &RendererMenu::aboutToShow, m_renderManager, &RendererManager::StartScan );
    connect( m_renderManager, &RendererManager::statusChanged, this, &RendererMenu::updateStatus );
    connect( m_renderManager, &RendererManager::scanRemainChanged, this, &RendererMenu::updateStatus );
    updateStatus();
}

RendererMenu::~RendererMenu()
{}

void RendererMenu::updateStatus()
{

    switch (m_renderManager->getStatus())
    {
    case RendererManager::RendererStatus::RUNNING:
    {
        int scanRemain = m_renderManager->getScanRemain();
        m_statusLabel->setText( qtr("Scanning...").
               append( QString(" (%1s)").arg( scanRemain ) ) );
        m_statusProgressBar->setVisible( true );
        m_statusAction->setVisible( true );
        break;
    }
    case RendererManager::RendererStatus::FAILED:
    {
        m_statusLabel->setText( "Failed (no discovery module available)" );
        m_statusProgressBar->setVisible( false );
        m_statusAction->setVisible( true );
        break;
    }
    case RendererManager::RendererStatus::IDLE:
        m_statusAction->setVisible( false );
        break;
    }
}


/*   CheckableListMenu   */

CheckableListMenu::CheckableListMenu(QString title, QAbstractListModel* model , QActionGroup::ExclusionPolicy grouping,  QWidget *parent)
    : QMenu(parent)
    , m_model(model)
{
    this->setTitle(title);

    ListMenuHelper* helper = new ListMenuHelper(this, model, nullptr, this);
    helper->getActionGroup()->setExclusionPolicy(grouping);
    connect(helper, &ListMenuHelper::select, this, [this](int row, bool checked){
        m_model->setData(m_model->index(row), checked, Qt::CheckStateRole);
    });
}

// ListMenuHelper

ListMenuHelper::ListMenuHelper(QMenu * menu, QAbstractListModel * model, QAction * before,
                               QObject * parent)
    : QObject(parent), m_menu(menu), m_model(model), m_before(before)
{
    m_group = new QActionGroup(this);

    onModelReset();

    connect(m_model, &QAbstractListModel::rowsInserted, this, &ListMenuHelper::onRowsInserted);
    connect(m_model, &QAbstractListModel::rowsRemoved,  this, &ListMenuHelper::onRowsRemoved);

    connect(m_model, &QAbstractListModel::dataChanged, this, &ListMenuHelper::onDataChanged);

    connect(m_model, &QAbstractListModel::modelReset, this, &ListMenuHelper::onModelReset);
}


ListMenuHelper::~ListMenuHelper()
{}
// Interface

int ListMenuHelper::count() const
{
    return m_actions.count();
}

QActionGroup* ListMenuHelper::getActionGroup() const
{
    return m_group;
}


void ListMenuHelper::setIcon(QAction* action,  const QUrl& iconUrl)
{

    if (!iconUrl.isValid())
    {
        action->setIcon({});
        return;
    }

    if (m_iconLoader)
    {
        disconnect(m_iconLoader.get(), nullptr, this, nullptr);
        m_iconLoader->cancel();
    }
    m_iconLoader.reset(VLCAccessImageProvider::requestImageResponseUnWrapped(iconUrl, {64,64}));
    connect(m_iconLoader.get(), &QQuickImageResponse::finished, this, [this, action] {
        std::unique_ptr<QQuickTextureFactory> factory(m_iconLoader->textureFactory());
        if (!factory)
        {
            action->setIcon({});
            return;
        }
        QImage img = factory->image();
        action->setIcon(QIcon(QPixmap::fromImage(img)));
    });
}


// Private slots

void ListMenuHelper::onRowsInserted(const QModelIndex &, int first, int last)
{
    QAction * before;

    if (first < m_actions.count())
        before = m_actions.at(first);
    else
        before = m_before;

    for (int i = first; i <= last; i++)
    {
        QModelIndex index = m_model->index(i, 0);

        QString name = m_model->data(index, Qt::DisplayRole).toString();

        QAction * action = new QAction(name, this);

        QVariant checked = m_model->data(index, Qt::CheckStateRole);
        if (checked.isValid() && checked.canConvert<bool>())
        {
            action->setCheckable(true);
            action->setChecked(checked.toBool());
        }

        QVariant iconPath = m_model->data(index, Qt::DecorationRole);
        if (iconPath.isValid())
        {
            QUrl iconUrl;
            if (iconPath.canConvert<QUrl>())
                iconUrl = iconPath.toUrl();
            else if (iconPath.canConvert<QString>())
                iconUrl = QUrl::fromEncoded(iconPath.toString().toUtf8());

            setIcon(action, iconUrl);
        }

        // NOTE: We are adding sequentially *before* the next action in the list.
        m_menu->insertAction(before, action);

        m_group->addAction(action);

        m_actions.insert(i, action);

        connect(action, &QAction::triggered, this, &ListMenuHelper::onTriggered);
    }

    emit countChanged(m_actions.count());
}

void ListMenuHelper::onRowsRemoved(const QModelIndex &, int first, int last)
{
    for (int i = first; i <= last; i++)
    {
        QAction * action = m_actions.at(i);

        m_group->removeAction(action);

        delete action;
    }

    QList<QAction *>::iterator begin = m_actions.begin();

    m_actions.erase(begin + first, begin + last + 1);

    emit countChanged(m_actions.count());
}

void ListMenuHelper::onDataChanged(const QModelIndex & topLeft,
                                   const QModelIndex & bottomRight, const QVector<int> & roles)
{
    const bool updateDisplay = roles.contains(Qt::DisplayRole);
    const bool updateChecked = roles.contains(Qt::CheckStateRole);
    const bool udpateIcon = roles.contains(Qt::DecorationRole);

    for (int i = topLeft.row(); i <= bottomRight.row(); i++)
    {
        QAction * action = m_actions.at(i);
        QModelIndex index = m_model->index(i, 0);

        if (updateDisplay)
        {
            QString name = m_model->data(index, Qt::DisplayRole).toString();
            action->setText(name);
        }

        if (updateChecked)
        {
            QVariant checked = m_model->data(index, Qt::CheckStateRole);
            if (checked.isValid() && checked.canConvert<bool>())
                action->setChecked(checked.toBool());
        }

        if (udpateIcon)
        {
            QVariant iconPath = m_model->data(index, Qt::DecorationRole);
            if (iconPath.isValid())
            {
                QUrl iconUrl;
                if (iconPath.canConvert<QUrl>())
                    iconUrl = iconPath.toUrl();
                else if (iconPath.canConvert<QString>())
                    iconUrl = QUrl::fromEncoded(iconPath.toString().toUtf8());

                setIcon(action, iconUrl);
            }
        }
    }
}

void ListMenuHelper::onModelReset()
{
    for (QAction * action : m_actions)
    {
        m_group->removeAction(action);

        delete action;
    }

    m_actions.clear();

    int count = m_model->rowCount();

    if (count)
        onRowsInserted(QModelIndex(), 0, count - 1);
}

void ListMenuHelper::onTriggered(bool checked)
{
    QAction * action = static_cast<QAction *> (sender());

    emit select(m_actions.indexOf(action), checked);
}

/*     BooleanPropertyAction    */

BooleanPropertyAction::BooleanPropertyAction(QString title, QObject *model, QString propertyName, QWidget *parent)
    : QAction(parent)
    , m_model(model)
    , m_propertyName(propertyName)
{
    setText(title);
    assert(model);
    const QMetaObject* meta = model->metaObject();
    int propertyId = meta->indexOfProperty(qtu(propertyName));
    assert(propertyId != -1);
    QMetaProperty property = meta->property(propertyId);
    assert(property.typeId() ==  QMetaType::Bool);
    const QMetaObject* selfMeta = this->metaObject();

    assert(property.hasNotifySignal());
    QMetaMethod checkedSlot = selfMeta->method(selfMeta->indexOfSlot( "setChecked(bool)" ));
    connect( model, property.notifySignal(), this, checkedSlot );
    connect( this, &BooleanPropertyAction::triggered, this, &BooleanPropertyAction::setModelChecked );

    setCheckable(true);
    setChecked(property.read(model).toBool());
}

void BooleanPropertyAction::setModelChecked(bool checked)
{
    m_model->setProperty(qtu(m_propertyName), QVariant::fromValue<bool>(checked) );
}


RecentMenu::RecentMenu(MLRecentMediaModel* model, MediaLib* ml,  QWidget* parent)
    : QMenu(parent)
    , m_model(model)
    , m_ml(ml)
{
    QAction* separator = addSeparator();

    ListMenuHelper* helper = new ListMenuHelper(this, model, separator, this);
    connect(helper, &ListMenuHelper::select, this, [this](int row, bool){
        QModelIndex index = m_model->index(row);

        MLItemId id = m_model->data(index, MLRecentMediaModel::MEDIA_ID).value<MLItemId>();
        m_ml->addAndPlay(id);
    });

    addAction( qtr("&Clear"), model, &MLRecentMediaModel::clearHistory );
}

// BookmarkMenu

BookmarkMenu::BookmarkMenu(MediaLib * mediaLib, vlc_player_t * player, QWidget * parent)
    : QMenu(parent)
{
    addAction(qtr("&Manage"), THEDP, &DialogsProvider::bookmarksDialog )->setShortcut(QKeySequence("Ctrl+B"));

    addSeparator();

    MLBookmarkModel * model = new MLBookmarkModel(this);
    model->setPlayer(player);
    model->setMl(mediaLib);

    ListMenuHelper * helper = new ListMenuHelper(this, model, nullptr, this);

    connect(helper, &ListMenuHelper::select, [model](int index, bool )
    {
        model->select(model->index(index, 0));
    });

    setTearOffEnabled(true);
}

Messung
CHZG
859910094

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104857
#Domains=418080