Commit d7731cec4fb275291549275d0c674b284c660aa0

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

Implementing validity signal and oversize input.

src/dialogs/hostselect.c
@@ -118,8 +118,8 @@ @@ -118,8 +118,8 @@
118 118
119 }, 119 },
120 { 120 {
121 - .top = 0,  
122 - .left = 6, 121 + .top = 1,
  122 + .left = 0,
123 .width = 2, 123 .width = 2,
124 .height = 1, 124 .height = 1,
125 125
@@ -179,6 +179,18 @@ @@ -179,6 +179,18 @@
179 .tooltip = N_("Port or service name (empty for \"telnet\")."), 179 .tooltip = N_("Port or service name (empty for \"telnet\")."),
180 .max_length = 6, 180 .max_length = 6,
181 .width_chars = 7, 181 .width_chars = 7,
  182 + },
  183 +
  184 + {
  185 + .top = 1,
  186 + .left = 3,
  187 + .width = 2,
  188 + .height = 1,
  189 +
  190 + .label = N_( "Oversize" ),
  191 + .tooltip = N_("Makes the screen larger than the default for the chosen model number."),
  192 + .max_length = 7,
  193 + .width_chars = 8,
182 } 194 }
183 }; 195 };
184 196
@@ -224,6 +236,30 @@ static void V3270HostSelectWidget_class_init(G_GNUC_UNUSED V3270HostSelectWidget @@ -224,6 +236,30 @@ static void V3270HostSelectWidget_class_init(G_GNUC_UNUSED V3270HostSelectWidget
224 236
225 } 237 }
226 238
  239 +static void oversize_changed(GtkEditable *editable, GtkWidget *settings)
  240 +{
  241 + const gchar * chars = gtk_editable_get_chars(editable,0,-1);
  242 + gboolean valid = TRUE;
  243 + char junk;
  244 + unsigned int ovc = 0, ovr = 0;
  245 +
  246 + if(*chars)
  247 + {
  248 + if(sscanf(chars, "%ux%u%c", &ovc, &ovr, &junk) != 2)
  249 + {
  250 + valid = FALSE;
  251 + debug("Can't parse \"%s\"",chars);
  252 + }
  253 + else if( (ovc * ovr) > 0x4000)
  254 + {
  255 + valid = FALSE;
  256 + debug("Invalid values on \"%s\"",chars);
  257 + }
  258 + }
  259 +
  260 + v3270_settings_set_valid(settings,valid);
  261 +}
  262 +
227 static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget) 263 static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget)
228 { 264 {
229 // Cell renderer 265 // Cell renderer
@@ -258,21 +294,35 @@ static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget) @@ -258,21 +294,35 @@ static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget)
258 for(entry = 0; entry < G_N_ELEMENTS(entryfields); entry++) 294 for(entry = 0; entry < G_N_ELEMENTS(entryfields); entry++)
259 { 295 {
260 widget->input.entry[entry] = GTK_ENTRY(gtk_entry_new()); 296 widget->input.entry[entry] = GTK_ENTRY(gtk_entry_new());
261 -  
262 gtk_entry_set_max_length(widget->input.entry[entry],entryfields[entry].max_length); 297 gtk_entry_set_max_length(widget->input.entry[entry],entryfields[entry].max_length);
263 gtk_entry_set_width_chars(widget->input.entry[entry],entryfields[entry].width_chars); 298 gtk_entry_set_width_chars(widget->input.entry[entry],entryfields[entry].width_chars);
264 -  
265 - v3270_grid_attach(  
266 - GTK_GRID(connection),  
267 - (struct v3270_entry_field *) & entryfields[entry],  
268 - GTK_WIDGET(widget->input.entry[entry])  
269 - );  
270 -  
271 } 299 }
272 300
  301 + // Custom settings
