Commit 812163f45eed9c412eb5f5ccb045b0fb8deb0905

Authored by Perry Werneck
1 parent 3d1738f1
Exists in master and in 1 other branch develop

Refactoring settings dialogs to a more standard and consistent behavior.

Makefile.in
... ... @@ -46,7 +46,8 @@ SOURCES= \
46 46 $(wildcard src/dialogs/@OSNAME@/*.c) \
47 47 $(wildcard src/dialogs/print/*.c) \
48 48 $(wildcard src/dialogs/save/*.c) \
49   - $(wildcard src/dialogs/font/*.c)
  49 + $(wildcard src/dialogs/font/*.c) \
  50 + $(wildcard src/dialogs/settings/*.c)
50 51  
51 52 TEST_SOURCES= \
52 53 $(wildcard src/testprogram/*.c)
... ...
src/dialogs/colors.c
... ... @@ -215,7 +215,7 @@ static void load(GtkWidget G_GNUC_UNUSED(*w), GtkWidget *terminal)
215 215 static void V3270ColorSelection_class_init(G_GNUC_UNUSED V3270ColorSelectionClass *klass)
216 216 {
217 217 GTK_V3270_SETTINGS_CLASS(klass)->load = load;
218   - GTK_V3270_SETTINGS_CLASS(klass)->cancel = cancel;
  218 + GTK_V3270_SETTINGS_CLASS(klass)->revert = cancel;
219 219 }
220 220  
221 221 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)
354 354  
355 355 LIB3270_EXPORT GtkWidget * v3270_color_selection_new()
356 356 {
357   - return GTK_WIDGET(g_object_new(GTK_TYPE_V3270_COLOR_SELECTION, NULL));
  357 + V3270Settings * settings = GTK_V3270_SETTINGS(g_object_new(GTK_TYPE_V3270_COLOR_SELECTION, NULL));
  358 +
  359 + settings->title = _("Terminal colors");
  360 + settings->label = _("Colors");
  361 +
  362 + return GTK_WIDGET(settings);
358 363 }
359 364  
360 365 LIB3270_EXPORT void v3270_edit_color_table(GtkWidget *terminal)
361 366 {
362   - g_return_if_fail(GTK_IS_V3270(terminal));
363   -
364   - GtkWidget * dialog = v3270_settings_dialog_new(terminal, v3270_color_selection_new());
365   -
366   - v3270_dialog_setup(dialog,_("Color setup"),_("_Save"));
367   -
368   - gtk_widget_show_all(dialog);
369   - gtk_dialog_run(GTK_DIALOG(dialog));
370   - gtk_widget_destroy(dialog);
  367 + v3270_settings_popup_dialog(
  368 + v3270_color_selection_new(),
  369 + terminal,
  370 + FALSE
  371 + );
371 372  
372 373 }
... ...
src/dialogs/commondialog.c
... ... @@ -98,6 +98,7 @@ LIB3270_EXPORT GtkWidget * v3270_dialog_new(GtkWidget *widget, const gchar *titl
98 98 LIB3270_EXPORT void v3270_dialog_setup(GtkWidget *dialog, const gchar *title, const gchar *apply)
99 99 {
100 100  
  101 +/*
101 102 #if GTK_CHECK_VERSION(3,12,0)
102 103  
103 104 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
137 138 );
138 139  
139 140 #endif // GTK 3.12
  141 +*/
140 142  
141 143 }
142 144  
... ...
src/dialogs/font/chooser.c
... ... @@ -148,7 +148,7 @@
148 148  
149 149 G_OBJECT_CLASS(klass)->dispose = dispose;
150 150  
151   - widget->cancel = cancel;
  151 + widget->revert = cancel;
152 152 widget->load = load;
153 153  
154 154 }
... ... @@ -323,9 +323,11 @@ static void V3270FontChooserWidget_init(V3270FontChooserWidget *widget)
323 323  
324 324 GtkWidget * v3270_font_chooser_widget_new()
325 325 {
326   - V3270FontChooserWidget * font_chooser = (V3270FontChooserWidget *) g_object_new(GTK_TYPE_V3270_FONT_CHOOSER, NULL);
  326 + V3270Settings * settings = GTK_V3270_SETTINGS(g_object_new(GTK_TYPE_V3270_FONT_CHOOSER, NULL));
327 327  
  328 + settings->title = _("Terminal font");
  329 + settings->label = _("Font");
328 330  
329   - return GTK_WIDGET(font_chooser);
  331 + return GTK_WIDGET(settings);
330 332 }
331 333  
... ...
src/dialogs/hostselect.c
... ... @@ -349,26 +349,28 @@ static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget)
349 349  
350 350 LIB3270_EXPORT GtkWidget * v3270_host_select_new()
351 351 {
352   - return GTK_WIDGET(g_object_new(GTK_TYPE_V3270HostSelectWidget, NULL));
  352 + V3270Settings * settings = GTK_V3270_SETTINGS(g_object_new(GTK_TYPE_V3270HostSelectWidget, NULL));
  353 +
  354 + settings->title = _("Host definition");
  355 + settings->label = _("Host");
  356 +
  357 + return GTK_WIDGET(settings);
353 358 }
354 359  
355 360 LIB3270_EXPORT void v3270_select_host(GtkWidget *widget)
356 361 {
357 362 g_return_if_fail(GTK_IS_V3270(widget));
358 363  
359   - /*
360   - if(v3270_is_connected(widget))
361   - {
362   - gtk_widget_error_bell(widget);
363   - return;
364   - }
365   - */
  364 + GtkWidget * dialog = v3270_settings_dialog_new();
366 365  
367   - debug("V3270HostSelectWidget::%s",__FUNCTION__);
  366 + gtk_window_set_title(GTK_WINDOW(dialog), _("Host definition"));
  367 +
  368 + gtk_container_add(GTK_CONTAINER(dialog), v3270_host_select_new());
368 369  
369   - GtkWidget * dialog = v3270_settings_dialog_new(widget, v3270_host_select_new());
  370 + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(gtk_widget_get_toplevel(widget)));
  371 + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE);
