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