Commit be833d0a7cb29e9639739b843b443e5d95620d95
1 parent
437a1c76
Exists in
master
and in
1 other branch
Working on the new File transfer components.
Showing
3 changed files
with
165 additions
and
12 deletions
Show diff stats
src/v3270ft/dialog.c
| @@ -40,6 +40,7 @@ | @@ -40,6 +40,7 @@ | ||
| 40 | GtkWidget * settings; | 40 | GtkWidget * settings; |
| 41 | 41 | ||
| 42 | struct { | 42 | struct { |
| 43 | + GtkWidget * valid; | ||
| 43 | GtkWidget * insert; | 44 | GtkWidget * insert; |
| 44 | GtkWidget * update; | 45 | GtkWidget * update; |
| 45 | GtkWidget * reset; | 46 | GtkWidget * reset; |
| @@ -102,9 +103,16 @@ void activity_selected(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn G | @@ -102,9 +103,16 @@ void activity_selected(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn G | ||
| 102 | 103 | ||
| 103 | } | 104 | } |
| 104 | 105 | ||
| 106 | +static void validity_changed(GtkWidget G_GNUC_UNUSED(*settings), gboolean valid, V3270FTDialog *widget) | ||
| 107 | +{ | ||
| 108 | + debug("The file transfer settings are now %s",valid ? "valid" : "invalid"); | ||
| 109 | + gtk_widget_set_sensitive(widget->button.valid,valid); | ||
| 110 | +} | ||
| 111 | + | ||
| 105 | static void V3270FTDialog_init(V3270FTDialog *widget) | 112 | static void V3270FTDialog_init(V3270FTDialog *widget) |
| 106 | { | 113 | { |
| 107 | widget->settings = v3270_ft_settings_new(); | 114 | widget->settings = v3270_ft_settings_new(); |
| 115 | + g_signal_connect(G_OBJECT(widget->settings),"validity",G_CALLBACK(validity_changed),widget); | ||
| 108 | 116 | ||
| 109 | gtk_window_set_title(GTK_WINDOW(widget),_( "3270 File transfer")); | 117 | gtk_window_set_title(GTK_WINDOW(widget),_( "3270 File transfer")); |
| 110 | 118 | ||
| @@ -123,18 +131,19 @@ static void V3270FTDialog_init(V3270FTDialog *widget) | @@ -123,18 +131,19 @@ static void V3270FTDialog_init(V3270FTDialog *widget) | ||
| 123 | 131 | ||
| 124 | // Create action buttons | 132 | // Create action buttons |
| 125 | { | 133 | { |
| 126 | - GtkWidget * buttons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,6); | 134 | + widget->button.valid = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,6); |
| 127 | 135 | ||
| 128 | - g_object_set(G_OBJECT(buttons),"margin-top",6,NULL); | 136 | + g_object_set(G_OBJECT(widget->button.valid),"margin-top",6,NULL); |
| 129 | 137 | ||
| 130 | - widget->button.reset = v3270_box_pack_end(buttons,gtk_button_new_with_mnemonic("_Reset"),FALSE,FALSE,0); | ||
| 131 | - widget->button.update = v3270_box_pack_end(buttons,gtk_button_new_with_mnemonic("_Update"),FALSE,FALSE,0); | ||
| 132 | - widget->button.insert = v3270_box_pack_end(buttons,gtk_button_new_with_mnemonic("_Insert"),FALSE,FALSE,0); | 138 | + widget->button.reset = v3270_box_pack_end(widget->button.valid,gtk_button_new_with_mnemonic("_Reset"),FALSE,FALSE,0); |
| 139 | + widget->button.update = v3270_box_pack_end(widget->button.valid,gtk_button_new_with_mnemonic("_Update"),FALSE,FALSE,0); | ||
| 140 | + widget->button.insert = v3270_box_pack_end(widget->button.valid,gtk_button_new_with_mnemonic("_Insert"),FALSE,FALSE,0); | ||
| 133 | 141 | ||
| 134 | gtk_widget_set_sensitive(widget->button.update,FALSE); | 142 | gtk_widget_set_sensitive(widget->button.update,FALSE); |
| 135 | gtk_widget_set_sensitive(widget->button.reset,FALSE); | 143 | gtk_widget_set_sensitive(widget->button.reset,FALSE); |
| 136 | 144 | ||
| 137 | - gtk_box_pack_start(GTK_BOX(container),buttons,FALSE,FALSE,0); | 145 | + gtk_box_pack_start(GTK_BOX(container),widget->button.valid,FALSE,FALSE,0); |
| 146 | + gtk_widget_set_sensitive(widget->button.valid,FALSE); | ||
| 138 | 147 | ||
| 139 | } | 148 | } |
| 140 | 149 |
src/v3270ft/marshal
src/v3270ft/settings.c
| @@ -30,6 +30,7 @@ | @@ -30,6 +30,7 @@ | ||
| 30 | #include <string.h> | 30 | #include <string.h> |
| 31 | #include <internals.h> | 31 | #include <internals.h> |
| 32 | #include "private.h" | 32 | #include "private.h" |
| 33 | + #include "marshal.h" | ||
| 33 | #include <v3270/filetransfer.h> | 34 | #include <v3270/filetransfer.h> |
| 34 | 35 | ||
| 35 | /*--[ Widget definition ]----------------------------------------------------------------------------*/ | 36 | /*--[ Widget definition ]----------------------------------------------------------------------------*/ |
| @@ -38,31 +39,82 @@ | @@ -38,31 +39,82 @@ | ||
| 38 | { | 39 | { |
| 39 | GtkGridClass parent_class; | 40 | GtkGridClass parent_class; |
| 40 | 41 | ||
| 42 | + struct | ||
| 43 | + { | ||
| 44 | + void (*validity)(GtkWidget *, gboolean); | ||
| 45 | + } signal; | ||
| 46 | + | ||
| 41 | }; | 47 | }; |
| 42 | 48 | ||
| 49 | + typedef enum _invalid | ||
| 50 | + { | ||
| 51 | + VALIDITY_TRANSFER_TYPE = 0x0001, | ||
| 52 | + VALIDITY_LOCAL_FILENAME = 0x0002, | ||
| 53 | + VALIDITY_REMOTE_FILENAME = 0x0004, | ||
| 54 | + } VALIDITY_TYPE; | ||
| 55 | + | ||
| 43 | struct _V3270FTSettings | 56 | struct _V3270FTSettings |
| 44 | { | 57 | { |
| 45 | GtkGrid parent; | 58 | GtkGrid parent; |
| 46 | 59 | ||
| 47 | - struct { | 60 | + struct |
| 61 | + { | ||
| 48 | GtkEntry * local; | 62 | GtkEntry * local; |
| 49 | GtkEntry * remote; | 63 | GtkEntry * remote; |
| 50 | } file; | 64 | } file; |
| 51 | 65 | ||
| 52 | - GtkComboBox * type; | ||
| 53 | - GtkWidget * recordFormatBox; | ||
| 54 | - GtkWidget * spaceAllocationBox; | ||
| 55 | 66 | ||
| 56 | - GtkWidget * options[NUM_OPTIONS_WIDGETS]; | ||
| 57 | - GtkWidget * spins[LIB3270_FT_VALUE_COUNT]; | 67 | + struct |
| 68 | + { | ||
| 69 | + LIB3270_FT_OPTION options; | ||
| 70 | + gboolean is_valid; | ||
| 71 | + VALIDITY_TYPE invalid; | ||
| 72 | + } transfer; | ||
| 73 | + | ||
| 74 | + GtkComboBox * type; | ||
| 75 | + GtkWidget * recordFormatBox; | ||
| 76 | + GtkWidget * spaceAllocationBox; | ||
| 77 | + | ||
| 78 | + GtkWidget * options[NUM_OPTIONS_WIDGETS]; | ||
| 79 | + GtkWidget * spins[LIB3270_FT_VALUE_COUNT]; | ||
| 80 | + | ||
| 58 | }; | 81 | }; |
| 59 | 82 | ||
| 60 | G_DEFINE_TYPE(V3270FTSettings, V3270FTSettings, GTK_TYPE_GRID); | 83 | G_DEFINE_TYPE(V3270FTSettings, V3270FTSettings, GTK_TYPE_GRID); |
| 61 | 84 | ||
| 85 | +/*--[ Globals ]--------------------------------------------------------------------------------------*/ | ||
| 86 | + | ||
| 87 | + enum _SIGNALS | ||
| 88 | + { | ||
| 89 | + V3270_FT_SETTINGS_VALIDITY_SIGNAL, ///< @brief Indicates if the dialog contents is valid. | ||
| 90 | + | ||
| 91 | + V3270_FT_SETTINGS_LAST_SIGNAL | ||
| 92 | + }; | ||
| 93 | + | ||
| 94 | + static guint v3270_ft_settings_signals[V3270_FT_SETTINGS_LAST_SIGNAL] = { 0 }; | ||
| 95 | + | ||
| 62 | /*--[ Implement ]------------------------------------------------------------------------------------*/ | 96 | /*--[ Implement ]------------------------------------------------------------------------------------*/ |
| 63 | 97 | ||
| 98 | + static void V3270FTSettings_validity(GtkWidget G_GNUC_UNUSED(*widget), gboolean G_GNUC_UNUSED(is_valid)) | ||
| 99 | + { | ||
| 100 | + debug("%s",__FUNCTION__); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + | ||
| 64 | static void V3270FTSettings_class_init(G_GNUC_UNUSED V3270FTSettingsClass *klass) | 104 | static void V3270FTSettings_class_init(G_GNUC_UNUSED V3270FTSettingsClass *klass) |
| 65 | { | 105 | { |
| 106 | + GObjectClass * gobject_class = G_OBJECT_CLASS(klass); | ||
| 107 | + | ||
| 108 | + klass->signal.validity = V3270FTSettings_validity; | ||
| 109 | + | ||
| 110 | + v3270_ft_settings_signals[V3270_FT_SETTINGS_VALIDITY_SIGNAL] = | ||
| 111 | + g_signal_new( "validity", | ||
| 112 | + G_OBJECT_CLASS_TYPE (gobject_class), | ||
| 113 | + G_SIGNAL_RUN_FIRST, | ||
| 114 | + G_STRUCT_OFFSET (V3270FTSettingsClass, signal.validity), | ||
| 115 | + NULL, NULL, | ||
| 116 | + v3270ft_VOID__VOID_BOOLEAN, | ||
| 117 | + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); | ||
| 66 | 118 | ||
| 67 | 119 | ||
| 68 | } | 120 | } |
| @@ -152,6 +204,8 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | @@ -152,6 +204,8 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | ||
| 152 | { | 204 | { |
| 153 | size_t ix; | 205 | size_t ix; |
| 154 | 206 | ||
| 207 | + widget->transfer.options = options; | ||
| 208 | + | ||
| 155 | if(options & LIB3270_FT_OPTION_RECEIVE) | 209 | if(options & LIB3270_FT_OPTION_RECEIVE) |
| 156 | { | 210 | { |
| 157 | debug("%s option selected","LIB3270_FT_OPTION_RECEIVE"); | 211 | debug("%s option selected","LIB3270_FT_OPTION_RECEIVE"); |
| @@ -191,6 +245,34 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | @@ -191,6 +245,34 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | ||
| 191 | 245 | ||
| 192 | } | 246 | } |
| 193 | 247 | ||
| 248 | + static void check_for_validity_signal(V3270FTSettings *widget) | ||
| 249 | + { | ||
| 250 | + gboolean is_valid = (widget->transfer.invalid == 0) ? TRUE : FALSE; | ||
| 251 | + | ||
| 252 | + if(is_valid == widget->transfer.is_valid) | ||
| 253 | + return; | ||
| 254 | + | ||
| 255 | + widget->transfer.is_valid = is_valid; | ||
| 256 | + | ||
| 257 | + debug("Transfer is now \"%s\"", is_valid ? "valid" : "invalid"); | ||
| 258 | + g_signal_emit(widget, v3270_ft_settings_signals[V3270_FT_SETTINGS_VALIDITY_SIGNAL], 0, widget->transfer.is_valid); | ||
| 259 | + | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + static void set_invalid(V3270FTSettings *widget, VALIDITY_TYPE option) | ||
| 263 | + { | ||
| 264 | + widget->transfer.invalid |= option; | ||
| 265 | + debug("Invalid: %08lx", (unsigned int) widget->transfer.invalid); | ||
| 266 | + check_for_validity_signal(widget); | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + static void set_valid(V3270FTSettings *widget, VALIDITY_TYPE option) | ||
| 270 | + { | ||
| 271 | + widget->transfer.invalid &= ~option; | ||
| 272 | + debug("Invalid: %08lx", (unsigned int) widget->transfer.invalid); | ||
| 273 | + check_for_validity_signal(widget); | ||
| 274 | + } | ||
| 275 | + | ||
| 194 | static void transfer_type_changed(GtkComboBox *widget, V3270FTSettings *dialog) | 276 | static void transfer_type_changed(GtkComboBox *widget, V3270FTSettings *dialog) |
| 195 | { | 277 | { |
| 196 | gint selected = gtk_combo_box_get_active(widget); | 278 | gint selected = gtk_combo_box_get_active(widget); |
| @@ -199,20 +281,78 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | @@ -199,20 +281,78 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | ||
| 199 | 281 | ||
| 200 | if(selected >= 0) | 282 | if(selected >= 0) |
| 201 | { | 283 | { |
| 284 | + set_valid(dialog, VALIDITY_TRANSFER_TYPE); | ||
| 202 | set_options(dialog,ft_type[selected].opt); | 285 | set_options(dialog,ft_type[selected].opt); |
| 203 | } | 286 | } |
| 204 | else | 287 | else |
| 205 | { | 288 | { |
| 289 | + set_invalid(dialog, VALIDITY_TRANSFER_TYPE); | ||
| 206 | gtk_widget_set_sensitive(GTK_WIDGET(dialog->file.local),FALSE); | 290 | gtk_widget_set_sensitive(GTK_WIDGET(dialog->file.local),FALSE); |
| 207 | gtk_widget_set_sensitive(GTK_WIDGET(dialog->file.remote),FALSE); | 291 | gtk_widget_set_sensitive(GTK_WIDGET(dialog->file.remote),FALSE); |
| 208 | } | 292 | } |
| 209 | 293 | ||
| 210 | } | 294 | } |
| 211 | 295 | ||
| 296 | + | ||
| 297 | + static void local_file_changed(GtkEntry *entry, V3270FTSettings *widget) { | ||
| 298 | + | ||
| 299 | + const gchar * text = gtk_entry_get_text(entry); | ||
| 300 | + | ||
| 301 | + if(!text) | ||
| 302 | + { | ||
| 303 | + set_invalid(widget, VALIDITY_LOCAL_FILENAME); | ||
| 304 | + return; | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + if(widget->transfer.options & LIB3270_FT_OPTION_RECEIVE) | ||
| 308 | + { | ||
| 309 | + // Check for file receive options. | ||
| 310 | + g_autofree gchar * dir = g_path_get_dirname(text); | ||
| 311 | + | ||
| 312 | + if(*dir && !g_file_test(dir,G_FILE_TEST_IS_DIR)) | ||
| 313 | + { | ||
| 314 | + debug("Folder \"%s\" is invalid",dir); | ||
| 315 | + set_invalid(widget, VALIDITY_LOCAL_FILENAME); | ||
| 316 | + return; | ||
| 317 | + } | ||
| 318 | + | ||
| 319 | + } | ||
| 320 | + else | ||
| 321 | + { | ||
| 322 | + // Check for file send options. | ||
| 323 | + if(!g_file_test(text,G_FILE_TEST_IS_REGULAR)) | ||
| 324 | + { | ||
| 325 | + debug("File \"%s\" is invalid",text); | ||
| 326 | + set_valid(widget, VALIDITY_LOCAL_FILENAME); | ||
| 327 | + return; | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + set_valid(widget, VALIDITY_LOCAL_FILENAME); | ||
| 333 | + } | ||
| 334 | + | ||
| 335 | + static void remote_file_changed(GtkEntry *entry, V3270FTSettings *widget) { | ||
| 336 | + | ||
| 337 | + const gchar * text = gtk_entry_get_text(entry); | ||
| 338 | + | ||
| 339 | + if(!*text) | ||
| 340 | + { | ||
| 341 | + set_invalid(widget, VALIDITY_REMOTE_FILENAME); | ||
| 342 | + return; | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + set_valid(widget, VALIDITY_REMOTE_FILENAME); | ||
| 346 | + | ||
| 347 | + } | ||
| 348 | + | ||
| 212 | static void V3270FTSettings_init(V3270FTSettings *widget) | 349 | static void V3270FTSettings_init(V3270FTSettings *widget) |
| 213 | { | 350 | { |
| 214 | size_t ix; | 351 | size_t ix; |
| 215 | 352 | ||
| 353 | + // Begin with all invalid options set. | ||
| 354 | + widget->transfer.invalid = VALIDITY_TRANSFER_TYPE|VALIDITY_LOCAL_FILENAME|VALIDITY_REMOTE_FILENAME; | ||
| 355 | + | ||
| 216 | // https://developer.gnome.org/hig/stable/visual-layout.html.en | 356 | // https://developer.gnome.org/hig/stable/visual-layout.html.en |
| 217 | gtk_grid_set_row_spacing(GTK_GRID(widget),6); | 357 | gtk_grid_set_row_spacing(GTK_GRID(widget),6); |
| 218 | gtk_grid_set_column_spacing(GTK_GRID(widget),12); | 358 | gtk_grid_set_column_spacing(GTK_GRID(widget),12); |
| @@ -248,10 +388,12 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | @@ -248,10 +388,12 @@ static void open_select_file_dialog(GtkEntry *entry, G_GNUC_UNUSED GtkEntryIconP | ||
| 248 | gtk_entry_set_icon_tooltip_text(widget->file.local,GTK_ENTRY_ICON_SECONDARY,_("Select file")); | 388 | gtk_entry_set_icon_tooltip_text(widget->file.local,GTK_ENTRY_ICON_SECONDARY,_("Select file")); |
| 249 | 389 | ||
| 250 | g_signal_connect(G_OBJECT(widget->file.local),"icon-press",G_CALLBACK(open_select_file_dialog),widget); | 390 | g_signal_connect(G_OBJECT(widget->file.local),"icon-press",G_CALLBACK(open_select_file_dialog),widget); |
| 391 | + g_signal_connect(G_OBJECT(widget->file.local),"changed",G_CALLBACK(local_file_changed),widget); | ||
| 251 | 392 | ||
| 252 | // Remote file name | 393 | // Remote file name |
| 253 | widget->file.remote = GTK_ENTRY(create_entry(widget,"_Remote file",gtk_entry_new(),0,2,9)); | 394 | widget->file.remote = GTK_ENTRY(create_entry(widget,"_Remote file",gtk_entry_new(),0,2,9)); |
| 254 | gtk_entry_set_max_length(widget->file.remote,PATH_MAX); | 395 | gtk_entry_set_max_length(widget->file.remote,PATH_MAX); |
| 396 | + g_signal_connect(G_OBJECT(widget->file.remote),"changed",G_CALLBACK(remote_file_changed),widget); | ||
| 255 | 397 | ||
| 256 | } | 398 | } |
| 257 | 399 |