370 372  
371   - v3270_dialog_setup(dialog,_("Setup host"),_("C_onnect"));
  373 + v3270_settings_dialog_set_terminal_widget(dialog, widget);
372 374  
373 375 gtk_window_set_default_size(GTK_WINDOW(dialog), 700, 150);
374 376 gtk_widget_show_all(dialog);
... ... @@ -383,17 +385,18 @@ LIB3270_EXPORT void v3270_select_host(GtkWidget *widget)
383 385 {
384 386 case GTK_RESPONSE_APPLY:
385 387 debug("V3270HostSelectWidget::%s=%s",__FUNCTION__,"GTK_RESPONSE_APPLY");
  388 + v3270_settings_dialog_apply(dialog);
386 389 again = lib3270_reconnect(v3270_get_session(widget),0);
387 390 break;
388 391  
389 392 case GTK_RESPONSE_CANCEL:
390 393 again = FALSE;
391 394 debug("V3270HostSelectWidget::%s=%s",__FUNCTION__,"GTK_RESPONSE_CANCEL");
  395 + v3270_settings_dialog_revert(dialog);
392 396 break;
393 397 }
394 398 }
395 399  
396   - debug("%s end",__FUNCTION__);
397 400 gtk_widget_destroy(dialog);
398 401  
399 402 }
... ...
src/dialogs/settings.c
... ... @@ -1,212 +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   - #include "private.h"
31   - #include <v3270/settings.h>
32   - #include <lib3270/log.h>
33   -
34   - G_DEFINE_TYPE(V3270Settings, V3270Settings, GTK_TYPE_GRID);
35   -
36   -/*--[ Implement ]------------------------------------------------------------------------------------*/
37   -
38   -static void apply(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
39   -{
40   - debug("V3270Settings::%s",__FUNCTION__);
41   -}
42   -
43   -static void cancel(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
44   -{
45   - debug("V3270Settings::%s",__FUNCTION__);
46   -}
47   -
48   -static void load(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
49   -{
50   - debug("V3270Settings::%s",__FUNCTION__);
51   -}
52   -
53   -static void update_message(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
54   -{
55   - debug("V3270Settings::%s",__FUNCTION__);
56   -}
57   -
58   -static void finalize(GObject *object)
59   -{
60   - v3270_settings_set_terminal_widget(GTK_WIDGET(object),NULL);
61   - G_OBJECT_CLASS(V3270Settings_parent_class)->finalize(object);
62   -}
63   -
64   -static void V3270Settings_class_init(V3270SettingsClass *klass)
65   -{
66   - klass->apply = apply;
67   - klass->cancel = cancel;
68   - klass->load = load;
69   - klass->update_message = update_message;
70   -
71   - G_OBJECT_CLASS(klass)->finalize = finalize;
72   -}
73   -
74   -static void V3270Settings_init(V3270Settings *widget)
75   -{
76   - widget->terminal = NULL;
77   -
78   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
79   - gtk_grid_set_row_spacing(GTK_GRID(widget),6);
80   - gtk_grid_set_column_spacing(GTK_GRID(widget),12);
81   -
82   -}
83   -
84   -static void signal_update_message(GtkWidget *terminal, LIB3270_MESSAGE G_GNUC_UNUSED(id), GtkWidget *settings)
85   -{
86   - GTK_V3270_SETTINGS_GET_CLASS(settings)->update_message(settings,terminal);
87   -}
88   -
89   -LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal)
90   -{
91   - g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
92   -
93   - V3270Settings * settings = GTK_V3270_SETTINGS(widget);
94   -
95   - // Return if there's nothing to do.
96   - if(settings->terminal == terminal)
97   - return;
98   -
99   - if(settings->terminal)
100   - {
101   - // Disconnect old terminal widget
102   - gulong handler = g_signal_handler_find(
103   - settings->terminal,
104   - G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA,
105   - 0,
106   - 0,
107   - NULL,
108   - G_CALLBACK(signal_update_message),
109   - widget
110   - );
111   -
112   - debug("handler=%u",(unsigned long) handler);
113   -
114   - if(handler)
115   - g_signal_handler_disconnect(settings->terminal, handler);
116   -
117   - }
118   -
119   - // Update terminal
120   - settings->terminal = terminal;
121   -
122   - if(settings->terminal)
123   - {
124   - // Connect the new widget.
125   - g_signal_connect(G_OBJECT(terminal),I_("message_changed"), G_CALLBACK(signal_update_message), widget);
126   -
127   - // Update dialog state.
128   - GTK_V3270_SETTINGS_GET_CLASS(widget)->update_message(widget,terminal);
129   -
130   - // Load the dialog contents.
131   - GTK_V3270_SETTINGS_GET_CLASS(widget)->load(widget,terminal);
132   - }
133   -
134   - }
135   -
136   - LIB3270_EXPORT GtkWidget * v3270_settings_get_terminal_widget(GtkWidget *widget)
137   - {
138   - g_return_val_if_fail(GTK_IS_V3270_SETTINGS(widget),NULL);
139   - return GTK_V3270_SETTINGS(widget)->terminal;
140   - }
141   -
142   - LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget)
143   - {
144   - g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
145   - GTK_V3270_SETTINGS_GET_CLASS(widget)->apply(widget,GTK_V3270_SETTINGS(widget)->terminal);
146   - }
147   -
148   - LIB3270_EXPORT void v3270_settings_cancel(GtkWidget *widget)
149   - {
150   - g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
151   - GTK_V3270_SETTINGS_GET_CLASS(widget)->cancel(widget,GTK_V3270_SETTINGS(widget)->terminal);
152   - }
153   -
154   - LIB3270_EXPORT void v3270_settings_on_dialog_response(GtkDialog G_GNUC_UNUSED(*dialog), gint response_id, GtkWidget *settings)
155   - {
156   - switch(response_id)
157   - {
158   - case GTK_RESPONSE_APPLY:
159   - v3270_settings_apply(settings);
160   - break;
161   -
162   - case GTK_RESPONSE_CANCEL:
163   - v3270_settings_cancel(settings);
164   - break;
165   -
166   - }
167   - }
168   -
169   - LIB3270_EXPORT GtkWidget * v3270_settings_dialog_new(GtkWidget *terminal, GtkWidget *settings)
170   - {
171   -#if GTK_CHECK_VERSION(3,12,0)
172   -
173   - gboolean use_header;
174   - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
175   -
176   - GtkWidget * dialog =
177   - GTK_WIDGET(g_object_new(
178   - GTK_TYPE_DIALOG,
179   - "use-header-bar", (use_header ? 1 : 0),
180   - NULL
181   - ));
182   -
183   -#else
184   -
185   - GtkWidget * dialog = gtk_dialog_new();
186   -
187   -#endif // GTK 3.12
188   -
189   - GtkWidget * content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
190   -
191   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
192   - gtk_box_set_spacing(
193   - GTK_BOX(content_area),
194   - 18
195   - );
196   -
197   - gtk_box_pack_start(GTK_BOX(content_area),settings,TRUE,TRUE,2);
198   - v3270_settings_set_terminal_widget(settings,terminal);
199   -
200   - g_signal_connect(G_OBJECT(dialog),"response",G_CALLBACK(v3270_settings_on_dialog_response),settings);
201   -
202   - gtk_window_set_deletable(GTK_WINDOW(dialog),FALSE);
203   -
204   - // https://developer.gnome.org/hig/stable/visual-layout.html.en
205   - gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),18);
206   -
207   - gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gtk_widget_get_toplevel(terminal)));
208   - //gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
209   - gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
210   -
211   - return dialog;
212   - }
src/dialogs/settings/dialog.c 0 → 100644
... ... @@ -0,0 +1,276 @@
  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 "../private.h"
  31 + #include <internals.h>
  32 + #include <v3270/settings.h>
  33 + #include <lib3270/log.h>
  34 +
  35 + G_DEFINE_TYPE(V3270SettingsDialog, V3270SettingsDialog, GTK_TYPE_DIALOG);
  36 +
  37 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  38 +
  39 +static gboolean on_tab_focus(V3270Settings *settings, GdkEvent G_GNUC_UNUSED(*event), GtkWindow *dialog)
  40 +{
  41 + debug("title: %s",settings->title);
  42 + debug("label: %s",settings->label);
  43 +
  44 + if(settings->title)
  45 + gtk_window_set_title(dialog,settings->title);
  46 +
  47 + return FALSE;
  48 +}
  49 +
  50 +static void add(GtkContainer *container, GtkWidget *widget)
  51 +{
  52 + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
  53 +
  54 + debug("Added settings dialog %p",widget);
  55 +
  56 + GtkWidget * label = NULL;
  57 + if(GTK_V3270_SETTINGS(widget)->label)
  58 + {
  59 + label = gtk_label_new(GTK_V3270_SETTINGS(widget)->label);
  60 +
  61 + if(GTK_V3270_SETTINGS(widget)->tooltip)
  62 + gtk_widget_set_tooltip_markup(label,GTK_V3270_SETTINGS(widget)->tooltip);
  63 +
  64 + }
  65 +
  66 + gtk_notebook_append_page(
  67 + GTK_V3270_SETTINGS_DIALOG(container)->tabs,
  68 + widget,
  69 + label
  70 + );
  71 +
  72 + g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(on_tab_focus), container);
  73 +
  74 +
  75 +}
  76 +
  77 +static void apply_settings(GtkWidget *widget, GtkWidget G_GNUC_UNUSED(* terminal))
  78 +{
  79 + if(GTK_IS_V3270_SETTINGS(widget))
  80 + v3270_settings_apply(widget);
  81 +}
  82 +
  83 +static void revert_settings(GtkWidget *widget, GtkWidget G_GNUC_UNUSED(* terminal))
  84 +{
  85 + if(GTK_IS_V3270_SETTINGS(widget))
  86 + v3270_settings_revert(widget);
  87 +}
  88 +
  89 +void v3270_settings_dialog_apply(GtkWidget *dialog)
  90 +{
  91 + debug("%s",__FUNCTION__);
  92 +
  93 + GtkWidget * terminal = GTK_V3270_SETTINGS_DIALOG(dialog)->terminal;
  94 + if(!terminal)
  95 + return;
  96 +
  97 + gtk_container_foreach(
  98 + GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(dialog)->tabs),
  99 + (GtkCallback) apply_settings,
  100 + terminal
  101 + );
  102 +
  103 + v3270_emit_save_settings(terminal);
  104 +
  105 +}
  106 +
  107 +void v3270_settings_dialog_revert(GtkWidget *dialog)
  108 +{
  109 + debug("%s",__FUNCTION__);
  110 +
  111 + GtkWidget * terminal = GTK_V3270_SETTINGS_DIALOG(dialog)->terminal;
  112 + if(!terminal)
  113 + return;
  114 +
  115 + gtk_container_foreach(
  116 + GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(dialog)->tabs),
  117 + (GtkCallback) revert_settings,
  118 + terminal
  119 + );
  120 +
  121 +}
  122 +
  123 +/*
  124 +static void response(GtkDialog *dialog, gint response_id)
  125 +{
  126 + if(!terminal)
  127 + return;
  128 +
  129 +
  130 +}
  131 +*/
  132 +
  133 +static void dispose(GObject *object)
  134 +{
  135 + debug("%s",__FUNCTION__);
  136 +
  137 + V3270SettingsDialog * widget = GTK_V3270_SETTINGS_DIALOG(object);
  138 +
  139 +
  140 + G_OBJECT_CLASS(V3270SettingsDialog_parent_class)->dispose(object);
  141 +}
  142 +
  143 +static void V3270SettingsDialog_class_init(V3270SettingsDialogClass *klass)
  144 +{
  145 + GTK_CONTAINER_CLASS(klass)->add = add;
  146 +
  147 + // Object class
  148 + G_OBJECT_CLASS(klass)->dispose = dispose;
  149 +
  150 +}
  151 +
  152 +static void on_page_changed(GtkNotebook *notebook, GtkWidget G_GNUC_UNUSED(*child), guint G_GNUC_UNUSED(page_num), V3270SettingsDialog G_GNUC_UNUSED(*dialog)) {
  153 + gtk_notebook_set_show_tabs(notebook,gtk_notebook_get_n_pages(notebook) > 1);
  154 +}
  155 +
  156 +static void V3270SettingsDialog_init(V3270SettingsDialog *dialog)
  157 +{
  158 + GtkWidget * content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
  159 +
  160 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  161 + gtk_box_set_spacing(GTK_BOX(content_area),18);
  162 + gtk_container_set_border_width(GTK_CONTAINER(content_area),18);
  163 +
  164 + gtk_window_set_deletable(GTK_WINDOW(dialog),FALSE);
  165 + gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
  166 +
  167 + gtk_dialog_add_buttons(
  168 + GTK_DIALOG(dialog),
  169 + _("_Cancel"), GTK_RESPONSE_CANCEL,
  170 + _("_Apply"), GTK_RESPONSE_APPLY,
  171 + NULL
  172 + );
  173 +
  174 + // Create notebook for settings widgets
  175 + dialog->tabs = GTK_NOTEBOOK(gtk_notebook_new());
  176 +
  177 + gtk_notebook_set_scrollable(dialog->tabs,TRUE);
  178 + gtk_notebook_set_show_tabs(dialog->tabs,FALSE);
  179 + gtk_notebook_set_show_border(dialog->tabs, FALSE);
  180 + g_signal_connect(G_OBJECT(dialog->tabs), "page-added", G_CALLBACK(on_page_changed), dialog);
  181 + g_signal_connect(G_OBJECT(dialog->tabs), "page-removed", G_CALLBACK(on_page_changed), dialog);
  182 + gtk_box_pack_start(GTK_BOX(content_area),GTK_WIDGET(dialog->tabs),TRUE,TRUE,0);
  183 +
  184 +}
  185 +
  186 +GtkWidget * v3270_settings_dialog_new()
  187 +{
  188 +#if GTK_CHECK_VERSION(3,12,0)
  189 +
  190 + gboolean use_header;
  191 + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL);
  192 +
  193 + GtkWidget * dialog =
  194 + GTK_WIDGET(g_object_new(
  195 + GTK_TYPE_V3270_SETTINGS_DIALOG,
  196 + "use-header-bar", (use_header ? 1 : 0),
  197 + NULL
  198 + ));
  199 +
  200 +#else
  201 +
  202 + GtkWidget * dialog = GTK_WIDGET(g_object_new(GTK_TYPE_V3270_SETTINGS_DIALOG, NULL));
  203 +
  204 +#endif // GTK 3.12
  205 +
  206 + return dialog;
  207 +
  208 +}
  209 +
  210 +static void set_terminal_widget(GtkWidget *settings, GtkWidget *terminal)
  211 +{
  212 + if(GTK_IS_V3270_SETTINGS(settings))
  213 + v3270_settings_set_terminal_widget(settings,terminal);
  214 +}
  215 +
  216 +void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal)
  217 +{
  218 + g_return_if_fail(GTK_IS_V3270_SETTINGS_DIALOG(widget));
  219 +
  220 + GTK_V3270_SETTINGS_DIALOG(widget)->terminal = terminal;
  221 +
  222 + gtk_container_foreach(
  223 + GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(widget)->tabs),
  224 + (GtkCallback) set_terminal_widget,
  225 + terminal
  226 + );
  227 +}
  228 +
  229 +void v3270_settting_dialog_response(GtkDialog *dialog, gint response_id, GtkWidget *terminal)
  230 +{
  231 + switch(response_id)
  232 + {
  233 + case GTK_RESPONSE_APPLY:
  234 + debug("%s:apply",__FUNCTION__);
  235 + v3270_settings_dialog_apply(dialog);
  236 + break;
  237 +
  238 + case GTK_RESPONSE_CANCEL:
  239 + case GTK_RESPONSE_DELETE_EVENT:
  240 + debug("%s:cancel",__FUNCTION__);
  241 + v3270_settings_dialog_revert(dialog);
  242 + break;
  243 +
  244 + default:
  245 + g_warning("Unexpected settings dialog response \"%d\"",response_id);
  246 + }
  247 +
  248 + gtk_widget_destroy(dialog);
  249 +
  250 +}
  251 +
  252 +void v3270_settings_popup_dialog(GtkWidget *widget, GtkWidget *terminal, gboolean modal)
  253 +{
  254 + g_return_if_fail(GTK_IS_V3270(terminal) && GTK_IS_V3270_SETTINGS(widget));
  255 +
  256 + GtkWidget * dialog = v3270_settings_dialog_new();
  257 + V3270Settings * settings = GTK_V3270_SETTINGS(widget);
  258 +
  259 + if(settings->title)
  260 + gtk_window_set_title(GTK_WINDOW(dialog),settings->title);
  261 +
  262 + gtk_container_add(GTK_CONTAINER(dialog), widget);
  263 + gtk_window_set_transient_for(GTK_WINDOW(dialog),GTK_WINDOW(gtk_widget_get_toplevel(terminal)));
  264 +
  265 + gtk_window_set_modal(GTK_WINDOW(dialog),modal);
  266 +
  267 + v3270_settings_dialog_set_terminal_widget(dialog, terminal);
  268 +
  269 + g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL);
  270 + g_signal_connect(dialog,"response",G_CALLBACK(v3270_settting_dialog_response),NULL);
  271 +
  272 + gtk_widget_show_all(dialog);
  273 +
  274 +}
  275 +
  276 +
