Commit 62e67d83660fa6d4281db743004811353982f7ed

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

Working on FT worker widget.

src/dialogs/tools.c
... ... @@ -82,5 +82,16 @@
82 82 return child;
83 83 }
84 84  
  85 + void gtk_entry_set_text_printf(GtkEntry *entry, const gchar *fmt, ...)
  86 + {
  87 + va_list arg_ptr;
  88 + va_start(arg_ptr, fmt);
  89 + gchar *text = g_strdup_vprintf(fmt,arg_ptr);
  90 + va_end(arg_ptr);
  91 +
  92 + gtk_entry_set_text(entry,text);
85 93  
  94 + g_free(text);
  95 +
  96 + }
86 97  
... ...
src/filetransfer/activity.c
... ... @@ -298,3 +298,22 @@
298 298 g_markup_parse_context_push(context,&parser,activity);
299 299  
300 300 }
  301 +
  302 + LIB3270_EXPORT H3270FT * v3270_ft_activity_begin_transfer(GObject * object, H3270 *hSession, const char **message)
  303 + {
  304 + V3270FTActivity * activity = G_V3270_FT_ACTIVITY(object);
  305 +
  306 + return lib3270_ft_new(
  307 + hSession,
  308 + activity->options,
  309 + activity->file.local,
  310 + activity->file.remote,
  311 + activity->values[LIB3270_FT_VALUE_LRECL],
  312 + activity->values[LIB3270_FT_VALUE_BLKSIZE],
  313 + activity->values[LIB3270_FT_VALUE_PRIMSPACE],
  314 + activity->values[LIB3270_FT_VALUE_SECSPACE],
  315 + activity->values[LIB3270_FT_VALUE_DFT],
  316 + message
  317 + );
  318 +
  319 + }
... ...
src/filetransfer/marshal
1 1 VOID:POINTER,POINTER
2 2 VOID:VOID,BOOLEAN
3 3 VOID:VOID,OBJECT
  4 +VOID:UINT,POINTER
