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 | 40 | GtkWidget * settings; |
| 41 | 41 | |
| 42 | 42 | struct { |
| 43 | + GtkWidget * valid; | |
| 43 | 44 | GtkWidget * insert; |
| 44 | 45 | GtkWidget * update; |
| 45 | 46 | GtkWidget * reset; |
| ... | ... | @@ -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 | 112 | static void V3270FTDialog_init(V3270FTDialog *widget) |
| 106 | 113 | { |
| 107 | 114 | widget->settings = v3270_ft_settings_new(); |
| 115 | + g_signal_connect(G_OBJECT(widget->settings),"validity",G_CALLBACK(validity_changed),widget); | |
| 108 | 116 | |
| 109 | 117 | gtk_window_set_title(GTK_WINDOW(widget),_( "3270 File transfer")); |
| 110 | 118 | |
| ... | ... | @@ -123,18 +131,19 @@ static void V3270FTDialog_init(V3270FTDialog *widget) |
| 123 | 131 | |
| 124 | 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 | 142 | gtk_widget_set_sensitive(widget->button.update,FALSE); |
| 135 | 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 | 30 | #include <string.h> |
| 31 | 31 | #include <internals.h> |
| 32 | 32 | #include "private.h" |
| 33 | + #include "marshal.h" | |
| 33 | 34 | #include <v3270/filetransfer.h> |
| 34 | 35 | |
| 35 | 36 | /*--[ Widget definition ]----------------------------------------------------------------------------*/ |
| ... | ... | @@ -38,31 +39,82 @@ |
| 38 | 39 | { |
| 39 | 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 | 56 | struct _V3270FTSettings |
| 44 | 57 | { |
| 45 | 58 | GtkGrid parent; |
| 46 | 59 | |
| 47 | - struct { | |
| 60 | + struct | |
| 61 | + { | |
| 48 | 62 | GtkEntry * local; |
| 49 | 63 | GtkEntry * remote; |
| 50 | 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 | 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 | 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 | 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 | 204 | { |
| 153 | 205 | size_t ix; |
| 154 | 206 | |
| 207 | + widget->transfer.options = options; | |
| 208 | + | |
| 155 | 209 | if(options & LIB3270_FT_OPTION_RECEIVE) |
| 156 | 210 | { |
| 157 | 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 | 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 | 276 | static void transfer_type_changed(GtkComboBox *widget, V3270FTSettings *dialog) |
| 195 | 277 | { |
| 196 | 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 | 281 | |
| 200 | 282 | if(selected >= 0) |
| 201 | 283 | { |
| 284 | + set_valid(dialog, VALIDITY_TRANSFER_TYPE); | |
| 202 | 285 | set_options(dialog,ft_type[selected].opt); |
| 203 | 286 | } |
| 204 | 287 | else |
| 205 | 288 | { |
| 289 | + set_invalid(dialog, VALIDITY_TRANSFER_TYPE); | |
| 206 | 290 | gtk_widget_set_sensitive(GTK_WIDGET(dialog->file.local),FALSE); |
| 207 | 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 | 349 | static void V3270FTSettings_init(V3270FTSettings *widget) |
| 213 | 350 | { |
| 214 | 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 | 356 | // https://developer.gnome.org/hig/stable/visual-layout.html.en |
| 217 | 357 | gtk_grid_set_row_spacing(GTK_GRID(widget),6); |
| 218 | 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 | 388 | gtk_entry_set_icon_tooltip_text(widget->file.local,GTK_ENTRY_ICON_SECONDARY,_("Select file")); |
| 249 | 389 | |
| 250 | 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 | 393 | // Remote file name |
| 253 | 394 | widget->file.remote = GTK_ENTRY(create_entry(widget,"_Remote file",gtk_entry_new(),0,2,9)); |
| 254 | 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 | ... | ... |