Commit 32cedac0e4c6e69f5d41b3fa70fbb590b1c04727

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

Implementing the "save to keyfile" method.

@@ -54,3 +54,5 @@ glade/v3270.xml @@ -54,3 +54,5 @@ glade/v3270.xml
54 ValgrindOut.xml 54 ValgrindOut.xml
55 *.crl 55 *.crl
56 *.patch 56 *.patch
  57 +*.sh
  58 +*.conf
src/dialogs/popups.c
@@ -206,6 +206,13 @@ @@ -206,6 +206,13 @@
206 GTK_V3270(widget)->responses[id] = response; 206 GTK_V3270(widget)->responses[id] = response;
207 g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->responses[id]); 207 g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->responses[id]);
208 v3270_emit_save_settings(widget); 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 gtk_widget_destroy(dialog); 218 gtk_widget_destroy(dialog);
src/include/terminal.h
@@ -36,8 +36,6 @@ G_BEGIN_DECLS @@ -36,8 +36,6 @@ G_BEGIN_DECLS
36 { 36 {
37 GtkWidgetClass parent_class; 37 GtkWidgetClass parent_class;
38 38
39 - // Dialog boxes.  
40 -  
41 // Internal properties. 39 // Internal properties.
42 struct { 40 struct {
43 41
@@ -66,12 +64,13 @@ G_BEGIN_DECLS @@ -66,12 +64,13 @@ G_BEGIN_DECLS
66 guint integer; 64 guint integer;
67 guint uint; 65 guint uint;
68 guint str; 66 guint str;
  67 + guint responses;
69 } type; 68 } type;
70 69
71 } properties; 70 } properties;
72 71
73 // Predefined responses. 72 // Predefined responses.
74 - GParamSpec *responses[V3270_TOGGLEABLE_DIALOG_CUSTOM]; 73 + GParamSpec * responses[V3270_TOGGLEABLE_DIALOG_CUSTOM];
75 74
76 // Cursors 75 // Cursors
77 GdkCursor * cursors[LIB3270_POINTER_COUNT]; 76 GdkCursor * cursors[LIB3270_POINTER_COUNT];
src/include/v3270/settings.h
@@ -35,6 +35,14 @@ @@ -35,6 +35,14 @@
35 35
36 G_BEGIN_DECLS 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 /*--[ V3270 Settings Widget ]------------------------------------------------------------------------*/ 46 /*--[ V3270 Settings Widget ]------------------------------------------------------------------------*/
39 47
40 #define GTK_TYPE_V3270_SETTINGS (V3270Settings_get_type()) 48 #define GTK_TYPE_V3270_SETTINGS (V3270Settings_get_type())
src/terminal/keyfile.c 0 → 100644
@@ -0,0 +1,217 @@ @@ -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,7 +39,11 @@
39 39
40 debug("%s(%u,%s)",__FUNCTION__,prop_id,g_param_spec_get_name(pspec)); 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 const LIB3270_STRING_PROPERTY * prop = (lib3270_get_string_properties_list()+(prop_id - klass->properties.type.str)); 48 const LIB3270_STRING_PROPERTY * prop = (lib3270_get_string_properties_list()+(prop_id - klass->properties.type.str));
45 debug("%s.%s.%s",__FUNCTION__,"string",prop->name); 49 debug("%s.%s.%s",__FUNCTION__,"string",prop->name);
@@ -77,7 +81,7 @@ @@ -77,7 +81,7 @@
77 } 81 }
78 else if(prop_id >= klass->properties.type.toggle) 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 g_value_set_boolean(value,lib3270_get_toggle(window->host,prop_id - klass->properties.type.toggle) ? TRUE : FALSE ); 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,6 +28,7 @@
28 */ 28 */
29 29
30 #include "private.h" 30 #include "private.h"
  31 + #include <lib3270/toggle.h>
31 32
32 /*--[ Implement ]------------------------------------------------------------------------------------*/ 33 /*--[ Implement ]------------------------------------------------------------------------------------*/
33 34
@@ -80,7 +81,7 @@ @@ -80,7 +81,7 @@
80 "font_family", 81 "font_family",
81 "font_family", 82 "font_family",
82 _("Font family for terminal contents"), 83 _("Font family for terminal contents"),
83 - FALSE, 84 + v3270_get_default_font_name(),
84 G_PARAM_READABLE|G_PARAM_WRITABLE 85 G_PARAM_READABLE|G_PARAM_WRITABLE
85 ); 86 );
86 87
@@ -106,11 +107,13 @@ @@ -106,11 +107,13 @@
106 ); 107 );
107 108
108 // Auto disconnect 109 // Auto disconnect
109 - klass->properties.auto_disconnect = g_param_spec_string( 110 + klass->properties.auto_disconnect = g_param_spec_uint(
110 "auto_disconnect", 111 "auto_disconnect",
111 "auto_disconnect", 112 "auto_disconnect",
112 _("IDLE minutes for automatic disconnection"), 113 _("IDLE minutes for automatic disconnection"),
113 - FALSE, 114 + 0,
  115 + G_MAXUINT,
  116 + 0,
114 G_PARAM_READABLE|G_PARAM_WRITABLE 117 G_PARAM_READABLE|G_PARAM_WRITABLE
115 ); 118 );
116 119
@@ -200,61 +203,36 @@ @@ -200,61 +203,36 @@
200 klass->properties.count = V3270_PROPERTY_DYNAMIC; 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,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,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 static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) { 78 static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) {
69 79
70 GtkWidget * window = gtk_application_window_new(app); 80 GtkWidget * window = gtk_application_window_new(app);
@@ -109,6 +119,7 @@ @@ -109,6 +119,7 @@
109 gtk_widget_show_all(window); 119 gtk_widget_show_all(window);
110 120
111 g_signal_connect(G_OBJECT(terminal),"session_changed",G_CALLBACK(session_changed),window); 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 // g_signal_connect(G_OBJECT(terminal),"field_clicked",G_CALLBACK(field_clicked),window); 123 // g_signal_connect(G_OBJECT(terminal),"field_clicked",G_CALLBACK(field_clicked),window);
113 124
114 gtk_widget_grab_focus(terminal); 125 gtk_widget_grab_focus(terminal);
@@ -267,6 +267,9 @@ @@ -267,6 +267,9 @@
267 <Unit filename="src/terminal/keyboard.c"> 267 <Unit filename="src/terminal/keyboard.c">
268 <Option compilerVar="CC" /> 268 <Option compilerVar="CC" />
269 </Unit> 269 </Unit>
  270 + <Unit filename="src/terminal/keyfile.c">
  271 + <Option compilerVar="CC" />
  272 + </Unit>
270 <Unit filename="src/terminal/linux/iosource.c"> 273 <Unit filename="src/terminal/linux/iosource.c">
271 <Option compilerVar="CC" /> 274 <Option compilerVar="CC" />
272 </Unit> 275 </Unit>