4 5  
... ...
src/filetransfer/set.c
... ... @@ -182,7 +182,7 @@ void v3270ftprogress_set_session(GtkWidget *widget, H3270 *session) {
182 182 v3270ftprogress * dialog = GTK_V3270FTPROGRESS(widget);
183 183  
184 184 if(dialog->session) {
185   - lib3270_ft_destroy(dialog->session);
  185 + lib3270_ft_destroy(dialog->session,NULL);
186 186 }
187 187  
188 188 dialog->session = session;
... ...
src/filetransfer/v3270ftprogress.c
... ... @@ -247,7 +247,7 @@ gboolean v3270ftprogress_cleanup(v3270ftprogress * dialog) {
247 247 if(dialog->session) {
248 248 debug("%s: FT session was destroyed",__FUNCTION__);
249 249 lib3270_ft_set_user_data(dialog->session,NULL);
250   - lib3270_ft_destroy(dialog->session);
  250 + lib3270_ft_destroy(dialog->session,NULL);
251 251 }
252 252  
253 253 return FALSE;
... ... @@ -282,7 +282,7 @@ static void dialog_response(GtkDialog *widget, gint response_id) {
282 282  
283 283 // Removo do objeto para evitar a geração de sinais e destruo.
284 284 lib3270_ft_set_user_data(dialog->session,NULL);
285   - lib3270_ft_destroy(dialog->session);
  285 + lib3270_ft_destroy(dialog->session,NULL);
286 286  
287 287 }
288 288  
... ... @@ -298,7 +298,7 @@ static void dialog_close(GtkDialog *object) {
298 298 debug("%s",__FUNCTION__);
299 299  
300 300 // Se tem sessão e conseguiu cancelar.
301   - if(dialog->session && lib3270_ft_cancel(dialog->session,0) == 0)
  301 + if(dialog->session && lib3270_ft_cancel(dialog->session,0,NULL) == 0)
302 302 return;
303 303  
304 304 GTK_DIALOG_CLASS(v3270ftprogress_parent_class)->close(object);
... ... @@ -367,7 +367,7 @@ static void cancel_clicked(G_GNUC_UNUSED GtkButton *button,v3270ftprogress *dial
367 367 debug("%s",__FUNCTION__);
368 368  
369 369 if(dialog->session) {
370   - lib3270_ft_cancel(dialog->session,1);
  370 + lib3270_ft_cancel(dialog->session,1,NULL);
371 371 }
372 372 }
373 373  
... ... @@ -540,7 +540,7 @@ gboolean send_delayed_signal(struct delayed_signal *sig) {
540 540 void * userdata = lib3270_ft_get_user_data(sig->hSession);
541 541  
542 542 lib3270_ft_set_user_data(sig->hSession,NULL);
543   - lib3270_ft_destroy(sig->hSession);
  543 + lib3270_ft_destroy(sig->hSession,NULL);
544 544  
545 545 if(userdata) {
546 546 g_signal_emit(GTK_WIDGET(userdata),v3270ftprogress_signal[sig->signal], 0, sig->msg, sig->text);
... ... @@ -679,10 +679,10 @@ static void ft_running(G_GNUC_UNUSED H3270 *hSession, G_GNUC_UNUSED int is_cut,
679 679 GTK_V3270FTPROGRESS(widget)->timeout = time(NULL)+10;
680 680 }
681 681  
682   -static void ft_aborting(G_GNUC_UNUSED H3270 *hSession, void *widget) {
  682 +static void ft_aborting(G_GNUC_UNUSED H3270 *hSession, const char *reason, void *widget) {
683 683  
684 684 if(widget) {
685   - v3270ftprogress_set_header(GTK_WIDGET(widget),_("Aborting transfer"));
  685 + v3270ftprogress_set_header(GTK_WIDGET(widget),reason);
686 686 }
687 687  
688 688 }
... ... @@ -714,7 +714,7 @@ static gboolean do_timer(v3270ftprogress *dialog) {
714 714  
715 715 if(dialog->session) {
716 716 lib3270_ft_set_user_data(dialog->session,NULL);
717   - lib3270_ft_destroy(dialog->session);
  717 + lib3270_ft_destroy(dialog->session,NULL);
718 718 }
719 719  
720 720 g_signal_emit(GTK_WIDGET(dialog),v3270ftprogress_signal[V3270FTPROGRESS_SIGNAL_FAILED], 0, _( "Transfer failed" ), strerror(ETIMEDOUT));
... ... @@ -768,7 +768,7 @@ void v3270ftprogress_start_transfer(GtkWidget *widget) {
768 768  
769 769 if(!cbk) {
770 770  
771   - lib3270_ft_destroy(dialog->session);
  771 + lib3270_ft_destroy(dialog->session,NULL);
772 772 g_signal_emit(GTK_WIDGET(widget),v3270ftprogress_signal[V3270FTPROGRESS_SIGNAL_FAILED], 0, _( "Can't set callback table" ), NULL);
773 773  
774 774 return;
... ...
src/filetransfer/worker.c
... ... @@ -35,21 +35,20 @@
35 35  
36 36 /*--[ Widget definition ]----------------------------------------------------------------------------*/
37 37  
38   - enum _SIGNALS
  38 + typedef enum _V3270_WORKER_SIGNAL
39 39 {
40   - V3270_WORKER_ACTIVITY_SIGNAL, ///< @brief Indicates if the list has an activity set.
  40 + V3270_WORKER_ACTIVITY_SIGNAL, ///< @brief Indicates if the list has an activity set.
  41 + V3270_WORKER_TRANSFER_FAILED_SIGNAL, ///< @brief Transfer has failed.
  42 + V3270_WORKER_TRANSFER_SUCCESS_SIGNAL, ///< @brief Transfer complete.
  43 + V3270_WORKER_TRANSFER_STATE_SIGNAL, ///< @brief Transfer state has changed.
41 44  
42 45 V3270_WORKER_LAST_SIGNAL
43   - };
  46 + } V3270_WORKER_SIGNAL;
44 47  
45 48 struct _V3270FTWorkerClass
46 49 {
47 50 GtkGridClass parent_class;
48 51  
49   - struct
50   - {
51   - void (*activity)(GtkWidget *, GObject *);
52   - } signal;
53 52  
54 53 };
55 54  
... ... @@ -57,10 +56,20 @@
57 56 {
58 57 GtkGrid parent;
59 58  
  59 + H3270 * hSession;
  60 +
60 61 GtkProgressBar * pbar; ///< @brief Progress bar.
61 62 GObject * activity; ///< @brief File transfer activity.
62 63 GSource * pulse; ///< @brief Process pulse.
63 64  
  65 + struct
  66 + {
  67 + GSource * timer; ///< @brief Timeout timer.
  68 + time_t limit; ///< @brief Timestamp for timeout transfer.
  69 + time_t value; ///< @brief Timeout value.
  70 +
  71 + } timeout;
  72 +
64 73 GtkEntry * field[PROGRESS_FIELD_COUNT]; ///< @brief Transfer information widgets.
65 74  
66 75 };
... ... @@ -96,13 +105,30 @@
96 105 }
97 106 }
98 107  
  108 + static void timer_stop(V3270FTWorker *worker)
  109 + {
  110 + if(worker->timeout.timer)
  111 + {
  112 + g_source_destroy(worker->timeout.timer);
  113 + worker->timeout.timer = NULL;
  114 + }
  115 + }
  116 +
99 117 static void finalize(GObject *object)
100 118 {
101 119 debug("%s",__FUNCTION__);
102 120  
103 121 V3270FTWorker * worker = GTK_V3270_FT_WORKER(object);
104 122  
  123 + if(worker->hSession)
  124 + {
  125 + lib3270_ft_set_user_data(worker->hSession,NULL);
  126 + lib3270_ft_destroy(worker->hSession,NULL);
  127 + worker->hSession = NULL;
  128 + }
  129 +
105 130 pulse_stop(worker);
  131 + timer_stop(worker);
106 132  
107 133 if(worker->activity)
108 134 {
... ... @@ -114,27 +140,45 @@
114 140  
115 141 }
116 142  
117   - static void V3270FTWorker_activity(GtkWidget G_GNUC_UNUSED(*widget), GObject G_GNUC_UNUSED(*activity))
118   - {
119   - debug("%s",__FUNCTION__);
120   - }
121   -
122 143 static void V3270FTWorker_class_init(G_GNUC_UNUSED V3270FTWorkerClass *klass)
123 144 {
124 145 GObjectClass * gobject_class = G_OBJECT_CLASS(klass);
125 146  
126 147 gobject_class->finalize = finalize;
127 148  
128   - klass->signal.activity = V3270FTWorker_activity;
129   -
130 149 v3270_worker_signals[V3270_WORKER_ACTIVITY_SIGNAL] =
131   - g_signal_new( "activity",
132   - G_OBJECT_CLASS_TYPE (gobject_class),
133   - G_SIGNAL_RUN_FIRST,
134   - G_STRUCT_OFFSET (V3270FTWorkerClass, signal.activity),
135   - NULL, NULL,
136   - v3270ft_VOID__VOID_OBJECT,
137   - G_TYPE_NONE, 1, G_TYPE_OBJECT);
  150 + g_signal_new(
  151 + "activity",
  152 + G_OBJECT_CLASS_TYPE (gobject_class),
  153 + G_SIGNAL_RUN_FIRST,
  154 + 0,
  155 + NULL, NULL,
  156 + v3270ft_VOID__VOID_OBJECT,
  157 + G_TYPE_NONE, 1, G_TYPE_OBJECT
  158 + );
  159 +
  160 + v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL] =
  161 + g_signal_new(
  162 + "failed",
  163 + G_OBJECT_CLASS_TYPE (gobject_class),
  164 + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
  165 + 0,
  166 + NULL, NULL,
  167 + v3270ft_VOID__POINTER_POINTER,
  168 + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER
  169 + );
  170 +
  171 + v3270_worker_signals[V3270_WORKER_TRANSFER_STATE_SIGNAL] =
  172 + g_signal_new(
  173 + "ft-state-changed",
  174 + G_OBJECT_CLASS_TYPE (gobject_class),
  175 + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
  176 + 0,
  177 + NULL, NULL,
  178 + v3270ft_VOID__UINT_POINTER,
  179 + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER
  180 + );
  181 +
138 182  
139 183 }
140 184  
... ... @@ -162,6 +206,7 @@
162 206 gtk_grid_attach(GTK_GRID(grid),label,0,top,1,1);
163 207  
164 208 widget->field[id] = GTK_ENTRY(gtk_entry_new());
  209 + gtk_entry_set_alignment(widget->field[id],1);
165 210  
166 211 gtk_grid_attach(GTK_GRID(grid),GTK_WIDGET(widget->field[id]),1,top,1,1);
167 212  
... ... @@ -169,6 +214,9 @@
169 214  
170 215 static void V3270FTWorker_init(V3270FTWorker *widget)
171 216 {
  217 + // Set defaults.
  218 + widget->timeout.value = 10;
  219 +
172 220 // https://developer.gnome.org/hig/stable/visual-layout.html.en
173 221 gtk_grid_set_row_spacing(GTK_GRID(widget),6);
174 222 gtk_grid_set_column_spacing(GTK_GRID(widget),12);
... ... @@ -240,6 +288,11 @@
240 288  
241 289 V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget);
242 290  
  291 + if(worker->hSession)
  292 + {
  293 + lib3270_ft_destroy(worker->hSession,NULL);
  294 + }
  295 +
243 296 if(worker->activity)
244 297 {
245 298 g_object_unref(worker->activity);
... ... @@ -254,11 +307,16 @@
254 307 gtk_entry_set_text(worker->field[PROGRESS_FIELD_LOCAL],v3270_ft_activity_get_local_filename(activity));
255 308 gtk_entry_set_text(worker->field[PROGRESS_FIELD_REMOTE],v3270_ft_activity_get_remote_filename(activity));
256 309  
  310 + gtk_progress_bar_set_text(worker->pbar,_("Starting transfer"));
  311 + pulse_start(worker);
  312 +
257 313 }
258 314 else
259 315 {
260 316 gtk_entry_set_text(worker->field[PROGRESS_FIELD_LOCAL],"");
261 317 gtk_entry_set_text(worker->field[PROGRESS_FIELD_REMOTE],"");
  318 + pulse_stop(worker);
  319 +
262 320 }
263 321  
264 322 for(ix = PROGRESS_FIELD_TOTAL; ix < PROGRESS_FIELD_COUNT; ix++)
... ... @@ -266,10 +324,321 @@
266 324 gtk_entry_set_text(worker->field[ix],"");
267 325 }
268 326  
269   - gtk_progress_bar_set_text(worker->pbar,_("Starting transfer"));
270   - pulse_start(worker);
271   -
272 327 g_signal_emit(widget, v3270_worker_signals[V3270_WORKER_ACTIVITY_SIGNAL], 0, worker->activity);
273 328  
274 329 }
275 330  
  331 + LIB3270_EXPORT void v3270_ft_worker_set_session(GtkWidget *widget, H3270 *hSession)
  332 + {
  333 + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget);
  334 + worker->hSession = hSession;
  335 +
  336 + }
  337 +
  338 + struct bg_complete
  339 + {
  340 + V3270FTWorker * worker;
  341 + V3270_WORKER_SIGNAL signal;
  342 + unsigned long length;
  343 + double kbytes_sec;
  344 + char msg[1];
  345 + };
  346 +
  347 + static gboolean bg_emit_complete(struct bg_complete * cfg)
  348 + {
  349 + // Try to get more detailed info.
  350 + const gchar * description = NULL;
  351 +
  352 + if(cfg->length)
  353 + {
  354 + gtk_entry_set_text_printf(cfg->worker->field[PROGRESS_FIELD_TOTAL],"%lu",cfg->length);
  355 + }
  356 + else
  357 + {
  358 + gtk_entry_set_text(cfg->worker->field[PROGRESS_FIELD_TOTAL],"");
  359 + }
  360 +
  361 + gtk_entry_set_text(cfg->worker->field[PROGRESS_FIELD_ETA],"");
  362 +
  363 +
  364 + const LIB3270_FT_MESSAGE * ftMessage = lib3270_translate_ft_message(cfg->msg);
  365 +
  366 + if(ftMessage)
  367 + {
  368 + description = ftMessage->description;
  369 + if(ftMessage->failed)
  370 + cfg->signal = V3270_WORKER_TRANSFER_FAILED_SIGNAL;
  371 +
  372 + }
  373 +
  374 + gtk_progress_bar_set_text(cfg->worker->pbar,cfg->msg);
  375 +
  376 + g_signal_emit(
  377 + GTK_WIDGET(cfg->worker),
  378 + v3270_worker_signals[cfg->signal],
  379 + 0,
  380 + cfg->msg,
  381 + description
  382 + );
  383 +
  384 + return FALSE;
  385 +
  386 + }
  387 +
  388 + static void ft_complete(H3270 G_GNUC_UNUSED(*hSession), unsigned long length, double kbytes_sec, const char *msg, void *widget)
  389 + {
  390 + struct bg_complete * state = g_malloc0(sizeof(struct bg_complete)+strlen(msg)+1);
  391 +
  392 + state->worker = GTK_V3270_FT_WORKER(widget);
  393 + state->signal = V3270_WORKER_TRANSFER_SUCCESS_SIGNAL;
  394 + state->length = length;
  395 + state->kbytes_sec = kbytes_sec;
  396 +
  397 + strcpy(state->msg,msg);
  398 +
  399 + pulse_stop(state->worker);
  400 + timer_stop(state->worker);
  401 +
  402 + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_complete, state, g_free);
  403 +
  404 + }
  405 +
  406 + static void ft_failed(H3270 G_GNUC_UNUSED(*hSession), unsigned long length, double kbytes_sec, const char *msg, void *widget)
  407 + {
  408 + debug("%s(%p,%s)",__FUNCTION__,widget,msg);
  409 +
  410 + struct bg_complete * state = g_malloc0(sizeof(struct bg_complete)+strlen(msg));
  411 + strcpy(state->msg,msg);
  412 +
  413 + state->worker = GTK_V3270_FT_WORKER(widget);
  414 + state->signal = V3270_WORKER_TRANSFER_FAILED_SIGNAL;
  415 + state->length = length;
  416 + state->kbytes_sec = kbytes_sec;
  417 +
  418 + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_complete, state, g_free);
  419 +
  420 + }
  421 +
  422 + static void ft_message(G_GNUC_UNUSED H3270 *hSession, const char *msg, void *widget)
  423 + {
  424 + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget);
  425 + debug("%s(%p,%s)",__FUNCTION__,worker,msg);
  426 +
  427 + gtk_progress_bar_set_text(worker->pbar,msg);
  428 +
  429 + }
  430 +
  431 + struct bg_update
  432 + {
  433 + V3270FTWorker * worker;
  434 + unsigned long current;
  435 + unsigned long total;
  436 + double kbytes_sec;
  437 + };
  438 +
  439 + static gboolean bg_emit_update(struct bg_update * update)
  440 + {
  441 + // Update values
  442 + gtk_entry_set_text_printf(update->worker->field[PROGRESS_FIELD_CURRENT],"%lu",update->current);
  443 + gtk_entry_set_text_printf(update->worker->field[PROGRESS_FIELD_TOTAL],"%lu",update->total);
  444 +
  445 + if(update->total)
  446 + {
  447 + // Calculate ETA
  448 + double remaining = ((double) (update->total - update->current))/1024.0;
  449 +
  450 + if(remaining > 0 && update->kbytes_sec > 0) {
  451 +
  452 + char buffer[40];
  453 + double seconds = ((double) remaining) / update->kbytes_sec;
  454 + time_t eta = time(NULL) + ((time_t) seconds);
  455 + strftime(buffer, 39, "%H:%M:%S", localtime(&eta));
  456 +
  457 + gtk_entry_set_text(update->worker->field[PROGRESS_FIELD_ETA],buffer);
  458 +
  459 + } else {
  460 +
  461 + gtk_entry_set_text(update->worker->field[PROGRESS_FIELD_ETA],"");
  462 +
  463 + }
  464 +
  465 + if(update->current)
  466 + {
  467 + // Update progress bar
  468 + pulse_stop(update->worker);
  469 + gtk_progress_bar_set_fraction(update->worker->pbar, ((gdouble) update->current) / ((gdouble) update->total));
  470 + }
  471 +
  472 + gtk_entry_set_text_printf(update->worker->field[PROGRESS_FIELD_ETA],"%lu",update->total);
  473 +
  474 + }
  475 +
  476 + return FALSE;
  477 + }
  478 +
  479 + static void ft_update(G_GNUC_UNUSED H3270 *hSession, unsigned long current, unsigned long total, double kbytes_sec, void *widget)
  480 + {
  481 + debug("%s(%p,%p)",__FUNCTION__,widget,widget);
  482 +
  483 + struct bg_update * update = g_new0(struct bg_update,1);
  484 +
  485 + update->worker = GTK_V3270_FT_WORKER(widget);
  486 + update->current = current;
  487 + update->total = total;
  488 + update->kbytes_sec = kbytes_sec;
  489 +
  490 + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_update, update, g_free);
  491 +
  492 + }
  493 +
  494 + static void ft_running(G_GNUC_UNUSED H3270 *hSession, G_GNUC_UNUSED int is_cut, void *widget)
  495 + {
  496 + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget);
  497 + debug("%s(%p,%p)",__FUNCTION__,worker,widget);
  498 +
  499 + // Reset timeout.
  500 + worker->timeout.limit = time(NULL) + worker->timeout.value;
  501 +
  502 + }
  503 +
  504 + static void ft_aborting(G_GNUC_UNUSED H3270 *hSession, const char *reason, void *widget)
  505 + {
  506 + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget);
  507 + debug("%s(%p,%p)",__FUNCTION__,worker,widget);
  508 +
  509 + gtk_progress_bar_set_text(worker->pbar,reason);
  510 +
  511 + }
  512 +
  513 + struct bg_state_changed
  514 + {
  515 + V3270FTWorker * worker;
  516 + LIB3270_FT_STATE st;
  517 + char msg[1];
  518 + };
  519 +
  520 + static gboolean bg_emit_state_changed(struct bg_state_changed * cfg)
  521 + {
  522 + g_signal_emit(cfg->worker, v3270_worker_signals[V3270_WORKER_TRANSFER_STATE_SIGNAL], 0, (guint) cfg->st, cfg->msg);
  523 + return FALSE;
  524 + }
  525 +
  526 + static void ft_state_changed(G_GNUC_UNUSED H3270 *hSession, LIB3270_FT_STATE st, const char *msg, void *widget)
  527 + {
  528 + debug("%s(%p,%s)",__FUNCTION__,widget,msg);
  529 +
  530 + struct bg_state_changed * state = g_malloc0(sizeof(struct bg_state_changed)+strlen(msg)+1);
  531 + state->worker = GTK_V3270_FT_WORKER(widget);
  532 + state->st = st;
  533 + strcpy(state->msg,msg);
  534 +
  535 + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_state_changed, state, g_free);
  536 +
  537 + }
  538 +
  539 +static gboolean do_timer(V3270FTWorker *worker) {
  540 +
  541 + debug("%d",(int) worker->timeout.limit - time(NULL));
  542 +
  543 + if(time(NULL) > worker->timeout.limit) {
  544 +
  545 + // Timeout.
  546 + debug("%s: Transfer timeout",__FUNCTION__);
  547 +
  548 + pulse_stop(worker);
  549 + timer_stop(worker);
  550 +
  551 + const gchar * message = _("Transfer operation has timed out");
  552 +
  553 + if(worker->hSession)
  554 + {
  555 + lib3270_ft_destroy(worker->hSession, message);
  556 + }
  557 + else
  558 + {
  559 + gtk_progress_bar_set_text(worker->pbar,message);
  560 +
  561 + g_signal_emit(
  562 + GTK_WIDGET(worker),
  563 + v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL],
  564 + 0,
  565 + _( "Transfer failed" ),
  566 + message
  567 + );
  568 +
  569 + }
  570 + }
  571 +
  572 + return TRUE;
  573 + }
  574 +
  575 + LIB3270_EXPORT int v3270_ft_worker_start(GtkWidget *widget)
  576 + {
  577 + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget);
  578 +
  579 + if(!(worker->hSession && worker->activity))
  580 + return errno = EINVAL;
  581 +
  582 + const char *message = NULL;
  583 + H3270FT * ft = v3270_ft_activity_begin_transfer(worker->activity, worker->hSession, &message);
  584 +
  585 + if(!ft)
  586 + {
  587 + if(!message)
  588 + message = N_("Can't start file transfer session");
  589 +
  590 + gtk_progress_bar_set_text(worker->pbar,gettext(message));
  591 +
  592 + pulse_stop(worker);
  593 + g_signal_emit(GTK_WIDGET(widget),v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL], 0, gettext(message), NULL);
  594 +
  595 + return -1;
  596 + }
  597 +
  598 + struct lib3270_ft_callbacks * cbk = lib3270_get_ft_callbacks(worker->hSession, sizeof(struct lib3270_ft_callbacks));
  599 +
  600 + if(!cbk) {
  601 +
  602 + gchar *message = _( "Can't set callback table" );
  603 +
  604 + lib3270_ft_destroy(worker->hSession,message);
  605 +
  606 + gtk_progress_bar_set_text(worker->pbar,message);
  607 + pulse_stop(worker);
  608 +
  609 + g_signal_emit(
  610 + GTK_WIDGET(widget),
  611 + v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL],
  612 + 0,
  613 + message,
  614 + _("The callback table for file transfer was rejected, possible version mismatch on lib3270")
  615 + );
  616 +
  617 + return -1;
  618 + }
  619 +
  620 + debug("*************************************worker=%p",widget);
  621 + lib3270_ft_set_user_data(worker->hSession,widget);
  622 +
  623 + cbk->complete = ft_complete;
  624 + cbk->failed = ft_failed;
  625 + cbk->update = ft_update;
  626 + cbk->running = ft_running;
  627 + cbk->aborting = ft_aborting;
  628 + cbk->state_changed = ft_state_changed;
  629 + cbk->message = ft_message;
  630 +
  631 + worker->timeout.limit = time(NULL) + worker->timeout.value;
  632 +
  633 + if(!worker->timeout.timer)
  634 + {
  635 + worker->timeout.timer = g_timeout_source_new_seconds(1);
  636 + g_source_set_callback(worker->timeout.timer,(GSourceFunc) do_timer,worker,NULL);
  637 + g_source_attach(worker->timeout.timer,NULL);
  638 + }
  639 +
  640 + lib3270_ft_start(worker->hSession);
  641 +
  642 + return 0;
  643 + }
  644 +
