Commit 6308992cabf8a74de2e06da1dbd7bb99c21d8c4f

Authored by Perry Werneck
1 parent ae3f4e70

Implementing action connected to v3270 boolean property for automatic

enabling.
pw3270.cbp
... ... @@ -91,7 +91,7 @@
91 91 <Unit filename="src/objects/actions/simple.c">
92 92 <Option compilerVar="CC" />
93 93 </Unit>
94   - <Unit filename="src/objects/actions/v3270/copy.c">
  94 + <Unit filename="src/objects/actions/v3270/conditional.c">
95 95 <Option compilerVar="CC" />
96 96 </Unit>
97 97 <Unit filename="src/objects/actions/v3270/property.c">
... ...
src/include/pw3270/actions.h
... ... @@ -104,6 +104,9 @@
104 104 /// @brief Get action name.
105 105 const gchar * pw3270_action_get_name(GAction *action);
106 106  
  107 + /// @brief Set action name.
  108 + void pw3270_action_set_name(GAction *action, const gchar *name);
  109 +
107 110 /// @brief Get the action icon name.
108 111 const gchar * pw3270_action_get_icon_name(GAction *action);
109 112  
... ... @@ -216,32 +219,32 @@
216 219 GAction * v3270_property_action_new(GtkWidget *widget, const gchar *property_name);
217 220  
218 221 //
219   - // V3270 Copy action
  222 + // V3270 action who can be enable based on property
220 223 //
221   - #define V3270_TYPE_COPY_ACTION (v3270CopyAction_get_type())
222   - #define V3270_COPY_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), V3270_TYPE_COPY_ACTION, v3270CopyAction))
223   - #define V3270_COPY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), V3270_TYPE_COPY_ACTION, v3270CopyActionClass))
224   - #define V3270_IS_COPY_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), V3270_TYPE_COPY_ACTION))
225   - #define V3270_IS_COPY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), V3270_TYPE_COPY_ACTION))
226   - #define V3270_COPY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), V3270_TYPE_COPY_ACTION, v3270CopyActionClass))
  224 + #define V3270_TYPE_CONDITIONAL_ACTION (v3270ConditionalAction_get_type())
  225 + #define V3270_CONDITIONAL_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), V3270_TYPE_CONDITIONAL_ACTION, v3270ConditionalAction))
  226 + #define V3270_CONDITIONAL_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), V3270_TYPE_CONDITIONAL_ACTION, v3270ConditionalActionClass))
  227 + #define V3270_IS_CONDITIONAL_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), V3270_TYPE_CONDITIONAL_ACTION))
  228 + #define V3270_IS_CONDITIONAL_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), V3270_TYPE_CONDITIONAL_ACTION))
  229 + #define V3270_CONDITIONAL_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), V3270_TYPE_CONDITIONAL_ACTION, v3270ConditionalActionClass))
227 230  
228   - typedef struct _v3270CopyAction {
  231 + typedef struct _v3270ConditionalAction {
229 232  
230 233 pw3270SimpleAction parent;
231 234  
232 235 GParamSpec *pspec;
233 236  
234   - } v3270CopyAction;
  237 + } v3270ConditionalAction;
235 238  
236 239 typedef struct _v3270CopyActionClass {
237 240  
238 241 pw3270SimpleActionClass parent_class;
239 242  
240   - } v3270CopyActionClass;
  243 + } v3270ConditionalActionClass;
241 244  
242   - GType v3270CopyAction_get_type(void) G_GNUC_CONST;
  245 + GType v3270ConditionalAction_get_type(void) G_GNUC_CONST;
243 246  
244   - GAction * v3270_copy_action_new(GtkWidget *widget);
  247 + GAction * v3270_conditional_action_new(GtkWidget *widget, const gchar *property_name);
