diff --git a/src/include/lib3270/filetransfer.h b/src/include/lib3270/filetransfer.h index 08939b0..b0318ea 100644 --- a/src/include/lib3270/filetransfer.h +++ b/src/include/lib3270/filetransfer.h @@ -74,11 +74,12 @@ H3270 * host; void * widget; /**< File transfer dialog handle */ FILE * ft_local_file; /**< File descriptor for local file */ + unsigned long length; /**< File length */ + LIB3270_FT_STATE state; void (*complete)(struct _h3270ft *ft, const char *errmsg,unsigned long length,double kbytes_sec,const char *mode); - void (*setlength)(struct _h3270ft *ft, unsigned long length); - void (*update)(struct _h3270ft *ft, unsigned long length, double kbytes_sec); + void (*update)(struct _h3270ft *ft, unsigned long current, unsigned long length, double kbytes_sec); void (*running)(struct _h3270ft *ft, int is_cut); void (*aborting)(struct _h3270ft *ft); void (*state_changed)(struct _h3270ft *ft, LIB3270_FT_STATE state); @@ -102,7 +103,8 @@ * @return Filetransfer handle if ok, NULL if failed * */ - LIB3270_EXPORT H3270FT * lib3270_ft_start(H3270 *session, LIB3270_FT_OPTION flags, const char *local, const char *remote, int lrecl, int blksize, int primspace, int secspace, int dft, const char **msg); + LIB3270_EXPORT H3270FT * lib3270_ft_new(H3270 *session, LIB3270_FT_OPTION flags, const char *local, const char *remote, int lrecl, int blksize, int primspace, int secspace, int dft, const char **msg); + LIB3270_EXPORT void lib3270_ft_destroy(H3270FT *ft); LIB3270_EXPORT int lib3270_ft_cancel(H3270FT *ft, int force); diff --git a/src/lib3270/api.h b/src/lib3270/api.h index efa0afb..efcec27 100644 --- a/src/lib3270/api.h +++ b/src/lib3270/api.h @@ -226,20 +226,21 @@ LOCAL_EXTERN int CancelFileTransfer(int force); // LOCAL_EXTERN enum ft_state GetFileTransferState(void); +/* struct filetransfer_callbacks { unsigned short sz; void (*begin)(unsigned short flags, const char *local, const char *remote); void (*complete)(const char *errmsg,unsigned long length,double kbytes_sec,const char *mode); - void (*setlength)(unsigned long length); - void (*update)(unsigned long length,double kbytes_sec); + void (*update)(unsigned long length,unsigned long total,double kbytes_sec); void (*running)(int is_cut); void (*aborting)(void); }; LOCAL_EXTERN int RegisterFTCallbacks(const struct filetransfer_callbacks *cbk); +*/ #define PCONNECTED lib3270_pconnected(NULL) #define HALF_CONNECTED lib3270_half_connected(NULL) diff --git a/src/lib3270/ft.c b/src/lib3270/ft.c index 19f63de..02a978d 100644 --- a/src/lib3270/ft.c +++ b/src/lib3270/ft.c @@ -165,12 +165,7 @@ static void set_ft_state(H3270FT *session, LIB3270_FT_STATE state); } - static void def_setlength(H3270FT *ft, unsigned long length) - { - - } - - static void def_update(H3270FT *ft, unsigned long length,double kbytes_sec) + static void def_update(H3270FT *ft, unsigned long current, unsigned long length, double kbytes_sec) { } @@ -191,7 +186,7 @@ static void set_ft_state(H3270FT *session, LIB3270_FT_STATE state); } - LIB3270_EXPORT H3270FT * lib3270_ft_start(H3270 *session, LIB3270_FT_OPTION flags, const char *local, const char *remote, int lrecl, int blksize, int primspace, int secspace, int dft, const char **msg) + LIB3270_EXPORT H3270FT * lib3270_ft_new(H3270 *session, LIB3270_FT_OPTION flags, const char *local, const char *remote, int lrecl, int blksize, int primspace, int secspace, int dft, const char **msg) { H3270FT * ftHandle = NULL; static const char * rec = "fvu"; @@ -201,6 +196,7 @@ static void set_ft_state(H3270FT *session, LIB3270_FT_STATE state); unsigned short units = (flags & FT_ALLOCATION_UNITS_MASK) >> 12; FILE * ft_local_file = NULL; + unsigned long ft_length = 0L; char op[4096]; char buffer[4096]; @@ -215,16 +211,16 @@ static void set_ft_state(H3270FT *session, LIB3270_FT_STATE state); return NULL; } - if(ftsession) + if(session->ft) { - *msg = N_( "File transfer is already active" ); + *msg = N_( "File transfer is already active in this session" ); errno = EBUSY; return NULL; } - if(session->ft) + if(ftsession) { - *msg = N_( "File transfer is already active in this session" ); + *msg = N_( "File transfer is already active" ); errno = EBUSY; return NULL; } @@ -254,7 +250,25 @@ static void set_ft_state(H3270FT *session, LIB3270_FT_STATE state); cr_flag = ((flags & LIB3270_FT_OPTION_CRLF) != 0); remap_flag = ((flags & LIB3270_FT_OPTION_ASCII) != 0); - lib3270_write_log(session, "%s file \"%s\"",(flags & LIB3270_FT_OPTION_RECEIVE) ? "Receiving" : "Sending", local); + if(flags & LIB3270_FT_OPTION_RECEIVE) + { + // Receiving file + lib3270_write_log(session,"ft","Receiving file %s",local); + } + else + { + // Sending file + if(fseek(ft_local_file,0L,SEEK_END) < 0) + { + *msg = N_( "Can't get file size" ); + return NULL; + } + + ft_length = ftell(ft_local_file); + + lib3270_write_log(session,"ft","Sending file %s (%ld bytes)",local,ft_length); + rewind(ft_local_file); + } /* Build the ind$file command */ snprintf(op,4095,"%s%s%s", @@ -331,7 +345,7 @@ static void set_ft_state(H3270FT *session, LIB3270_FT_STATE state); return NULL; } - trace("Command: \"%s\"",buffer); + trace_event("Sending FT request:\n%s\n",buffer); (void) lib3270_emulate_input(NULL, buffer, strlen(buffer), False); @@ -345,9 +359,9 @@ static void set_ft_state(H3270FT *session, LIB3270_FT_STATE state); ftHandle->sz = sizeof(H3270FT); ftHandle->host = session; ftHandle->ft_local_file = ft_local_file; + ftHandle->length = ft_length; ftHandle->state = LIB3270_FT_STATE_AWAIT_ACK; ftHandle->complete = def_complete; - ftHandle->setlength = def_setlength; ftHandle->update = def_update; ftHandle->running = def_running; ftHandle->aborting = def_aborting; @@ -390,6 +404,21 @@ void ft_complete(H3270FT *session, const char *errmsg) session->complete(session,errmsg,ft_length,kbytes_sec,ft_is_cut ? "CUT" : "DFT"); +} + +LIB3270_EXPORT void lib3270_ft_destroy(H3270FT *session) +{ + CHECK_FT_HANDLE(session); + + if (session->state != LIB3270_FT_STATE_NONE) + lib3270_ft_cancel(session,1); + + if(session->ft_local_file) + { + fclose(session->ft_local_file); + session->ft_local_file = NULL; + } + if(session == ftsession) ftsession = NULL; @@ -417,7 +446,7 @@ void ft_update_length(H3270FT *session) (double)(t1.tv_usec - starting_time.tv_usec) / 1.0e6); } - session->update(session,ft_length,kbytes_sec); + session->update(session,ft_length,session->length,kbytes_sec); } diff --git a/src/pw3270/filetransfer.c b/src/pw3270/filetransfer.c index 287f8fb..f3c5221 100644 --- a/src/pw3270/filetransfer.c +++ b/src/pw3270/filetransfer.c @@ -174,7 +174,6 @@ static void add_file_fields(GObject *action, struct ftdialog *dlg) gtk_table_attach(GTK_TABLE(table),widget,0,1,f,f+1,GTK_FILL,GTK_FILL,2,2); dlg->file[f] = GTK_ENTRY(gtk_entry_new()); - g_signal_connect(G_OBJECT(dlg->file[f]),"changed",G_CALLBACK(check_entry),dlg); gtk_widget_set_name(GTK_WIDGET(dlg->file[f]),attr[f]); @@ -196,6 +195,8 @@ static void add_file_fields(GObject *action, struct ftdialog *dlg) gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dlg->dialog))),GTK_WIDGET(table),FALSE,FALSE,2); + for(f=0;f<2;f++) + g_signal_connect(G_OBJECT(dlg->file[f]),"changed",G_CALLBACK(check_entry),dlg); } static void toggle_option(GtkToggleButton *button, const struct ftoption *option) @@ -282,13 +283,28 @@ static void setup_dft(GObject *action, struct ftdialog *dlg, GtkWidget **label) } -static gboolean run_ft_dialog(GObject *action, GtkWidget *widget, struct ftdialog *dlg) + +static void ft_complete(H3270FT *ft, const char *errmsg,unsigned long length,double kbytes_sec,const char *mode) +{ + if(!ft->widget) + return; + + + + ft->widget = NULL; +} + + +static void run_ft_dialog(GObject *action, GtkWidget *widget, struct ftdialog *dlg) { H3270FT * ft = NULL; const char * msg = NULL; int f; int parm[G_N_ELEMENTS(dlg->parm)]; + for(f=0;f<2;f++) + gtk_widget_set_sensitive(dlg->ready,is_dialog_ok(GTK_EDITABLE(dlg->file[f]),dlg)); + gtk_widget_show_all(dlg->dialog); for(f=0;fparm);f++) @@ -303,7 +319,11 @@ static gboolean run_ft_dialog(GObject *action, GtkWidget *widget, struct ftdialo } if(gtk_dialog_run(GTK_DIALOG(dlg->dialog)) != GTK_RESPONSE_ACCEPT) - return FALSE; + { + gtk_widget_destroy(dlg->dialog); + dlg->dialog = NULL; + return; + } for(f=0;fparm);f++) { @@ -321,7 +341,7 @@ static gboolean run_ft_dialog(GObject *action, GtkWidget *widget, struct ftdialo set_string_to_config(dlg->name,"local","%s",gtk_entry_get_text(dlg->file[0])); set_string_to_config(dlg->name,"remote","%s",gtk_entry_get_text(dlg->file[1])); - ft = lib3270_ft_start( v3270_get_session(widget), + ft = lib3270_ft_new( v3270_get_session(widget), dlg->option, gtk_entry_get_text(dlg->file[0]), gtk_entry_get_text(dlg->file[1]), @@ -332,6 +352,9 @@ static gboolean run_ft_dialog(GObject *action, GtkWidget *widget, struct ftdialo parm[4], // dft &msg ); + + gtk_widget_set_visible(dlg->dialog,FALSE); + if(msg) { GtkWidget *popup = gtk_message_dialog_new_with_markup( @@ -351,10 +374,90 @@ static gboolean run_ft_dialog(GObject *action, GtkWidget *widget, struct ftdialo } - if(!ft) - return FALSE; + if(ft) + { + // Setup FT callbacks, create popup window + /* + http://www.suggestsoft.com/images/medieval-software/medieval-bluetooth-obex-file-transfer.gif + + --Informations---------------------------------------- + | + | From: xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx + | + | To: xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx + | + | Status: xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx.xxx + ------------------------------------------------------ + + --Progress---------------------------------------------- + | + | Total: xxx.xxx.xxx Current: xxx.xxx.xxx + | + | Started: xx:xx:xx ETA: xx:xx:xx + | + | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + -------------------------------------------------------- + + [Cancel] + */ + GtkWidget *container; + + ft->widget = gtk_dialog_new_with_buttons( _( "File transfer" ), + GTK_WINDOW(gtk_widget_get_toplevel(widget)), + GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CLOSE,GTK_RESPONSE_CLOSE ); + + + container = gtk_vbox_new(FALSE,2); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(ft->widget))),container,TRUE,TRUE,2); + + // Information frame + { + static const gchar *text[] = { N_( "_From:" ), N_( "_To:" ), N_( "_Status:" ) }; + + GtkWidget * frame = gtk_frame_new( _( "Informations" ) ); + GtkWidget * table = gtk_table_new(G_N_ELEMENTS(text),2,FALSE); + int f; + GtkWidget **entry = g_new0(GtkWidget *, G_N_ELEMENTS(text)); + + g_object_set_data_full(G_OBJECT(ft->widget),"info",entry,g_free); + gtk_container_set_border_width(GTK_CONTAINER(frame),3); + + for(f=0;ffile[f])); + + gtk_container_add(GTK_CONTAINER(frame),table); + gtk_box_pack_start(GTK_BOX(container),frame,TRUE,TRUE,2); + + } + + + + gtk_widget_show_all(ft->widget); + gtk_dialog_run(GTK_DIALOG(ft->widget)); + gtk_widget_destroy(ft->widget); + + lib3270_ft_destroy(ft); + + } + + gtk_widget_destroy(dlg->dialog); + dlg->dialog = NULL; - return TRUE; } static void add_buttons(struct ftdialog *dlg) @@ -409,8 +512,6 @@ void download_action(GtkAction *action, GtkWidget *widget) run_ft_dialog(G_OBJECT(action),widget,&dlg); - gtk_widget_destroy(dlg.dialog); - } static void toggle_format(GtkToggleButton *button, const struct ftmask *option) @@ -565,9 +666,9 @@ void upload_action(GtkAction *action, GtkWidget *widget) } - run_ft_dialog(G_OBJECT(action),widget,&dlg); + trace("Running ft fialog %p",&dlg); - gtk_widget_destroy(dlg.dialog); + run_ft_dialog(G_OBJECT(action),widget,&dlg); } -- libgit2 0.21.2