diff --git a/src/include/pw3270/actions.h b/src/include/pw3270/actions.h index 241f1d5..150f1d8 100644 --- a/src/include/pw3270/actions.h +++ b/src/include/pw3270/actions.h @@ -70,6 +70,8 @@ /// @brief Get State method. GVariant * (*get_state_property)(GAction *action, GtkWidget *terminal); + /// @brief Get state hint. + GVariant * (*get_state_hint)(GAction *action, GtkWidget *terminal); } pw3270Action; @@ -209,7 +211,7 @@ GType v3270PropertyAction_get_type(void) G_GNUC_CONST; - v3270PropertyAction * v3270_property_action_new(GtkWidget *widget, const gchar *property_name); + GAction * v3270_property_action_new(GtkWidget *widget, const gchar *property_name); G_END_DECLS diff --git a/src/objects/actions/abstract.c b/src/objects/actions/abstract.c index 2b32870..a10b50a 100644 --- a/src/objects/actions/abstract.c +++ b/src/objects/actions/abstract.c @@ -49,6 +49,7 @@ static GVariant * internal_get_state_property(GAction *action, GtkWidget *terminal); static gboolean internal_get_enabled(GAction *action, GtkWidget *terminal); static void internal_activate(GAction *action, GVariant *parameter, GtkWidget *terminal); + static GVariant * internal_get_state_hint(GAction *action, GtkWidget *terminal); static const GVariantType * get_parameter_type(GAction *action); static GVariant * get_state_hint(GAction *action); @@ -176,6 +177,7 @@ action->activate = internal_activate; action->get_state_property = internal_get_state_property; + action->get_state_hint = internal_get_state_hint; } @@ -266,6 +268,10 @@ } + GVariant * internal_get_state_hint(GAction G_GNUC_UNUSED(*action), GtkWidget G_GNUC_UNUSED(*terminal)) { + return NULL; + } + GVariant * internal_get_state_property(GAction *object, GtkWidget G_GNUC_UNUSED(*terminal)) { pw3270Action * action = PW3270_ACTION(object); @@ -300,11 +306,12 @@ return PW3270_ACTION(object)->types.state; } - GVariant * get_state_hint(GAction G_GNUC_UNUSED(*action)) { - return NULL; + GVariant * get_state_hint(GAction *object) { + pw3270Action *action = PW3270_ACTION(object); + return action->get_state_hint(object,action->terminal); } - void change_state(GAction *object, GVariant *value) { + void change_state(GAction G_GNUC_UNUSED(*object), GVariant G_GNUC_UNUSED(*value)) { debug("%s",__FUNCTION__) } diff --git a/src/objects/actions/v3270/property.c b/src/objects/actions/v3270/property.c index 4f74526..3674a6b 100644 --- a/src/objects/actions/v3270/property.c +++ b/src/objects/actions/v3270/property.c @@ -37,18 +37,19 @@ */ #include "../private.h" + #include #include #include static void v3270PropertyAction_class_init(v3270PropertyActionClass *klass); static void v3270PropertyAction_init(v3270PropertyAction *action); static GVariant * get_state(GAction *action, GtkWidget *terminal); - + static void change_widget(GAction *object, GtkWidget *from, GtkWidget *to); G_DEFINE_TYPE(v3270PropertyAction, v3270PropertyAction, PW3270_TYPE_ACTION); void v3270PropertyAction_class_init(v3270PropertyActionClass *klass) { - + klass->parent_class.change_widget = change_widget; } static void v3270PropertyAction_init(v3270PropertyAction *action) { @@ -57,22 +58,25 @@ } - GVariant * get_state(GAction *action, GtkWidget *terminal) { - - if(!terminal) - return NULL; - - debug("%s",__FUNCTION__); + GVariant * get_state(GAction *object, GtkWidget *terminal) { - v3270PropertyAction * paction = V3270_PROPERTY_ACTION(action); + v3270PropertyAction * action = V3270_PROPERTY_ACTION(object); + GVariant * result = NULL; GValue value = G_VALUE_INIT; - GVariant *result = NULL; - g_value_init(&value, paction->pspec->value_type); - g_object_get_property(G_OBJECT(terminal), paction->pspec->name, &value); + g_value_init(&value, action->pspec->value_type); + g_object_get_property(G_OBJECT(terminal), action->pspec->name, &value); - switch(paction->pspec->value_type) { + switch(action->pspec->value_type) { + case G_TYPE_UINT: + result = g_variant_new_take_string(g_strdup_printf("%d",g_value_get_uint(&value))); + break; + + case G_TYPE_STRING: + result = g_variant_new_string(g_value_get_string(&value)); + break; + /* case G_TYPE_BOOLEAN: result = g_variant_new_boolean(g_value_get_boolean(&value)); break; @@ -81,11 +85,6 @@ result = g_variant_new_int32(g_value_get_int(&value)); break; - case G_TYPE_UINT: - result = g_variant_new_uint32(g_value_get_uint(&value)); - debug("state of %s is %u",g_action_get_name(action),g_value_get_uint(&value)); - break; - case G_TYPE_DOUBLE: result = g_variant_new_double(g_value_get_double(&value)); break; @@ -94,85 +93,133 @@ result = g_variant_new_double(g_value_get_float(&value)); break; - case G_TYPE_STRING: - result = g_variant_new_string(g_value_get_string(&value)); - break; - + */ + default: + g_warning("Unexpected value type getting state for action \"%s\"",g_action_get_name(object)); } g_value_unset (&value); - return result; - - } - - static void activate(GAction *action, GVariant *parameter, GtkWidget *terminal) { +#ifdef DEBUG + if(result) + { + debug("Action %s set to \"%s\"",g_action_get_name(object),g_variant_get_string(result,NULL)); + } + else + { + debug("Action %s set to \"%s\"",g_action_get_name(object),"NULL"); + } +#endif // DEBUG - debug("%s(%s,%p,%p)",__FUNCTION__,g_action_get_name(action),parameter,terminal); + return result; } - v3270PropertyAction * v3270_property_action_new(GtkWidget *widget, const gchar *property_name) { + static void activate(GAction *object, GVariant *parameter, GtkWidget *terminal) { - GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(widget), property_name); + debug("%s(%s,%s,%p)",__FUNCTION__,g_action_get_name(object),g_variant_get_string(parameter,NULL),terminal); - if(~pspec->flags & G_PARAM_READABLE || ~pspec->flags & G_PARAM_WRITABLE || pspec->flags & G_PARAM_CONSTRUCT_ONLY) { + v3270PropertyAction * action = V3270_PROPERTY_ACTION(object); - g_warning( - "Property '%s::%s' must be readable, writable, and not construct-only", - G_OBJECT_TYPE_NAME(G_OBJECT(widget)), - property_name - ); - - return NULL; - } + GValue value = G_VALUE_INIT; + g_value_init(&value, action->pspec->value_type); - // Get state type - const GVariantType * type; + switch(action->pspec->value_type) + { + case G_TYPE_UINT: + g_value_set_uint(&value,atoi(g_variant_get_string(parameter,NULL))); + break; - switch(pspec->value_type) { + /* case G_TYPE_BOOLEAN: - type = G_VARIANT_TYPE_BOOLEAN; - debug("%s: Type of \"%s\" is %s",__FUNCTION__,property_name,"boolean"); break; case G_TYPE_INT: - type = G_VARIANT_TYPE_INT32; - debug("%s: Type of \"%s\" is %s",__FUNCTION__,property_name,"int32"); break; - case G_TYPE_UINT: - type = G_VARIANT_TYPE_UINT32; - debug("%s: Type of \"%s\" is %s",__FUNCTION__,property_name,"uint32"); + case G_TYPE_DOUBLE: break; - case G_TYPE_DOUBLE: case G_TYPE_FLOAT: - type = G_VARIANT_TYPE_DOUBLE; break; case G_TYPE_STRING: - type = G_VARIANT_TYPE_STRING; break; + */ default: + g_warning("Can't activate action \"%s\"",g_action_get_name(object)); + g_value_unset(&value); + return; + } + + g_object_set_property(G_OBJECT(terminal),action->pspec->name,&value); + + g_value_unset(&value); + + } + + static void on_notify(GtkWidget G_GNUC_UNUSED(*terminal), GParamSpec G_GNUC_UNUSED(*pspec), GAction *action) { + + debug("%s: State of action %s has changed",__FUNCTION__, g_action_get_name(G_ACTION(action))); + pw3270_action_notify_state(action); + + } + + GAction * v3270_property_action_new(GtkWidget *widget, const gchar *property_name) { + + GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(widget), property_name); + + if(~pspec->flags & G_PARAM_READABLE || ~pspec->flags & G_PARAM_WRITABLE || pspec->flags & G_PARAM_CONSTRUCT_ONLY) { + g_warning( - "Unable to create action for property '%s::%s' of type '%s'", - g_type_name(pspec->owner_type), - pspec->name, - g_type_name(pspec->value_type) - ); + "Property '%s::%s' must be readable, writable, and not construct-only", + G_OBJECT_TYPE_NAME(G_OBJECT(widget)), + property_name + ); + return NULL; } v3270PropertyAction * action = (v3270PropertyAction *) g_object_new(V3270_TYPE_PROPERTY_ACTION, NULL); action->parent.name = pspec->name; - action->parent.types.state = type; - action->parent.types.parameter = type; + action->parent.types.state = G_VARIANT_TYPE_STRING; + action->parent.types.parameter = G_VARIANT_TYPE_STRING; action->parent.activate = activate; action->pspec = pspec; pw3270_action_set_terminal_widget(G_ACTION(action), widget); - return action; + + return G_ACTION(action); + } + + void change_widget(GAction *object, GtkWidget *from, GtkWidget *to) { + + v3270PropertyAction * action = V3270_PROPERTY_ACTION(object); + g_autofree gchar * signal_name = g_strconcat("notify::", action->pspec->name,NULL); + + if(from) { + gulong handler = g_signal_handler_find( + from, + G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + G_CALLBACK(on_notify), + action + ); + + if(handler) + g_signal_handler_disconnect(from, handler); + + } + + PW3270_ACTION_CLASS(v3270PropertyAction_parent_class)->change_widget(object,from,to); + + if(to) { + g_signal_connect(G_OBJECT(to),signal_name,G_CALLBACK(on_notify),action); + } + } + diff --git a/src/objects/application/application.c b/src/objects/application/application.c index f8fd865..6b5935e 100644 --- a/src/objects/application/application.c +++ b/src/objects/application/application.c @@ -245,6 +245,15 @@ .name = "open.window", .activate = pw3270_application_generic_activated, }, + + /* + { + .name = "model-number", + .activate = model_cb, + .parameter_type = "s" + } + */ + }; g_action_map_add_action_entries( @@ -276,12 +285,35 @@ // Create terminal widget & associated widget GtkWidget * terminal = pw3270_terminal_new(window); + /* GAction * action = G_ACTION(v3270_property_action_new(terminal,"model_number")); - if(action) { debug("Adding window action \"%s\"",g_action_get_name(action)); g_action_map_add_action(G_ACTION_MAP(window),action); } + */ + + // https://developer.gnome.org/gnome-devel-demos/stable/menubar.vala.html.en + + /* + static const GActionEntry actions[] = { + + { + .name = "model-number", + .activate = model_cb, + .parameter_type = "s", + .state = "2" + } + + }; + + g_action_map_add_action_entries(G_ACTION_MAP(window),actions,G_N_ELEMENTS(actions),NULL); + */ + + g_action_map_add_action( + G_ACTION_MAP(window), + v3270_property_action_new(terminal,"model-number") + ); // Present the new window pw3270_window_set_current_page(window,0); diff --git a/src/objects/window/private.h b/src/objects/window/private.h index e61a468..87b7190 100644 --- a/src/objects/window/private.h +++ b/src/objects/window/private.h @@ -70,6 +70,9 @@ GAction * pw3270_session_preferences_action_new(void); GAction * pw3270_file_transfer_action_new(void); + // Terminal actions. + GAction * pw3270_model_number_action_new(GtkWidget *terminal); + G_GNUC_INTERNAL void pw3270_window_open_activated(GSimpleAction * action, GVariant *parameter, gpointer application); G_GNUC_INTERNAL void pw3270_window_close_activated(GSimpleAction * action, GVariant *parameter, gpointer application); diff --git a/ui/application.xml b/ui/application.xml index 01392ca..5f042a9 100644 --- a/ui/application.xml +++ b/ui/application.xml @@ -242,23 +242,30 @@ + Screen size + + + Model 2 - 80x24 win.model-number - 2 + 2 Model 3 - 80x32 win.model-number + 3 Model 4 - 80x43 win.model-number + 4 Model 5 - 132x27 win.model-number + 5 -- libgit2 0.21.2