You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
7.5 KiB
240 lines
7.5 KiB
/*****************************************************************************
|
|
* 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.
|
|
*****************************************************************************/
|
|
|
|
#include "varchoicemodel.hpp"
|
|
|
|
int VLCVarChoiceModel::on_variable_callback( vlc_object_t * object, char const * , vlc_value_t oldvalue, vlc_value_t newvalue, void * data)
|
|
{
|
|
VLCVarChoiceModel* that = static_cast<VLCVarChoiceModel*>(data);
|
|
return that->updateData(object, oldvalue, newvalue);
|
|
}
|
|
|
|
int VLCVarChoiceModel::on_variable_list_callback( vlc_object_t * object, char const * , int action, vlc_value_t* value, void * data)
|
|
{
|
|
VLCVarChoiceModel* that = static_cast<VLCVarChoiceModel*>(data);
|
|
return that->updateList(object, action, value);
|
|
}
|
|
|
|
VLCVarChoiceModel::~VLCVarChoiceModel()
|
|
{
|
|
if (m_object->get())
|
|
{
|
|
var_DelCallback(m_object->get(), qtu(m_varname), VLCVarChoiceModel::on_variable_callback, this);
|
|
var_DelListCallback(m_object->get(), qtu(m_varname), VLCVarChoiceModel::on_variable_list_callback, this);
|
|
var_Destroy(m_object->get(), qtu(m_varname));
|
|
}
|
|
}
|
|
|
|
Qt::ItemFlags VLCVarChoiceModel::flags(const QModelIndex &) const
|
|
{
|
|
return Qt::ItemFlag::ItemIsUserCheckable;
|
|
}
|
|
|
|
QHash<int, QByteArray> VLCVarChoiceModel::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> roleNames = this->QAbstractListModel::roleNames();
|
|
roleNames[Qt::CheckStateRole] = "checked";
|
|
return roleNames;
|
|
}
|
|
|
|
int VLCVarChoiceModel::rowCount(const QModelIndex &) const
|
|
{
|
|
if (!m_object->get())
|
|
return 0;
|
|
return m_values.count();
|
|
}
|
|
|
|
QVariant VLCVarChoiceModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!m_object->get())
|
|
return {};
|
|
|
|
int row = index.row();
|
|
if (row < 0 || row >= m_values.count())
|
|
return {};
|
|
|
|
if (role == Qt::DisplayRole)
|
|
return m_titles[row];
|
|
else if (role == Qt::CheckStateRole)
|
|
return row == m_current;
|
|
return {};
|
|
}
|
|
|
|
bool VLCVarChoiceModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
{
|
|
if (!m_object->get())
|
|
return false;
|
|
|
|
int row = index.row();
|
|
if (role == Qt::CheckStateRole && row >= 0 && row < m_values.count())
|
|
{
|
|
//only update the variable when we select an entry
|
|
if (!value.toBool())
|
|
return false;
|
|
|
|
int ret = VLC_EGENERIC;
|
|
switch (m_type & VLC_VAR_CLASS) {
|
|
case VLC_VAR_STRING:
|
|
ret = var_SetString(m_object->get(), qtu(m_varname), qtu(m_values[row].toString()) );
|
|
break;
|
|
case VLC_VAR_INTEGER:
|
|
ret = var_SetInteger(m_object->get(), qtu(m_varname), m_values[row].toInt() );
|
|
break;
|
|
case VLC_VAR_FLOAT:
|
|
ret = var_SetFloat(m_object->get(), qtu(m_varname), m_values[row].toFloat() );
|
|
break;
|
|
case VLC_VAR_BOOL:
|
|
ret = var_SetBool(m_object->get(), qtu(m_varname), m_values[row].toBool() );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return ret == VLC_SUCCESS;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
//update the choices of the variable, called on variable thread from the var_AddCallback callback
|
|
//calling vlcValToVariant is safe here as m_type will only be modified when no callbacks is registered
|
|
int VLCVarChoiceModel::updateData(const vlc_object_t* object, const vlc_value_t& oldvalue, const vlc_value_t& newvalue)
|
|
{
|
|
QVariant oldvalueVariant = vlcValToVariant(oldvalue);
|
|
QVariant newvalueVariant = vlcValToVariant(newvalue);
|
|
|
|
emit dataUpdated(object, oldvalueVariant, newvalueVariant, QPrivateSignal{});
|
|
return VLC_SUCCESS;
|
|
}
|
|
|
|
//update the choices of the variable, called on variable thread from the var_AddListCallback callback
|
|
//calling vlcValToVariant is safe here as m_type will only be modified when no callbacks is registered
|
|
int VLCVarChoiceModel::updateList(const vlc_object_t* object, int action, const vlc_value_t* p_value)
|
|
{
|
|
QVariant valueVariant = p_value ? vlcValToVariant(*p_value) : QVariant();
|
|
emit listUpdated(object, action, valueVariant, QPrivateSignal{});
|
|
return VLC_SUCCESS;
|
|
}
|
|
|
|
//update the current value of the variable, called on UI thread
|
|
void VLCVarChoiceModel::onDataUpdated(const vlc_object_t* object, QVariant , QVariant newvalue)
|
|
{
|
|
if (object != m_object->get())
|
|
return;
|
|
|
|
int oldCurrent = m_current;
|
|
m_current = -1;
|
|
for (int i = 0; i < m_values.count(); i++)
|
|
if( newvalue == m_values[i] )
|
|
{
|
|
m_current = i;
|
|
break;
|
|
}
|
|
|
|
if (m_current != oldCurrent)
|
|
emit hasCurrentChanged(m_current != -1);
|
|
if (m_current != -1)
|
|
emit dataChanged(index(m_current), index(m_current), { Qt::CheckStateRole } );
|
|
if (oldCurrent != -1)
|
|
emit dataChanged(index(oldCurrent), index(oldCurrent), { Qt::CheckStateRole } );
|
|
}
|
|
|
|
//update the choices of the variable, called on UI thread
|
|
void VLCVarChoiceModel::onListUpdated(const vlc_object_t* object, int action, QVariant newvalue)
|
|
{
|
|
if (object != m_object->get())
|
|
return;
|
|
|
|
switch (action) {
|
|
case VLC_VAR_ADDCHOICE:
|
|
beginInsertRows( QModelIndex{}, m_values.count(), m_values.count() );
|
|
m_values.append( newvalue );
|
|
//we should probably rather get the whole choices list to get the associated text
|
|
m_titles.append( newvalue.toString() );
|
|
endInsertRows();
|
|
break;
|
|
case VLC_VAR_DELCHOICE:
|
|
{
|
|
int i = 0;
|
|
for (i = 0; i < m_values.count(); i++)
|
|
if (newvalue == m_values[i])
|
|
break;
|
|
if (i != m_values.count())
|
|
{
|
|
beginRemoveRows( QModelIndex{}, i, i);
|
|
m_values.removeAt(i);
|
|
m_titles.removeAt(i);
|
|
endRemoveRows();
|
|
}
|
|
break;
|
|
}
|
|
case VLC_VAR_CLEARCHOICES:
|
|
beginResetModel();
|
|
m_values.clear();
|
|
m_titles.clear();
|
|
endResetModel();
|
|
break;
|
|
default:
|
|
//N/A
|
|
break;
|
|
}
|
|
}
|
|
|
|
QString VLCVarChoiceModel::vlcValToString(const vlc_value_t &value)
|
|
{
|
|
switch (m_type & VLC_VAR_CLASS) {
|
|
case VLC_VAR_INTEGER:
|
|
return QString::number(value.i_int);
|
|
case VLC_VAR_STRING:
|
|
return qfu(value.psz_string);
|
|
case VLC_VAR_FLOAT:
|
|
return QString::number(value.f_float);
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
QVariant VLCVarChoiceModel::vlcValToVariant(const vlc_value_t &value)
|
|
{
|
|
switch (m_type & VLC_VAR_CLASS) {
|
|
case VLC_VAR_INTEGER:
|
|
return QVariant::fromValue<qlonglong>(value.i_int);
|
|
case VLC_VAR_STRING:
|
|
return qfu(value.psz_string);
|
|
case VLC_VAR_FLOAT:
|
|
return value.f_float;
|
|
case VLC_VAR_BOOL:
|
|
return value.b_bool;
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
bool VLCVarChoiceModel::hasCurrent() const
|
|
{
|
|
return m_current != -1;
|
|
}
|
|
|
|
int VLCVarChoiceModel::currentRow() const
|
|
{
|
|
return m_current;
|
|
}
|
|
|
|
void VLCVarChoiceModel::toggleIndex(int index)
|
|
{
|
|
setData(QAbstractItemModel::createIndex(index,0),true,Qt::CheckStateRole);
|
|
}
|
|
|