Commit 32cedac0e4c6e69f5d41b3fa70fbb590b1c04727

Authored by Perry Werneck
1 parent 7f8543bd
Exists in master and in 1 other branch develop

Implementing the "save to keyfile" method.

.gitignore
... ... @@ -54,3 +54,5 @@ glade/v3270.xml
54 54 ValgrindOut.xml
55 55 *.crl
56 56 *.patch
  57 +*.sh
  58 +*.conf
... ...
src/dialogs/popups.c
... ... @@ -206,6 +206,13 @@
206 206 GTK_V3270(widget)->responses[id] = response;
207 207 g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->responses[id]);
208 208 v3270_emit_save_settings(widget);
  209 +
  210 + debug(
  211 + "Property %s is now %d",
  212 + g_param_spec_get_name(GTK_V3270_GET_CLASS(widget)->responses[id]),
  213 + GTK_V3270(widget)->responses[id]
  214 + );
  215 +
209 216 }
210 217  
211 218 gtk_widget_destroy(dialog);
... ...
src/include/terminal.h
... ... @@ -36,8 +36,6 @@ G_BEGIN_DECLS
36 36 {
37 37 GtkWidgetClass parent_class;
38 38  
39   - // Dialog boxes.
40   -
41 39 // Internal properties.
42 40 struct {
43 41  
... ... @@ -66,12 +64,13 @@ G_BEGIN_DECLS
66 64 guint integer;
67 65 guint uint;
68 66 guint str;
  67 + guint responses;
69 68 } type;
70 69  
71 70 } properties;
72 71  
73 72 // Predefined responses.
74   - GParamSpec *responses[V3270_TOGGLEABLE_DIALOG_CUSTOM];
  73 + GParamSpec * responses[V3270_TOGGLEABLE_DIALOG_CUSTOM];
75 74  
76 75 // Cursors
77 76 GdkCursor * cursors[LIB3270_POINTER_COUNT];
... ...
src/include/v3270/settings.h
... ... @@ -35,6 +35,14 @@
35 35  
36 36 G_BEGIN_DECLS
37 37  
  38 +/*--[ Tools ]----------------------------------------------------------------------------------------*/
  39 +
  40 + /// @brief Reads the terminal settings from the group group_name in key_file.
  41 + LIB3270_EXPORT gboolean v3270_load_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name, GError **error);
  42 +
  43 + /// @brief This function adds the terminal settings from widget to key_file.
  44 + LIB3270_EXPORT void v3270_to_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name);
  45 +
