experimental cancel on upload
This commit is contained in:
+56
-2
@@ -110,6 +110,7 @@ void file_download(file_args_t *f_args, query_args_t *q_args) {
|
||||
fl_item_t *f_selected = &(f_args->f_selected);
|
||||
static int32_t it_count = 0;
|
||||
static size_t it_interval = 0;
|
||||
|
||||
if (it_interval == 0) {
|
||||
it_interval = (f_selected->size / INBUFSIZE / 100) * 5; /* every 1% */
|
||||
if (it_interval == 0)
|
||||
@@ -161,6 +162,7 @@ void file_download(file_args_t *f_args, query_args_t *q_args) {
|
||||
int32_t file_upload_open(char *dpath, char *fname, query_args_t *q_args) {
|
||||
q_args->file = malloc(sizeof(p_file_t));
|
||||
q_args->file->path = malloc(strlen(dpath) + strlen(fname) + 2);
|
||||
q_args->file->signal = sig_continue;
|
||||
sprintf(q_args->file->path, "%s/%s", dpath, fname);
|
||||
int fd = open(q_args->file->path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
@@ -192,6 +194,8 @@ int32_t file_upload_start(query_args_t *q_args) {
|
||||
int32_t file_upload(query_args_t *q_args) {
|
||||
static int32_t it_count = 0;
|
||||
static size_t it_interval = 0;
|
||||
static int package_rest = 0;
|
||||
int send_len = q_args->buf_used;
|
||||
if (it_interval == 0) {
|
||||
it_interval = (q_args->file->size / INBUFSIZE / 100) * 5; /* every 1% */
|
||||
if (it_interval == 0)
|
||||
@@ -201,10 +205,30 @@ int32_t file_upload(query_args_t *q_args) {
|
||||
(q_args->file->size - q_args->file->rest) * 100 / q_args->file->size;
|
||||
w_pgb_ui_t *pb = (w_pgb_ui_t *)q_args->progress_bar;
|
||||
w_dialogue_t *d = (w_dialogue_t *)q_args->active_dialogue;
|
||||
|
||||
if (package_rest == 0) {
|
||||
if (q_args->file->signal == sig_cancel) {
|
||||
/* reset function before exit */
|
||||
it_count = 0;
|
||||
it_interval = 0;
|
||||
return -2;
|
||||
}
|
||||
package_rest = PACKAGE_SIZE;
|
||||
s_file_pd_t fpd = {.signal = q_args->file->signal,
|
||||
.package_size = package_rest};
|
||||
write(q_args->sd, &fpd, sizeof(s_file_pd_t));
|
||||
} else if (package_rest < send_len) {
|
||||
send_len = package_rest;
|
||||
}
|
||||
|
||||
if (q_args->buf_used > 0) {
|
||||
int wlen = write(q_args->sd, q_args->buf, q_args->buf_used);
|
||||
int wlen = write(q_args->sd, q_args->buf, send_len);
|
||||
if (q_args->buf_used != wlen) {
|
||||
/* TODO: ошибка */
|
||||
/* reset function before exit */
|
||||
it_count = 0;
|
||||
it_interval = 0;
|
||||
package_rest = 0;
|
||||
return -1;
|
||||
} else {
|
||||
it_count++;
|
||||
@@ -212,13 +236,43 @@ int32_t file_upload(query_args_t *q_args) {
|
||||
pb->procent = progress;
|
||||
d->needs_update = true;
|
||||
}
|
||||
q_args->file->rest -= wlen;
|
||||
package_rest -= wlen;
|
||||
if (package_rest == 0) {
|
||||
if (q_args->file->signal == sig_cancel) {
|
||||
/* reset function before exit */
|
||||
it_count = 0;
|
||||
it_interval = 0;
|
||||
return -2;
|
||||
}
|
||||
package_rest = PACKAGE_SIZE;
|
||||
s_file_pd_t fpd = {.signal = q_args->file->signal,
|
||||
.package_size = package_rest};
|
||||
write(q_args->sd, &fpd, sizeof(s_file_pd_t));
|
||||
/* send the rest */
|
||||
if (q_args->buf_used > send_len) {
|
||||
wlen = write(q_args->sd, q_args->buf + send_len,
|
||||
q_args->buf_used - send_len);
|
||||
if (q_args->buf_used != wlen) {
|
||||
/* TODO: ошибка */
|
||||
/* reset function before exit */
|
||||
it_count = 0;
|
||||
it_interval = 0;
|
||||
package_rest = 0;
|
||||
return -1;
|
||||
}
|
||||
q_args->file->rest -= wlen;
|
||||
package_rest -= wlen;
|
||||
}
|
||||
}
|
||||
q_args->buf[0] = 0;
|
||||
q_args->buf_used = 0;
|
||||
q_args->file->rest -= wlen;
|
||||
}
|
||||
} else {
|
||||
/* reset function before exit */
|
||||
it_count = 0;
|
||||
it_interval = 0;
|
||||
package_rest = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#ifndef FILE_PROCESSOR_H
|
||||
#define FILE_PROCESSOR_H
|
||||
|
||||
#include "main.h"
|
||||
|
||||
void file_list(file_args_t *f_args, query_args_t *q_args);
|
||||
|
||||
+15
-6
@@ -17,6 +17,7 @@
|
||||
#define DIALOGUE_TITLE 64
|
||||
#define DIALOGUE_TEXT 4096
|
||||
#define INPUT_TEXT DIALOGUE_TITLE
|
||||
#define PACKAGE_SIZE INBUFSIZE * 10
|
||||
|
||||
typedef struct params {
|
||||
unsigned short port;
|
||||
@@ -59,12 +60,20 @@ enum state {
|
||||
WAIT_CLIENT,
|
||||
};
|
||||
|
||||
enum package_signal { sig_continue, sig_cancel, sig_finish, sig_pause };
|
||||
|
||||
typedef struct {
|
||||
enum package_signal signal;
|
||||
size_t package_size;
|
||||
} s_file_pd_t; /* file package descriptor */
|
||||
|
||||
typedef struct p_file {
|
||||
char *name;
|
||||
char *path;
|
||||
char *description;
|
||||
size_t size;
|
||||
size_t rest;
|
||||
enum package_signal signal;
|
||||
int fd;
|
||||
} p_file_t;
|
||||
|
||||
@@ -85,18 +94,18 @@ typedef struct file_args {
|
||||
|
||||
enum main_window_type {
|
||||
mw_fl_server, /* file list on the server */
|
||||
mw_fl_local, /* local file list */
|
||||
mw_f_desc, /* file description */
|
||||
mw_fl_local, /* local file list */
|
||||
mw_f_desc, /* file description */
|
||||
};
|
||||
|
||||
typedef void (draw_f_t) (void *fui) ;
|
||||
typedef void(draw_f_t)(void *fui);
|
||||
|
||||
typedef struct main_window {
|
||||
enum main_window_type type;
|
||||
void *ui; /* structure which describes window UI */
|
||||
int32_t (*cb_b_press) (void *app, void *args); /* callback on button press */
|
||||
void (*cb_ui_refresh) (void *app); /* refresh callback */
|
||||
void (*reset) (void *app); /* reset state of the window */
|
||||
int32_t (*cb_b_press)(void *app, void *args); /* callback on button press */
|
||||
void (*cb_ui_refresh)(void *app); /* refresh callback */
|
||||
void (*reset)(void *app); /* function to reset the state of the window */
|
||||
draw_f_t *draw;
|
||||
struct action_key *b_keys;
|
||||
int32_t b_keys_len;
|
||||
|
||||
+17
-7
@@ -1,11 +1,17 @@
|
||||
#include "group.h"
|
||||
#include <widget.h>
|
||||
#include <ncursesw/ncurses.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <widget.h>
|
||||
|
||||
void dwn_pr_modal_cb(w_cb_args_t *args) {
|
||||
/* TODO: cancel action */
|
||||
/* only cancel action */
|
||||
int32_t key = *((int32_t *)args->data);
|
||||
if (key != '\n') {
|
||||
return;
|
||||
}
|
||||
app_t *app = args->app;
|
||||
app->query_args->file->signal = sig_cancel;
|
||||
}
|
||||
|
||||
w_dialogue_t *m_load_pr_init(app_t *app, bool is_upload) {
|
||||
@@ -17,18 +23,22 @@ w_dialogue_t *m_load_pr_init(app_t *app, bool is_upload) {
|
||||
|
||||
char text[256];
|
||||
sprintf(text, "%s file: %s", is_upload ? "Uploading" : "Downloading",
|
||||
is_upload ? app->query_args->file->name : app->file_args->f_selected.name);
|
||||
is_upload ? app->query_args->file->name
|
||||
: app->file_args->f_selected.name);
|
||||
w_group_el_init_t actions[] = {
|
||||
{.type = w_button, .label = "Cancel", .is_default = true, .val.num = 1}, {.type = w_end}};
|
||||
{.type = w_button, .label = "Cancel", .is_default = true, .val.num = 1},
|
||||
{.type = w_end}};
|
||||
|
||||
app->modal.w.parent_win = &app->win;
|
||||
w_dialogue_init(&(app->modal), is_upload ? "Upload" : "Download", text,
|
||||
&(app->coordinates));
|
||||
&(app->coordinates));
|
||||
w_dialogue_t *d = &(app->modal);
|
||||
|
||||
d->w.callback = dwn_pr_modal_cb;
|
||||
d->g_content = w_group_init(&(d->win), &(d->w), content, &(d->id_map), horizontal, g_content);
|
||||
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map), horizontal, g_action);
|
||||
d->g_content = w_group_init(&(d->win), &(d->w), content, &(d->id_map),
|
||||
horizontal, g_content);
|
||||
d->g_action = w_group_init(&(d->win), &(d->w), actions, &(d->id_map),
|
||||
horizontal, g_action);
|
||||
|
||||
app->query_args->progress_bar = d->g_content->elements[0].element;
|
||||
app->query_args->active_dialogue = d;
|
||||
|
||||
+16
-5
@@ -45,6 +45,13 @@ int32_t process_user_input(app_t *app, w_cb_args_t *d_args);
|
||||
app_destroy(app, exit_code); \
|
||||
}
|
||||
|
||||
#define FILE_CLEAN(app) \
|
||||
if (app->query_args->file != NULL) { \
|
||||
FREE_MLC(app->query_args->file->name); \
|
||||
FREE_MLC(app->query_args->file->path); \
|
||||
FREE_MLC(app->query_args->file); \
|
||||
}
|
||||
|
||||
void query_loop(app_t *app) {
|
||||
query_args_t *query_args = app->query_args;
|
||||
fd_set readfds;
|
||||
@@ -183,11 +190,7 @@ int process_query(app_t *app) {
|
||||
if (!file_upload_start(query_args)) {
|
||||
query_args->state = S_UPLOAD_FILE;
|
||||
} else {
|
||||
if (app->query_args->file != NULL) {
|
||||
FREE_MLC(app->query_args->file->name);
|
||||
FREE_MLC(app->query_args->file->path)
|
||||
FREE_MLC(app->query_args->file);
|
||||
}
|
||||
FILE_CLEAN(app);
|
||||
query_args->state = WAIT_CLIENT;
|
||||
}
|
||||
break;
|
||||
@@ -198,6 +201,14 @@ int process_query(app_t *app) {
|
||||
query_args->state = S_UPLOAD_SERVER_FINISHES;
|
||||
} else if (res == -1) {
|
||||
/* TODO: Error */
|
||||
} else if (res == -2) {
|
||||
/* cancel case */
|
||||
w_notification("Alert", dc_alert, "File %s didn't upload!",
|
||||
query_args->file->name);
|
||||
FILE_CLEAN(app);
|
||||
w_dialogue_t *d = &(app->modal);
|
||||
d->needs_destroy = true;
|
||||
query_args->state = WAIT_CLIENT;
|
||||
}
|
||||
break;
|
||||
case S_UPLOAD_SERVER_FINISHES:
|
||||
|
||||
+5
-11
@@ -136,18 +136,12 @@ void w_dialogue_callback_default(w_cb_args_t *args) {
|
||||
}
|
||||
break;
|
||||
case KEY_UP:
|
||||
if (d->active_el->g_type == g_content &&
|
||||
d->g_content->direction == vertical) {
|
||||
decr_active_id(d);
|
||||
args->resp_data.code = cbrc_none;
|
||||
}
|
||||
decr_active_id(d);
|
||||
args->resp_data.code = cbrc_none;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (d->active_el->g_type == g_content &&
|
||||
d->g_content->direction == vertical) {
|
||||
incr_active_id(d);
|
||||
args->resp_data.code = cbrc_none;
|
||||
}
|
||||
incr_active_id(d);
|
||||
args->resp_data.code = cbrc_none;
|
||||
break;
|
||||
default:
|
||||
/* run callback function */
|
||||
@@ -329,7 +323,7 @@ void w_dialogue_destroy(w_dialogue_t *d, void *_app) {
|
||||
}
|
||||
delwin(d->win);
|
||||
d->win = NULL;
|
||||
d->is_initiated = 0;
|
||||
d->is_initiated = false;
|
||||
d->needs_destroy = false;
|
||||
app->active_callback = (w_cb_t)app->main_ui.cb_b_press;
|
||||
app->query_args->active_dialogue = NULL;
|
||||
|
||||
+7
-7
@@ -5,8 +5,8 @@
|
||||
#define W_INPUT_H
|
||||
|
||||
#include "../main.h"
|
||||
#include <widget_core.h>
|
||||
#include <stdint.h>
|
||||
#include <widget_core.h>
|
||||
|
||||
typedef struct {
|
||||
w_t w;
|
||||
@@ -18,11 +18,11 @@ typedef struct {
|
||||
bool is_hidden;
|
||||
} w_input_t;
|
||||
|
||||
bool w_input_default_key_action(w_cb_args_t *args);
|
||||
w_input_t *w_input_init(WINDOW **win, w_t *w_parent, char *label,
|
||||
int32_t size, int32_t is_hidden_value);
|
||||
int32_t w_input_draw(w_input_t *input, int32_t active_id);
|
||||
void w_input_destroy(w_input_t *input);
|
||||
char *w_input_get_value(w_input_t *input);
|
||||
bool w_input_default_key_action(w_cb_args_t *args);
|
||||
w_input_t *w_input_init(WINDOW **win, w_t *w_parent, char *label, int32_t size,
|
||||
int32_t is_hidden_value);
|
||||
int32_t w_input_draw(w_input_t *input, int32_t active_id);
|
||||
void w_input_destroy(w_input_t *input);
|
||||
char *w_input_get_value(w_input_t *input);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user