... ...
src/dialogs/settings/widget.c 0 → 100644
... ... @@ -0,0 +1,163 @@
  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 "../private.h"
  31 + #include <internals.h>
  32 + #include <v3270/settings.h>
  33 + #include <lib3270/log.h>
  34 +
  35 + G_DEFINE_TYPE(V3270Settings, V3270Settings, GTK_TYPE_GRID);
  36 +
  37 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  38 +
  39 +static void apply(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
  40 +{
  41 + debug("V3270Settings::%s",__FUNCTION__);
  42 +}
  43 +
  44 +static void cancel(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
  45 +{
  46 + debug("V3270Settings::%s",__FUNCTION__);
  47 +}
  48 +
  49 +static void load(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
  50 +{
  51 + debug("V3270Settings::%s",__FUNCTION__);
  52 +}
  53 +
  54 +static void update_message(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
  55 +{
  56 + debug("V3270Settings::%s",__FUNCTION__);
  57 +}
  58 +
  59 +static void finalize(GObject *object)
  60 +{
  61 + v3270_settings_set_terminal_widget(GTK_WIDGET(object),NULL);
  62 + G_OBJECT_CLASS(V3270Settings_parent_class)->finalize(object);
  63 +}
  64 +
  65 +static void V3270Settings_class_init(V3270SettingsClass *klass)
  66 +{
  67 + klass->apply = apply;
  68 + klass->revert = cancel;
  69 + klass->load = load;
  70 + klass->update_message = update_message;
  71 +
  72 + G_OBJECT_CLASS(klass)->finalize = finalize;
  73 +}
  74 +
  75 +static void V3270Settings_init(V3270Settings *widget)
  76 +{
  77 + widget->terminal = NULL;
  78 +
  79 + // https://developer.gnome.org/hig/stable/visual-layout.html.en
  80 + gtk_grid_set_row_spacing(GTK_GRID(widget),6);
  81 + gtk_grid_set_column_spacing(GTK_GRID(widget),12);
  82 +
  83 +}
  84 +
  85 +static void signal_update_message(GtkWidget *terminal, LIB3270_MESSAGE G_GNUC_UNUSED(id), GtkWidget *settings)
  86 +{
  87 + GTK_V3270_SETTINGS_GET_CLASS(settings)->update_message(settings,terminal);
  88 +}
  89 +
  90 +LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal)
  91 +{
  92 + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
  93 +
  94 + V3270Settings * settings = GTK_V3270_SETTINGS(widget);
  95 +
  96 + // Return if there's nothing to do.
  97 + if(settings->terminal == terminal)
  98 + return;
  99 +
  100 + if(settings->terminal)
  101 + {
  102 + // Disconnect old terminal widget
  103 + gulong handler = g_signal_handler_find(
  104 + settings->terminal,
  105 + G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA,
  106 + 0,
  107 + 0,
  108 + NULL,
  109 + G_CALLBACK(signal_update_message),
  110 + widget
  111 + );
  112 +
  113 + debug("handler=%u",(unsigned long) handler);
  114 +
  115 + if(handler)
  116 + g_signal_handler_disconnect(settings->terminal, handler);
  117 +
  118 + }
  119 +
  120 + // Update terminal
  121 + settings->terminal = terminal;
  122 +
  123 + if(settings->terminal)
  124 + {
  125 + // Connect the new widget.
  126 + g_signal_connect(G_OBJECT(terminal),I_("message_changed"), G_CALLBACK(signal_update_message), widget);
  127 +
  128 + // Update dialog state.
  129 + GTK_V3270_SETTINGS_GET_CLASS(widget)->update_message(widget,terminal);
  130 +
  131 + // Load the dialog contents.
  132 + GTK_V3270_SETTINGS_GET_CLASS(widget)->load(widget,terminal);
  133 + }
  134 +
  135 + }
  136 +
  137 + LIB3270_EXPORT GtkWidget * v3270_settings_get_terminal_widget(GtkWidget *widget)
  138 + {
  139 + g_return_val_if_fail(GTK_IS_V3270_SETTINGS(widget),NULL);
  140 + return GTK_V3270_SETTINGS(widget)->terminal;
  141 + }
  142 +
  143 + LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget)
  144 + {
  145 + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
  146 + GTK_V3270_SETTINGS_GET_CLASS(widget)->apply(widget,GTK_V3270_SETTINGS(widget)->terminal);
  147 +
  148 + /*
  149 +
  150 + BUG: The signal should be sent by the dialog!
  151 +
  152 + V3270Settings * settings = GTK_V3270_SETTINGS(widget);
  153 + if(settings && settings->terminal)
  154 + v3270_emit_save_settings(settings->terminal);
  155 + */
  156 + }
  157 +
  158 + LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget)
  159 + {
  160 + g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
  161 + GTK_V3270_SETTINGS_GET_CLASS(widget)->revert(widget,GTK_V3270_SETTINGS(widget)->terminal);
  162 + }
  163 +
... ...
src/include/internals.h
... ... @@ -65,21 +65,38 @@
65 65 V3270_SIGNAL_TOGGLE_CHANGED,
66 66 V3270_SIGNAL_MESSAGE_CHANGED,
67 67 V3270_SIGNAL_KEYPRESS,
68   - V3270_SIGNAL_CONNECTED,
69   - V3270_SIGNAL_DISCONNECTED,
70   - V3270_SIGNAL_UPDATE_CONFIG,
71 68 V3270_SIGNAL_MODEL_CHANGED,
72   - V3270_SIGNAL_SELECTING,
73 69 V3270_SIGNAL_POPUP,
74   - V3270_SIGNAL_PASTENEXT,
75   - V3270_SIGNAL_CLIPBOARD,
76 70 V3270_SIGNAL_CHANGED,
77 71 V3270_SIGNAL_MESSAGE,
78 72 V3270_SIGNAL_FIELD,
  73 + V3270_SIGNAL_SESSION_CHANGED,
  74 +
  75 + //
  76 + // Clipboard signals.
  77 + //
  78 + V3270_SIGNAL_SELECTING,
  79 + V3270_SIGNAL_CLIPBOARD,
  80 + V3270_SIGNAL_PASTENEXT,
  81 +
  82 + //
  83 + // Network signals.
  84 + //
  85 + V3270_SIGNAL_CONNECTED,
  86 + V3270_SIGNAL_DISCONNECTED,
  87 +
  88 + //
  89 + // Print session signals.
  90 + //
79 91 V3270_SIGNAL_PRINT_SETUP,
80 92 V3270_SIGNAL_PRINT_APPLY,
81 93 V3270_SIGNAL_PRINT_DONE,
82   - V3270_SIGNAL_SESSION_CHANGED,
  94 +
  95 + //
  96 + // Settings signals (Mostly fired by V3270Settings dialogs).
  97 + //
  98 + V3270_SIGNAL_SAVE_SETTINGS, ///< @brief Notify main application to save all widget settings.
  99 + V3270_SIGNAL_UPDATE_CONFIG, ///< @brief Update config signal (deprecated!)
83 100  
84 101 V3270_SIGNAL_LAST
85 102 };
... ... @@ -102,6 +119,9 @@
102 119  
103 120 G_GNUC_INTERNAL void v3270_dialog_close(GtkDialog *dialog, gpointer user_data);
104 121  
  122 + /// @brief Emit the "save-settings" signal.
  123 + G_GNUC_INTERNAL void v3270_emit_save_settings(GtkWidget *widget);
  124 +
