From 21b256b8057776dc7ea9be44a25c6d222d406f26 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Tue, 14 Jul 2026 18:49:36 +0200 Subject: [PATCH] Harden URL list handling and add keyboard actions --- CMakeLists.txt | 2 +- README | 2 ++ src/main.cpp | 82 +++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 169fef0..e161ebf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) -project(prozgui VERSION 2.4.0 LANGUAGES C CXX) +project(prozgui VERSION 2.4.1 LANGUAGES C CXX) include(GNUInstallDirs) find_package(Threads REQUIRED) diff --git a/README b/README index 2cd7d4c..724061a 100644 --- a/README +++ b/README @@ -14,6 +14,8 @@ Supports HTTP including redirection. Supports dragging URLs, newline-separated URL lists, and local URL-list files onto the main window. Supports pasting one or more URLs into the main window with Ctrl+V. +In the saved download list, Enter starts the selected URL and Delete or +Backspace removes it. Selects a suitable FLTK appearance for GNOME/MATE and KDE automatically; set FLTK_SCHEME to override the automatic choice. Proxy servers supported. diff --git a/src/main.cpp b/src/main.cpp index 960091e..3c71257 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -114,6 +114,29 @@ public: }; +class Download_Browser:public Fl_Hold_Browser { +public: + Download_Browser(int x, int y, int w, int h):Fl_Hold_Browser(x, y, w, h) {} + + int handle(int event) override + { + if (event == FL_KEYDOWN && value() > 0) + { + if (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter) + { + menu_download_start(); + return 1; + } + if (Fl::event_key() == FL_Delete || Fl::event_key() == FL_BackSpace) + { + menu_download_remove(); + return 1; + } + } + return Fl_Hold_Browser::handle(event); + } +}; + Main_Window::Main_Window(int w, int h, const char *l):Fl_Window(w, h, l) { @@ -229,12 +252,12 @@ void open_new_dl_win(urlinfo * url_data, boolean ftpsearch) num_dl_wins++; dl_wins = (DL_Window **) realloc(dl_wins, - (sizeof(DL_Window **) * num_dl_wins)); + (sizeof(*dl_wins) * num_dl_wins)); dl_wins[num_dl_wins - 1] = new DL_Window(url_data, FL_DOWN_BOX, 70, 70, ""); - dl_wins[num_dl_wins - 1]->label(strdup(url_data->url)); + dl_wins[num_dl_wins - 1]->copy_label(url_data->url); dl_wins[num_dl_wins - 1]->show(); @@ -260,6 +283,14 @@ void open_new_dl_win(urlinfo * url_data, boolean ftpsearch) namespace { +void discard_url(urlinfo *url) +{ + if (!url) + return; + proz_free_url(url, 0); + free(url); +} + std::string trim(const std::string &value) { const std::string::size_type first = value.find_first_not_of(" \t\r\n"); @@ -334,8 +365,7 @@ bool start_dropped_url(const std::string &url) if (proz_parse_url(url.c_str(), url_data, 0) != URLOK || strlen(url_data->file) == 0) { - proz_free_url(url_data, 0); - free(url_data); + discard_url(url_data); return false; } @@ -343,8 +373,7 @@ bool start_dropped_url(const std::string &url) { if (strcmp(url_data->url, browser->text(i + 1)) == 0) { - proz_free_url(url_data, 0); - free(url_data); + discard_url(url_data); return false; } } @@ -440,6 +469,7 @@ void cb_url_input_ok(Fl_Return_Button * button, void *data) if (err != URLOK) { fl_message(_("%s does not seem to be a valid URL"), in_url->value()); + discard_url(url_data); return; } @@ -450,6 +480,7 @@ void cb_url_input_ok(Fl_Return_Button * button, void *data) if(strcmp(url_data->url, browser->text(i+1))==0) { fl_message(_("%s is already in the list of downloads"), in_url->value()); + discard_url(url_data); return; } } @@ -464,6 +495,7 @@ void cb_url_input_ok(Fl_Return_Button * button, void *data) dl_wins[i]->status!=DL_IDLING) { fl_message(_("%s is already running!"), in_url->value()); + discard_url(url_data); return; } } @@ -474,6 +506,7 @@ void cb_url_input_ok(Fl_Return_Button * button, void *data) fl_message(_ ("%s contains just a hostname, it does not contain a file to download!"), url_data->url); + discard_url(url_data); return; } @@ -523,13 +556,20 @@ void cb_main_win(Fl_Window * widget, void *) void menu_download_start() { int select=browser->value(); + if (select <= 0 || select > browser->size()) + return; + + const char *selected_url = browser->text(select); + if (!selected_url) + return; + boolean running=FALSE; int i; /*Search and se eif DL is in list */ for ( i = 0; i < num_dl_wins; i++) { - if(strcmp(dl_wins[i]->u.url, browser->text(select))==0) + if(strcmp(dl_wins[i]->u.url, selected_url)==0) { if(dl_wins[i]->status!= DL_ABORTED && dl_wins[i]->status!=DL_FATALERR && @@ -552,10 +592,11 @@ void menu_download_start() url_data = (urlinfo *) malloc(sizeof(urlinfo)); memset(url_data, 0, sizeof(urlinfo)); - err = proz_parse_url(browser->text(select), url_data, 0); + err = proz_parse_url(selected_url, url_data, 0); if (err != URLOK) { - fl_message(_("%s does not seem to be a valid URL"), in_url->value()); + fl_message(_("%s does not seem to be a valid URL"), selected_url); + discard_url(url_data); return; } @@ -564,6 +605,7 @@ void menu_download_start() fl_message(_ ("%s contains just a hostname, it does not contain a file to download!"), url_data->url); + discard_url(url_data); return; } @@ -573,12 +615,13 @@ void menu_download_start() void menu_download_stop() { - int select=browser->value(); } void menu_download_remove() { int select=browser->value(); + if (select <= 0 || select > browser->size()) + return; browser->remove(select); menuitems[6].deactivate(); menuitems[7].deactivate(); @@ -680,7 +723,7 @@ int main(int argc, char **argv) drop_hint->labelcolor(FL_DARK3); /*The browser window */ - browser = new Fl_Hold_Browser(2, 250, 495, 80); + browser = new Download_Browser(2, 250, 495, 80); browser->callback(browser_cb); load_savefile(browser); rt.prefs_win = make_prefs_win(); @@ -701,9 +744,20 @@ int main(int argc, char **argv) err = proz_parse_url(argv[i], url_data, 0); if (err != URLOK) { - printf(_("%s does not seem to be a valid URL"), argv[optind]); - proz_debug("%s does not seem to be a valid URL", argv[optind]); - exit(0); + fprintf(stderr, _("%s does not seem to be a valid URL"), argv[i]); + fputc('\n', stderr); + proz_debug("%s does not seem to be a valid URL", argv[i]); + discard_url(url_data); + continue; + } + if (strlen(url_data->file) == 0) + { + fprintf(stderr, + _("%s contains just a hostname, it does not contain a file to download!"), + url_data->url); + fputc('\n', stderr); + discard_url(url_data); + continue; } open_new_dl_win(url_data,rt.use_ftpsearch);