diff --git a/.gitignore b/.gitignore index 40053ef..f50ae6d 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ glade/v3270.xml ValgrindOut.xml *.crl *.patch +*.sh +*.conf diff --git a/src/dialogs/popups.c b/src/dialogs/popups.c index ac0eea6..efa8432 100644 --- a/src/dialogs/popups.c +++ b/src/dialogs/popups.c @@ -206,6 +206,13 @@ GTK_V3270(widget)->responses[id] = response; g_object_notify_by_pspec(G_OBJECT(widget), GTK_V3270_GET_CLASS(widget)->responses[id]); v3270_emit_save_settings(widget); + + debug( + "Property %s is now %d", + g_param_spec_get_name(GTK_V3270_GET_CLASS(widget)->responses[id]), + GTK_V3270(widget)->responses[id] + ); + } gtk_widget_destroy(dialog); diff --git a/src/include/terminal.h b/src/include/terminal.h index 3d7f2c8..aed903c 100644 --- a/src/include/terminal.h +++ b/src/include/terminal.h @@ -36,8 +36,6 @@ G_BEGIN_DECLS { GtkWidgetClass parent_class; - // Dialog boxes. - // Internal properties. struct { @@ -66,12 +64,13 @@ G_BEGIN_DECLS guint integer; guint uint; guint str; + guint responses; } type; } properties; // Predefined responses. - GParamSpec *responses[V3270_TOGGLEABLE_DIALOG_CUSTOM]; + GParamSpec * responses[V3270_TOGGLEABLE_DIALOG_CUSTOM]; // Cursors GdkCursor * cursors[LIB3270_POINTER_COUNT]; diff --git a/src/include/v3270/settings.h b/src/include/v3270/settings.h index 9c203ea..4238f41 100644 --- a/src/include/v3270/settings.h +++ b/src/include/v3270/settings.h @@ -35,6 +35,14 @@ G_BEGIN_DECLS +/*--[ Tools ]----------------------------------------------------------------------------------------*/ + + /// @brief Reads the terminal settings from the group group_name in key_file. + LIB3270_EXPORT gboolean v3270_load_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name, GError **error); + + /// @brief This function adds the terminal settings from widget to key_file. + LIB3270_EXPORT void v3270_to_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name); + /*--[ V3270 Settings Widget ]------------------------------------------------------------------------*/ #define GTK_TYPE_V3270_SETTINGS (V3270Settings_get_type()) diff --git a/src/terminal/keyfile.c b/src/terminal/keyfile.c new file mode 100644 index 0000000..bec57a8 --- /dev/null +++ b/src/terminal/keyfile.c @@ -0,0 +1,217 @@ +/* + * "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) + * + */ + + #include + #include + #include + #include + #include + #include + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + + static void save_by_pspec(GtkWidget *widget, GParamSpec *pspec, GKeyFile *key_file, const gchar *group_name) + { + const gchar * name = g_param_spec_get_name(pspec); + GValue value = G_VALUE_INIT; + + g_value_init(&value, pspec->value_type); + g_object_get_property(G_OBJECT(widget),name,&value); + + switch(pspec->value_type) + { + case G_TYPE_STRING: + { + const gchar * current = g_value_get_string(&value); + + if(current && G_PARAM_SPEC_STRING(pspec)->default_value && strcmp(current,G_PARAM_SPEC_STRING(pspec)->default_value)) + { + g_key_file_set_string( + key_file, + group_name, + name, + current + ); + } + else + { + g_key_file_remove_key( + key_file, + group_name, + name, + NULL + ); + } + } + break; + + case G_TYPE_BOOLEAN: + { + gboolean current = g_value_get_boolean(&value); + + if(current != G_PARAM_SPEC_BOOLEAN(pspec)->default_value) + { + g_key_file_set_boolean( + key_file, + group_name, + name, + current + ); + } + else + { + g_key_file_remove_key( + key_file, + group_name, + name, + NULL + ); + } + } + break; + + case G_TYPE_INT: + { + gint current = g_value_get_int(&value); + + if(current != G_PARAM_SPEC_INT(pspec)->default_value) + { + g_key_file_set_integer( + key_file, + group_name, + name, + current + ); + } + else + { + g_key_file_remove_key( + key_file, + group_name, + name, + NULL + ); + } + + } + break; + + case G_TYPE_UINT: + { + guint current = (gint) g_value_get_uint(&value); + + if(current != G_PARAM_SPEC_UINT(pspec)->default_value) + { + g_key_file_set_integer( + key_file, + group_name, + name, + (gint) current + ); + } + else + { + g_key_file_remove_key( + key_file, + group_name, + name, + NULL + ); + } + + } + break; + + default: + lib3270_write_trace(v3270_get_session(widget),"%s has an unexpected value type\n",name); + + } + + g_value_unset(&value); + + + } + + /// @brief Reads the terminal settings from the group group_name in key_file. + LIB3270_EXPORT void v3270_to_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name) + { + g_return_if_fail(GTK_IS_V3270(widget)); + + size_t ix; + GString * str; + + v3270 * terminal = GTK_V3270(widget); + v3270Class * klass = GTK_V3270_GET_CLASS(widget); + + // Save Toggles + for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++) + save_by_pspec(widget,klass->properties.toggle[ix],key_file,group_name); + + // Save V3270 Responses + for(ix = 0; ix < G_N_ELEMENTS(terminal->responses); ix++) + save_by_pspec(widget,klass->responses[ix],key_file,group_name); + + // Save V3270 properties + save_by_pspec(widget,klass->properties.font_family,key_file,group_name); + save_by_pspec(widget,klass->properties.url,key_file,group_name); + save_by_pspec(widget,klass->properties.session_name,key_file,group_name); + save_by_pspec(widget,klass->properties.auto_disconnect,key_file,group_name); + save_by_pspec(widget,klass->properties.remap_file,key_file,group_name); + save_by_pspec(widget,klass->properties.dynamic_spacing,key_file,group_name); + save_by_pspec(widget,klass->properties.lu_names,key_file,group_name); + + // Save V3270 colors + str = g_string_new(""); + for(ix=0; ixstr + ); + + g_string_free(str,TRUE); + + } + + /// @brief This function adds the terminal settings from widget to key_file. + LIB3270_EXPORT gboolean v3270_load_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name, GError **error) + { + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); + + + return FALSE; + } diff --git a/src/terminal/properties/get.c b/src/terminal/properties/get.c index e8d2057..420411d 100644 --- a/src/terminal/properties/get.c +++ b/src/terminal/properties/get.c @@ -39,7 +39,11 @@ debug("%s(%u,%s)",__FUNCTION__,prop_id,g_param_spec_get_name(pspec)); - if(prop_id >= klass->properties.type.str) + if(prop_id >= klass->properties.type.responses) + { + g_value_set_int(value,(int) window->responses[prop_id - klass->properties.type.responses]); + } + else if(prop_id >= klass->properties.type.str) { const LIB3270_STRING_PROPERTY * prop = (lib3270_get_string_properties_list()+(prop_id - klass->properties.type.str)); debug("%s.%s.%s",__FUNCTION__,"string",prop->name); @@ -77,7 +81,7 @@ } else if(prop_id >= klass->properties.type.toggle) { - debug("%s.%s.%s",__FUNCTION__,"toggle",lib3270_get_toggle_name(prop_id - klass->properties.type.toggle)); +// debug("%s.%s.%s",__FUNCTION__,"toggle",lib3270_get_toggle_name(prop_id - klass->properties.type.toggle)); g_value_set_boolean(value,lib3270_get_toggle(window->host,prop_id - klass->properties.type.toggle) ? TRUE : FALSE ); } diff --git a/src/terminal/properties/init.c b/src/terminal/properties/init.c index e94c488..ab05b3f 100644 --- a/src/terminal/properties/init.c +++ b/src/terminal/properties/init.c @@ -28,6 +28,7 @@ */ #include "private.h" + #include /*--[ Implement ]------------------------------------------------------------------------------------*/ @@ -80,7 +81,7 @@ "font_family", "font_family", _("Font family for terminal contents"), - FALSE, + v3270_get_default_font_name(), G_PARAM_READABLE|G_PARAM_WRITABLE ); @@ -106,11 +107,13 @@ ); // Auto disconnect - klass->properties.auto_disconnect = g_param_spec_string( + klass->properties.auto_disconnect = g_param_spec_uint( "auto_disconnect", "auto_disconnect", _("IDLE minutes for automatic disconnection"), - FALSE, + 0, + G_MAXUINT, + 0, G_PARAM_READABLE|G_PARAM_WRITABLE ); @@ -200,61 +203,36 @@ klass->properties.count = V3270_PROPERTY_DYNAMIC; // - // Create action properties. + // Extract properties from LIB3270 control tables // - static const struct - { - const gchar *name; ///< @brief canonical name of the property specified. - const gchar *nick; ///< @brief nick name for the property specified. - const gchar *blurb; ///< @brief description of the property specified. - } actions[G_N_ELEMENTS(klass->responses)] = - { - { - .name = "paste_fails", - .nick = "paste_fails", - .blurb = "The action when formatted paste fails" - } - - }; + // Extract toggle class. + klass->properties.type.toggle = klass->properties.count; - for(ix = 0; ix < G_N_ELEMENTS(klass->responses); ix++) { - if(actions[ix].name) - { - klass->responses[ix] = - g_param_spec_enum( - actions[ix].name, - actions[ix].nick, - actions[ix].blurb, - GTK_TYPE_RESPONSE_TYPE, - GTK_RESPONSE_NONE, - (G_PARAM_READABLE|G_PARAM_WRITABLE) - ); + const LIB3270_TOGGLE * toggles = lib3270_get_toggles(); - v3270_install_property(gobject_class, klass->properties.count++, klass->responses[ix]); - } + for(ix = 0; ix < LIB3270_TOGGLE_COUNT; ix++) + { + if(!toggles[ix].name) + { + g_warning("Unexpected toggle id: %u", (unsigned int) ix); + break; + } - } + // debug("Property %u=%s (Toggle)",(unsigned int) klass->properties.type.toggle + ix, lib3270_get_toggle_name(ix)); - // - // Extract properties from LIB3270 control tables - // - // Extract toggle class. - klass->properties.type.toggle = klass->properties.count; - for(ix = 0; ix < LIB3270_TOGGLE_COUNT; ix++) - { -// debug("Property %u=%s (Toggle)",(unsigned int) klass->properties.type.toggle + ix, lib3270_get_toggle_name(ix)); + klass->properties.toggle[ix] = + g_param_spec_boolean( + toggles[ix].name, + toggles[ix].name, + toggles[ix].description, + (toggles[ix].def == 0 ? FALSE : TRUE), + G_PARAM_WRITABLE|G_PARAM_READABLE + ); - klass->properties.toggle[ix] = - g_param_spec_boolean( - lib3270_get_toggle_name(ix), - lib3270_get_toggle_name(ix), - lib3270_get_toggle_description(ix), - FALSE, - G_PARAM_WRITABLE|G_PARAM_READABLE - ); + v3270_install_property(gobject_class, klass->properties.count++, klass->properties.toggle[ix]); - v3270_install_property(gobject_class, klass->properties.count++, klass->properties.toggle[ix]); + } } @@ -342,5 +320,47 @@ } + // + // Create action properties. + // + klass->properties.type.responses = klass->properties.count; + + static const struct + { + const gchar *name; ///< @brief canonical name of the property specified. + const gchar *nick; ///< @brief nick name for the property specified. + const gchar *blurb; ///< @brief description of the property specified. + } actions[G_N_ELEMENTS(klass->responses)] = + { + { + .name = "paste_fails", + .nick = "paste_fails", + .blurb = "The action when formatted paste fails" + } + + }; + + for(ix = 0; ix < G_N_ELEMENTS(klass->responses); ix++) + { + if(actions[ix].name) + { + // Should be int to make it easier to GKeyFile methods. + klass->responses[ix] = + g_param_spec_int( + actions[ix].name, + actions[ix].nick, + actions[ix].blurb, + INT_MIN, + INT_MAX, + (int) GTK_RESPONSE_NONE, + (G_PARAM_READABLE|G_PARAM_WRITABLE) + ); + + v3270_install_property(gobject_class, klass->properties.count++, klass->responses[ix]); + } + + } + + } diff --git a/src/testprogram/testprogram.c b/src/testprogram/testprogram.c index 442fb1e..44d9e35 100644 --- a/src/testprogram/testprogram.c +++ b/src/testprogram/testprogram.c @@ -65,6 +65,16 @@ } */ + static void save_settings(GtkWidget *terminal, GtkWidget *window) + { + debug("%s: Saving settings for windows %p",__FUNCTION__,window); + + GKeyFile * key_file = g_key_file_new(); + v3270_to_key_file(terminal,key_file,"terminal"); + g_key_file_save_to_file(key_file,"terminal.conf",NULL); + g_key_file_free(key_file); + } + static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) { GtkWidget * window = gtk_application_window_new(app); @@ -109,6 +119,7 @@ gtk_widget_show_all(window); g_signal_connect(G_OBJECT(terminal),"session_changed",G_CALLBACK(session_changed),window); + g_signal_connect(G_OBJECT(terminal),"save-settings",G_CALLBACK(save_settings),window); // g_signal_connect(G_OBJECT(terminal),"field_clicked",G_CALLBACK(field_clicked),window); gtk_widget_grab_focus(terminal); diff --git a/v3270.cbp b/v3270.cbp index fe9be99..7e2b020 100644 --- a/v3270.cbp +++ b/v3270.cbp @@ -267,6 +267,9 @@ + + -- libgit2 0.21.2