105 125 G_GNUC_INTERNAL gchar * v3270_convert_to_3270_charset(GtkWidget *widget, const gchar *text, const gchar *encoding, GError **error);
106 126  
107 127  
... ...
src/include/v3270/settings.h
... ... @@ -35,7 +35,7 @@
35 35  
36 36 G_BEGIN_DECLS
37 37  
38   -/*--[ Progress widget ]------------------------------------------------------------------------------*/
  38 +/*--[ V3270 Settings Widget ]------------------------------------------------------------------------*/
39 39  
40 40 #define GTK_TYPE_V3270_SETTINGS (V3270Settings_get_type())
41 41 #define GTK_V3270_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_V3270_SETTINGS, V3270Settings))
... ... @@ -47,6 +47,9 @@
47 47 typedef struct _V3270Settings {
48 48 GtkGrid parent;
49 49 GtkWidget * terminal;
  50 + const gchar * label; ///< @brief Label for settings dialog.
  51 + const gchar * title; ///< @brief Title for settings dialog.
  52 + const gchar * tooltip; ///< @brief Tooltip for settings dialog.
50 53 } V3270Settings;
51 54  
52 55 typedef struct _V3270SettingsClass {
... ... @@ -54,25 +57,52 @@
54 57  
55 58 void (*load)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method to load the properties from terminal widget
56 59 void (*apply)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_APPLY
57   - void (*cancel)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_CANCEL
  60 + void (*revert)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_CANCEL
58 61 void (*update_message)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Lib3270 message has changed.
59 62  
60 63 } V3270SettingsClass;
61 64  
62   -/*--[ Prototypes ]-----------------------------------------------------------------------------------*/
  65 + LIB3270_EXPORT GType V3270Settings_get_type(void);