38 46 /*--[ V3270 Settings Widget ]------------------------------------------------------------------------*/
39 47  
40 48 #define GTK_TYPE_V3270_SETTINGS (V3270Settings_get_type())
... ...
src/terminal/keyfile.c 0 → 100644
... ... @@ -0,0 +1,217 @@
  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 + #include <config.h>
  31 + #include <terminal.h>
  32 + #include <internals.h>
  33 + #include <v3270/settings.h>
  34 + #include <lib3270/toggle.h>
  35 + #include <lib3270/log.h>
  36 + #include <lib3270/trace.h>
  37 +
  38 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  39 +
  40 + static void save_by_pspec(GtkWidget *widget, GParamSpec *pspec, GKeyFile *key_file, const gchar *group_name)
  41 + {
  42 + const gchar * name = g_param_spec_get_name(pspec);
  43 + GValue value = G_VALUE_INIT;
  44 +
  45 + g_value_init(&value, pspec->value_type);
  46 + g_object_get_property(G_OBJECT(widget),name,&value);
  47 +
  48 + switch(pspec->value_type)
  49 + {
  50 + case G_TYPE_STRING:
  51 + {
  52 + const gchar * current = g_value_get_string(&value);
  53 +
  54 + if(current && G_PARAM_SPEC_STRING(pspec)->default_value && strcmp(current,G_PARAM_SPEC_STRING(pspec)->default_value))
  55 + {
  56 + g_key_file_set_string(
  57 + key_file,
  58 + group_name,
  59 + name,
  60 + current
  61 + );
  62 + }
  63 + else
  64 + {
  65 + g_key_file_remove_key(
  66 + key_file,
  67 + group_name,
  68 + name,
  69 + NULL
  70 + );
  71 + }
  72 + }
  73 + break;
  74 +
  75 + case G_TYPE_BOOLEAN:
  76 + {
  77 + gboolean current = g_value_get_boolean(&value);
  78 +
  79 + if(current != G_PARAM_SPEC_BOOLEAN(pspec)->default_value)
  80 + {
  81 + g_key_file_set_boolean(
  82 + key_file,
  83 + group_name,
  84 + name,
  85 + current
  86 + );
  87 + }
  88 + else
  89 + {
  90 + g_key_file_remove_key(
  91 + key_file,
  92 + group_name,
  93 + name,
  94 + NULL
  95 + );
  96 + }
  97 + }
  98 + break;
  99 +
  100 + case G_TYPE_INT:
  101 + {
  102 + gint current = g_value_get_int(&value);
  103 +
  104 + if(current != G_PARAM_SPEC_INT(pspec)->default_value)
  105 + {
  106 + g_key_file_set_integer(
  107 + key_file,
  108 + group_name,
  109 + name,
  110 + current
  111 + );
  112 + }
  113 + else
  114 + {
  115 + g_key_file_remove_key(
  116 + key_file,
  117 + group_name,
  118 + name,
  119 + NULL
  120 + );
  121 + }
  122 +
  123 + }
  124 + break;
  125 +
  126 + case G_TYPE_UINT:
  127 + {
  128 + guint current = (gint) g_value_get_uint(&value);
  129 +
  130 + if(current != G_PARAM_SPEC_UINT(pspec)->default_value)
  131 + {
  132 + g_key_file_set_integer(
  133 + key_file,
  134 + group_name,
  135 + name,
  136 + (gint) current
  137 + );
  138 + }
  139 + else
  140 + {
  141 + g_key_file_remove_key(
  142 + key_file,
  143 + group_name,
  144 + name,
  145 + NULL
  146 + );
  147 + }
  148 +
  149 + }
  150 + break;
  151 +
  152 + default:
  153 + lib3270_write_trace(v3270_get_session(widget),"%s has an unexpected value type\n",name);
  154 +
  155 + }
  156 +
  157 + g_value_unset(&value);
  158 +
  159 +
  160 + }
  161 +
  162 + /// @brief Reads the terminal settings from the group group_name in key_file.
  163 + LIB3270_EXPORT void v3270_to_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name)
  164 + {
  165 + g_return_if_fail(GTK_IS_V3270(widget));
  166 +
  167 + size_t ix;
  168 + GString * str;
  169 +
  170 + v3270 * terminal = GTK_V3270(widget);
  171 + v3270Class * klass = GTK_V3270_GET_CLASS(widget);
  172 +
  173 + // Save Toggles
  174 + for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++)
  175 + save_by_pspec(widget,klass->properties.toggle[ix],key_file,group_name);
  176 +
  177 + // Save V3270 Responses
  178 + for(ix = 0; ix < G_N_ELEMENTS(terminal->responses); ix++)
  179 + save_by_pspec(widget,klass->responses[ix],key_file,group_name);
  180 +
  181 + // Save V3270 properties
  182 + save_by_pspec(widget,klass->properties.font_family,key_file,group_name);
  183 + save_by_pspec(widget,klass->properties.url,key_file,group_name);
  184 + save_by_pspec(widget,klass->properties.session_name,key_file,group_name);
  185 + save_by_pspec(widget,klass->properties.auto_disconnect,key_file,group_name);
  186 + save_by_pspec(widget,klass->properties.remap_file,key_file,group_name);
  187 + save_by_pspec(widget,klass->properties.dynamic_spacing,key_file,group_name);
  188 + save_by_pspec(widget,klass->properties.lu_names,key_file,group_name);
  189 +
  190 + // Save V3270 colors
  191 + str = g_string_new("");
  192 + for(ix=0; ix<V3270_COLOR_COUNT; ix++)
  193 + {
  194 + if(ix)
  195 + g_string_append_c(str,';');
  196 + g_string_append_printf(str,"%s",gdk_rgba_to_string(v3270_get_color(widget,ix)));
  197 + }
  198 +
  199 + g_key_file_set_string(
  200 + key_file,
  201 + group_name,
  202 + "colors",
  203 + str->str
  204 + );
  205 +
  206 + g_string_free(str,TRUE);
  207 +
  208 + }
  209 +
  210 + /// @brief This function adds the terminal settings from widget to key_file.
  211 + LIB3270_EXPORT gboolean v3270_load_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name, GError **error)
  212 + {
  213 + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE);
  214 +
  215 +
  216 + return FALSE;
  217 + }
... ...
src/terminal/properties/get.c
... ... @@ -39,7 +39,11 @@
39 39  
40 40 debug("%s(%u,%s)",__FUNCTION__,prop_id,g_param_spec_get_name(pspec));
41 41  
42   - if(prop_id >= klass->properties.type.str)
  42 + if(prop_id >= klass->properties.type.responses)
  43 + {
  44 + g_value_set_int(value,(int) window->responses[prop_id - klass->properties.type.responses]);
  45 + }
  46 + else if(prop_id >= klass->properties.type.str)
