diff --git a/src/actions/abstract.c b/src/actions/abstract.c index eeaf314..cea7cf0 100644 --- a/src/actions/abstract.c +++ b/src/actions/abstract.c @@ -60,6 +60,13 @@ PROP_STATE }; + enum { + SIGNAL_CHANGE_STATE, + NR_SIGNALS + }; + + static guint action_signals[NR_SIGNALS]; + G_DEFINE_TYPE_WITH_CODE(pw3270Action, pw3270Action, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_ACTION, pw3270_action_iface_init)) void pw3270_action_iface_init(GActionInterface *iface) { @@ -128,6 +135,18 @@ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + // Install signals + action_signals[SIGNAL_CHANGE_STATE] = + g_signal_new( + I_("change-state"), + G_TYPE_SIMPLE_ACTION, + G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT, + 0, NULL, NULL, + NULL, + G_TYPE_NONE, 1, + G_TYPE_VARIANT + ); } void pw3270Action_init(pw3270Action *action) { @@ -304,6 +323,10 @@ action->state = g_variant_ref(value); + if (g_signal_has_handler_pending(object, action_signals[SIGNAL_CHANGE_STATE], 0, TRUE)) { + g_signal_emit(object, action_signals[SIGNAL_CHANGE_STATE], 0, value); + } + g_object_notify(G_OBJECT(object), "state"); } @@ -314,6 +337,14 @@ } + void pw3270_action_set_enabled(GAction *object, gboolean state) { + +// pw3270Action * action = PW3270_ACTION(object); + + g_object_notify(G_OBJECT(object), "enabled"); + } + + static void change_widget(GAction *action, GtkWidget G_GNUC_UNUSED(*from), GtkWidget *to) { PW3270_ACTION(action)->terminal = to; } @@ -354,7 +385,7 @@ debug("%s: terminal=%p",__FUNCTION__,action->terminal); if(action && action->terminal) { - return PW3270_ACTION_GET_CLASS(object)->activate(object,parameter,action->terminal); + PW3270_ACTION_GET_CLASS(object)->activate(object,parameter,action->terminal); } } diff --git a/src/actions/lib3270/action.c b/src/actions/lib3270/action.c index 53095fd..c307e20 100644 --- a/src/actions/lib3270/action.c +++ b/src/actions/lib3270/action.c @@ -53,11 +53,17 @@ static void Lib3270Action_class_init(Lib3270ActionClass *klass); static void Lib3270Action_init(Lib3270Action *action); + static void change_widget(GAction *object, GtkWidget *from, GtkWidget *to); G_DEFINE_TYPE(Lib3270Action, Lib3270Action, PW3270_TYPE_ACTION); static gboolean get_enabled(GAction *action, GtkWidget *terminal) { - return PW3270_LIB3270_ACTION(action)->definition->activatable(v3270_get_session(terminal)) > 0 ? TRUE : FALSE; + + if(terminal) + return PW3270_LIB3270_ACTION(action)->definition->activatable(v3270_get_session(terminal)) > 0 ? TRUE : FALSE; + + return FALSE; + } static void activate(GAction *action, GVariant *parameter, GtkWidget *terminal) { @@ -70,6 +76,7 @@ action->activate = activate; action->get_enabled = get_enabled; + action->change_widget = change_widget; } @@ -92,4 +99,14 @@ return G_ACTION(action); } + void change_widget(GAction *object, GtkWidget *from, GtkWidget *to) { + + PW3270_ACTION_CLASS(Lib3270Action_parent_class)->change_widget(object,from,to); + + // Does the "enabled" state has changed? If yes notify customers. + gboolean enabled = get_enabled(object,to); + if(get_enabled(object,from) != enabled) + pw3270_action_set_enabled(object,enabled); + + } diff --git a/src/actions/private.h b/src/actions/private.h index 32b0cd1..772998f 100644 --- a/src/actions/private.h +++ b/src/actions/private.h @@ -48,6 +48,9 @@ #include + /* not really I18N-related, but also a string marker macro */ + #define I_(string) g_intern_static_string (string) + struct _pw3270Action { GObject parent; @@ -71,6 +74,7 @@ G_GNUC_INTERNAL GAction * pw3270_toggle_action_new_from_lib3270(const LIB3270_TOGGLE * definition); G_GNUC_INTERNAL void pw3270_action_change_state_boolean(GAction *action, gboolean state); + G_GNUC_INTERNAL void pw3270_action_set_enabled(GAction *action, gboolean state); #endif // PRIVATE_H_INCLUDED -- libgit2 0.21.2