From 161a5af516f0be93d79727f9a5b5b92c931bfefc Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Thu, 22 Nov 2012 13:55:38 +0400 Subject: [PATCH 1/3] Ticket #2111: allow pause in copy/move/delete file operation. Initial step: if button callback retuns zero, don't close the dialog after button press. Signed-off-by: Andrew Borodin --- lib/widget/button.c | 10 +++------- lib/widget/button.h | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/widget/button.c b/lib/widget/button.c index 0c1b5fc90..4740f9373 100644 --- a/lib/widget/button.c +++ b/lib/widget/button.c @@ -59,7 +59,6 @@ button_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void * { WButton *b = BUTTON (w); WDialog *h = w->owner; - int stop = 0; int off = 0; switch (msg) @@ -94,13 +93,10 @@ button_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void * if (parm != ' ' && parm != '\n') return MSG_NOT_HANDLED; - if (b->callback != NULL) - stop = b->callback (b, b->action); - if (b->callback == NULL || stop != 0) - { - h->ret_value = b->action; + h->ret_value = b->action; + if (b->callback == NULL || b->callback (b, b->action) != 0) dlg_stop (h); - } + return MSG_HANDLED; case MSG_CURSOR: diff --git a/lib/widget/button.h b/lib/widget/button.h index dccb2b26b..f85be8b3c 100644 --- a/lib/widget/button.h +++ b/lib/widget/button.h @@ -13,6 +13,7 @@ struct WButton; /* button callback */ +/* return 0 to continue work with dialog, non-zero to close */ typedef int (*bcback_fn) (struct WButton * button, int action); /*** enums ***************************************************************************************/ From 68ee80abb86a35c7ca99676149074f2a978d8a2f Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Thu, 22 Nov 2012 13:58:58 +0400 Subject: [PATCH 2/3] Implement pause in copy/move/delete file operation. Signed-off-by: Andrew Borodin Signed-off-by: Slava Zanko --- src/filemanager/filegui.c | 134 +++++++++++++++++++++++++++++------- src/filemanager/fileopctx.h | 6 +- 2 files changed, 114 insertions(+), 26 deletions(-) diff --git a/src/filemanager/filegui.c b/src/filemanager/filegui.c index edfc7c648..63284d3c4 100644 --- a/src/filemanager/filegui.c +++ b/src/filemanager/filegui.c @@ -260,6 +260,24 @@ typedef struct /*** file scope variables ************************************************************************/ +struct +{ + Widget *w; + FileProgressStatus action; + const char *text; + button_flags_t flags; + int len; +} progress_buttons[] = +{ + /* *INDENT-OFF* */ + { NULL, FILE_SKIP, N_("&Skip"), NORMAL_BUTTON, -1 }, + { NULL, FILE_SUSPEND, N_("S&uspend"), NORMAL_BUTTON, -1 }, + { NULL, FILE_SUSPEND, N_("Con&tinue"), NORMAL_BUTTON, -1 }, + { NULL, FILE_ABORT, N_("&Abort"), NORMAL_BUTTON, -1 } + /* *INDENT-ON* */ +}; + +/* --------------------------------------------------------------------------------------------- */ /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -590,6 +608,36 @@ is_wildcarded (char *p) return FALSE; } +/* --------------------------------------------------------------------------------------------- */ + +static void +place_progress_buttons (WDialog * h, gboolean suspended) +{ + const size_t i = suspended ? 2 : 1; + Widget *w = WIDGET (h); + int buttons_width; + + buttons_width = 2 + progress_buttons[0].len + progress_buttons[3].len; + buttons_width += progress_buttons[i].len; + button_set_text (BUTTON (progress_buttons[i].w), progress_buttons[i].text); + + progress_buttons[0].w->x = w->x + (w->cols - buttons_width) / 2; + progress_buttons[i].w->x = progress_buttons[0].w->x + progress_buttons[0].len + 1; + progress_buttons[3].w->x = progress_buttons[i].w->x + progress_buttons[i].len + 1; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +progress_start_stop (WButton * button, int action) +{ + (void) button; + (void) action; + + /* don't close dialog in any case */ + return 0; +} + /* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -605,29 +653,37 @@ check_progress_buttons (FileOpContext * ctx) ui = ctx->ui; + get_event: event.x = -1; /* Don't show the GPM cursor */ - c = tty_get_event (&event, FALSE, FALSE); + c = tty_get_event (&event, FALSE, ctx->suspended); if (c == EV_NONE) return FILE_CONT; - /* Reinitialize to avoid old values after events other than - selecting a button */ + /* Reinitialize to avoid old values after events other than selecting a button */ ui->op_dlg->ret_value = FILE_CONT; dlg_process_event (ui->op_dlg, c, &event); switch (ui->op_dlg->ret_value) { case FILE_SKIP: + ctx->suspended = FALSE; return FILE_SKIP; case B_CANCEL: case FILE_ABORT: + ctx->suspended = FALSE; return FILE_ABORT; + case FILE_SUSPEND: + ctx->suspended = !ctx->suspended; + place_progress_buttons (ui->op_dlg, ctx->suspended); + dlg_redraw (ui->op_dlg); + /* fallthrough */ default: + if (ctx->suspended) + goto get_event; return FILE_CONT; } } - /* --------------------------------------------------------------------------------------------- */ /* {{{ File progress display routines */ @@ -636,28 +692,23 @@ file_op_context_create_ui (FileOpContext * ctx, gboolean with_eta, filegui_dialog_type_t dialog_type) { FileOpContextUI *ui; - - const char *abort_button_label = N_("&Abort"); - const char *skip_button_label = N_("&Skip"); - int abort_button_width, skip_button_width, buttons_width; - int dlg_width, dlg_height; + int buttons_width; + int dlg_width = 58, dlg_height = 17; int y = 2, x = 3; - Widget *skip_button; g_return_if_fail (ctx != NULL); g_return_if_fail (ctx->ui == NULL); #ifdef ENABLE_NLS - abort_button_label = _(abort_button_label); - skip_button_label = _(skip_button_label); + if (progress_buttons[0].len == -1) + { + size_t i; + + for (i = 0; i < G_N_ELEMENTS (progress_buttons); i++) + progress_buttons[i].text = _(progress_buttons[i].text); + } #endif - abort_button_width = str_term_width1 (abort_button_label) + 3; - skip_button_width = str_term_width1 (skip_button_label) + 3; - buttons_width = abort_button_width + skip_button_width + 1; - - dlg_width = max (58, buttons_width + 6); - dlg_height = 17; /* will be adjusted later */ ctx->dialog_type = dialog_type; ctx->recursive_result = RECURSIVE_YES; @@ -716,17 +767,50 @@ file_op_context_create_ui (FileOpContext * ctx, gboolean with_eta, add_widget (ui->op_dlg, hline_new (y++, -1, -1)); - x = (dlg_width - buttons_width) / 2; - skip_button = WIDGET (button_new (y, x, FILE_SKIP, NORMAL_BUTTON, skip_button_label, NULL)); - add_widget (ui->op_dlg, skip_button); + progress_buttons[0].w = WIDGET (button_new (y, 0, progress_buttons[0].action, + progress_buttons[0].flags, progress_buttons[0].text, + NULL)); + if (progress_buttons[0].len == -1) + progress_buttons[0].len = button_get_len (BUTTON (progress_buttons[0].w)); - x += skip_button_width + 1; - add_widget (ui->op_dlg, button_new (y, x, FILE_ABORT, NORMAL_BUTTON, abort_button_label, NULL)); + progress_buttons[1].w = WIDGET (button_new (y, 0, progress_buttons[1].action, + progress_buttons[1].flags, progress_buttons[1].text, + progress_start_stop)); + if (progress_buttons[1].len == -1) + progress_buttons[1].len = button_get_len (BUTTON (progress_buttons[1].w)); - /* adjust dialog height */ + if (progress_buttons[2].len == -1) + { + /* create and destroy button to get it length */ + progress_buttons[2].w = WIDGET (button_new (y, 0, progress_buttons[2].action, + progress_buttons[2].flags, + progress_buttons[2].text, progress_start_stop)); + progress_buttons[2].len = button_get_len (BUTTON (progress_buttons[2].w)); + send_message (progress_buttons[2].w, NULL, MSG_DESTROY, 0, NULL); + g_free (progress_buttons[2].w); + } + progress_buttons[2].w = progress_buttons[1].w; + + progress_buttons[3].w = WIDGET (button_new (y, 0, progress_buttons[3].action, + progress_buttons[3].flags, progress_buttons[3].text, + NULL)); + if (progress_buttons[3].len == -1) + progress_buttons[3].len = button_get_len (BUTTON (progress_buttons[3].w)); + + add_widget (ui->op_dlg, progress_buttons[0].w); + add_widget (ui->op_dlg, progress_buttons[1].w); + add_widget (ui->op_dlg, progress_buttons[3].w); + + buttons_width = 2 + + progress_buttons[0].len + max (progress_buttons[1].len, progress_buttons[2].len) + + progress_buttons[3].len; + + /* adjust dialog sizes */ dlg_set_size (ui->op_dlg, y + 3, dlg_width); - dlg_select_widget (skip_button); + place_progress_buttons (ui->op_dlg, FALSE); + + dlg_select_widget (progress_buttons[0].w); /* We will manage the dialog without any help, that's why we have to call init_dlg */ diff --git a/src/filemanager/fileopctx.h b/src/filemanager/fileopctx.h index 923084443..b1af1887f 100644 --- a/src/filemanager/fileopctx.h +++ b/src/filemanager/fileopctx.h @@ -58,7 +58,8 @@ typedef enum FILE_RETRY = 1, FILE_SKIP = 2, FILE_ABORT = 3, - FILE_SKIPALL = 4 + FILE_SKIPALL = 4, + FILE_SUSPEND = 5 } FileProgressStatus; /* First argument passed to real functions */ @@ -160,6 +161,9 @@ typedef struct FileOpContext /* toggle if all errors should be ignored */ gboolean skip_all; + /* Whether the file operation is in pause */ + gboolean suspended; + /* User interface data goes here */ void *ui; } FileOpContext; From 9862323d111e32e4823d17a9f7ab316aea151598 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Thu, 22 Nov 2012 14:18:34 +0400 Subject: [PATCH 3/3] src/filemanager/find.c: unify i18n resource (button name). Signed-off-by: Andrew Borodin --- src/filemanager/find.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filemanager/find.c b/src/filemanager/find.c index 2aea14d5f..02aa1d071 100644 --- a/src/filemanager/find.c +++ b/src/filemanager/find.c @@ -185,7 +185,7 @@ static struct { { B_ENTER, DEFPUSH_BUTTON, N_("&Chdir"), 0, 0, NULL, NULL }, { B_AGAIN, NORMAL_BUTTON, N_("&Again"), 0, 0, NULL, NULL }, - { B_STOP, NORMAL_BUTTON, N_("&Suspend"), 0, 0, NULL, start_stop }, + { B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop }, { B_STOP, NORMAL_BUTTON, N_("Con&tinue"), 0, 0, NULL, NULL }, { B_CANCEL, NORMAL_BUTTON, N_("&Quit"), 0, 0, NULL, NULL },