43 47 {
44 48 const LIB3270_STRING_PROPERTY * prop = (lib3270_get_string_properties_list()+(prop_id - klass->properties.type.str));
45 49 debug("%s.%s.%s",__FUNCTION__,"string",prop->name);
... ... @@ -77,7 +81,7 @@
77 81 }
78 82 else if(prop_id >= klass->properties.type.toggle)
79 83 {
80   - debug("%s.%s.%s",__FUNCTION__,"toggle",lib3270_get_toggle_name(prop_id - klass->properties.type.toggle));
  84 +// debug("%s.%s.%s",__FUNCTION__,"toggle",lib3270_get_toggle_name(prop_id - klass->properties.type.toggle));
81 85 g_value_set_boolean(value,lib3270_get_toggle(window->host,prop_id - klass->properties.type.toggle) ? TRUE : FALSE );
82 86  
83 87 }
... ...
src/terminal/properties/init.c
... ... @@ -28,6 +28,7 @@
28 28 */
29 29  
30 30 #include "private.h"
  31 + #include <lib3270/toggle.h>
31 32  
32 33 /*--[ Implement ]------------------------------------------------------------------------------------*/
33 34  
... ... @@ -80,7 +81,7 @@
80 81 "font_family",
81 82 "font_family",
82 83 _("Font family for terminal contents"),
83   - FALSE,
  84 + v3270_get_default_font_name(),
84 85 G_PARAM_READABLE|G_PARAM_WRITABLE
85 86 );
86 87  
... ... @@ -106,11 +107,13 @@
106 107 );
107 108  
108 109 // Auto disconnect
109   - klass->properties.auto_disconnect = g_param_spec_string(
  110 + klass->properties.auto_disconnect = g_param_spec_uint(
110 111 "auto_disconnect",
111 112 "auto_disconnect",
112 113 _("IDLE minutes for automatic disconnection"),
113   - FALSE,
  114 + 0,
  115 + G_MAXUINT,
  116 + 0,
114 117 G_PARAM_READABLE|G_PARAM_WRITABLE
115 118 );
116 119  
... ... @@ -200,61 +203,36 @@
200 203 klass->properties.count = V3270_PROPERTY_DYNAMIC;
201 204  
202 205 //
203   - // Create action properties.
  206 + // Extract properties from LIB3270 control tables
204 207 //
205   - static const struct
206   - {
207   - const gchar *name; ///< @brief canonical name of the property specified.
208   - const gchar *nick; ///< @brief nick name for the property specified.
209   - const gchar *blurb; ///< @brief description of the property specified.
210   - } actions[G_N_ELEMENTS(klass->responses)] =
211   - {
212   - {
213   - .name = "paste_fails",
214   - .nick = "paste_fails",
215   - .blurb = "The action when formatted paste fails"
216   - }
217   -
218   - };
  208 + // Extract toggle class.
  209 + klass->properties.type.toggle = klass->properties.count;
219 210  
220   - for(ix = 0; ix < G_N_ELEMENTS(klass->responses); ix++)
221 211 {
222   - if(actions[ix].name)
223   - {
224   - klass->responses[ix] =
225   - g_param_spec_enum(
226   - actions[ix].name,
227   - actions[ix].nick,
228   - actions[ix].blurb,
229   - GTK_TYPE_RESPONSE_TYPE,
230   - GTK_RESPONSE_NONE,
231   - (G_PARAM_READABLE|G_PARAM_WRITABLE)
232   - );
  212 + const LIB3270_TOGGLE * toggles = lib3270_get_toggles();
233 213  
234   - v3270_install_property(gobject_class, klass->properties.count++, klass->responses[ix]);
235   - }
  214 + for(ix = 0; ix < LIB3270_TOGGLE_COUNT; ix++)
  215 + {
  216 + if(!toggles[ix].name)
  217 + {
  218 + g_warning("Unexpected toggle id: %u", (unsigned int) ix);
  219 + break;
  220 + }
236 221  
237   - }
  222 + // debug("Property %u=%s (Toggle)",(unsigned int) klass->properties.type.toggle + ix, lib3270_get_toggle_name(ix));
238 223  
239   - //
240   - // Extract properties from LIB3270 control tables
241   - //
242   - // Extract toggle class.
243   - klass->properties.type.toggle = klass->properties.count;
244   - for(ix = 0; ix < LIB3270_TOGGLE_COUNT; ix++)
245   - {
246   -// debug("Property %u=%s (Toggle)",(unsigned int) klass->properties.type.toggle + ix, lib3270_get_toggle_name(ix));
  224 + klass->properties.toggle[ix] =
  225 + g_param_spec_boolean(
  226 + toggles[ix].name,
  227 + toggles[ix].name,
  228 + toggles[ix].description,
  229 + (toggles[ix].def == 0 ? FALSE : TRUE),
  230 + G_PARAM_WRITABLE|G_PARAM_READABLE
  231 + );
247 232  
248   - klass->properties.toggle[ix] =
249   - g_param_spec_boolean(
250   - lib3270_get_toggle_name(ix),
251   - lib3270_get_toggle_name(ix),
252   - lib3270_get_toggle_description(ix),
253   - FALSE,
254   - G_PARAM_WRITABLE|G_PARAM_READABLE
255   - );
  233 + v3270_install_property(gobject_class, klass->properties.count++, klass->properties.toggle[ix]);
256 234  
257   - v3270_install_property(gobject_class, klass->properties.count++, klass->properties.toggle[ix]);
  235 + }
258 236  
259 237 }
260 238  
... ... @@ -342,5 +320,47 @@
342 320  
343 321 }
344 322  
  323 + //
  324 + // Create action properties.
  325 + //
  326 + klass->properties.type.responses = klass->properties.count;
  327 +
  328 + static const struct
  329 + {
  330 + const gchar *name; ///< @brief canonical name of the property specified.
  331 + const gchar *nick; ///< @brief nick name for the property specified.
  332 + const gchar *blurb; ///< @brief description of the property specified.
  333 + } actions[G_N_ELEMENTS(klass->responses)] =
  334 + {
  335 + {
  336 + .name = "paste_fails",
  337 + .nick = "paste_fails",
  338 + .blurb = "The action when formatted paste fails"
  339 + }
  340 +
  341 + };
  342 +
  343 + for(ix = 0; ix < G_N_ELEMENTS(klass->responses); ix++)
  344 + {
  345 + if(actions[ix].name)
  346 + {
  347 + // Should be int to make it easier to GKeyFile methods.
  348 + klass->responses[ix] =
  349 + g_param_spec_int(
  350 + actions[ix].name,
  351 + actions[ix].nick,
  352 + actions[ix].blurb,
  353 + INT_MIN,
  354 + INT_MAX,
  355 + (int) GTK_RESPONSE_NONE,
  356 + (G_PARAM_READABLE|G_PARAM_WRITABLE)
  357 + );
  358 +
  359 + v3270_install_property(gobject_class, klass->properties.count++, klass->responses[ix]);
  360 + }
  361 +
  362 + }
  363 +
  364 +
