Commit 347b73a8 authored by Stepan Salenikovich's avatar Stepan Salenikovich Committed by Eloi Bail
Browse files

gnome: bind to the UserActionModel

GActions call the UserActionModel and the UAM
updates the state of the GActions. This also
solves the problem of the unsyced hold action.

Refs #67159

Change-Id: I70900888deb51275decdff19607a846b191b24d1
parent 2efd1981
......@@ -146,129 +146,11 @@ ring_client_command_line(GApplication *app, GApplicationCommandLine *cmdline)
return 0;
}
static void
call_accept(G_GNUC_UNUSED GSimpleAction *action, G_GNUC_UNUSED GVariant *param, G_GNUC_UNUSED gpointer client)
{
g_debug("call accpet action");
/* TODO: implement using UserActionModel once its fixed */
QModelIndex idx = CallModel::instance()->selectionModel()->currentIndex();
if (idx.isValid()) {
Call *call = CallModel::instance()->getCall(idx);
call->performAction(Call::Action::ACCEPT);
}
}
static void
call_hangup(G_GNUC_UNUSED GSimpleAction *action, G_GNUC_UNUSED GVariant *param, G_GNUC_UNUSED gpointer client)
{
g_debug("call hangup action");
/* TODO: implement using UserActionModel once its fixed */
QModelIndex idx = CallModel::instance()->selectionModel()->currentIndex();
if (idx.isValid()) {
Call *call = CallModel::instance()->getCall(idx);
call->performAction(Call::Action::REFUSE);
}
}
static void
call_hold(GSimpleAction *action, GVariant *state, G_GNUC_UNUSED gpointer data)
{
g_debug("call hold action");
/* TODO: implement using UserActionModel once its fixed */
/* get the requested state and apply it */
gboolean requested = g_variant_get_boolean(state);
g_simple_action_set_state(action, g_variant_new_boolean(requested));
QModelIndex idx = CallModel::instance()->selectionModel()->currentIndex();
if (idx.isValid()) {
Call *call = CallModel::instance()->getCall(idx);
call->performAction(Call::Action::HOLD);
}
}
/* starting glib 2.40 the action() parameter in the action entry (the second one)
* can be left NULL for stateful boolean actions and they will automatically be
* toggled; for older versions of glib we must explicitly set a handler to toggle them */
#if GLIB_CHECK_VERSION(2,40,0)
static const GActionEntry ring_actions[] =
{
{ "accept", call_accept, NULL, NULL, NULL, {0} },
{ "hangup", call_hangup, NULL, NULL, NULL, {0} },
{ "hold", NULL, NULL, "false", call_hold, {0} },
/* TODO implement the other actions */
// { "mute_audio", NULL, NULL, "false", NULL, {0} },
// { "mute_video", NULL, NULL, "false", NULL, {0} },
// { "transfer", NULL, NULL, "flase", NULL, {0} },
// { "record", NULL, NULL, "false", NULL, {0} }
};
#else
/* adapted from glib 2.40, gsimpleaction.c */
static void
g_simple_action_change_state(GSimpleAction *simple, GVariant *value)
{
GAction *action = G_ACTION(simple);
guint change_state_id = g_signal_lookup("change-state", G_OBJECT_TYPE(simple));
/* If the user connected a signal handler then they are responsible
* for handling state changes.
*/
if (g_signal_has_handler_pending(action, change_state_id, 0, TRUE))
g_signal_emit(action, change_state_id, 0, value);
/* If not, then the default behaviour is to just set the state. */
else
g_simple_action_set_state(simple, value);
}
/* define activate handler for simple toggle actions for glib < 2.40
* adapted from glib 2.40, gsimpleaction.c */
static void
g_simple_action_toggle(GSimpleAction *action, GVariant *parameter, G_GNUC_UNUSED gpointer user_data)
{
const GVariantType *parameter_type = g_action_get_parameter_type(G_ACTION(action));
g_return_if_fail(parameter_type == NULL ?
parameter == NULL :
(parameter != NULL &&
g_variant_is_of_type(parameter, parameter_type)));
if (parameter != NULL)
g_variant_ref_sink(parameter);
if (g_action_get_enabled(G_ACTION(action))) {
/* make sure it is a stateful action and toggle it */
GVariant *state = g_action_get_state(G_ACTION(action));
if (state) {
/* If we have no parameter and this is a boolean action, toggle. */
if (parameter == NULL && g_variant_is_of_type(state, G_VARIANT_TYPE_BOOLEAN)) {
gboolean was_enabled = g_variant_get_boolean(state);
g_simple_action_change_state(action, g_variant_new_boolean(!was_enabled));
}
/* else, if the parameter and state type are the same, do a change-state */
else if (g_variant_is_of_type (state, g_variant_get_type(parameter)))
g_simple_action_change_state(action, parameter);
}
g_variant_unref(state);
}
if (parameter != NULL)
g_variant_unref (parameter);
}
static const GActionEntry ring_actions[] =
{
{ "accept", call_accept, NULL, NULL, NULL, {0} },
{ "hangup", call_hangup, NULL, NULL, NULL, {0} },
{ "hold", g_simple_action_toggle, NULL, "false", call_hold, {0} },
{ "accept", NULL, NULL, NULL, NULL, {0} },
{ "hangup", NULL, NULL, NULL, NULL, {0} },
{ "hold", NULL, NULL, "false", NULL, {0} },
/* TODO implement the other actions */
// { "mute_audio", NULL, NULL, "false", NULL, {0} },
// { "mute_video", NULL, NULL, "false", NULL, {0} },
......@@ -276,9 +158,7 @@ static const GActionEntry ring_actions[] =
// { "record", NULL, NULL, "false", NULL, {0} }
};
#endif
/* TODO: uncomment when UserActionModel is fixed and used
/* this union is used to pass the int refering to the Action as a parameter to the GAction callback */
typedef union _int_ptr_t
{
int value;
......@@ -297,7 +177,6 @@ activate_action(GSimpleAction *action, G_GNUC_UNUSED GVariant *parameter, gpoint
uam << a;
}
*/
static void
ring_client_startup(GApplication *app)
......@@ -309,43 +188,39 @@ ring_client_startup(GApplication *app)
g_action_map_add_action_entries(
G_ACTION_MAP(app), ring_actions, G_N_ELEMENTS(ring_actions), client);
/* TODO: Bind actions to the useractionmodel once it is working */
// UserActionModel* uam = CallModel::instance()->userActionModel();
// QHash<int, GSimpleAction*> actionHash;
// actionHash[ (int)UserActionModel::Action::ACCEPT ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "accept"));
// actionHash[ (int)UserActionModel::Action::HOLD ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "hold"));
// // actionHash[ (int)UserActionModel::Action::MUTE_AUDIO ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "mute_audio"));
// // actionHash[ (int)UserActionModel::Action::SERVER_TRANSFER ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "transfer"));
// // actionHash[ (int)UserActionModel::Action::RECORD ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "record"));
// actionHash[ (int)UserActionModel::Action::HANGUP ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "hangup"));
// for (QHash<int,GSimpleAction*>::const_iterator i = actionHash.begin(); i != actionHash.end(); ++i) {
// GSimpleAction* sa = i.value();
// // UserActionModel::Action a = static_cast<UserActionModel::Action>(i.key());
// // connect(ea, &QAction::triggered, [uam,a](bool) {uam << a;});
// int_ptr_t user_data;
// user_data.value = i.key();
// g_signal_connect(G_OBJECT(sa), "activate", G_CALLBACK(activate_action), user_data.ptr);
// }
// QObject::connect(uam,&UserActionModel::dataChanged, [actionHash,uam](const QModelIndex& tl, const QModelIndex& br) {
// const int first(tl.row()),last(br.row());
// for(int i = first; i <= last;i++) {
// const QModelIndex& idx = uam->index(i,0);
// GSimpleAction* sa = actionHash[(int)qvariant_cast<UserActionModel::Action>(idx.data(UserActionModel::Role::ACTION))];
// if (sa) {
// // a->setText ( idx.data(Qt::DisplayRole).toString() );
// // a->setEnabled( idx.flags() & Qt::ItemIsEnabled );
// g_simple_action_set_enabled(sa, idx.flags() & Qt::ItemIsEnabled);
// // a->setChecked( idx.data(Qt::CheckStateRole) == Qt::Checked );
// /* check if statefull action */
// if (g_action_get_state_type(G_ACTION(sa)) != NULL)
// g_simple_action_set_state(sa, g_variant_new_boolean(idx.data(Qt::CheckStateRole) == Qt::Checked));
// // a->setAltIcon( qvariant_cast<QPixmap>(idx.data(Qt::DecorationRole)) );
// }
// }
// });
/* Bind GActions to the UserActionModel */
UserActionModel* uam = CallModel::instance()->userActionModel();
QHash<int, GSimpleAction*> actionHash;
actionHash[ (int)UserActionModel::Action::ACCEPT ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "accept"));
actionHash[ (int)UserActionModel::Action::HOLD ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "hold"));
/* TODO: add commented actions when ready */
// actionHash[ (int)UserActionModel::Action::MUTE_AUDIO ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "mute_audio"));
// actionHash[ (int)UserActionModel::Action::SERVER_TRANSFER ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "transfer"));
// actionHash[ (int)UserActionModel::Action::RECORD ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "record"));
actionHash[ (int)UserActionModel::Action::HANGUP ] = G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "hangup"));
for (QHash<int,GSimpleAction*>::const_iterator i = actionHash.begin(); i != actionHash.end(); ++i) {
GSimpleAction* sa = i.value();
int_ptr_t user_data;
user_data.value = i.key();
g_signal_connect(G_OBJECT(sa), "activate", G_CALLBACK(activate_action), user_data.ptr);
}
/* change the state of the GActions based on the UserActionModel */
QObject::connect(uam,&UserActionModel::dataChanged, [actionHash,uam](const QModelIndex& tl, const QModelIndex& br) {
const int first(tl.row()),last(br.row());
for(int i = first; i <= last;i++) {
const QModelIndex& idx = uam->index(i,0);
GSimpleAction* sa = actionHash[(int)qvariant_cast<UserActionModel::Action>(idx.data(UserActionModel::Role::ACTION))];
if (sa) {
/* enable/disable GAction based on UserActionModel */
g_simple_action_set_enabled(sa, idx.flags() & Qt::ItemIsEnabled);
/* set the state of the action if its stateful */
if (g_action_get_state_type(G_ACTION(sa)) != NULL)
g_simple_action_set_state(sa, g_variant_new_boolean(idx.data(Qt::CheckStateRole) == Qt::Checked));
}
}
});
}
static void
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment