summaryrefslogtreecommitdiff
path: root/gtk/gtk_download.c
diff options
context:
space:
mode:
authorRob Kendrick <rjek@netsurf-browser.org>2008-07-26 17:30:26 +0000
committerRob Kendrick <rjek@netsurf-browser.org>2008-07-26 17:30:26 +0000
commite894e38c37e8565c3672b1a9bde42fb5e0648aeb (patch)
tree827c4b68934b6eca60cb9fb95d318da91273a89e /gtk/gtk_download.c
parent7ae05a60ae7f12774bfea3efc57938c97d6b7c1f (diff)
downloadnetsurf-e894e38c37e8565c3672b1a9bde42fb5e0648aeb.tar.gz
netsurf-e894e38c37e8565c3672b1a9bde42fb5e0648aeb.tar.bz2
Merged revisions 4282-4285,4288-4293,4297-4298,4307,4309-4313,4322,4324-4431,4434-4494,4500-4508,4515,4517,4525-4545,4548-4555,4558-4572,4574-4576,4579,4582-4615,4618-4628,4630-4634,4636-4641,4643-4654,4656-4675,4677,4679-4685,4687-4750 via svnmerge from
svn://svn.netsurf-browser.org/branches/mikeL/netsurf ........ r4689 | mikeL | 2008-07-17 19:59:20 +0100 (Thu, 17 Jul 2008) | 1 line Changed the toolbar at the bottom of the downloads dialog to a horizontal button box and added a 'Close' button (Based on a suggestion from the dev list). Internationalized the rest of the strings. Fixed many style errors (thanks rjek). Set authentication fields in the options dialog to be insensitive when proxy type is simple. Namespace'd the rest of download.h ........ r4690 | mikeL | 2008-07-17 21:39:39 +0100 (Thu, 17 Jul 2008) | 1 line Removed close button. fixed text on resume button ........ r4691 | mikeL | 2008-07-17 22:13:13 +0100 (Thu, 17 Jul 2008) | 1 line Added gtk downloads section ........ r4715 | mikeL | 2008-07-20 19:41:39 +0100 (Sun, 20 Jul 2008) | 1 line Downloads are now automatically sorted (Downloading, Error'd, Completed, Canceled). New downloads appear at the beginning of the list. Removed leftover callback for close button. Downloads without a known total size are now handled correctly (bouncing progress block). Fixed bug where shift+click downloads would throw an error (encoding is now always set to binary). ........ r4716 | mikeL | 2008-07-20 19:45:24 +0100 (Sun, 20 Jul 2008) | 1 line Removed unnecessary wndDownloads section ........ r4717 | mikeL | 2008-07-20 19:53:44 +0100 (Sun, 20 Jul 2008) | 1 line Removed label on url in about dialog. Removed extra variable from the input callback. These changes should have already been committed a while back but for some reason they were skipped ........ r4718 | mikeL | 2008-07-21 04:56:28 +0100 (Mon, 21 Jul 2008) | 1 line Total progress bar is now working and acts correctly with downloads of unknown size. All downloads are now stored in a GList (this will later make it possible to implement things like clearing all inactive downloads). Individual downloads no longer update themselves every .5 seconds, the function nsgtk_download_update is called using a g_timeout and cycles through the GList updating the total progress bar and each download. Downloads of unknown size now report their total size upon completion. ........ r4719 | mikeL | 2008-07-21 05:06:17 +0100 (Mon, 21 Jul 2008) | 1 line Changed names of two functions that change sensitivity and status. ........ r4720 | mikeL | 2008-07-21 16:56:41 +0100 (Mon, 21 Jul 2008) | 1 line Updated messages file ........ r4722 | mikeL | 2008-07-21 21:44:23 +0100 (Mon, 21 Jul 2008) | 1 line Clear button now clears all inactive downloads when there is no selection. ........ r4723 | mikeL | 2008-07-21 22:11:00 +0100 (Mon, 21 Jul 2008) | 1 line Fixed the total progress bar lagging behind events such as cancelations. ........ r4727 | mikeL | 2008-07-23 19:33:53 +0100 (Wed, 23 Jul 2008) | 1 line Added an overwrite confirmation dialog for the 'save' button ........ r4728 | mikeL | 2008-07-23 19:43:44 +0100 (Wed, 23 Jul 2008) | 1 line Save as dialog now starts in the default download directory instead of the user's home folder ........ r4729 | mikeL | 2008-07-23 20:02:34 +0100 (Wed, 23 Jul 2008) | 1 line Updated Copyright information ........ r4734 | mikeL | 2008-07-24 19:30:12 +0100 (Thu, 24 Jul 2008) | 1 line Fixed Info column not being set to expand ........ svn path=/trunk/netsurf/; revision=4752
Diffstat (limited to 'gtk/gtk_download.c')
-rw-r--r--gtk/gtk_download.c482
1 files changed, 327 insertions, 155 deletions
diff --git a/gtk/gtk_download.c b/gtk/gtk_download.c
index e84b6d2fd..6657ce1fc 100644
--- a/gtk/gtk_download.c
+++ b/gtk/gtk_download.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Rob Kendrick <rjek@netsurf-browser.org>
+ * Copyright 2008 Michael Lester <element3260@gmail.com>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -30,43 +30,51 @@
#include "gtk/options.h"
#include "gtk/gtk_download.h"
+#define UPDATE_RATE 500 /* In milliseconds */
#define GLADE_NAME "downloads.glade"
static GtkWindow *nsgtk_download_window, *nsgtk_download_parent;
-static GtkWidget *nsgtk_download_progressBar;
+static GtkProgressBar *nsgtk_download_progress_bar;
static GtkTreeView *nsgtk_download_tree;
static GtkListStore *nsgtk_download_store;
static GtkTreeSelection *nsgtk_download_selection;
static GtkTreeIter nsgtk_download_iter;
-static GList *nsgtk_download_buttons;
-static gint nsgtk_downloads;
-gchar* status_messages[] = { "gtkWorking", "gtkError", "gtkComplete",
- "gtkCanceled" };
-static gboolean nsgtk_download_hide (GtkWidget *window);
+static GTimer *nsgtk_downloads_timer;
+static GList *nsgtk_downloads_list, *nsgtk_download_buttons;
+static gint nsgtk_downloads_num_active;
+static gchar* status_messages[] = { NULL, "gtkWorking", "gtkError",
+ "gtkComplete", "gtkCanceled" };
+
+static gboolean nsgtk_download_hide(GtkWidget *window);
static GtkTreeView *nsgtk_download_tree_view_new(GladeXML *gladeFile);
static void nsgtk_download_tree_view_row_activated(GtkTreeView *tree,
GtkTreePath *path, GtkTreeViewColumn *column, gpointer data);
+static gint nsgtk_download_sort(GtkTreeModel *model, GtkTreeIter *a,
+ GtkTreeIter *b, gpointer userdata);
+static gboolean nsgtk_download_update(gboolean force_update);
+static void nsgtk_download_do(nsgtk_download_selection_action action);
+
static void nsgtk_download_store_update_item(struct gui_download_window *dl);
static void nsgtk_download_store_create_item (struct gui_download_window *dl);
static void nsgtk_download_store_clear_item (struct gui_download_window *dl);
static void nsgtk_download_store_cancel_item (struct gui_download_window *dl);
-static void nsgtk_download_selection_do(GtkWidget *button,
- selection_action action);
-
-static void nsgtk_download_sensitivity_set(struct gui_download_window *dl,
- nsgtk_download_actions sensitivity);
-static void nsgtk_download_sensitivity_selection_changed(
+static void nsgtk_download_sensitivity_evaluate(
GtkTreeSelection *selection);
static void nsgtk_download_sensitivity_update_buttons(
nsgtk_download_actions sensitivity);
+
+static void nsgtk_download_change_sensitivity(
+ struct gui_download_window *dl, nsgtk_download_actions sens);
+static void nsgtk_download_change_status (
+ struct gui_download_window *dl, nsgtk_download_status status);
static gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain,
- gchar *size);
+ const gchar *size);
static gchar* nsgtk_download_info_to_string (struct gui_download_window *dl);
static gchar* nsgtk_download_time_to_string (gint seconds);
static gboolean nsgtk_download_handle_error (GError *error);
@@ -81,8 +89,8 @@ void nsgtk_download_init()
nsgtk_download_buttons =
glade_xml_get_widget_prefix(gladeFile, "button");
- nsgtk_download_progressBar =
- glade_xml_get_widget(gladeFile, "progressBar");
+ nsgtk_download_progress_bar = GTK_PROGRESS_BAR(glade_xml_get_widget(
+ gladeFile, "progressBar"));
nsgtk_download_window = GTK_WINDOW(glade_xml_get_widget(gladeFile,
"wndDownloads"));
nsgtk_download_parent = NULL;
@@ -92,6 +100,8 @@ void nsgtk_download_init()
gtk_window_set_destroy_with_parent(GTK_WINDOW(nsgtk_download_window),
FALSE);
+ nsgtk_downloads_timer = g_timer_new();
+
nsgtk_download_tree = nsgtk_download_tree_view_new(gladeFile);
nsgtk_download_store = gtk_list_store_new(NSGTK_DOWNLOAD_N_COLUMNS,
@@ -99,12 +109,22 @@ void nsgtk_download_init()
G_TYPE_STRING, /* Description */
G_TYPE_STRING, /* Time remaining */
G_TYPE_STRING, /* Speed */
+ G_TYPE_INT, /* Pulse */
G_TYPE_STRING, /* Status */
G_TYPE_POINTER /* Download structure */
);
+
gtk_tree_view_set_model(nsgtk_download_tree,
GTK_TREE_MODEL(nsgtk_download_store));
+
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(nsgtk_download_store),
+ NSGTK_DOWNLOAD_STATUS,
+ (GtkTreeIterCompareFunc) nsgtk_download_sort, NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(nsgtk_download_store),
+ NSGTK_DOWNLOAD_STATUS, GTK_SORT_ASCENDING);
+
g_object_unref(nsgtk_download_store);
nsgtk_download_selection =
@@ -113,38 +133,36 @@ void nsgtk_download_init()
GTK_SELECTION_MULTIPLE);
g_signal_connect(G_OBJECT(nsgtk_download_selection), "changed",
- G_CALLBACK(nsgtk_download_sensitivity_selection_changed),
- NULL);
- g_signal_connect(G_OBJECT(nsgtk_download_window), "delete-event",
- G_CALLBACK(nsgtk_download_hide), NULL);
- g_signal_connect(glade_xml_get_widget(gladeFile, "buttonClear"),
- "clicked", G_CALLBACK(nsgtk_download_selection_do),
- nsgtk_download_store_clear_item);
- g_signal_connect(glade_xml_get_widget(gladeFile, "buttonCancel"),
- "clicked", G_CALLBACK(nsgtk_download_selection_do),
- nsgtk_download_store_cancel_item);
+ G_CALLBACK(nsgtk_download_sensitivity_evaluate), NULL);
g_signal_connect(nsgtk_download_tree, "row-activated",
G_CALLBACK(nsgtk_download_tree_view_row_activated),
NULL);
+ g_signal_connect_swapped(glade_xml_get_widget(gladeFile, "buttonClear"),
+ "clicked", G_CALLBACK(nsgtk_download_do),
+ nsgtk_download_store_clear_item);
+ g_signal_connect_swapped(glade_xml_get_widget(gladeFile, "buttonCancel"),
+ "clicked", G_CALLBACK(nsgtk_download_do),
+ nsgtk_download_store_cancel_item);
+ g_signal_connect(G_OBJECT(nsgtk_download_window), "delete-event",
+ G_CALLBACK(nsgtk_download_hide), NULL);
+
}
void nsgtk_download_destroy ()
{
- gtk_tree_selection_select_all(nsgtk_download_selection);
- nsgtk_download_selection_do(NULL, nsgtk_download_store_cancel_item);
+ nsgtk_download_do(nsgtk_download_store_cancel_item);
}
bool nsgtk_check_for_downloads (GtkWindow *parent)
{
- if (nsgtk_downloads != 0) {
+ if (nsgtk_downloads_num_active != 0) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new_with_markup(parent,
GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
- "<big><b>Quit NetSurf?</b></big>\n\n"
- "<small>There are still downloads running, "
- "if you quit now these will be canceled and the"
- " files deleted</small>");
+ "<big><b>%s</b></big>\n\n"
+ "<small>%s</small>", messages_get("gtkQuit"),
+ messages_get("gtkDownloadsRunning"));
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "gtk-cancel",
GTK_RESPONSE_CANCEL, "gtk-quit",
GTK_RESPONSE_CLOSE, NULL);
@@ -176,13 +194,16 @@ struct gui_download_window *gui_download_window_create(const char *url,
const char *mime_type, struct fetch *fetch,
unsigned int total_size, struct gui_window *gui)
{
- nsgtk_download_parent = nsgtk_scaffolding_get_window(gui);
- struct gui_download_window *download;
gchar *domain;
gchar *filename;
gchar *destination;
- gchar *size = (total_size == 0 ?
- "Unknown" : human_friendly_bytesize(total_size));
+ gboolean unknown_size = total_size == 0;
+ const gchar *size = (total_size == 0 ?
+ messages_get("gtkUnknownSize") :
+ human_friendly_bytesize(total_size));
+
+ nsgtk_download_parent = nsgtk_scaffolding_get_window(gui);
+ struct gui_download_window *download = malloc(sizeof *download);
if (url_nice(url, &filename, false) != URL_FUNC_OK)
strcpy(filename, messages_get("gtkUnknownFile"));
@@ -192,20 +213,26 @@ struct gui_download_window *gui_download_window_create(const char *url,
destination = nsgtk_download_dialog_show(filename, domain, size);
if (destination == NULL)
return NULL;
-
- download = malloc(sizeof *download);
+
+ /* Add the new row and store the reference to it (which keeps track of
+ * the tree changes) */
+ gtk_list_store_prepend(nsgtk_download_store, &nsgtk_download_iter);
+ download->row = gtk_tree_row_reference_new(
+ GTK_TREE_MODEL(nsgtk_download_store),
+ gtk_tree_model_get_path(GTK_TREE_MODEL
+ (nsgtk_download_store), &nsgtk_download_iter));
+
download->fetch = fetch;
download->name = g_string_new(filename);
download->time_left = g_string_new("");
download->size_total = total_size;
download->size_downloaded = 0;
download->speed = 0;
+ download->start_time = g_timer_elapsed(nsgtk_downloads_timer, NULL);
download->time_remaining = -1;
+ download->status = NSGTK_DOWNLOAD_NONE;
download->filename = destination;
- download->status = (total_size == 0 ? NSGTK_DOWNLOAD_WORKING :
- NSGTK_DOWNLOAD_NONE);
- download->progress = (total_size == 0 ? 100 : 0);
- download->timer = g_timer_new();
+ download->progress = 0;
download->error = NULL;
download->write = g_io_channel_new_file(destination, "w",
&download->error);
@@ -213,25 +240,23 @@ struct gui_download_window *gui_download_window_create(const char *url,
free(download);
return NULL;
}
-
- if (g_str_has_prefix(mime_type, "text") == FALSE)
- g_io_channel_set_encoding(download->write, NULL,
- &download->error);
-
- /* Add the new row and store the reference to it (which keeps track of
- * the tree changes) */
- gtk_list_store_append(nsgtk_download_store, &nsgtk_download_iter);
- download->row = gtk_tree_row_reference_new(
- GTK_TREE_MODEL(nsgtk_download_store),
- gtk_tree_model_get_path(GTK_TREE_MODEL
- (nsgtk_download_store), &nsgtk_download_iter));
-
- nsgtk_download_sensitivity_set(download, NSGTK_DOWNLOAD_CANCEL);
+ g_io_channel_set_encoding(download->write, NULL,
+ &download->error);
+
+ nsgtk_download_change_sensitivity(download, NSGTK_DOWNLOAD_CANCEL);
nsgtk_download_store_create_item(download);
nsgtk_download_show(nsgtk_download_parent);
- nsgtk_downloads++;
+ if (unknown_size)
+ nsgtk_download_change_status(download,
+ NSGTK_DOWNLOAD_WORKING);
+
+ if (nsgtk_downloads_num_active == 0)
+ g_timeout_add(UPDATE_RATE, (GSourceFunc)nsgtk_download_update,
+ FALSE);
+ nsgtk_downloads_list = g_list_prepend(nsgtk_downloads_list, download);
+
return download;
}
@@ -241,35 +266,19 @@ void gui_download_window_data(struct gui_download_window *dw, const char *data,
{
g_io_channel_write_chars(dw->write, data, size, NULL, &dw->error);
if (dw->error != NULL) {
- dw->status = NSGTK_DOWNLOAD_ERROR;
dw->speed = 0;
dw->time_remaining = -1;
- dw->sensitivity = NSGTK_DOWNLOAD_CLEAR;
- nsgtk_download_store_update_item(dw);
+
+ nsgtk_download_change_sensitivity(dw, NSGTK_DOWNLOAD_CLEAR);
+ nsgtk_download_change_status(dw, NSGTK_DOWNLOAD_ERROR);
+
+ nsgtk_download_update(TRUE);
fetch_abort(dw->fetch);
- nsgtk_downloads--;
gtk_window_present(nsgtk_download_window);
return;
- }
-
+ }
dw->size_downloaded += size;
- gfloat elapsed = g_timer_elapsed(dw->timer, NULL);
-
- /* If enough time has gone by, update the window */
- if (elapsed - dw->last_update > .5 &&
- GTK_WIDGET_VISIBLE(nsgtk_download_window)) {
- dw->speed = dw->size_downloaded / elapsed;
- dw->time_remaining = (dw->size_total - dw->size_downloaded)/
- dw->speed;
-
- if (dw->size_total)
- dw->progress = (gfloat)(dw->size_downloaded)/
- dw->size_total*100;
-
- nsgtk_download_store_update_item(dw);
- dw->last_update = elapsed;
- }
}
@@ -285,16 +294,16 @@ void gui_download_window_done(struct gui_download_window *dw)
g_io_channel_unref(dw->write);
dw->speed = 0;
+ dw->time_remaining = -1;
dw->progress = 100;
- nsgtk_download_sensitivity_set(dw, NSGTK_DOWNLOAD_CLEAR);
- dw->status = NSGTK_DOWNLOAD_COMPLETE;
+ dw->size_total = dw->size_downloaded;
+ nsgtk_download_change_sensitivity(dw, NSGTK_DOWNLOAD_CLEAR);
+ nsgtk_download_change_status(dw, NSGTK_DOWNLOAD_COMPLETE);
if (option_downloads_clear)
nsgtk_download_store_clear_item(dw);
else
- nsgtk_download_store_update_item(dw);
-
- nsgtk_downloads--;
+ nsgtk_download_update(TRUE);
}
@@ -309,8 +318,8 @@ GtkTreeView* nsgtk_download_tree_view_new(GladeXML *gladeFile)
renderer = gtk_cell_renderer_progress_new();
gtk_tree_view_insert_column_with_attributes (treeview, -1,
messages_get("gtkProgress"), renderer, "value",
- NSGTK_DOWNLOAD_PROGRESS, "text",
- NSGTK_DOWNLOAD_STATUS, NULL);
+ NSGTK_DOWNLOAD_PROGRESS, "pulse", NSGTK_DOWNLOAD_PULSE,
+ "text", NSGTK_DOWNLOAD_STATUS, NULL);
/* Information column */
renderer = gtk_cell_renderer_text_new();
@@ -347,34 +356,146 @@ void nsgtk_download_tree_view_row_activated(GtkTreeView *tree,
if (gtk_tree_model_get_iter(model, &iter, path)) {
/* TODO: This will be a context action (pause, start, clear) */
- nsgtk_download_selection_do(NULL,
- nsgtk_download_store_clear_item);
+ nsgtk_download_do(nsgtk_download_store_clear_item);
}
}
+gint nsgtk_download_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
+ gpointer userdata)
+{
+ struct gui_download_window *dl1, *dl2;
+
+ gtk_tree_model_get(model, a, NSGTK_DOWNLOAD, &dl1, -1);
+ gtk_tree_model_get(model, b, NSGTK_DOWNLOAD, &dl2, -1);
+
+ return dl1->status - dl2->status;
+}
+
+void nsgtk_download_do(nsgtk_download_selection_action action)
+{
+ GList *rows, *dls = NULL;
+ GtkTreeModel *model = GTK_TREE_MODEL(nsgtk_download_store);
+ gboolean selection_exists = gtk_tree_selection_count_selected_rows(
+ nsgtk_download_selection);
+
+ if (selection_exists) {
+ rows = gtk_tree_selection_get_selected_rows(
+ nsgtk_download_selection, &model);
+ while (rows != NULL) {
+ struct gui_download_window *dl;
+ gtk_tree_model_get_iter(GTK_TREE_MODEL(
+ nsgtk_download_store),
+ &nsgtk_download_iter,
+ (GtkTreePath*)rows->data);
+ gtk_tree_model_get(GTK_TREE_MODEL(nsgtk_download_store),
+ &nsgtk_download_iter, NSGTK_DOWNLOAD,
+ &dl, -1);
+ dls = g_list_prepend(dls, dl);
+
+ rows = rows->next;
+ }
+ g_list_foreach(rows, (GFunc)gtk_tree_path_free, NULL);
+ g_list_foreach(rows, (GFunc)g_free, NULL);
+ g_list_free(rows);
+ } else
+ dls = g_list_copy(nsgtk_downloads_list);
+
+ g_list_foreach(dls, (GFunc)action, NULL);
+ g_list_free(dls);
+}
+
+gboolean nsgtk_download_update(gboolean force_update)
+{
+ /* Be sure we need to update */
+ if (!GTK_WIDGET_VISIBLE(nsgtk_download_window))
+ return TRUE;
+
+ GList *list;
+ gchar *text;
+ gboolean update, pulse_mode = FALSE;
+ gint downloaded = 0, total = 0, dls = 0;
+ gfloat percent, elapsed = g_timer_elapsed(nsgtk_downloads_timer, NULL);
+ nsgtk_downloads_num_active = 0;
+
+ for (list = nsgtk_downloads_list; list != NULL; list = list->next) {
+ struct gui_download_window *dl = list->data;
+ update = force_update;
+
+ switch (dl->status) {
+ case NSGTK_DOWNLOAD_WORKING:
+ pulse_mode = TRUE;
+ case NSGTK_DOWNLOAD_NONE:
+ dl->speed = dl->size_downloaded /
+ (elapsed - dl->start_time);
+ if (dl->status == NSGTK_DOWNLOAD_NONE) {
+ dl->time_remaining = (dl->size_total -
+ dl->size_downloaded)/
+ dl->speed;
+ dl->progress = (gfloat)
+ dl->size_downloaded /
+ dl->size_total * 100;
+ } else
+ dl->progress++;
+
+ nsgtk_downloads_num_active++;
+ update = TRUE;
+
+ case NSGTK_DOWNLOAD_COMPLETE:
+ downloaded += dl->size_downloaded;
+ total += dl->size_total;
+ dls++;
+ }
+ if (update)
+ nsgtk_download_store_update_item(dl);
+ }
+
+ if (pulse_mode) {
+ text = g_strdup_printf(
+ messages_get(nsgtk_downloads_num_active > 1 ?
+ "gtkProgressBarPulse" :
+ "gtkProgressBarPulseSingle"),
+ nsgtk_downloads_num_active);
+ gtk_progress_bar_pulse(nsgtk_download_progress_bar);
+ gtk_progress_bar_set_text(nsgtk_download_progress_bar, text);
+ } else {
+ percent = total != 0 ? (gfloat)downloaded / total : 0;
+ text = g_strdup_printf(messages_get("gtkProgressBar"),
+ floor(percent*100), dls);
+ gtk_progress_bar_set_fraction(nsgtk_download_progress_bar,
+ percent);
+ gtk_progress_bar_set_text(nsgtk_download_progress_bar, text);
+ }
+
+ g_free(text);
+
+ if (nsgtk_downloads_num_active == 0)
+ return FALSE; /* Returning FALSE here cancels the g_timeout */
+ else
+ return TRUE;
+}
+
void nsgtk_download_store_update_item (struct gui_download_window *dl)
{
gchar *info = nsgtk_download_info_to_string(dl);
gchar *speed = g_strconcat(human_friendly_bytesize(dl->speed), "/s",
NULL);
gchar *time = nsgtk_download_time_to_string(dl->time_remaining);
+ gboolean pulse = dl->status == NSGTK_DOWNLOAD_WORKING;
/* Updates iter (which is needed to set and get data) with the dl row */
gtk_tree_model_get_iter(GTK_TREE_MODEL(nsgtk_download_store),
&nsgtk_download_iter,
gtk_tree_row_reference_get_path(dl->row));
- gtk_list_store_set (nsgtk_download_store, &nsgtk_download_iter,
- NSGTK_DOWNLOAD_PROGRESS, dl->progress,
+ gtk_list_store_set(nsgtk_download_store, &nsgtk_download_iter,
+ NSGTK_DOWNLOAD_PULSE, pulse ? dl->progress : -1,
+ NSGTK_DOWNLOAD_PROGRESS, pulse ? 0 : dl->progress,
NSGTK_DOWNLOAD_INFO, info,
NSGTK_DOWNLOAD_SPEED, dl->speed == 0 ? "-" : speed,
NSGTK_DOWNLOAD_REMAINING, time,
+ NSGTK_DOWNLOAD, dl,
-1);
- if (dl->status != NSGTK_DOWNLOAD_NONE)
- gtk_list_store_set(nsgtk_download_store, &nsgtk_download_iter,
- NSGTK_DOWNLOAD_STATUS,
- messages_get(status_messages[dl->status]));
-
+
g_free(info);
g_free(speed);
g_free(time);
@@ -384,94 +505,75 @@ void nsgtk_download_store_create_item (struct gui_download_window *dl)
{
nsgtk_download_store_update_item(dl);
/* The iter has already been updated to this row */
- gtk_list_store_set (nsgtk_download_store, &nsgtk_download_iter,
+ gtk_list_store_set(nsgtk_download_store, &nsgtk_download_iter,
NSGTK_DOWNLOAD, dl, -1);
}
void nsgtk_download_store_clear_item (struct gui_download_window *dl)
{
if (dl->sensitivity & NSGTK_DOWNLOAD_CLEAR) {
+ nsgtk_downloads_list = g_list_remove(nsgtk_downloads_list, dl);
+
gtk_tree_model_get_iter(GTK_TREE_MODEL(nsgtk_download_store),
&nsgtk_download_iter,
gtk_tree_row_reference_get_path(dl->row));
gtk_list_store_remove(nsgtk_download_store,
&nsgtk_download_iter);
g_free(dl);
+
+ nsgtk_download_sensitivity_evaluate(nsgtk_download_selection);
+ nsgtk_download_update(FALSE);
}
}
void nsgtk_download_store_cancel_item (struct gui_download_window *dl)
{
if (dl->sensitivity & NSGTK_DOWNLOAD_CANCEL) {
- dl->status = NSGTK_DOWNLOAD_CANCELED;
dl->speed = 0;
+ dl->size_downloaded = 0;
dl->progress = 0;
dl->time_remaining = -1;
- nsgtk_download_sensitivity_set(dl, NSGTK_DOWNLOAD_CLEAR);
+ nsgtk_download_change_sensitivity(dl, NSGTK_DOWNLOAD_CLEAR);
+ nsgtk_download_change_status(dl, NSGTK_DOWNLOAD_CANCELED);
if (dl->fetch)
fetch_abort(dl->fetch);
g_unlink(dl->filename);
- nsgtk_download_store_update_item(dl);
-
- nsgtk_downloads--;
+ nsgtk_download_update(TRUE);
}
}
-void nsgtk_download_selection_do(GtkWidget *button, selection_action action)
-{
- GList *rows, *dls = NULL;
- GtkTreeModel *model = GTK_TREE_MODEL(nsgtk_download_store);
-
- rows = gtk_tree_selection_get_selected_rows(nsgtk_download_selection,
- &model);
- while (rows != NULL) {
- struct gui_download_window *dl;
- gtk_tree_model_get_iter(GTK_TREE_MODEL(nsgtk_download_store),
- &nsgtk_download_iter, (GtkTreePath*)rows->data);
- gtk_tree_model_get(GTK_TREE_MODEL(nsgtk_download_store),
- &nsgtk_download_iter, NSGTK_DOWNLOAD,
- &dl, -1);
- dls = g_list_prepend(dls, dl);
-
- rows = rows->next;
- }
- g_list_foreach(dls, (GFunc)action, NULL);
-
- g_list_foreach(rows, (GFunc)gtk_tree_path_free, NULL);
- g_list_foreach(rows, (GFunc)g_free, NULL);
- g_list_free(rows);
- g_list_free(dls);
-}
-
-void nsgtk_download_sensitivity_set(struct gui_download_window *dl,
- nsgtk_download_actions sensitivity)
+void nsgtk_download_sensitivity_evaluate (GtkTreeSelection *selection)
{
- dl->sensitivity = sensitivity;
- if (gtk_tree_selection_path_is_selected(nsgtk_download_selection,
- gtk_tree_row_reference_get_path(dl->row)))
- nsgtk_download_sensitivity_update_buttons(sensitivity);
-
-}
-
-void nsgtk_download_sensitivity_selection_changed (GtkTreeSelection *selection)
-{
- GtkTreeModel *model = GTK_TREE_MODEL(nsgtk_download_store);
GtkTreeIter iter;
GList *rows;
+ gboolean selected = gtk_tree_selection_count_selected_rows(selection);
+ GtkTreeModel *model = GTK_TREE_MODEL(nsgtk_download_store);
nsgtk_download_actions sensitivity = 0;
-
- rows = gtk_tree_selection_get_selected_rows(selection, &model);
- while (rows != NULL) {
- struct gui_download_window *dl;
- gtk_tree_model_get_iter(model, &iter, (GtkTreePath*)rows->data);
- gtk_tree_model_get(model, &iter, NSGTK_DOWNLOAD, &dl, -1);
- sensitivity |= dl->sensitivity;
- rows = rows->next;
+ struct gui_download_window *dl;
+
+ if (selected) {
+ rows = gtk_tree_selection_get_selected_rows(selection, &model);
+ while (rows != NULL) {
+ gtk_tree_model_get_iter(model, &iter,
+ (GtkTreePath*)rows->data);
+ gtk_tree_model_get(model, &iter, NSGTK_DOWNLOAD,
+ &dl, -1);
+ sensitivity |= dl->sensitivity;
+ rows = rows->next;
+ }
+ } else {
+ rows = nsgtk_downloads_list;
+ while (rows != NULL) {
+ dl = rows->data;
+ sensitivity |= (dl->sensitivity & NSGTK_DOWNLOAD_CLEAR);
+ rows = rows->next;
+ }
}
+
nsgtk_download_sensitivity_update_buttons(sensitivity);
}
@@ -490,12 +592,36 @@ void nsgtk_download_sensitivity_update_buttons(
gtk_widget_set_sensitive(g_list_nth_data(nsgtk_download_buttons,
RESUME_BUTTON), sensitivity & NSGTK_DOWNLOAD_RESUME);
}
+
+void nsgtk_download_change_sensitivity(struct gui_download_window *dl,
+ nsgtk_download_actions sensitivity)
+{
+ dl->sensitivity = sensitivity;
+ nsgtk_download_sensitivity_evaluate(nsgtk_download_selection);
+}
+
+void nsgtk_download_change_status (
+ struct gui_download_window *dl, nsgtk_download_status status)
+{
+ dl->status = status;
+ if (status != NSGTK_DOWNLOAD_NONE) {
+ gtk_tree_model_get_iter(GTK_TREE_MODEL(nsgtk_download_store),
+ &nsgtk_download_iter,
+ gtk_tree_row_reference_get_path(dl->row));
+
+ gtk_list_store_set(nsgtk_download_store, &nsgtk_download_iter,
+ NSGTK_DOWNLOAD_STATUS,
+ messages_get(status_messages[status]), -1);
+ }
+}
-gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain, gchar *size)
+gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain,
+ const gchar *size)
{
enum { GTK_RESPONSE_DOWNLOAD, GTK_RESPONSE_SAVE_AS };
GtkWidget *dialog;
gchar *destination = NULL;
+ gchar *message = g_strdup(messages_get("gtkStartDownload"));
gchar *info = g_strdup_printf(messages_get("gtkInfo"), filename,
domain, size);
@@ -504,7 +630,7 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain, gchar *size)
GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
"<span size=\"x-large\" weight=\"ultrabold\">%s</span>"
"\n\n<small>%s</small>",
- messages_get("gtkStartDownload"), info);
+ message, info);
gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_SAVE,
GTK_RESPONSE_DOWNLOAD, GTK_STOCK_CANCEL,
@@ -513,6 +639,7 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain, gchar *size)
gint result = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
+ g_free(message);
g_free(info);
switch (result) {
@@ -526,6 +653,9 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain, gchar *size)
NULL);
gtk_file_chooser_set_current_name
(GTK_FILE_CHOOSER(dialog), filename);
+ gtk_file_chooser_set_current_folder
+ (GTK_FILE_CHOOSER(dialog),
+ option_downloads_directory);
gtk_file_chooser_set_do_overwrite_confirmation
(GTK_FILE_CHOOSER(dialog),
option_request_overwrite);
@@ -540,6 +670,44 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain, gchar *size)
case GTK_RESPONSE_DOWNLOAD: {
destination = g_strconcat(option_downloads_directory,
"/", filename, NULL);
+ /* Test if file already exists and display overwrite
+ * confirmation if needed */
+ if (g_file_test(destination, G_FILE_TEST_EXISTS)
+ && option_request_overwrite) {
+ message = g_strdup_printf(messages_get(
+ "gtkOverwrite"), filename);
+ info = g_strdup_printf(messages_get(
+ "gtkOverwriteInfo"),
+ option_downloads_directory);
+
+ dialog = gtk_message_dialog_new_with_markup(
+ nsgtk_download_parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_CANCEL,
+ "<b>%s</b>",message);
+ gtk_message_dialog_format_secondary_markup(
+ GTK_MESSAGE_DIALOG(dialog),
+ info);
+
+ GtkWidget *button = gtk_dialog_add_button(
+ GTK_DIALOG(dialog),
+ "_Replace",
+ GTK_RESPONSE_DOWNLOAD);
+ gtk_button_set_image(GTK_BUTTON(button),
+ gtk_image_new_from_stock(
+ "gtk-save",
+ GTK_ICON_SIZE_BUTTON));
+
+ gint result = gtk_dialog_run(GTK_DIALOG(
+ dialog));
+ if (result == GTK_RESPONSE_CANCEL)
+ destination = NULL;
+
+ gtk_widget_destroy(dialog);
+ g_free(message);
+ g_free(info);
+ }
break;
}
}
@@ -548,15 +716,19 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain, gchar *size)
gchar* nsgtk_download_info_to_string (struct gui_download_window *dl)
{
- if (dl->status != NSGTK_DOWNLOAD_ERROR)
- return g_strdup_printf("%s\n%s of %s completed",
- dl->name->str,
+ gchar *size_info = g_strdup_printf(messages_get("gtkSizeInfo"),
human_friendly_bytesize(dl->size_downloaded),
- dl->size_total == 0 ? "Unknown" :
- human_friendly_bytesize(dl->size_total));
+ dl->size_total == 0 ? messages_get("gtkUnknownSize") :
+ human_friendly_bytesize(dl->size_total));
+
+ if (dl->status != NSGTK_DOWNLOAD_ERROR)
+ return g_strdup_printf("%s\n%s",
+ dl->name->str, size_info);
else
return g_strdup_printf("%s\n%s", dl->name->str,
dl->error->message);
+
+ g_free(size_info);
}
gchar* nsgtk_download_time_to_string (gint seconds)