273 gtk_entry_set_placeholder_text(widget->input.entry[ENTRY_SRVCNAME],"telnet"); 302 gtk_entry_set_placeholder_text(widget->input.entry[ENTRY_SRVCNAME],"telnet");
274 gtk_widget_set_hexpand(GTK_WIDGET(widget->input.entry[ENTRY_HOSTNAME]),TRUE); 303 gtk_widget_set_hexpand(GTK_WIDGET(widget->input.entry[ENTRY_HOSTNAME]),TRUE);
275 304
  305 + // Add to containers
  306 + v3270_grid_attach(
  307 + GTK_GRID(connection),
  308 + (struct v3270_entry_field *) & entryfields[0],
  309 + GTK_WIDGET(widget->input.entry[0])
  310 + );
  311 +
  312 + v3270_grid_attach(
  313 + GTK_GRID(connection),
  314 + (struct v3270_entry_field *) & entryfields[1],
  315 + GTK_WIDGET(widget->input.entry[1])
  316 + );
  317 +
  318 + v3270_grid_attach(
  319 + GTK_GRID(emulation),
  320 + (struct v3270_entry_field *) & entryfields[2],
  321 + GTK_WIDGET(widget->input.entry[2])
  322 + );
  323 +
  324 + g_signal_connect(G_OBJECT(widget->input.entry[2]),"changed",G_CALLBACK(oversize_changed),widget);
  325 +