245 248  
246 249 G_END_DECLS
247 250  
... ...
src/objects/actions/abstract.c
... ... @@ -261,11 +261,8 @@
261 261 return PW3270_ACTION(action)->name;
262 262 }
263 263  
264   - void pw3270_action_set_name(GAction *object, const gchar *name) {
265   -
266   - if(name)
267   - g_warning("Invalid call to %s on action %s with value \"%s\"",__FUNCTION__,g_action_get_name(object),name);
268   -
  264 + void pw3270_action_set_name(GAction *action, const gchar *name) {
  265 + PW3270_ACTION(action)->name = g_intern_string(name);
269 266 }
270 267  
271 268 GVariant * internal_get_state_hint(GAction G_GNUC_UNUSED(*action), GtkWidget G_GNUC_UNUSED(*terminal)) {
... ...
src/objects/actions/simple.c
... ... @@ -131,6 +131,7 @@
131 131  
132 132 }
133 133  
  134 +
134 135 pw3270SimpleAction * pw3270_simple_action_new_from_name(const gchar *source_name, const gchar *name) {
135 136 return pw3270_simple_action_new_from_lib3270(lib3270_action_get_by_name(source_name),name);
136 137 }
... ...
src/objects/actions/v3270/conditional.c 0 → 100644
... ... @@ -0,0 +1,172 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 + /**
  31 + * @brief Implement GAction who enables/disable based on a v3270 boolean property.
  32 + *
  33 + * Reference:
  34 + *
  35 + * <https://github.com/GNOME/glib/blob/master/gio/gpropertyaction.c>
  36 + *
  37 + */
  38 +
  39 + #include "../private.h"
  40 + #include <stdlib.h>
  41 + #include <pw3270/window.h>
  42 + #include <v3270.h>
  43 + #include <lib3270/properties.h>
  44 +
  45 + static void v3270ConditionalAction_class_init(v3270ConditionalActionClass *klass);
  46 + static void v3270ConditionalAction_init(v3270ConditionalAction *action);
  47 + static gboolean get_enabled(GAction *action, GtkWidget *terminal);
  48 + static void change_widget(GAction *object, GtkWidget *from, GtkWidget *to);
  49 +
  50 + G_DEFINE_TYPE(v3270ConditionalAction, v3270ConditionalAction, PW3270_TYPE_SIMPLE_ACTION);
  51 +
  52 + void v3270ConditionalAction_class_init(v3270ConditionalActionClass *klass) {
  53 +
  54 + klass->parent_class.parent_class.change_widget = change_widget;
  55 + klass->parent_class.parent_class.get_enabled = get_enabled;
  56 +
  57 + }
  58 +
  59 + static void v3270ConditionalAction_init(v3270ConditionalAction G_GNUC_UNUSED(*action)) {
  60 + }
  61 +
  62 + static void on_notify(GtkWidget G_GNUC_UNUSED(*terminal), GParamSpec G_GNUC_UNUSED(*pspec), GAction *action) {
  63 + debug("%s: Enabled of action %s has changed",__FUNCTION__, g_action_get_name(G_ACTION(action)));
  64 + pw3270_action_notify_enabled(action);
  65 + }
  66 +
  67 + GAction * v3270_conditional_action_new(GtkWidget *widget, const gchar *property_name) {
  68 +
  69 + GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(widget), property_name);
  70 +
  71 + if(!pspec) {
  72 +
  73 + g_warning(
  74 + "Can't find property '%s::%s'",
  75 + G_OBJECT_TYPE_NAME(G_OBJECT(widget)),
  76 + property_name
  77 + );
  78 +
  79 + return NULL;
  80 +
  81 + }
  82 +
  83 + debug("%s: pspec(%s)=%p",__FUNCTION__,property_name,pspec);
  84 +
  85 + if(~pspec->flags & G_PARAM_READABLE || pspec->flags & G_PARAM_CONSTRUCT_ONLY) {
  86 +
  87 + g_warning(
  88 + "Property '%s::%s' must be readable and not construct-only",
  89 + G_OBJECT_TYPE_NAME(G_OBJECT(widget)),
  90 + property_name
  91 + );
  92 +
  93 + return NULL;
  94 + }
  95 +
  96 + v3270ConditionalAction * action = (v3270ConditionalAction *) g_object_new(V3270_TYPE_CONDITIONAL_ACTION, NULL);
  97 +
  98 + pw3270_simple_action_set_lib3270_property(PW3270_SIMPLE_ACTION(action), lib3270_property_get_by_name(pspec->name));
  99 +
  100 + action->parent.parent.name = g_param_spec_get_name(pspec);
  101 + action->parent.tooltip = g_param_spec_get_blurb(pspec);
  102 + action->pspec = pspec;
  103 +
  104 + pw3270_action_set_terminal_widget(G_ACTION(action), widget);
  105 +
  106 + return G_ACTION(action);
  107 + }
  108 +
  109 + void change_widget(GAction *object, GtkWidget *from, GtkWidget *to) {
  110 +
  111 + v3270ConditionalAction * action = V3270_CONDITIONAL_ACTION(object);
  112 + g_autofree gchar * signal_name = g_strconcat("notify::", action->pspec->name,NULL);
  113 +
  114 + if(from) {
  115 + gulong handler = g_signal_handler_find(
  116 + from,
  117 + G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA,
  118 + 0,
  119 + 0,
  120 + NULL,
  121 + G_CALLBACK(on_notify),
  122 + action
  123 + );
  124 +
  125 + if(handler)
  126 + g_signal_handler_disconnect(from, handler);
  127 +
  128 + }
  129 +
  130 + PW3270_ACTION_CLASS(v3270ConditionalAction_parent_class)->change_widget(object,from,to);
  131 +
  132 + if(to) {
  133 + g_signal_connect(G_OBJECT(to),signal_name,G_CALLBACK(on_notify),action);
  134 + }
  135 +
  136 + pw3270_action_notify_enabled(G_ACTION(object));
  137 +
  138 + }
  139 +
  140 + gboolean get_enabled(GAction *object, GtkWidget *terminal) {
  141 +
  142 + gboolean enabled = PW3270_ACTION_CLASS(v3270ConditionalAction_parent_class)->get_enabled(object,terminal);
  143 +
  144 + if(enabled && terminal) {
  145 +
  146 + // The action is enabled, check property to confirm.
  147 + v3270ConditionalAction * action = V3270_CONDITIONAL_ACTION(object);
  148 +
  149 + GValue value = G_VALUE_INIT;
  150 + g_value_init(&value, action->pspec->value_type);
  151 + g_object_get_property(G_OBJECT(terminal), action->pspec->name, &value);
  152 +
  153 + switch(action->pspec->value_type) {
  154 + case G_TYPE_UINT:
  155 + enabled = g_value_get_uint(&value) != 0;
  156 + break;
  157 +
  158 + case G_TYPE_BOOLEAN:
  159 + enabled = g_value_get_boolean(&value);
  160 + break;
  161 +
  162 + default:
  163 + enabled = FALSE;
  164 + }
  165 +
  166 + g_value_unset (&value);
  167 +
  168 + }
  169 +
  170 + return enabled;
  171 +
  172 + }