63 66  
64 67 LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal);
65 68 LIB3270_EXPORT GtkWidget * v3270_settings_get_terminal_widget(GtkWidget *widget);
66 69  
67   - LIB3270_EXPORT GType V3270Settings_get_type(void);
68 70 LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget);
69   - LIB3270_EXPORT void v3270_settings_cancel(GtkWidget *widget);
  71 + LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget);
  72 +
  73 + /// @brief Popup a settings dialog for the terminal.
  74 + LIB3270_EXPORT void v3270_settings_popup_dialog(GtkWidget *settings, GtkWidget *terminal, gboolean modal);
  75 +
  76 +/*--[ V3270 Settings Dialog ]------------------------------------------------------------------------*/
  77 +
  78 + #define GTK_TYPE_V3270_SETTINGS_DIALOG (V3270SettingsDialog_get_type())
  79 + #define GTK_V3270_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_V3270_SETTINGS_DIALOG, V3270SettingsDialog))
  80 + #define GTK_V3270_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_V3270_SETTINGS_DIALOG, V3270SettingsDialogClass))
  81 + #define GTK_IS_V3270_SETTINGS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_V3270_SETTINGS_DIALOG))
  82 + #define GTK_IS_V3270_SETTINGS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_V3270_SETTINGS_DIALOG))
  83 + #define GTK_V3270_SETTINGS_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_V3270_SETTINGS_DIALOG, V3270SettingsDialogClass))
  84 +
  85 + typedef struct _V3270SettingsDialog {
  86 + GtkDialog parent;
  87 + GtkNotebook * tabs;
  88 + GtkWidget * terminal;
  89 + } V3270SettingsDialog;
  90 +
  91 + typedef struct _V3270SettingsDialogClass {
  92 + GtkDialogClass parent_class;
  93 +
  94 + } V3270SettingsDialogClass;
  95 +
  96 + LIB3270_EXPORT GType V3270SettingsDialog_get_type(void);
  97 +
  98 + LIB3270_EXPORT GtkWidget * v3270_settings_dialog_new();
  99 + LIB3270_EXPORT void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal);