... ...
src/include/internals.h
... ... @@ -78,6 +78,8 @@
78 78 G_GNUC_INTERNAL void v3270_activity_list_save(GtkWidget *widget);
79 79 G_GNUC_INTERNAL void v3270_activity_list_save_as(GtkWidget *widget);
80 80  
  81 + G_GNUC_INTERNAL void gtk_entry_set_text_printf(GtkEntry *entry, const gchar *fmt, ...);
  82 +
81 83 G_END_DECLS
82 84  
83 85 #endif // V3270_INTERNALS_H_INCLUDED
... ...
src/include/v3270/filetransfer.h
... ... @@ -129,6 +129,7 @@
129 129 LIB3270_EXPORT void v3270_ft_activity_set_remote_filename(GObject *object, const gchar *filename);
130 130 LIB3270_EXPORT void v3270_ft_activity_set_options(GObject * object, LIB3270_FT_OPTION options);
131 131 LIB3270_EXPORT void v3270_ft_activity_set_value(GObject * object, LIB3270_FT_VALUE id, guint value);
  132 + LIB3270_EXPORT H3270FT * v3270_ft_activity_begin_transfer(GObject * object, H3270 *hSession, const char **message);
132 133  
133 134 // FT Dialog widget
134 135 #define GTK_TYPE_V3270_FT_DIALOG (V3270FTDialog_get_type ())
... ... @@ -159,5 +160,7 @@
159 160  
160 161 LIB3270_EXPORT GtkWidget * v3270_ft_worker_new();
161 162 LIB3270_EXPORT void v3270_ft_worker_set_activity(GtkWidget *widget, GObject *activity);
  163 + LIB3270_EXPORT void v3270_ft_worker_set_session(GtkWidget *widget, H3270 *hSession);
  164 + LIB3270_EXPORT int v3270_ft_worker_start(GtkWidget *widget);