345 365 }
346 366  
... ...
src/testprogram/testprogram.c
... ... @@ -65,6 +65,16 @@
65 65 }
66 66 */
67 67  
  68 + static void save_settings(GtkWidget *terminal, GtkWidget *window)
  69 + {
  70 + debug("%s: Saving settings for windows %p",__FUNCTION__,window);
  71 +
  72 + GKeyFile * key_file = g_key_file_new();
  73 + v3270_to_key_file(terminal,key_file,"terminal");
  74 + g_key_file_save_to_file(key_file,"terminal.conf",NULL);
  75 + g_key_file_free(key_file);
  76 + }
  77 +
68 78 static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) {
69 79  
70 80 GtkWidget * window = gtk_application_window_new(app);
... ... @@ -109,6 +119,7 @@
109 119 gtk_widget_show_all(window);
110 120  
111 121 g_signal_connect(G_OBJECT(terminal),"session_changed",G_CALLBACK(session_changed),window);
  122 + g_signal_connect(G_OBJECT(terminal),"save-settings",G_CALLBACK(save_settings),window);
112 123 // g_signal_connect(G_OBJECT(terminal),"field_clicked",G_CALLBACK(field_clicked),window);
113 124  
114 125 gtk_widget_grab_focus(terminal);
... ...
v3270.cbp
... ... @@ -267,6 +267,9 @@
267 267 <Unit filename="src/terminal/keyboard.c">
268 268 <Option compilerVar="CC" />
269 269 </Unit>
  270 + <Unit filename="src/terminal/keyfile.c">
  271 + <Option compilerVar="CC" />
  272 + </Unit>
270 273 <Unit filename="src/terminal/linux/iosource.c">
271 274 <Option compilerVar="CC" />
272 275 </Unit>
... ...