70 100  
71   - /// @brief Callback for GtkDialog's "response" signal.
72   - LIB3270_EXPORT void v3270_settings_on_dialog_response(GtkDialog *dialog, gint response_id, GtkWidget *settings);
  101 + /// @brief Process GtkDialog's "response" signal.
  102 + LIB3270_EXPORT void v3270_settting_dialog_response(GtkDialog *dialog, gint response_id, GtkWidget *terminal);
73 103  
74   - LIB3270_EXPORT GtkWidget * v3270_settings_dialog_new(GtkWidget *terminal, GtkWidget *settings);
75   - // LIB3270_EXPORT gint v3270_settings_dialog_run(GtkWidget *widget, GtkWidget *terminal);
  104 + LIB3270_EXPORT void v3270_settings_dialog_apply(GtkWidget *widget);
  105 + LIB3270_EXPORT void v3270_settings_dialog_revert(GtkWidget *widget);
76 106  
77 107 G_END_DECLS
78 108  
... ...
src/terminal/widget.c
... ... @@ -456,6 +456,15 @@ static void v3270_class_init(v3270Class *klass)
456 456 v3270_VOID__VOID_POINTER_UINT,
457 457 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT, 0);
458 458  
  459 + v3270_widget_signal[V3270_SIGNAL_SAVE_SETTINGS] =
  460 + g_signal_new( I_("save-settings"),
  461 + G_OBJECT_CLASS_TYPE (gobject_class),
  462 + G_SIGNAL_RUN_FIRST,
  463 + 0,
  464 + NULL, NULL,
  465 + v3270_VOID__VOID,
  466 + G_TYPE_NONE, 0);
  467 +