162 165  
163 166 #endif // V3270FT_H_INCLUDED
... ...
src/testprogram/testprogram.c
... ... @@ -153,12 +153,17 @@ static void ft_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal)
153 153 GtkWidget * worker = v3270_ft_worker_new();
154 154 gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),worker,TRUE,TRUE,2);
155 155  
  156 + v3270_ft_worker_set_session(worker,v3270_get_session(terminal));
  157 +
156 158 GObject * activity = v3270_ft_activity_new();
157   - v3270_ft_activity_set_local_filename(activity,"local_file");
158   - v3270_ft_activity_set_remote_filename(activity,"remove_file");
  159 + v3270_ft_activity_set_local_filename(activity,"/tmp/test.txt");
  160 + v3270_ft_activity_set_remote_filename(activity,"remote_file");
  161 + v3270_ft_activity_set_options(activity,LIB3270_FT_OPTION_RECEIVE|LIB3270_FT_OPTION_ASCII|LIB3270_FT_OPTION_REMAP);
159 162 v3270_ft_worker_set_activity(worker,activity);
160 163 g_object_unref(activity);
161 164  
  165 + v3270_ft_worker_start(worker);
  166 +
162 167 // GtkWidget * dialog = v3270ftprogress_new();
163 168 // GtkWidget * dialog = v3270_ft_dialog_new(terminal);
164 169  
... ...