mirror of https://code.videolan.org/videolan/vlc
qt/dialogmodel: Update error handling before the GUI display
Signed-off-by: Pierre Lamot <pierre@videolabs.io>
This commit is contained in:
parent
fa26844047
commit
7695e065e8
|
@ -1,5 +1,7 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2019 VLC authors and VideoLAN
|
||||
* Copyright (C) 2021 VLC authors and VideoLAN
|
||||
*
|
||||
* Authors: Benjamin Arnaud <bunjee@omega.gg>
|
||||
*
|
||||
* 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
|
||||
|
@ -15,99 +17,195 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "dialogmodel.hpp"
|
||||
|
||||
static void displayErrorCb(void *p_data, const char *psz_title, const char *psz_text)
|
||||
// VLC includes
|
||||
#include <vlc_dialog.h>
|
||||
#include <qt.hpp>
|
||||
|
||||
//=================================================================================================
|
||||
// DialogErrorModel
|
||||
//=================================================================================================
|
||||
|
||||
/* explicit */ DialogErrorModel::DialogErrorModel(QObject * parent) : QAbstractListModel(parent) {}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// QAbstractItemModel implementation
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
QVariant DialogErrorModel::data(const QModelIndex & index, int role) const /* override */
|
||||
{
|
||||
DialogModel* that = static_cast<DialogModel*>(p_data);
|
||||
emit that->errorDisplayed(psz_title, psz_text);
|
||||
int row = index.row();
|
||||
|
||||
if (row < 0 || row >= m_data.count())
|
||||
return QVariant();
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case DIALOG_TITLE:
|
||||
return QVariant::fromValue(m_data.at(row).title);
|
||||
case DIALOG_TEXT:
|
||||
return QVariant::fromValue(m_data.at(row).text);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
static void displayLoginCb(void *p_data, vlc_dialog_id *dialogId,
|
||||
const char *psz_title, const char *psz_text,
|
||||
const char *psz_default_username,
|
||||
bool b_ask_store)
|
||||
int DialogErrorModel::rowCount(const QModelIndex &) const /* override */
|
||||
{
|
||||
DialogModel* that = static_cast<DialogModel*>(p_data);
|
||||
emit that->loginDisplayed( dialogId, psz_title, psz_text, psz_default_username, b_ask_store );
|
||||
return count();
|
||||
}
|
||||
|
||||
static void displayQuestionCb(void *p_data, vlc_dialog_id *dialogId,
|
||||
const char *psz_title, const char *psz_text,
|
||||
vlc_dialog_question_type i_type,
|
||||
const char *psz_cancel, const char *psz_action1,
|
||||
const char *psz_action2)
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// QAbstractItemModel reimplementation
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
QHash<int, QByteArray> DialogErrorModel::roleNames() const /* override */
|
||||
{
|
||||
DialogModel* that = static_cast<DialogModel*>(p_data);
|
||||
emit that->questionDisplayed( dialogId, psz_title, psz_text, static_cast<int>(i_type), psz_cancel, psz_action1, psz_action2 );
|
||||
return
|
||||
{
|
||||
{ DialogErrorModel::DIALOG_TITLE, "title" },
|
||||
{ DialogErrorModel::DIALOG_TEXT, "text" }
|
||||
};
|
||||
}
|
||||
|
||||
static void displayProgressCb(void *p_data, vlc_dialog_id *dialogId,
|
||||
const char *psz_title, const char *psz_text,
|
||||
bool b_indeterminate, float f_position,
|
||||
const char *psz_cancel)
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Private functions
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
void DialogErrorModel::pushError(const DialogError & error)
|
||||
{
|
||||
DialogModel* that = static_cast<DialogModel*>(p_data);
|
||||
emit that->progressDisplayed( dialogId, psz_title, psz_text, b_indeterminate, f_position, psz_cancel);
|
||||
int row = m_data.count();
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
|
||||
m_data.append(error);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
static void cancelCb(void *p_data, vlc_dialog_id *dialogId)
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Properties
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
int DialogErrorModel::count() const
|
||||
{
|
||||
DialogModel* that = static_cast<DialogModel*>(p_data);
|
||||
emit that->cancelled(dialogId);
|
||||
return m_data.count();
|
||||
}
|
||||
|
||||
static void updateProgressCb(void *p_data, vlc_dialog_id *dialogId, float f_value, const char *psz_text)
|
||||
//=================================================================================================
|
||||
// DialogModel
|
||||
//=================================================================================================
|
||||
|
||||
/* explicit */ DialogModel::DialogModel(intf_thread_t * intf, QObject * parent)
|
||||
: QObject(parent), m_intf(intf)
|
||||
{
|
||||
DialogModel* that = static_cast<DialogModel*>(p_data);
|
||||
emit that->progressUpdated( dialogId, f_value, psz_text );
|
||||
m_model = new DialogErrorModel(this);
|
||||
|
||||
const vlc_dialog_cbs cbs =
|
||||
{
|
||||
onError, onLogin, onQuestion, onProgress, onCancelled, onProgressUpdated
|
||||
};
|
||||
|
||||
vlc_dialog_provider_set_callbacks(intf, &cbs, this);
|
||||
}
|
||||
|
||||
const vlc_dialog_cbs cbs = {
|
||||
displayErrorCb,
|
||||
displayLoginCb,
|
||||
displayQuestionCb,
|
||||
displayProgressCb,
|
||||
cancelCb,
|
||||
updateProgressCb
|
||||
};
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Interface
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
DialogModel::DialogModel(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
DialogModel::~DialogModel()
|
||||
{
|
||||
if (m_mainCtx)
|
||||
vlc_dialog_provider_set_callbacks(m_mainCtx->getIntf(), nullptr, nullptr);
|
||||
}
|
||||
|
||||
void DialogModel::dismiss(DialogId dialogId)
|
||||
{
|
||||
vlc_dialog_id_dismiss(dialogId.m_id);
|
||||
}
|
||||
|
||||
void DialogModel::post_login(DialogId dialogId, const QString& username, const QString& password, bool store)
|
||||
/* Q_INVOKABLE */ void DialogModel::post_login(DialogId dialogId, const QString & username,
|
||||
const QString & password, bool store)
|
||||
{
|
||||
vlc_dialog_id_post_login(dialogId.m_id, qtu(username), qtu(password), store);
|
||||
}
|
||||
|
||||
void DialogModel::post_action1(DialogId dialogId)
|
||||
/* Q_INVOKABLE */ void DialogModel::post_action1(DialogId dialogId)
|
||||
{
|
||||
vlc_dialog_id_post_action(dialogId.m_id, 1);
|
||||
}
|
||||
|
||||
void DialogModel::post_action2(DialogId dialogId)
|
||||
/* Q_INVOKABLE */ void DialogModel::post_action2(DialogId dialogId)
|
||||
{
|
||||
vlc_dialog_id_post_action(dialogId.m_id, 2);
|
||||
}
|
||||
|
||||
void DialogModel::setMainCtx(QmlMainContext* ctx)
|
||||
/* Q_INVOKABLE */ void DialogModel::dismiss(DialogId dialogId)
|
||||
{
|
||||
if (ctx)
|
||||
vlc_dialog_provider_set_callbacks(ctx->getIntf(), &cbs, this);
|
||||
else if (m_mainCtx)
|
||||
vlc_dialog_provider_set_callbacks(m_mainCtx->getIntf(), nullptr, nullptr);
|
||||
m_mainCtx = ctx;
|
||||
vlc_dialog_id_dismiss(dialogId.m_id);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Private static functions
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
/* static */ void DialogModel::onError(void * p_data,
|
||||
const char * psz_title, const char * psz_text)
|
||||
{
|
||||
DialogModel * model = static_cast<DialogModel *>(p_data);
|
||||
|
||||
DialogErrorModel::DialogError error { psz_title, psz_text };
|
||||
|
||||
QMetaObject::invokeMethod(model, [model, error = std::move(error)]()
|
||||
{
|
||||
model->m_model->pushError(error);
|
||||
});
|
||||
}
|
||||
|
||||
/* static */ void DialogModel::onLogin(void * p_data, vlc_dialog_id * dialogId,
|
||||
const char * psz_title, const char * psz_text,
|
||||
const char * psz_default_username, bool b_ask_store)
|
||||
{
|
||||
DialogModel * model = static_cast<DialogModel *>(p_data);
|
||||
|
||||
emit model->login(dialogId, psz_title, psz_text, psz_default_username, b_ask_store);
|
||||
}
|
||||
|
||||
/* static */ void DialogModel::onQuestion(void * p_data, vlc_dialog_id * dialogId,
|
||||
const char * psz_title, const char * psz_text,
|
||||
vlc_dialog_question_type i_type,
|
||||
const char * psz_cancel, const char * psz_action1,
|
||||
const char * psz_action2)
|
||||
{
|
||||
DialogModel * model = static_cast<DialogModel *>(p_data);
|
||||
|
||||
emit model->question(dialogId, psz_title, psz_text, static_cast<int>(i_type), psz_cancel,
|
||||
psz_action1, psz_action2);
|
||||
}
|
||||
|
||||
/* static */ void DialogModel::onProgress(void * p_data, vlc_dialog_id * dialogId,
|
||||
const char * psz_title, const char * psz_text,
|
||||
bool b_indeterminate, float f_position,
|
||||
const char * psz_cancel)
|
||||
{
|
||||
DialogModel * model = static_cast<DialogModel *>(p_data);
|
||||
|
||||
emit model->progress(dialogId, psz_title, psz_text, b_indeterminate, f_position, psz_cancel);
|
||||
}
|
||||
|
||||
/* static */ void DialogModel::onProgressUpdated(void * p_data, vlc_dialog_id * dialogId,
|
||||
float f_value, const char * psz_text)
|
||||
{
|
||||
DialogModel * model = static_cast<DialogModel *>(p_data);
|
||||
|
||||
emit model->progressUpdated(dialogId, f_value, psz_text);
|
||||
}
|
||||
|
||||
/* static */ void DialogModel::onCancelled(void * p_data, vlc_dialog_id * dialogId)
|
||||
{
|
||||
DialogModel * model = static_cast<DialogModel *>(p_data);
|
||||
|
||||
emit model->cancelled(dialogId);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Properties
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
DialogErrorModel * DialogModel::model() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2019 VLC authors and VideoLAN
|
||||
* Copyright (C) 2021 VLC authors and VideoLAN
|
||||
*
|
||||
* Authors: Benjamin Arnaud <bunjee@omega.gg>
|
||||
*
|
||||
* 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
|
||||
|
@ -15,6 +17,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef DIALOGMODEL_HPP
|
||||
#define DIALOGMODEL_HPP
|
||||
|
||||
|
@ -22,79 +25,169 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
// VLC includes
|
||||
#include <vlc_common.h>
|
||||
#include <vlc_dialog.h>
|
||||
|
||||
#include <QObject>
|
||||
// Qt includes
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "util/qml_main_context.hpp"
|
||||
// Forward declarations
|
||||
class DialogModel;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// DialogId
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
class DialogId {
|
||||
class DialogId
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
DialogId(vlc_dialog_id * id = nullptr)
|
||||
: m_id(id)
|
||||
{}
|
||||
|
||||
bool operator ==(const DialogId& other) const {
|
||||
public:
|
||||
DialogId(vlc_dialog_id * id = nullptr) : m_id(id) {}
|
||||
|
||||
public: // Operators
|
||||
bool operator ==(const DialogId & other) const
|
||||
{
|
||||
return m_id == other.m_id;
|
||||
}
|
||||
vlc_dialog_id *m_id;
|
||||
|
||||
public: // Variables
|
||||
vlc_dialog_id * m_id;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(DialogId)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// DialogErrorModel
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
class DialogErrorModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_ENUMS(DialogRoles)
|
||||
|
||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||
|
||||
public: // Enums
|
||||
enum DialogRoles
|
||||
{
|
||||
DIALOG_TITLE = Qt::UserRole + 1,
|
||||
DIALOG_TEXT
|
||||
};
|
||||
|
||||
private:
|
||||
struct DialogError
|
||||
{
|
||||
QString title;
|
||||
QString text;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit DialogErrorModel(QObject * parent = nullptr);
|
||||
|
||||
public: // QAbstractItemModel implementation
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
|
||||
|
||||
public: // QAbstractItemModel reimplementation
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private: // Functions
|
||||
void pushError(const DialogError & error);
|
||||
|
||||
signals:
|
||||
void modelChanged();
|
||||
|
||||
void countChanged();
|
||||
|
||||
public: // Properties
|
||||
int count() const;
|
||||
|
||||
private: // Variables
|
||||
QList<DialogError> m_data;
|
||||
|
||||
private:
|
||||
friend class DialogModel;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// DialogModel
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
class DialogModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_PROPERTY(QmlMainContext* mainCtx READ getMainCtx WRITE setMainCtx NOTIFY mainCtxChanged)
|
||||
Q_ENUMS(QuestionType)
|
||||
|
||||
enum QuestionType {
|
||||
QUESTION_NORMAL,
|
||||
QUESTION_WARNING,
|
||||
QUESTION_CRITICAL
|
||||
};
|
||||
Q_ENUM(QuestionType)
|
||||
Q_PROPERTY(DialogErrorModel * model READ model CONSTANT)
|
||||
|
||||
public: // Enums
|
||||
// NOTE: Is it really useful to have this declared here ?
|
||||
enum QuestionType { QUESTION_NORMAL, QUESTION_WARNING, QUESTION_CRITICAL };
|
||||
|
||||
public:
|
||||
explicit DialogModel(QObject *parent = nullptr);
|
||||
~DialogModel();
|
||||
explicit DialogModel(intf_thread_t * intf, QObject * parent = nullptr);
|
||||
|
||||
inline QmlMainContext* getMainCtx() const { return m_mainCtx; }
|
||||
void setMainCtx(QmlMainContext*);
|
||||
public: // Interface
|
||||
Q_INVOKABLE void post_login(DialogId dialogId, const QString & username,
|
||||
const QString & password, bool store = false);
|
||||
|
||||
signals:
|
||||
void errorDisplayed(const QString &title, const QString &text);
|
||||
void loginDisplayed(DialogId dialogId, const QString &title,
|
||||
const QString &text, const QString &defaultUsername,
|
||||
Q_INVOKABLE void post_action1(DialogId dialogId);
|
||||
Q_INVOKABLE void post_action2(DialogId dialogId);
|
||||
|
||||
Q_INVOKABLE void dismiss(DialogId dialogId);
|
||||
|
||||
private: // Static functions
|
||||
static void onError(void * p_data, const char * psz_title, const char * psz_text);
|
||||
|
||||
static void onLogin(void * p_data, vlc_dialog_id * dialogId, const char * psz_title,
|
||||
const char * psz_text, const char * psz_default_username,
|
||||
bool b_ask_store);
|
||||
|
||||
void questionDisplayed(DialogId dialogId, const QString &title,
|
||||
const QString &text, int type,
|
||||
const QString &cancel, const QString &action1,
|
||||
const QString &action2);
|
||||
static void onQuestion(void * p_data, vlc_dialog_id * dialogId, const char * psz_title,
|
||||
const char * psz_text, vlc_dialog_question_type i_type,
|
||||
const char * psz_cancel, const char * psz_action1,
|
||||
const char * psz_action2);
|
||||
|
||||
void progressDisplayed(DialogId dialogId, const QString &title,
|
||||
const QString &text, bool b_indeterminate,
|
||||
float f_position, const QString &cancel);
|
||||
static void onProgress(void * p_data, vlc_dialog_id * dialogId, const char * psz_title,
|
||||
const char * psz_text, bool b_indeterminate, float f_position,
|
||||
const char *psz_cancel);
|
||||
|
||||
static void onProgressUpdated(void * p_data, vlc_dialog_id * dialogId, float f_value,
|
||||
const char * psz_text);
|
||||
|
||||
static void onCancelled(void * p_data, vlc_dialog_id * dialogId);
|
||||
|
||||
|
||||
signals:
|
||||
void errorBegin();
|
||||
void errorEnd ();
|
||||
|
||||
void login(DialogId dialogId, const QString & title,
|
||||
const QString & text, const QString & defaultUsername,
|
||||
bool b_ask_store);
|
||||
|
||||
void question(DialogId dialogId, const QString & title, const QString & text, int type,
|
||||
const QString & cancel, const QString & action1, const QString & action2);
|
||||
|
||||
void progress(DialogId dialogId, const QString & title, const QString & text,
|
||||
bool b_indeterminate, float f_position, const QString & cancel);
|
||||
|
||||
void progressUpdated(DialogId dialogId, float f_value, const QString & text);
|
||||
|
||||
void cancelled(DialogId dialogId);
|
||||
|
||||
void progressUpdated(DialogId dialogId, float f_value, const QString &text);
|
||||
public: // Properties
|
||||
DialogErrorModel * model() const;
|
||||
|
||||
void mainCtxChanged();
|
||||
private: // Variables
|
||||
DialogErrorModel * m_model;
|
||||
|
||||
public slots:
|
||||
void dismiss(DialogId dialogId);
|
||||
void post_login(DialogId dialogId, const QString& username, const QString& password, bool store = false);
|
||||
void post_action1(DialogId dialogId);
|
||||
void post_action2(DialogId dialogId);
|
||||
|
||||
private:
|
||||
QmlMainContext* m_mainCtx;
|
||||
intf_thread_t * m_intf;
|
||||
};
|
||||
|
||||
#endif // DIALOGMODEL_HPP
|
||||
|
|
|
@ -103,6 +103,7 @@ bool MainUI::setup(QQmlEngine* engine)
|
|||
rootCtx->setContextProperty( "topWindow", m_interfaceWindow);
|
||||
rootCtx->setContextProperty( "dialogProvider", DialogsProvider::getInstance());
|
||||
rootCtx->setContextProperty( "systemPalette", new SystemPalette(this));
|
||||
rootCtx->setContextProperty( "dialogModel", new DialogModel(m_intf, this));
|
||||
|
||||
if (m_mainInterface->hasMediaLibrary())
|
||||
rootCtx->setContextProperty( "medialib", m_mainInterface->getMediaLibrary() );
|
||||
|
@ -227,8 +228,10 @@ void MainUI::registerQMLTypes()
|
|||
qmlRegisterType<PlaylistControllerModel>( "org.videolan.vlc", 0, 1, "PlaylistControllerModel" );
|
||||
|
||||
qmlRegisterType<AboutModel>( "org.videolan.vlc", 0, 1, "AboutModel" );
|
||||
|
||||
qmlRegisterUncreatableType<DialogModel>("org.videolan.vlc", 0, 1, "DialogModel", "");
|
||||
qmlRegisterUncreatableType<DialogErrorModel>( "org.videolan.vlc", 0, 1, "DialogErrorModel", "");
|
||||
qRegisterMetaType<DialogId>();
|
||||
qmlRegisterType<DialogModel>("org.videolan.vlc", 0, 1, "DialogModel");
|
||||
|
||||
qmlRegisterType<QmlEventFilter>( "org.videolan.vlc", 0, 1, "EventFilter" );
|
||||
|
||||
|
|
Loading…
Reference in New Issue