459 468 v3270_init_properties(gobject_class);
460 469  
461 470 }
... ... @@ -750,3 +759,15 @@ LIB3270_EXPORT GtkIMContext * v3270_get_im_context(GtkWidget *widget)
750 759 return GTK_V3270(widget)->input_method;
751 760 }
752 761  
  762 +static gboolean bg_emit_save_settings(GObject *widget)
  763 +{
  764 + g_signal_emit(widget,v3270_widget_signal[V3270_SIGNAL_SAVE_SETTINGS], 0, FALSE);
  765 + return FALSE;
  766 +}
  767 +
  768 +void v3270_emit_save_settings(GtkWidget *widget)
  769 +{
  770 + if(widget)
  771 + g_idle_add((GSourceFunc) bg_emit_save_settings, G_OBJECT(widget));
  772 +}
  773 +
... ...
src/testprogram/toolbar.c
... ... @@ -54,13 +54,21 @@
54 54  
55 55 static void font_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal)
56 56 {
  57 + v3270_settings_popup_dialog(
  58 + v3270_font_chooser_widget_new(),
  59 + terminal,
  60 + FALSE
  61 + );
  62 +
  63 + /*
57 64 GtkWidget * dialog = v3270_settings_dialog_new(terminal, v3270_font_chooser_widget_new());
58 65  
59   - v3270_dialog_setup(dialog,_("Font setup"),_("_Save"));
  66 +// v3270_dialog_setup(dialog,_("Font setup"),_("_Save"));
60 67  
61 68 gtk_widget_show_all(dialog);
62 69 gtk_dialog_run(GTK_DIALOG(dialog));
63 70 gtk_widget_destroy(dialog);
  71 + */
64 72  
65 73 }
66 74  
... ...
v3270.cbp
... ... @@ -102,6 +102,12 @@
102 102 <Unit filename="src/dialogs/settings.c">
103 103 <Option compilerVar="CC" />
104 104 </Unit>
  105 + <Unit filename="src/dialogs/settings/dialog.c">
  106 + <Option compilerVar="CC" />
  107 + </Unit>
  108 + <Unit filename="src/dialogs/settings/widget.c">
  109 + <Option compilerVar="CC" />
  110 + </Unit>
105 111 <Unit filename="src/dialogs/togglebutton.c">
106 112 <Option compilerVar="CC" />
107 113 </Unit>
... ...