diff --git a/pw3270.cbp b/pw3270.cbp index fd059ab..bc822d9 100644 --- a/pw3270.cbp +++ b/pw3270.cbp @@ -91,7 +91,7 @@ - + diff --git a/src/include/pw3270/actions.h b/src/include/pw3270/actions.h index c02fefa..a7384d2 100644 --- a/src/include/pw3270/actions.h +++ b/src/include/pw3270/actions.h @@ -104,6 +104,9 @@ /// @brief Get action name. const gchar * pw3270_action_get_name(GAction *action); + /// @brief Set action name. + void pw3270_action_set_name(GAction *action, const gchar *name); + /// @brief Get the action icon name. const gchar * pw3270_action_get_icon_name(GAction *action); @@ -216,32 +219,32 @@ GAction * v3270_property_action_new(GtkWidget *widget, const gchar *property_name); // - // V3270 Copy action + // V3270 action who can be enable based on property // - #define V3270_TYPE_COPY_ACTION (v3270CopyAction_get_type()) - #define V3270_COPY_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), V3270_TYPE_COPY_ACTION, v3270CopyAction)) - #define V3270_COPY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), V3270_TYPE_COPY_ACTION, v3270CopyActionClass)) - #define V3270_IS_COPY_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), V3270_TYPE_COPY_ACTION)) - #define V3270_IS_COPY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), V3270_TYPE_COPY_ACTION)) - #define V3270_COPY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), V3270_TYPE_COPY_ACTION, v3270CopyActionClass)) + #define V3270_TYPE_CONDITIONAL_ACTION (v3270ConditionalAction_get_type()) + #define V3270_CONDITIONAL_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), V3270_TYPE_CONDITIONAL_ACTION, v3270ConditionalAction)) + #define V3270_CONDITIONAL_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), V3270_TYPE_CONDITIONAL_ACTION, v3270ConditionalActionClass)) + #define V3270_IS_CONDITIONAL_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), V3270_TYPE_CONDITIONAL_ACTION)) + #define V3270_IS_CONDITIONAL_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), V3270_TYPE_CONDITIONAL_ACTION)) + #define V3270_CONDITIONAL_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), V3270_TYPE_CONDITIONAL_ACTION, v3270ConditionalActionClass)) - typedef struct _v3270CopyAction { + typedef struct _v3270ConditionalAction { pw3270SimpleAction parent; GParamSpec *pspec; - } v3270CopyAction; + } v3270ConditionalAction; typedef struct _v3270CopyActionClass { pw3270SimpleActionClass parent_class; - } v3270CopyActionClass; + } v3270ConditionalActionClass; - GType v3270CopyAction_get_type(void) G_GNUC_CONST; + GType v3270ConditionalAction_get_type(void) G_GNUC_CONST; - GAction * v3270_copy_action_new(GtkWidget *widget); + GAction * v3270_conditional_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 d93c233..515288f 100644 --- a/src/objects/actions/abstract.c +++ b/src/objects/actions/abstract.c @@ -261,11 +261,8 @@ return PW3270_ACTION(action)->name; } - void pw3270_action_set_name(GAction *object, const gchar *name) { - - if(name) - g_warning("Invalid call to %s on action %s with value \"%s\"",__FUNCTION__,g_action_get_name(object),name); - + void pw3270_action_set_name(GAction *action, const gchar *name) { + PW3270_ACTION(action)->name = g_intern_string(name); } GVariant * internal_get_state_hint(GAction G_GNUC_UNUSED(*action), GtkWidget G_GNUC_UNUSED(*terminal)) { diff --git a/src/objects/actions/simple.c b/src/objects/actions/simple.c index e8df206..d86fa31 100644 --- a/src/objects/actions/simple.c +++ b/src/objects/actions/simple.c @@ -131,6 +131,7 @@ } + pw3270SimpleAction * pw3270_simple_action_new_from_name(const gchar *source_name, const gchar *name) { return pw3270_simple_action_new_from_lib3270(lib3270_action_get_by_name(source_name),name); } diff --git a/src/objects/actions/v3270/conditional.c b/src/objects/actions/v3270/conditional.c new file mode 100644 index 0000000..1fb95ed --- /dev/null +++ b/src/objects/actions/v3270/conditional.c @@ -0,0 +1,172 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + /** + * @brief Implement GAction who enables/disable based on a v3270 boolean property. + * + * Reference: + * + * + * + */ + + #include "../private.h" + #include + #include + #include + #include + + static void v3270ConditionalAction_class_init(v3270ConditionalActionClass *klass); + static void v3270ConditionalAction_init(v3270ConditionalAction *action); + static gboolean get_enabled(GAction *action, GtkWidget *terminal); + static void change_widget(GAction *object, GtkWidget *from, GtkWidget *to); + + G_DEFINE_TYPE(v3270ConditionalAction, v3270ConditionalAction, PW3270_TYPE_SIMPLE_ACTION); + + void v3270ConditionalAction_class_init(v3270ConditionalActionClass *klass) { + + klass->parent_class.parent_class.change_widget = change_widget; + klass->parent_class.parent_class.get_enabled = get_enabled; + + } + + static void v3270ConditionalAction_init(v3270ConditionalAction G_GNUC_UNUSED(*action)) { + } + + static void on_notify(GtkWidget G_GNUC_UNUSED(*terminal), GParamSpec G_GNUC_UNUSED(*pspec), GAction *action) { + debug("%s: Enabled of action %s has changed",__FUNCTION__, g_action_get_name(G_ACTION(action))); + pw3270_action_notify_enabled(action); + } + + GAction * v3270_conditional_action_new(GtkWidget *widget, const gchar *property_name) { + + GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(widget), property_name); + + if(!pspec) { + + g_warning( + "Can't find property '%s::%s'", + G_OBJECT_TYPE_NAME(G_OBJECT(widget)), + property_name + ); + + return NULL; + + } + + debug("%s: pspec(%s)=%p",__FUNCTION__,property_name,pspec); + + if(~pspec->flags & G_PARAM_READABLE || pspec->flags & G_PARAM_CONSTRUCT_ONLY) { + + g_warning( + "Property '%s::%s' must be readable and not construct-only", + G_OBJECT_TYPE_NAME(G_OBJECT(widget)), + property_name + ); + + return NULL; + } + + v3270ConditionalAction * action = (v3270ConditionalAction *) g_object_new(V3270_TYPE_CONDITIONAL_ACTION, NULL); + + pw3270_simple_action_set_lib3270_property(PW3270_SIMPLE_ACTION(action), lib3270_property_get_by_name(pspec->name)); + + action->parent.parent.name = g_param_spec_get_name(pspec); + action->parent.tooltip = g_param_spec_get_blurb(pspec); + action->pspec = pspec; + + pw3270_action_set_terminal_widget(G_ACTION(action), widget); + + return G_ACTION(action); + } + + void change_widget(GAction *object, GtkWidget *from, GtkWidget *to) { + + v3270ConditionalAction * action = V3270_CONDITIONAL_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(v3270ConditionalAction_parent_class)->change_widget(object,from,to); + + if(to) { + g_signal_connect(G_OBJECT(to),signal_name,G_CALLBACK(on_notify),action); + } + + pw3270_action_notify_enabled(G_ACTION(object)); + + } + + gboolean get_enabled(GAction *object, GtkWidget *terminal) { + + gboolean enabled = PW3270_ACTION_CLASS(v3270ConditionalAction_parent_class)->get_enabled(object,terminal); + + if(enabled && terminal) { + + // The action is enabled, check property to confirm. + v3270ConditionalAction * action = V3270_CONDITIONAL_ACTION(object); + + GValue value = G_VALUE_INIT; + g_value_init(&value, action->pspec->value_type); + g_object_get_property(G_OBJECT(terminal), action->pspec->name, &value); + + switch(action->pspec->value_type) { + case G_TYPE_UINT: + enabled = g_value_get_uint(&value) != 0; + break; + + case G_TYPE_BOOLEAN: + enabled = g_value_get_boolean(&value); + break; + + default: + enabled = FALSE; + } + + g_value_unset (&value); + + } + + return enabled; + + } diff --git a/src/objects/actions/v3270/copy.c b/src/objects/actions/v3270/copy.c deleted file mode 100644 index 7afba4d..0000000 --- a/src/objects/actions/v3270/copy.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a - * aplicativos mainframe. Registro no INPI sob o nome G3270. - * - * Copyright (C) <2008> - * - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela - * Free Software Foundation. - * - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para - * obter mais detalhes. - * - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301 USA - * - * Este programa está nomeado como - e possui - linhas de código. - * - * Contatos: - * - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) - * - */ - - /** - * @brief Implement PW3270 copy actions. - * - */ - - #include "../private.h" - #include - - static void v3270CopyAction_class_init(v3270CopyActionClass *klass); - static void v3270CopyAction_init(v3270CopyAction *action); - static GVariant * get_state(GAction *action, GtkWidget *terminal); - static void change_widget(GAction *object, GtkWidget *from, GtkWidget *to); - - G_DEFINE_TYPE(v3270CopyAction, v3270CopyAction, PW3270_TYPE_SIMPLE_ACTION); - - void v3270CopyAction_class_init(v3270CopyActionClass *klass) { - klass->parent_class.parent_class.change_widget = change_widget; - } - - static void v3270CopyAction_init(v3270CopyAction *action) { - - action->parent.parent.get_state_property = get_state; - - } - - GVariant * get_state(GAction *object, GtkWidget *terminal) { - - - return NULL; - - } - - static void activate(GAction *object, GVariant *parameter, GtkWidget *terminal) { - - - } - - 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); - - } - - void change_widget(GAction *object, GtkWidget *from, GtkWidget *to) { - - v3270CopyAction * action = V3270_COPY_ACTION(object); - - if(from) { - gulong handler = g_signal_handler_find( - "has-text", - 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(v3270CopyAction_parent_class)->change_widget(object,from,to); - - if(to) { - g_signal_connect(G_OBJECT(to),"has-text",G_CALLBACK(on_notify),action); - } - - } - - - GAction * pw3270_action_print_copy_new(GtkWidget *widget) { - - pw3270SimpleAction * action = (pw3270SimpleAction *) g_object_new(V3270_TYPE_COPY_ACTION, NULL);; - - action->group.id = LIB3270_ACTION_GROUP_ONLINE; - action->parent.name = "print_copy"; - action->label = N_( "Print copy" ); - - return G_ACTION(action); - - } - - GAction * pw3270_action_save_copy_new(GtkWidget *widget) { - - pw3270SimpleAction * action = (pw3270SimpleAction *) g_object_new(V3270_TYPE_COPY_ACTION, NULL);; - - action->group.id = LIB3270_ACTION_GROUP_ONLINE; - action->parent.name = "save_copy"; - action->label = N_( "Save copy" ); - - return G_ACTION(action); - - } diff --git a/src/objects/application/application.c b/src/objects/application/application.c index 7a1b11a..9effc89 100644 --- a/src/objects/application/application.c +++ b/src/objects/application/application.c @@ -299,16 +299,39 @@ } - // Create copy actions. - g_action_map_add_action( - G_ACTION_MAP(window), - pw3270_action_save_copy_new(terminal) - ); + // Create conditional actions. + static const struct { + const gchar * label; + const gchar * tooltip; + const gchar * action_name; + const gchar * property_name; + } conditional_actions[] = { + { + .label = N_("Save copy"), + .action_name = "save_copy", + .property_name = "has_copy" + }, + { + .label = N_("Print copy"), + .action_name = "print_copy", + .property_name = "has_copy" + } + }; - g_action_map_add_action( - G_ACTION_MAP(window), - pw3270_action_print_copy_new(terminal) - ); + for(ix = 0; ix < G_N_ELEMENTS(conditional_actions); ix++) { + + pw3270SimpleAction * action = PW3270_SIMPLE_ACTION(v3270_conditional_action_new(terminal,conditional_actions[ix].property_name)); + + action->parent.name = conditional_actions[ix].action_name; + action->label = conditional_actions[ix].label; + action->tooltip = conditional_actions[ix].tooltip; + + g_action_map_add_action( + G_ACTION_MAP(window), + G_ACTION(action) + ); + + } // Present the new window pw3270_window_set_current_page(window,0); -- libgit2 0.21.2