... ...
src/objects/actions/v3270/copy.c
... ... @@ -1,125 +0,0 @@
1   -/*
2   - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   - * aplicativos mainframe. Registro no INPI sob o nome G3270.
5   - *
6   - * Copyright (C) <2008> <Banco do Brasil S.A.>
7   - *
8   - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   - * Free Software Foundation.
11   - *
12   - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   - * obter mais detalhes.
16   - *
17   - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19   - * St, Fifth Floor, Boston, MA 02110-1301 USA
20   - *
21   - * Este programa está nomeado como - e possui - linhas de código.
22   - *
23   - * Contatos:
24   - *
25   - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
26   - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
27   - *
28   - */
29   -
30   - /**
31   - * @brief Implement PW3270 copy actions.
32   - *
33   - */
34   -
35   - #include "../private.h"
36   - #include <v3270.h>
37   -
38   - static void v3270CopyAction_class_init(v3270CopyActionClass *klass);
39   - static void v3270CopyAction_init(v3270CopyAction *action);
40   - static GVariant * get_state(GAction *action, GtkWidget *terminal);
41   - static void change_widget(GAction *object, GtkWidget *from, GtkWidget *to);
42   -
43   - G_DEFINE_TYPE(v3270CopyAction, v3270CopyAction, PW3270_TYPE_SIMPLE_ACTION);
44   -
45   - void v3270CopyAction_class_init(v3270CopyActionClass *klass) {
46   - klass->parent_class.parent_class.change_widget = change_widget;
47   - }
48   -
49   - static void v3270CopyAction_init(v3270CopyAction *action) {
50   -
51   - action->parent.parent.get_state_property = get_state;
52   -
53   - }
54   -
55   - GVariant * get_state(GAction *object, GtkWidget *terminal) {
56   -
57   -
58   - return NULL;
59   -
60   - }
61   -
62   - static void activate(GAction *object, GVariant *parameter, GtkWidget *terminal) {
63   -
64   -
65   - }
66   -
67   - static void on_notify(GtkWidget G_GNUC_UNUSED(*terminal), GParamSpec G_GNUC_UNUSED(*pspec), GAction *action) {
68   -
69   - debug("%s: State of action %s has changed",__FUNCTION__, g_action_get_name(G_ACTION(action)));
70   - pw3270_action_notify_state(action);
71   -
72   - }
73   -
74   - void change_widget(GAction *object, GtkWidget *from, GtkWidget *to) {
75   -
76   - v3270CopyAction * action = V3270_COPY_ACTION(object);
77   -
78   - if(from) {
79   - gulong handler = g_signal_handler_find(
80   - "has-text",
81   - G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA,
82   - 0,
83   - 0,
84   - NULL,
85   - G_CALLBACK(on_notify),
86   - action
87   - );
88   -
89   - if(handler)
90   - g_signal_handler_disconnect(from, handler);
91   -
92   - }
93   -
94   - PW3270_ACTION_CLASS(v3270CopyAction_parent_class)->change_widget(object,from,to);
95   -
96   - if(to) {
97   - g_signal_connect(G_OBJECT(to),"has-text",G_CALLBACK(on_notify),action);
98   - }
99   -
100   - }
101   -
102   -
103   - GAction * pw3270_action_print_copy_new(GtkWidget *widget) {
104   -
105   - pw3270SimpleAction * action = (pw3270SimpleAction *) g_object_new(V3270_TYPE_COPY_ACTION, NULL);;
106   -
107   - action->group.id = LIB3270_ACTION_GROUP_ONLINE;
108   - action->parent.name = "print_copy";
109   - action->label = N_( "Print copy" );
110   -
111   - return G_ACTION(action);
112   -
113   - }
114   -
115   - GAction * pw3270_action_save_copy_new(GtkWidget *widget) {
116   -
117   - pw3270SimpleAction * action = (pw3270SimpleAction *) g_object_new(V3270_TYPE_COPY_ACTION, NULL);;
118   -
119   - action->group.id = LIB3270_ACTION_GROUP_ONLINE;
120   - action->parent.name = "save_copy";
121   - action->label = N_( "Save copy" );
122   -
123   - return G_ACTION(action);
124   -
125   - }
src/objects/application/application.c
... ... @@ -299,16 +299,39 @@
299 299  
300 300 }
301 301  
302   - // Create copy actions.
303   - g_action_map_add_action(
304   - G_ACTION_MAP(window),
305   - pw3270_action_save_copy_new(terminal)
306   - );
  302 + // Create conditional actions.
  303 + static const struct {
  304 + const gchar * label;
  305 + const gchar * tooltip;
  306 + const gchar * action_name;
  307 + const gchar * property_name;
  308 + } conditional_actions[] = {
  309 + {
  310 + .label = N_("Save copy"),
  311 + .action_name = "save_copy",
  312 + .property_name = "has_copy"
  313 + },
  314 + {
  315 + .label = N_("Print copy"),
  316 + .action_name = "print_copy",
  317 + .property_name = "has_copy"
  318 + }
  319 + };
307 320  
308   - g_action_map_add_action(
309   - G_ACTION_MAP(window),
310   - pw3270_action_print_copy_new(terminal)
311   - );
  321 + for(ix = 0; ix < G_N_ELEMENTS(conditional_actions); ix++) {
  322 +
  323 + pw3270SimpleAction * action = PW3270_SIMPLE_ACTION(v3270_conditional_action_new(terminal,conditional_actions[ix].property_name));
  324 +
  325 + action->parent.name = conditional_actions[ix].action_name;
  326 + action->label = conditional_actions[ix].label;
  327 + action->tooltip = conditional_actions[ix].tooltip;
  328 +
  329 + g_action_map_add_action(
  330 + G_ACTION_MAP(window),
  331 + G_ACTION(action)
  332 + );
  333 +
  334 + }
312 335  
313 336 // Present the new window
314 337 pw3270_window_set_current_page(window,0);
... ...