276 } 326 }
277 327
278 // SSL checkbox 328 // SSL checkbox
@@ -338,8 +388,8 @@ static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget) @@ -338,8 +388,8 @@ static void V3270HostSelectWidget_init(V3270HostSelectWidget *widget)
338 388
339 static const struct v3270_entry_field descriptor = 389 static const struct v3270_entry_field descriptor =
340 { 390 {
341 - .top = 1,  
342 - .left = 0, 391 + .top = 0,
  392 + .left = 6,
343 .width = 2, 393 .width = 2,
344 .height = 1, 394 .height = 1,
345 395
src/dialogs/settings/dialog.c
@@ -47,6 +47,39 @@ static gboolean on_tab_focus(V3270Settings *settings, GdkEvent G_GNUC_UNUSED(*ev @@ -47,6 +47,39 @@ static gboolean on_tab_focus(V3270Settings *settings, GdkEvent G_GNUC_UNUSED(*ev
47 return FALSE; 47 return FALSE;
48 } 48 }
49 49
  50 +static void check_valid(GtkWidget *widget, gboolean *valid)
  51 +{
  52 + if(*valid && GTK_IS_V3270_SETTINGS(widget))
  53 + {
  54 + if(!v3270_settings_get_valid(widget))
  55 + *valid = FALSE;
  56 + }
  57 +
  58 +}
  59 +
  60 +static void on_validity(V3270Settings G_GNUC_UNUSED(*settings), gboolean valid, V3270SettingsDialog * dialog)
  61 +{
  62 + if(valid)
  63 + {
  64 + // Check validity of all childs.
  65 + gtk_container_foreach(
  66 + GTK_CONTAINER(dialog->tabs),
  67 + (GtkCallback) check_valid,
  68 + &valid
  69 + );
  70 +
  71 + }
  72 +
  73 + debug("The current state is %s",valid ? "valid" : "invalid");
  74 +
  75 + GtkWidget * button = gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
  76 +
  77 + if(button)
  78 + gtk_widget_set_sensitive(button,valid);
  79 +
  80 +
  81 +}
  82 +
50 static void add(GtkContainer *container, GtkWidget *widget) 83 static void add(GtkContainer *container, GtkWidget *widget)
51 { 84 {
52 g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); 85 g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
@@ -73,6 +106,7 @@ static void add(GtkContainer *container, GtkWidget *widget) @@ -73,6 +106,7 @@ static void add(GtkContainer *container, GtkWidget *widget)
73 ); 106 );
74 107
75 g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(on_tab_focus), container); 108 g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(on_tab_focus), container);
  109 + g_signal_connect(G_OBJECT(widget), "validity", G_CALLBACK(on_validity), container);
76 110
77 111
78 } 112 }
@@ -123,33 +157,9 @@ void v3270_settings_dialog_revert(GtkWidget *dialog) @@ -123,33 +157,9 @@ void v3270_settings_dialog_revert(GtkWidget *dialog)
123 157
124 } 158 }
125 159
126 -/*  
127 -static void response(GtkDialog *dialog, gint response_id)  
128 -{  
129 - if(!terminal)  
130 - return;  
131 -  
132 -  
133 -}  
134 -*/  
135 -  
136 -static void dispose(GObject *object)  
137 -{  
138 - debug("%s",__FUNCTION__);  
139 -  
140 -// V3270SettingsDialog * widget = GTK_V3270_SETTINGS_DIALOG(object);  
141 -  
142 -  
143 - G_OBJECT_CLASS(V3270SettingsDialog_parent_class)->dispose(object);  
144 -}  
145 -  
146 static void V3270SettingsDialog_class_init(V3270SettingsDialogClass *klass) 160 static void V3270SettingsDialog_class_init(V3270SettingsDialogClass *klass)
147 { 161 {
148 GTK_CONTAINER_CLASS(klass)->add = add; 162 GTK_CONTAINER_CLASS(klass)->add = add;
149 -  
150 - // Object class  
151 - G_OBJECT_CLASS(klass)->dispose = dispose;  
152 -  
153 } 163 }
154 164
155 static void on_page_changed(GtkNotebook *notebook, GtkWidget G_GNUC_UNUSED(*child), guint G_GNUC_UNUSED(page_num), V3270SettingsDialog G_GNUC_UNUSED(*dialog)) { 165 static void on_page_changed(GtkNotebook *notebook, GtkWidget G_GNUC_UNUSED(*child), guint G_GNUC_UNUSED(page_num), V3270SettingsDialog G_GNUC_UNUSED(*dialog)) {
@@ -220,6 +230,8 @@ void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *ter @@ -220,6 +230,8 @@ void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *ter
220 { 230 {
221 g_return_if_fail(GTK_IS_V3270_SETTINGS_DIALOG(widget)); 231 g_return_if_fail(GTK_IS_V3270_SETTINGS_DIALOG(widget));
222 232
  233 + debug("%s(%p,%p)",__FUNCTION__,widget,terminal);
  234 +
223 GTK_V3270_SETTINGS_DIALOG(widget)->terminal = terminal; 235 GTK_V3270_SETTINGS_DIALOG(widget)->terminal = terminal;
224 236
225 gtk_container_foreach( 237 gtk_container_foreach(
src/dialogs/settings/widget.c
@@ -28,12 +28,24 @@ @@ -28,12 +28,24 @@
28 */ 28 */
29 29
30 #include "../private.h" 30 #include "../private.h"
  31 + #include "../terminal/marshal.h"
31 #include <internals.h> 32 #include <internals.h>
32 #include <v3270/settings.h> 33 #include <v3270/settings.h>
33 #include <lib3270/log.h> 34 #include <lib3270/log.h>
34 35
  36 + static void signal_update_message(GtkWidget *terminal, LIB3270_MESSAGE G_GNUC_UNUSED(id), GtkWidget *settings);
  37 +
35 G_DEFINE_TYPE(V3270Settings, V3270Settings, GTK_TYPE_GRID); 38 G_DEFINE_TYPE(V3270Settings, V3270Settings, GTK_TYPE_GRID);
36 39
  40 + enum
  41 + {
  42 + VALIDITY_SIGNAL, ///< @brief Signal for valid state.
  43 + SIGNAL_LAST
  44 + };
  45 +
  46 + static guint signals[SIGNAL_LAST] = { 0 };
  47 +
  48 +
37 /*--[ Implement ]------------------------------------------------------------------------------------*/ 49 /*--[ Implement ]------------------------------------------------------------------------------------*/
38 50
39 static void apply(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal)) 51 static void apply(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UNUSED(*terminal))
@@ -58,23 +70,65 @@ static void update_message(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UN @@ -58,23 +70,65 @@ static void update_message(GtkWidget G_GNUC_UNUSED(*widget), GtkWidget G_GNUC_UN
58 70
59 static void finalize(GObject *object) 71 static void finalize(GObject *object)
60 { 72 {
61 - v3270_settings_set_terminal_widget(GTK_WIDGET(object),NULL); 73 + V3270Settings * settings = GTK_V3270_SETTINGS(object);
  74 +
  75 + if(settings->terminal)
  76 + {
  77 + // Disconnect terminal widget
  78 + //
  79 + // (Can't use v3270_settings_set_terminal_widget here)
  80 + //
  81 + gulong handler = g_signal_handler_find(
  82 + settings->terminal,
  83 + G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA,
  84 + 0,
  85 + 0,
  86 + NULL,
  87 + G_CALLBACK(signal_update_message),
  88 + object
  89 + );
  90 +
  91 + if(handler)
  92 + g_signal_handler_disconnect(settings->terminal, handler);
  93 +
  94 + settings->terminal = NULL;
  95 + }
  96 +
62 G_OBJECT_CLASS(V3270Settings_parent_class)->finalize(object); 97 G_OBJECT_CLASS(V3270Settings_parent_class)->finalize(object);
63 } 98 }
64 99
  100 +static void validity(GtkWidget *widget, gboolean state)
  101 +{
  102 +
  103 +}
  104 +
65 static void V3270Settings_class_init(V3270SettingsClass *klass) 105 static void V3270Settings_class_init(V3270SettingsClass *klass)
66 { 106 {
  107 + GObjectClass * gobject_class = G_OBJECT_CLASS(klass);
  108 +
67 klass->apply = apply; 109 klass->apply = apply;
68 klass->revert = cancel; 110 klass->revert = cancel;
69 klass->load = load; 111 klass->load = load;
  112 + klass->validity = validity;
70 klass->update_message = update_message; 113 klass->update_message = update_message;
71 114
72 - G_OBJECT_CLASS(klass)->finalize = finalize; 115 + gobject_class->finalize = finalize;
  116 +
  117 + signals[VALIDITY_SIGNAL] =
  118 + g_signal_new( I_("validity"),
  119 + G_OBJECT_CLASS_TYPE (gobject_class),
  120 + G_SIGNAL_RUN_FIRST,
  121 + G_STRUCT_OFFSET (V3270SettingsClass, validity),
  122 + NULL, NULL,
  123 + v3270_VOID__VOID_BOOLEAN,
  124 + G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
  125 +
73 } 126 }
74 127
75 static void V3270Settings_init(V3270Settings *widget) 128 static void V3270Settings_init(V3270Settings *widget)
76 { 129 {
77 - widget->terminal = NULL; 130 + widget->terminal = NULL;
  131 + widget->valid = FALSE;
78 132
79 // https://developer.gnome.org/hig/stable/visual-layout.html.en 133 // https://developer.gnome.org/hig/stable/visual-layout.html.en
80 gtk_grid_set_row_spacing(GTK_GRID(widget),6); 134 gtk_grid_set_row_spacing(GTK_GRID(widget),6);
@@ -93,6 +147,8 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid @@ -93,6 +147,8 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid
93 147
94 V3270Settings * settings = GTK_V3270_SETTINGS(widget); 148 V3270Settings * settings = GTK_V3270_SETTINGS(widget);
95 149
  150 + debug("%s(%p,%p)",__FUNCTION__,widget,terminal);
  151 +
96 // Return if there's nothing to do. 152 // Return if there's nothing to do.
97 if(settings->terminal == terminal) 153 if(settings->terminal == terminal)
98 return; 154 return;
@@ -125,12 +181,19 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid @@ -125,12 +181,19 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid
125 // Connect the new widget. 181 // Connect the new widget.
126 g_signal_connect(G_OBJECT(terminal),I_("message_changed"), G_CALLBACK(signal_update_message), widget); 182 g_signal_connect(G_OBJECT(terminal),I_("message_changed"), G_CALLBACK(signal_update_message), widget);
127 183
  184 + // Set as valid before update message and load contents.
  185 + v3270_settings_set_valid(widget,TRUE);
  186 +
128 // Update dialog state. 187 // Update dialog state.
129 GTK_V3270_SETTINGS_GET_CLASS(widget)->update_message(widget,terminal); 188 GTK_V3270_SETTINGS_GET_CLASS(widget)->update_message(widget,terminal);
130 189
131 // Load the dialog contents. 190 // Load the dialog contents.
132 GTK_V3270_SETTINGS_GET_CLASS(widget)->load(widget,terminal); 191 GTK_V3270_SETTINGS_GET_CLASS(widget)->load(widget,terminal);
133 } 192 }
  193 + else
  194 + {
  195 + v3270_settings_set_valid(widget,FALSE);
  196 + }
134 197
135 } 198 }
136 199
@@ -144,15 +207,6 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid @@ -144,15 +207,6 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid
144 { 207 {
145 g_return_if_fail(GTK_IS_V3270_SETTINGS(widget)); 208 g_return_if_fail(GTK_IS_V3270_SETTINGS(widget));
146 GTK_V3270_SETTINGS_GET_CLASS(widget)->apply(widget,GTK_V3270_SETTINGS(widget)->terminal); 209 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 } 210 }
157 211
158 LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget) 212 LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget)
@@ -178,3 +232,22 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid @@ -178,3 +232,22 @@ LIB3270_EXPORT void v3270_settings_set_terminal_widget(GtkWidget *widget, GtkWid
178 g_return_val_if_fail(GTK_IS_V3270_SETTINGS(widget),NULL); 232 g_return_val_if_fail(GTK_IS_V3270_SETTINGS(widget),NULL);
179 return GTK_V3270_SETTINGS(widget)->tooltip; 233 return GTK_V3270_SETTINGS(widget)->tooltip;
180 } 234 }
  235 +
  236 + LIB3270_EXPORT gboolean v3270_settings_get_valid(GtkWidget *widget)
  237 + {
  238 + // Non settings widget is always valid.
  239 + g_return_val_if_fail(GTK_IS_V3270_SETTINGS(widget),TRUE);
  240 + return GTK_V3270_SETTINGS(widget)->valid;
  241 + }
  242 +
  243 + LIB3270_EXPORT void v3270_settings_set_valid(GtkWidget *widget, gboolean is_valid)
  244 + {
  245 + V3270Settings * settings = GTK_V3270_SETTINGS(widget);
  246 +
  247 + if(is_valid != settings->valid)
  248 + {
  249 + settings->valid = is_valid;
  250 + g_signal_emit(widget, signals[VALIDITY_SIGNAL], 0, settings->valid);
  251 + }
  252 +
  253 + }
src/include/v3270/settings.h
@@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@
50 const gchar * label; ///< @brief Label for settings dialog. 50 const gchar * label; ///< @brief Label for settings dialog.
51 const gchar * title; ///< @brief Title for settings dialog. 51 const gchar * title; ///< @brief Title for settings dialog.
52 const gchar * tooltip; ///< @brief Tooltip for settings dialog. 52 const gchar * tooltip; ///< @brief Tooltip for settings dialog.
  53 + gboolean valid; ///< @brief True if the settings can be applyed.
53 } V3270Settings; 54 } V3270Settings;
54 55
55 typedef struct _V3270SettingsClass { 56 typedef struct _V3270SettingsClass {
@@ -59,7 +60,7 @@ @@ -59,7 +60,7 @@
59 void (*apply)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_APPLY 60 void (*apply)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_APPLY
60 void (*revert)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_CANCEL 61 void (*revert)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Method for GTK_RESPONSE_CANCEL
61 void (*update_message)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Lib3270 message has changed. 62 void (*update_message)(GtkWidget *widget, GtkWidget *terminal); ///< @brief Lib3270 message has changed.
62 - 63 + void (*validity)(GtkWidget *, gboolean);
63 } V3270SettingsClass; 64 } V3270SettingsClass;
64 65
65 LIB3270_EXPORT GType V3270Settings_get_type(void); 66 LIB3270_EXPORT GType V3270Settings_get_type(void);
@@ -70,6 +71,9 @@ @@ -70,6 +71,9 @@
70 LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget); 71 LIB3270_EXPORT void v3270_settings_apply(GtkWidget *widget);
71 LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget); 72 LIB3270_EXPORT void v3270_settings_revert(GtkWidget *widget);
72 73
  74 + LIB3270_EXPORT void v3270_settings_set_valid(GtkWidget *widget, gboolean is_valid);
  75 + LIB3270_EXPORT gboolean v3270_settings_get_valid(GtkWidget *widget);
  76 +
73 LIB3270_EXPORT const gchar * v3270_settings_get_title(GtkWidget *widget); 77 LIB3270_EXPORT const gchar * v3270_settings_get_title(GtkWidget *widget);
74 LIB3270_EXPORT const gchar * v3270_settings_get_label(GtkWidget *widget); 78 LIB3270_EXPORT const gchar * v3270_settings_get_label(GtkWidget *widget);
75 LIB3270_EXPORT const gchar * v3270_settings_get_tooltip(GtkWidget *widget); 79 LIB3270_EXPORT const gchar * v3270_settings_get_tooltip(GtkWidget *widget);
@@ -97,7 +101,6 @@ @@ -97,7 +101,6 @@
97 101
98 typedef struct _V3270SettingsDialogClass { 102 typedef struct _V3270SettingsDialogClass {
99 GtkDialogClass parent_class; 103 GtkDialogClass parent_class;
100 -  
101 } V3270SettingsDialogClass; 104 } V3270SettingsDialogClass;
102 105
103 LIB3270_EXPORT GType V3270SettingsDialog_get_type(void); 106 LIB3270_EXPORT GType V3270SettingsDialog_get_type(void);