summaryrefslogtreecommitdiff
path: root/gtk/gtk_download.c
diff options
context:
space:
mode:
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)