From 812163f45eed9c412eb5f5ccb045b0fb8deb0905 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 7 Nov 2019 16:08:14 -0300 Subject: [PATCH] Refactoring settings dialogs to a more standard and consistent behavior. --- Makefile.in | 3 ++- src/dialogs/colors.c | 23 ++++++++++++----------- src/dialogs/commondialog.c | 2 ++ src/dialogs/font/chooser.c | 8 +++++--- src/dialogs/hostselect.c | 27 +++++++++++++++------------ src/dialogs/settings.c | 212 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/dialogs/settings/dialog.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dialogs/settings/widget.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/include/internals.h | 34 +++++++++++++++++++++++++++------- src/include/v3270/settings.h | 48 +++++++++++++++++++++++++++++++++++++++--------- src/terminal/widget.c | 21 +++++++++++++++++++++ src/testprogram/toolbar.c | 10 +++++++++- v3270.cbp | 6 ++++++ 13 files changed, 577 insertions(+), 256 deletions(-) delete mode 100644 src/dialogs/settings.c create mode 100644 src/dialogs/settings/dialog.c create mode 100644 src/dialogs/settings/widget.c diff --git a/Makefile.in b/Makefile.in index fb7e2e6..46191a7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -46,7 +46,8 @@ SOURCES= \ $(wildcard src/dialogs/@OSNAME@/*.c) \ $(wildcard src/dialogs/print/*.c) \ $(wildcard src/dialogs/save/*.c) \ - $(wildcard src/dialogs/font/*.c) + $(wildcard src/dialogs/font/*.c) \ + $(wildcard src/dialogs/settings/*.c) TEST_SOURCES= \ $(wildcard src/testprogram/*.c) diff --git a/src/dialogs/colors.c b/src/dialogs/colors.c index e17a516..a4cc362 100644 --- a/src/dialogs/colors.c +++ b/src/dialogs/colors.c @@ -215,7 +215,7 @@ static void load(GtkWidget G_GNUC_UNUSED(*w), GtkWidget *terminal) static void V3270ColorSelection_class_init(G_GNUC_UNUSED V3270ColorSelectionClass *klass) { GTK_V3270_SETTINGS_CLASS(klass)->load = load; - GTK_V3270_SETTINGS_CLASS(klass)->cancel = cancel; + GTK_V3270_SETTINGS_CLASS(klass)->revert = cancel; } static void color_scheme_changed(GtkWidget G_GNUC_UNUSED(*dunno), const GdkRGBA *colors, V3270ColorSelection *widget) { @@ -354,19 +354,20 @@ static void load(GtkWidget G_GNUC_UNUSED(*w), GtkWidget *terminal) LIB3270_EXPORT GtkWidget * v3270_color_selection_new() { - return GTK_WIDGET(g_object_new(GTK_TYPE_V3270_COLOR_SELECTION, NULL)); + V3270Settings * settings = GTK_V3270_SETTINGS(g_object_new(GTK_TYPE_V3270_COLOR_SELECTION, NULL)); + + settings->title = _("Terminal colors"); + settings->label = _("Colors"); + + return GTK_WIDGET(settings); } LIB3270_EXPORT void v3270_edit_color_table(GtkWidget *terminal) { - g_return_if_fail(GTK_IS_V3270(terminal)); - - GtkWidget * dialog = v3270_settings_dialog_new(terminal, v3270_color_selection_new()); - - v3270_dialog_setup(dialog,_("Color setup"),_("_Save")); - - gtk_widget_show_all(dialog); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); + v3270_settings_popup_dialog( + v3270_color_selection_new(), + terminal, + FALSE + ); } diff --git a/src/dialogs/commondialog.c b/src/dialogs/commondialog.c index 552fba2..c5b0a2e 100644 --- a/src/dialogs/commondialog.c +++ b/src/dialogs/commondialog.c @@ -98,6 +98,7 @@ LIB3270_EXPORT GtkWidget * v3270_dialog_new(GtkWidget *widget, const gchar *titl LIB3270_EXPORT void v3270_dialog_setup(GtkWidget *dialog, const gchar *title, const gchar *apply) { +/* #if GTK_CHECK_VERSION(3,12,0) GtkWidget * header = gtk_dialog_get_header_bar(GTK_DIALOG(dialog)); @@ -137,6 +138,7 @@ LIB3270_EXPORT void v3270_dialog_setup(GtkWidget *dialog, const gchar *title, co ); #endif // GTK 3.12 +*/ } diff --git a/src/dialogs/font/chooser.c b/src/dialogs/font/chooser.c index 215f00b..68e3145 100644 --- a/src/dialogs/font/chooser.c +++ b/src/dialogs/font/chooser.c @@ -148,7 +148,7 @@ G_OBJECT_CLASS(klass)->dispose = dispose; - widget->cancel = cancel; + widget->revert = cancel; widget->load = load; } @@ -323,9 +323,11 @@ static void V3270FontChooserWidget_init(V3270FontChooserWidget *widget) GtkWidget * v3270_font_chooser_widget_new() { - V3270FontChooserWidget * font_chooser = (V3270FontChooserWidget *) g_object_new(GTK_TYPE_V3270_FONT_CHOOSER, NULL); + V3270Settings * settings = GTK_V3270_SETTINGS(g_object_new(GTK_TYPE_V3270_FONT_CHOOSER, NULL)); + settings->title = _("Terminal font"); + settings->label = _("Font"); - return GTK_WIDGET(font_chooser); + return GTK_WIDGET(settings); } diff --git a/src/dialogs/hostselect.c b/src/dialogs/hostselect.c index c6c609f..19813bd 100644 --- a/src/dialogs/hostselect.c +++ b/src/dialogs/hostselect.c @@ -349,26 +349,28 @@ static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget) LIB3270_EXPORT GtkWidget * v3270_host_select_new() { - return GTK_WIDGET(g_object_new(GTK_TYPE_V3270HostSelectWidget, NULL)); + V3270Settings * settings = GTK_V3270_SETTINGS(g_object_new(GTK_TYPE_V3270HostSelectWidget, NULL)); + + settings->title = _("Host definition"); + settings->label = _("Host"); + + return GTK_WIDGET(settings); } LIB3270_EXPORT void v3270_select_host(GtkWidget *widget) { g_return_if_fail(GTK_IS_V3270(widget)); - /* - if(v3270_is_connected(widget)) - { - gtk_widget_error_bell(widget); - return; - } - */ + GtkWidget * dialog = v3270_settings_dialog_new(); - debug("V3270HostSelectWidget::%s",__FUNCTION__); + gtk_window_set_title(GTK_WINDOW(dialog), _("Host definition")); + + gtk_container_add(GTK_CONTAINER(dialog), v3270_host_select_new()); - GtkWidget * dialog = v3270_settings_dialog_new(widget, v3270_host_select_new()); + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(gtk_widget_get_toplevel(widget))); + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); - v3270_dialog_setup(dialog,_("Setup host"),_("C_onnect")); + v3270_settings_dialog_set_terminal_widget(dialog, widget); gtk_window_set_default_size(GTK_WINDOW(dialog), 700, 150); gtk_widget_show_all(dialog); @@ -383,17 +385,18 @@ LIB3270_EXPORT void v3270_select_host(GtkWidget *widget) { case GTK_RESPONSE_APPLY: debug("V3270HostSelectWidget::%s=%s",__FUNCTION__,"GTK_RESPONSE_APPLY"); + v3270_settings_dialog_apply(dialog); again = lib3270_reconnect(v3270_get_session(widget),0); break; case GTK_RESPONSE_CANCEL: again = FALSE; debug("V3270HostSelectWidget::%s=%s",__FUNCTION__,"GTK_RESPONSE_CANCEL"); + v3270_settings_dialog_revert(dialog); break; } } - debug("%s end",__FUNCTION__); gtk_widget_destroy(dialog); } diff --git a/src/dialogs/settings.c b/src/dialogs/settings.c deleted file mode 100644 index ebc7ea1..0000000 --- a/src/dialogs/settings.c +++ /dev/null @@ -1,212 +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) - * - */ - - #include "private.h" - #include - #include - - G_DEFINE_TYPE(V3270Settings, V3270Settings, GTK_TYPE_GRID); - -/*--[ Implement ]------------------------------------------------------------------------------------*/ - -static void apply(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) -{ - debug("V3270Settings::%s",__FUNCTION__); -} - -static void cancel(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) -{ - debug("V3270Settings::%s",__FUNCTION__); -} - -static void load(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) -{ - debug("V3270Settings::%s",__FUNCTION__); -} - -static void update_message(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) -{ - debug("V3270Settings::%s",__FUNCTION__); -} - -static void finalize(GObject *object) -{ - v3270_settings_set_terminal_widget(GTK_WIDGET(object),NULL); - G_OBJECT_CLASS(V3270Settings_parent_class)->finalize(object); -} - -static void V3270Settings_class_init(V3270SettingsClass *klass) -{ - klass->apply = apply; - klass->cancel = cancel; - klass->load = load; - klass->update_message = update_message; - - G_OBJECT_CLASS(klass)->finalize = finalize; -} - -static void V3270Settings_init(V3270Settings *widget) -{ - widget->terminal = NULL; - - // https://developer.gnome.org/hig/stable/visual-layout.html.en - gtk_grid_set_row_spacing(GTK_GRID(widget),6); - gtk_grid_set_column_spacing(GTK_GRID(widget),12); - -} - -static void signal_update_message(GtkWidget *terminal, LIB3270_MESSAGE G_GNUC_UNUSED(id), GtkWidget *settings) -{ - GTK_V3270_SETTINGS_GET_CLASS(settings)->update_message(settings,terminal); -} - -LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal) -{ - g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); - - V3270Settings * settings = GTK_V3270_SETTINGS(widget); - - // Return if there's nothing to do. - if(settings->terminal == terminal) - return; - - if(settings->terminal) - { - // Disconnect old terminal widget - gulong handler = g_signal_handler_find( - settings->terminal, - G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA, - 0, - 0, - NULL, - G_CALLBACK(signal_update_message), - widget - ); - - debug("handler=%u",(unsigned long) handler); - - if(handler) - g_signal_handler_disconnect(settings->terminal, handler); - - } - - // Update terminal - settings->terminal = terminal; - - if(settings->terminal) - { - // Connect the new widget. - g_signal_connect(G_OBJECT(terminal),I_("message_changed"), G_CALLBACK(signal_update_message), widget); - - // Update dialog state. - GTK_V3270_SETTINGS_GET_CLASS(widget)->update_message(widget,terminal); - - // Load the dialog contents. - GTK_V3270_SETTINGS_GET_CLASS(widget)->load(widget,terminal); - } - - } - - LIB3270_EXPORT GtkWidget * v3270_settings_get_terminal_widget(GtkWidget *widget) - { - g_return_val_if_fail(GTK_IS_V3270_SETTINGS(widget),NULL); - return GTK_V3270_SETTINGS(widget)->terminal; - } - - LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget) - { - g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); - GTK_V3270_SETTINGS_GET_CLASS(widget)->apply(widget,GTK_V3270_SETTINGS(widget)->terminal); - } - - LIB3270_EXPORT void v3270_settings_cancel(GtkWidget *widget) - { - g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); - GTK_V3270_SETTINGS_GET_CLASS(widget)->cancel(widget,GTK_V3270_SETTINGS(widget)->terminal); - } - - LIB3270_EXPORT void v3270_settings_on_dialog_response(GtkDialog G_GNUC_UNUSED(*dialog), gint response_id, GtkWidget *settings) - { - switch(response_id) - { - case GTK_RESPONSE_APPLY: - v3270_settings_apply(settings); - break; - - case GTK_RESPONSE_CANCEL: - v3270_settings_cancel(settings); - break; - - } - } - - LIB3270_EXPORT GtkWidget * v3270_settings_dialog_new(GtkWidget *terminal, GtkWidget *settings) - { -#if GTK_CHECK_VERSION(3,12,0) - - gboolean use_header; - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL); - - GtkWidget * dialog = - GTK_WIDGET(g_object_new( - GTK_TYPE_DIALOG, - "use-header-bar", (use_header ? 1 : 0), - NULL - )); - -#else - - GtkWidget * dialog = gtk_dialog_new(); - -#endif // GTK 3.12 - - GtkWidget * content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - - // https://developer.gnome.org/hig/stable/visual-layout.html.en - gtk_box_set_spacing( - GTK_BOX(content_area), - 18 - ); - - gtk_box_pack_start(GTK_BOX(content_area),settings,TRUE,TRUE,2); - v3270_settings_set_terminal_widget(settings,terminal); - - g_signal_connect(G_OBJECT(dialog),"response",G_CALLBACK(v3270_settings_on_dialog_response),settings); - - gtk_window_set_deletable(GTK_WINDOW(dialog),FALSE); - - // https://developer.gnome.org/hig/stable/visual-layout.html.en - gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),18); - - gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gtk_widget_get_toplevel(terminal))); - //gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); - gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); - - return dialog; - } diff --git a/src/dialogs/settings/dialog.c b/src/dialogs/settings/dialog.c new file mode 100644 index 0000000..3e143f5 --- /dev/null +++ b/src/dialogs/settings/dialog.c @@ -0,0 +1,276 @@ +/* + * "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 "../private.h" + #include + #include + #include + + G_DEFINE_TYPE(V3270SettingsDialog, V3270SettingsDialog, GTK_TYPE_DIALOG); + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +static gboolean on_tab_focus(V3270Settings *settings, GdkEvent G_GNUC_UNUSED(*event), GtkWindow *dialog) +{ + debug("title: %s",settings->title); + debug("label: %s",settings->label); + + if(settings->title) + gtk_window_set_title(dialog,settings->title); + + return FALSE; +} + +static void add(GtkContainer *container, GtkWidget *widget) +{ + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); + + debug("Added settings dialog %p",widget); + + GtkWidget * label = NULL; + if(GTK_V3270_SETTINGS(widget)->label) + { + label = gtk_label_new(GTK_V3270_SETTINGS(widget)->label); + + if(GTK_V3270_SETTINGS(widget)->tooltip) + gtk_widget_set_tooltip_markup(label,GTK_V3270_SETTINGS(widget)->tooltip); + + } + + gtk_notebook_append_page( + GTK_V3270_SETTINGS_DIALOG(container)->tabs, + widget, + label + ); + + g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(on_tab_focus), container); + + +} + +static void apply_settings(GtkWidget *widget, GtkWidget G_GNUC_UNUSED(* terminal)) +{ + if(GTK_IS_V3270_SETTINGS(widget)) + v3270_settings_apply(widget); +} + +static void revert_settings(GtkWidget *widget, GtkWidget G_GNUC_UNUSED(* terminal)) +{ + if(GTK_IS_V3270_SETTINGS(widget)) + v3270_settings_revert(widget); +} + +void v3270_settings_dialog_apply(GtkWidget *dialog) +{ + debug("%s",__FUNCTION__); + + GtkWidget * terminal = GTK_V3270_SETTINGS_DIALOG(dialog)->terminal; + if(!terminal) + return; + + gtk_container_foreach( + GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(dialog)->tabs), + (GtkCallback) apply_settings, + terminal + ); + + v3270_emit_save_settings(terminal); + +} + +void v3270_settings_dialog_revert(GtkWidget *dialog) +{ + debug("%s",__FUNCTION__); + + GtkWidget * terminal = GTK_V3270_SETTINGS_DIALOG(dialog)->terminal; + if(!terminal) + return; + + gtk_container_foreach( + GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(dialog)->tabs), + (GtkCallback) revert_settings, + terminal + ); + +} + +/* +static void response(GtkDialog *dialog, gint response_id) +{ + if(!terminal) + return; + + +} +*/ + +static void dispose(GObject *object) +{ + debug("%s",__FUNCTION__); + + V3270SettingsDialog * widget = GTK_V3270_SETTINGS_DIALOG(object); + + + G_OBJECT_CLASS(V3270SettingsDialog_parent_class)->dispose(object); +} + +static void V3270SettingsDialog_class_init(V3270SettingsDialogClass *klass) +{ + GTK_CONTAINER_CLASS(klass)->add = add; + + // Object class + G_OBJECT_CLASS(klass)->dispose = dispose; + +} + +static void on_page_changed(GtkNotebook *notebook, GtkWidget G_GNUC_UNUSED(*child), guint G_GNUC_UNUSED(page_num), V3270SettingsDialog G_GNUC_UNUSED(*dialog)) { + gtk_notebook_set_show_tabs(notebook,gtk_notebook_get_n_pages(notebook) > 1); +} + +static void V3270SettingsDialog_init(V3270SettingsDialog *dialog) +{ + GtkWidget * content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + + // https://developer.gnome.org/hig/stable/visual-layout.html.en + gtk_box_set_spacing(GTK_BOX(content_area),18); + gtk_container_set_border_width(GTK_CONTAINER(content_area),18); + + gtk_window_set_deletable(GTK_WINDOW(dialog),FALSE); + gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); + + gtk_dialog_add_buttons( + GTK_DIALOG(dialog), + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Apply"), GTK_RESPONSE_APPLY, + NULL + ); + + // Create notebook for settings widgets + dialog->tabs = GTK_NOTEBOOK(gtk_notebook_new()); + + gtk_notebook_set_scrollable(dialog->tabs,TRUE); + gtk_notebook_set_show_tabs(dialog->tabs,FALSE); + gtk_notebook_set_show_border(dialog->tabs, FALSE); + g_signal_connect(G_OBJECT(dialog->tabs), "page-added", G_CALLBACK(on_page_changed), dialog); + g_signal_connect(G_OBJECT(dialog->tabs), "page-removed", G_CALLBACK(on_page_changed), dialog); + gtk_box_pack_start(GTK_BOX(content_area),GTK_WIDGET(dialog->tabs),TRUE,TRUE,0); + +} + +GtkWidget * v3270_settings_dialog_new() +{ +#if GTK_CHECK_VERSION(3,12,0) + + gboolean use_header; + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL); + + GtkWidget * dialog = + GTK_WIDGET(g_object_new( + GTK_TYPE_V3270_SETTINGS_DIALOG, + "use-header-bar", (use_header ? 1 : 0), + NULL + )); + +#else + + GtkWidget * dialog = GTK_WIDGET(g_object_new(GTK_TYPE_V3270_SETTINGS_DIALOG, NULL)); + +#endif // GTK 3.12 + + return dialog; + +} + +static void set_terminal_widget(GtkWidget *settings, GtkWidget *terminal) +{ + if(GTK_IS_V3270_SETTINGS(settings)) + v3270_settings_set_terminal_widget(settings,terminal); +} + +void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal) +{ + g_return_if_fail(GTK_IS_V3270_SETTINGS_DIALOG(widget)); + + GTK_V3270_SETTINGS_DIALOG(widget)->terminal = terminal; + + gtk_container_foreach( + GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(widget)->tabs), + (GtkCallback) set_terminal_widget, + terminal + ); +} + +void v3270_settting_dialog_response(GtkDialog *dialog, gint response_id, GtkWidget *terminal) +{ + switch(response_id) + { + case GTK_RESPONSE_APPLY: + debug("%s:apply",__FUNCTION__); + v3270_settings_dialog_apply(dialog); + break; + + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: + debug("%s:cancel",__FUNCTION__); + v3270_settings_dialog_revert(dialog); + break; + + default: + g_warning("Unexpected settings dialog response \"%d\"",response_id); + } + + gtk_widget_destroy(dialog); + +} + +void v3270_settings_popup_dialog(GtkWidget *widget, GtkWidget *terminal, gboolean modal) +{ + g_return_if_fail(GTK_IS_V3270(terminal) && GTK_IS_V3270_SETTINGS(widget)); + + GtkWidget * dialog = v3270_settings_dialog_new(); + V3270Settings * settings = GTK_V3270_SETTINGS(widget); + + if(settings->title) + gtk_window_set_title(GTK_WINDOW(dialog),settings->title); + + gtk_container_add(GTK_CONTAINER(dialog), widget); + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(gtk_widget_get_toplevel(terminal))); + + gtk_window_set_modal(GTK_WINDOW(dialog),modal); + + v3270_settings_dialog_set_terminal_widget(dialog, terminal); + + g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL); + g_signal_connect(dialog,"response",G_CALLBACK(v3270_settting_dialog_response),NULL); + + gtk_widget_show_all(dialog); + +} + + diff --git a/src/dialogs/settings/widget.c b/src/dialogs/settings/widget.c new file mode 100644 index 0000000..4ccca66 --- /dev/null +++ b/src/dialogs/settings/widget.c @@ -0,0 +1,163 @@ +/* + * "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 "../private.h" + #include + #include + #include + + G_DEFINE_TYPE(V3270Settings, V3270Settings, GTK_TYPE_GRID); + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +static void apply(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) +{ + debug("V3270Settings::%s",__FUNCTION__); +} + +static void cancel(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) +{ + debug("V3270Settings::%s",__FUNCTION__); +} + +static void load(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) +{ + debug("V3270Settings::%s",__FUNCTION__); +} + +static void update_message(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) +{ + debug("V3270Settings::%s",__FUNCTION__); +} + +static void finalize(GObject *object) +{ + v3270_settings_set_terminal_widget(GTK_WIDGET(object),NULL); + G_OBJECT_CLASS(V3270Settings_parent_class)->finalize(object); +} + +static void V3270Settings_class_init(V3270SettingsClass *klass) +{ + klass->apply = apply; + klass->revert = cancel; + klass->load = load; + klass->update_message = update_message; + + G_OBJECT_CLASS(klass)->finalize = finalize; +} + +static void V3270Settings_init(V3270Settings *widget) +{ + widget->terminal = NULL; + + // https://developer.gnome.org/hig/stable/visual-layout.html.en + gtk_grid_set_row_spacing(GTK_GRID(widget),6); + gtk_grid_set_column_spacing(GTK_GRID(widget),12); + +} + +static void signal_update_message(GtkWidget *terminal, LIB3270_MESSAGE G_GNUC_UNUSED(id), GtkWidget *settings) +{ + GTK_V3270_SETTINGS_GET_CLASS(settings)->update_message(settings,terminal); +} + +LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal) +{ + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); + + V3270Settings * settings = GTK_V3270_SETTINGS(widget); + + // Return if there's nothing to do. + if(settings->terminal == terminal) + return; + + if(settings->terminal) + { + // Disconnect old terminal widget + gulong handler = g_signal_handler_find( + settings->terminal, + G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA, + 0, + 0, + NULL, + G_CALLBACK(signal_update_message), + widget + ); + + debug("handler=%u",(unsigned long) handler); + + if(handler) + g_signal_handler_disconnect(settings->terminal, handler); + + } + + // Update terminal + settings->terminal = terminal; + + if(settings->terminal) + { + // Connect the new widget. + g_signal_connect(G_OBJECT(terminal),I_("message_changed"), G_CALLBACK(signal_update_message), widget); + + // Update dialog state. + GTK_V3270_SETTINGS_GET_CLASS(widget)->update_message(widget,terminal); + + // Load the dialog contents. + GTK_V3270_SETTINGS_GET_CLASS(widget)->load(widget,terminal); + } + + } + + LIB3270_EXPORT GtkWidget * v3270_settings_get_terminal_widget(GtkWidget *widget) + { + g_return_val_if_fail(GTK_IS_V3270_SETTINGS(widget),NULL); + return GTK_V3270_SETTINGS(widget)->terminal; + } + + LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget) + { + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); + GTK_V3270_SETTINGS_GET_CLASS(widget)->apply(widget,GTK_V3270_SETTINGS(widget)->terminal); + + /* + + BUG: The signal should be sent by the dialog! + + V3270Settings * settings = GTK_V3270_SETTINGS(widget); + if(settings && settings->terminal) + v3270_emit_save_settings(settings->terminal); + */ + } + + LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget) + { + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); + GTK_V3270_SETTINGS_GET_CLASS(widget)->revert(widget,GTK_V3270_SETTINGS(widget)->terminal); + } + diff --git a/src/include/internals.h b/src/include/internals.h index f6f5e7e..0703245 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -65,21 +65,38 @@ V3270_SIGNAL_TOGGLE_CHANGED, V3270_SIGNAL_MESSAGE_CHANGED, V3270_SIGNAL_KEYPRESS, - V3270_SIGNAL_CONNECTED, - V3270_SIGNAL_DISCONNECTED, - V3270_SIGNAL_UPDATE_CONFIG, V3270_SIGNAL_MODEL_CHANGED, - V3270_SIGNAL_SELECTING, V3270_SIGNAL_POPUP, - V3270_SIGNAL_PASTENEXT, - V3270_SIGNAL_CLIPBOARD, V3270_SIGNAL_CHANGED, V3270_SIGNAL_MESSAGE, V3270_SIGNAL_FIELD, + V3270_SIGNAL_SESSION_CHANGED, + + // + // Clipboard signals. + // + V3270_SIGNAL_SELECTING, + V3270_SIGNAL_CLIPBOARD, + V3270_SIGNAL_PASTENEXT, + + // + // Network signals. + // + V3270_SIGNAL_CONNECTED, + V3270_SIGNAL_DISCONNECTED, + + // + // Print session signals. + // V3270_SIGNAL_PRINT_SETUP, V3270_SIGNAL_PRINT_APPLY, V3270_SIGNAL_PRINT_DONE, - V3270_SIGNAL_SESSION_CHANGED, + + // + // Settings signals (Mostly fired by V3270Settings dialogs). + // + V3270_SIGNAL_SAVE_SETTINGS, ///< @brief Notify main application to save all widget settings. + V3270_SIGNAL_UPDATE_CONFIG, ///< @brief Update config signal (deprecated!) V3270_SIGNAL_LAST }; @@ -102,6 +119,9 @@ G_GNUC_INTERNAL void v3270_dialog_close(GtkDialog *dialog, gpointer user_data); + /// @brief Emit the "save-settings" signal. + G_GNUC_INTERNAL void v3270_emit_save_settings(GtkWidget *widget); + G_GNUC_INTERNAL gchar * v3270_convert_to_3270_charset(GtkWidget *widget, const gchar *text, const gchar *encoding, GError **error); diff --git a/src/include/v3270/settings.h b/src/include/v3270/settings.h index a654dc0..fd7989e 100644 --- a/src/include/v3270/settings.h +++ b/src/include/v3270/settings.h @@ -35,7 +35,7 @@ G_BEGIN_DECLS -/*--[ Progress widget ]------------------------------------------------------------------------------*/ +/*--[ V3270 Settings Widget ]------------------------------------------------------------------------*/ #define GTK_TYPE_V3270_SETTINGS (V3270Settings_get_type()) #define GTK_V3270_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_V3270_SETTINGS, V3270Settings)) @@ -47,6 +47,9 @@ typedef struct _V3270Settings { GtkGrid parent; GtkWidget * terminal; + const gchar * label; ///< @brief Label for settings dialog. + const gchar * title; ///< @brief Title for settings dialog. + const gchar * tooltip; ///< @brief Tooltip for settings dialog. } V3270Settings; typedef struct _V3270SettingsClass { @@ -54,25 +57,52 @@ void (*load)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method to load the properties from terminal widget void (*apply)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_APPLY - void (*cancel)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_CANCEL + void (*revert)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_CANCEL void (*update_message)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Lib3270 message has changed. } V3270SettingsClass; -/*--[ Prototypes ]-----------------------------------------------------------------------------------*/ + LIB3270_EXPORT GType V3270Settings_get_type(void); LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal); LIB3270_EXPORT GtkWidget * v3270_settings_get_terminal_widget(GtkWidget *widget); - LIB3270_EXPORT GType V3270Settings_get_type(void); LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget); - LIB3270_EXPORT void v3270_settings_cancel(GtkWidget *widget); + LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget); + + /// @brief Popup a settings dialog for the terminal. + LIB3270_EXPORT void v3270_settings_popup_dialog(GtkWidget *settings, GtkWidget *terminal, gboolean modal); + +/*--[ V3270 Settings Dialog ]------------------------------------------------------------------------*/ + + #define GTK_TYPE_V3270_SETTINGS_DIALOG (V3270SettingsDialog_get_type()) + #define GTK_V3270_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_V3270_SETTINGS_DIALOG, V3270SettingsDialog)) + #define GTK_V3270_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_V3270_SETTINGS_DIALOG, V3270SettingsDialogClass)) + #define GTK_IS_V3270_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_V3270_SETTINGS_DIALOG)) + #define GTK_IS_V3270_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_V3270_SETTINGS_DIALOG)) + #define GTK_V3270_SETTINGS_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_V3270_SETTINGS_DIALOG, V3270SettingsDialogClass)) + + typedef struct _V3270SettingsDialog { + GtkDialog parent; + GtkNotebook * tabs; + GtkWidget * terminal; + } V3270SettingsDialog; + + typedef struct _V3270SettingsDialogClass { + GtkDialogClass parent_class; + + } V3270SettingsDialogClass; + + LIB3270_EXPORT GType V3270SettingsDialog_get_type(void); + + LIB3270_EXPORT GtkWidget * v3270_settings_dialog_new(); + LIB3270_EXPORT void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal); - /// @brief Callback for GtkDialog's "response" signal. - LIB3270_EXPORT void v3270_settings_on_dialog_response(GtkDialog *dialog, gint response_id, GtkWidget *settings); + /// @brief Process GtkDialog's "response" signal. + LIB3270_EXPORT void v3270_settting_dialog_response(GtkDialog *dialog, gint response_id, GtkWidget *terminal); - LIB3270_EXPORT GtkWidget * v3270_settings_dialog_new(GtkWidget *terminal, GtkWidget *settings); - // LIB3270_EXPORT gint v3270_settings_dialog_run(GtkWidget *widget, GtkWidget *terminal); + LIB3270_EXPORT void v3270_settings_dialog_apply(GtkWidget *widget); + LIB3270_EXPORT void v3270_settings_dialog_revert(GtkWidget *widget); G_END_DECLS diff --git a/src/terminal/widget.c b/src/terminal/widget.c index 3e07619..cb97c11 100644 --- a/src/terminal/widget.c +++ b/src/terminal/widget.c @@ -456,6 +456,15 @@ static void v3270_class_init(v3270Class *klass) v3270_VOID__VOID_POINTER_UINT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT, 0); + v3270_widget_signal[V3270_SIGNAL_SAVE_SETTINGS] = + g_signal_new( I_("save-settings"), + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + v3270_VOID__VOID, + G_TYPE_NONE, 0); + v3270_init_properties(gobject_class); } @@ -750,3 +759,15 @@ LIB3270_EXPORT GtkIMContext * v3270_get_im_context(GtkWidget *widget) return GTK_V3270(widget)->input_method; } +static gboolean bg_emit_save_settings(GObject *widget) +{ + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_SAVE_SETTINGS], 0, FALSE); + return FALSE; +} + +void v3270_emit_save_settings(GtkWidget *widget) +{ + if(widget) + g_idle_add((GSourceFunc) bg_emit_save_settings, G_OBJECT(widget)); +} + diff --git a/src/testprogram/toolbar.c b/src/testprogram/toolbar.c index 3a95ffa..54f604a 100644 --- a/src/testprogram/toolbar.c +++ b/src/testprogram/toolbar.c @@ -54,13 +54,21 @@ static void font_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal) { + v3270_settings_popup_dialog( + v3270_font_chooser_widget_new(), + terminal, + FALSE + ); + + /* GtkWidget * dialog = v3270_settings_dialog_new(terminal, v3270_font_chooser_widget_new()); - v3270_dialog_setup(dialog,_("Font setup"),_("_Save")); +// v3270_dialog_setup(dialog,_("Font setup"),_("_Save")); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); + */ } diff --git a/v3270.cbp b/v3270.cbp index 8bd16d5..f312a50 100644 --- a/v3270.cbp +++ b/v3270.cbp @@ -102,6 +102,12 @@ + + + + -- libgit2 0.21.2