summaryrefslogtreecommitdiff
path: root/frontends/gtk
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2019-10-16 21:51:01 +0100
committerVincent Sanders <vince@kyllikki.org>2019-10-16 21:51:01 +0100
commita54cbb5aeaba6f6ecf6c04de38acda79733583ed (patch)
treeef87505c77cf80c4a7098146b77f796c2820353a /frontends/gtk
parent1f0dc9dd6e014e0e5d4093fef53c41cd09854897 (diff)
downloadnetsurf-a54cbb5aeaba6f6ecf6c04de38acda79733583ed.tar.gz
netsurf-a54cbb5aeaba6f6ecf6c04de38acda79733583ed.tar.bz2
commit a neatness on the gtk download window code
Diffstat (limited to 'frontends/gtk')
-rw-r--r--frontends/gtk/download.c814
-rw-r--r--frontends/gtk/download.h25
2 files changed, 511 insertions, 328 deletions
diff --git a/frontends/gtk/download.c b/frontends/gtk/download.c
index b981dce4b..6fb908195 100644
--- a/frontends/gtk/download.c
+++ b/frontends/gtk/download.c
@@ -65,12 +65,23 @@ typedef enum {
} nsgtk_download_status;
typedef enum {
- NSGTK_DOWNLOAD_PAUSE = 1 << 0,
+ NSGTK_DOWNLOAD_PAUSE = 1 << 0,
NSGTK_DOWNLOAD_RESUME = 1 << 1,
- NSGTK_DOWNLOAD_CANCEL = 1 << 2,
- NSGTK_DOWNLOAD_CLEAR = 1 << 3
+ NSGTK_DOWNLOAD_CANCEL = 1 << 2,
+ NSGTK_DOWNLOAD_CLEAR = 1 << 3
} nsgtk_download_actions;
+static const gchar* status_messages[] = {
+ NULL,
+ "gtkWorking",
+ "gtkError",
+ "gtkComplete",
+ "gtkCanceled"
+};
+
+/**
+ * context for each download.
+ */
struct gui_download_window {
struct download_context *ctx;
nsgtk_download_actions sensitivity;
@@ -90,28 +101,37 @@ struct gui_download_window {
GError *error;
};
-typedef void (*nsgtk_download_selection_action)(
- struct gui_download_window *dl,
- void *user_data);
+typedef void (*nsgtk_download_selection_action)(struct gui_download_window *dl,
+ void *user_data);
+
+/**
+ * context for a nsgtk download window.
+ */
+struct download_window_ctx {
+ GtkWindow *window;
+ GtkWindow *parent;
+
+ GtkProgressBar *progress;
-static GtkWindow *nsgtk_download_window, *nsgtk_download_parent;
-static GtkProgressBar *nsgtk_download_progress_bar;
+ GtkTreeView *tree;
+ GtkListStore *store;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
-static GtkTreeView *nsgtk_download_tree;
-static GtkListStore *nsgtk_download_store;
-static GtkTreeSelection *nsgtk_download_selection;
-static GtkTreeIter nsgtk_download_iter;
+ GTimer *timer;
+ GList *list;
+ GtkButton *pause;
+ GtkButton *clear;
+ GtkButton *cancel;
+ GtkButton *resume;
-static GTimer *nsgtk_downloads_timer;
-static GList *nsgtk_downloads_list;
-static GtkButton *nsgtk_download_button_pause;
-static GtkButton *nsgtk_download_button_clear;
-static GtkButton *nsgtk_download_button_cancel;
-static GtkButton *nsgtk_download_button_resume;
-static gint nsgtk_downloads_num_active;
-static const gchar* status_messages[] = { NULL, "gtkWorking", "gtkError",
- "gtkComplete", "gtkCanceled" };
+ gint num_active;
+};
+/**
+ * global instance of the download window
+ */
+static struct download_window_ctx dl_ctx;
static GtkTreeView* nsgtk_download_tree_view_new(GtkBuilder *gladeFile)
@@ -119,40 +139,66 @@ static GtkTreeView* nsgtk_download_tree_view_new(GtkBuilder *gladeFile)
GtkTreeView *treeview;
GtkCellRenderer *renderer;
- treeview = GTK_TREE_VIEW(gtk_builder_get_object(gladeFile, "treeDownloads"));
+ treeview = GTK_TREE_VIEW(gtk_builder_get_object(gladeFile,
+ "treeDownloads"));
/* Progress column */
renderer = gtk_cell_renderer_progress_new();
- gtk_tree_view_insert_column_with_attributes (treeview, -1,
- messages_get("gtkProgress"), renderer, "value",
- NSGTK_DOWNLOAD_PROGRESS, "pulse", NSGTK_DOWNLOAD_PULSE,
- "text", NSGTK_DOWNLOAD_STATUS, NULL);
+ gtk_tree_view_insert_column_with_attributes(treeview,
+ -1,
+ messages_get("gtkProgress"),
+ renderer,
+ "value",
+ NSGTK_DOWNLOAD_PROGRESS,
+ "pulse",
+ NSGTK_DOWNLOAD_PULSE,
+ "text",
+ NSGTK_DOWNLOAD_STATUS,
+ NULL);
/* Information column */
renderer = gtk_cell_renderer_text_new();
- g_object_set(G_OBJECT(renderer), "wrap-mode", PANGO_WRAP_WORD_CHAR,
- "wrap-width", 300, NULL);
- gtk_tree_view_insert_column_with_attributes (treeview, -1,
- messages_get("gtkDetails"), renderer, "text",
- NSGTK_DOWNLOAD_INFO, NULL);
- gtk_tree_view_column_set_expand(gtk_tree_view_get_column(treeview,
- NSGTK_DOWNLOAD_INFO), TRUE);
+ g_object_set(G_OBJECT(renderer),
+ "wrap-mode",
+ PANGO_WRAP_WORD_CHAR,
+ "wrap-width",
+ 300,
+ NULL);
+ gtk_tree_view_insert_column_with_attributes(treeview,
+ -1,
+ messages_get("gtkDetails"),
+ renderer,
+ "text",
+ NSGTK_DOWNLOAD_INFO,
+ NULL);
+ gtk_tree_view_column_set_expand(
+ gtk_tree_view_get_column(treeview,
+ NSGTK_DOWNLOAD_INFO), TRUE);
/* Time remaining column */
renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_insert_column_with_attributes (treeview, -1,
- messages_get("gtkRemaining"), renderer, "text",
- NSGTK_DOWNLOAD_REMAINING, NULL);
+ gtk_tree_view_insert_column_with_attributes(treeview,
+ -1,
+ messages_get("gtkRemaining"),
+ renderer,
+ "text",
+ NSGTK_DOWNLOAD_REMAINING,
+ NULL);
/* Speed column */
renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_insert_column_with_attributes (treeview, -1,
- messages_get("gtkSpeed"), renderer, "text",
- NSGTK_DOWNLOAD_SPEED, NULL);
+ gtk_tree_view_insert_column_with_attributes(treeview,
+ -1,
+ messages_get("gtkSpeed"),
+ renderer,
+ "text",
+ NSGTK_DOWNLOAD_SPEED,
+ NULL);
return treeview;
}
+
static gint
nsgtk_download_sort(GtkTreeModel *model,
GtkTreeIter *a,
@@ -167,43 +213,52 @@ nsgtk_download_sort(GtkTreeModel *model,
return dl1->status - dl2->status;
}
+
static void
nsgtk_download_sensitivity_update_buttons(nsgtk_download_actions sensitivity)
{
/* Glade seems to pack the buttons in an arbitrary order */
enum { PAUSE_BUTTON, CLEAR_BUTTON, CANCEL_BUTTON, RESUME_BUTTON };
- gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_download_button_pause),
+ gtk_widget_set_sensitive(GTK_WIDGET(dl_ctx.pause),
sensitivity & NSGTK_DOWNLOAD_PAUSE);
- gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_download_button_clear),
+ gtk_widget_set_sensitive(GTK_WIDGET(dl_ctx.clear),
sensitivity & NSGTK_DOWNLOAD_CLEAR);
- gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_download_button_cancel),
+ gtk_widget_set_sensitive(GTK_WIDGET(dl_ctx.cancel),
sensitivity & NSGTK_DOWNLOAD_CANCEL);
- gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_download_button_resume),
+ gtk_widget_set_sensitive(GTK_WIDGET(dl_ctx.resume),
sensitivity & NSGTK_DOWNLOAD_RESUME);
}
+
static void nsgtk_download_sensitivity_evaluate(GtkTreeSelection *selection)
{
GtkTreeIter iter;
GList *rows;
- gboolean selected = gtk_tree_selection_count_selected_rows(selection);
- GtkTreeModel *model = GTK_TREE_MODEL(nsgtk_download_store);
+ gboolean selected;
+ GtkTreeModel *model;
nsgtk_download_actions sensitivity = 0;
struct gui_download_window *dl;
+ model = GTK_TREE_MODEL(dl_ctx.store);
+
+ selected = gtk_tree_selection_count_selected_rows(selection);
if (selected) {
rows = gtk_tree_selection_get_selected_rows(selection, &model);
while (rows != NULL) {
- gtk_tree_model_get_iter(model, &iter,
+ gtk_tree_model_get_iter(model,
+ &iter,
(GtkTreePath*)rows->data);
- gtk_tree_model_get(model, &iter, NSGTK_DOWNLOAD,
- &dl, -1);
+ gtk_tree_model_get(model,
+ &iter,
+ NSGTK_DOWNLOAD,
+ &dl,
+ -1);
sensitivity |= dl->sensitivity;
rows = rows->next;
}
} else {
- rows = nsgtk_downloads_list;
+ rows = dl_ctx.list;
while (rows != NULL) {
dl = rows->data;
sensitivity |= (dl->sensitivity & NSGTK_DOWNLOAD_CLEAR);
@@ -211,103 +266,121 @@ static void nsgtk_download_sensitivity_evaluate(GtkTreeSelection *selection)
}
}
-
nsgtk_download_sensitivity_update_buttons(sensitivity);
}
+
/**
* Wrapper to GFunc-ify gtk_tree_path_free for g_list_foreach.
*/
-static void nsgtk_download_gfunc__gtk_tree_path_free(
- gpointer data,
- gpointer user_data)
+static void
+nsgtk_download_gfunc__gtk_tree_path_free(gpointer data, gpointer user_data)
{
gtk_tree_path_free(data);
}
+
/**
* Wrapper to GFunc-ify g_free for g_list_foreach.
*/
-static void nsgtk_download_gfunc__g_free(
- gpointer data,
- gpointer user_data)
+static void
+nsgtk_download_gfunc__g_free(gpointer data, gpointer user_data)
{
g_free(data);
}
+
static 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);
+ GtkTreeModel *model;
+
+ if (gtk_tree_selection_count_selected_rows(dl_ctx.selection)) {
+ model = GTK_TREE_MODEL(dl_ctx.store);
- if (selection_exists) {
- rows = gtk_tree_selection_get_selected_rows(
- nsgtk_download_selection, &model);
+ rows = gtk_tree_selection_get_selected_rows(dl_ctx.selection,
+ &model);
while (rows != NULL) {
struct gui_download_window *dl;
- gtk_tree_model_get_iter(GTK_TREE_MODEL(
- nsgtk_download_store),
- &nsgtk_download_iter,
+
+ gtk_tree_model_get_iter(GTK_TREE_MODEL(dl_ctx.store),
+ &dl_ctx.iter,
(GtkTreePath*)rows->data);
- gtk_tree_model_get(GTK_TREE_MODEL(nsgtk_download_store),
- &nsgtk_download_iter, NSGTK_DOWNLOAD,
- &dl, -1);
+
+ gtk_tree_model_get(GTK_TREE_MODEL(dl_ctx.store),
+ &dl_ctx.iter,
+ NSGTK_DOWNLOAD,
+ &dl,
+ -1);
+
dls = g_list_prepend(dls, dl);
rows = rows->next;
}
- g_list_foreach(rows, nsgtk_download_gfunc__gtk_tree_path_free, NULL);
- g_list_foreach(rows, nsgtk_download_gfunc__g_free, NULL);
+ g_list_foreach(rows,
+ nsgtk_download_gfunc__gtk_tree_path_free,
+ NULL);
+ g_list_foreach(rows,
+ nsgtk_download_gfunc__g_free,
+ NULL);
g_list_free(rows);
- } else
- dls = g_list_copy(nsgtk_downloads_list);
+ } else {
+ dls = g_list_copy(dl_ctx.list);
+ }
g_list_foreach(dls, (GFunc)action, NULL);
g_list_free(dls);
}
+
static gchar* nsgtk_download_info_to_string(struct gui_download_window *dl)
{
- gchar *size_info = g_strdup_printf(messages_get("gtkSizeInfo"),
- human_friendly_bytesize(dl->size_downloaded),
- dl->size_total == 0 ? messages_get("gtkUnknownSize") :
- human_friendly_bytesize(dl->size_total));
-
+ gchar *size_info;
gchar *r;
- if (dl->status != NSGTK_DOWNLOAD_ERROR)
+ size_info = g_strdup_printf(messages_get("gtkSizeInfo"),
+ human_friendly_bytesize(dl->size_downloaded),
+ dl->size_total == 0 ?
+ messages_get("gtkUnknownSize") :
+ human_friendly_bytesize(dl->size_total));
+
+ if (dl->status != NSGTK_DOWNLOAD_ERROR) {
r = g_strdup_printf("%s\n%s", dl->name->str, size_info);
- else
- r = g_strdup_printf("%s\n%s", dl->name->str,
- dl->error->message);
+ } else {
+ r = g_strdup_printf("%s\n%s", dl->name->str, dl->error->message);
+ }
g_free(size_info);
return r;
}
+
static gchar* nsgtk_download_time_to_string(gint seconds)
{
gint hours, minutes;
- if (seconds < 0)
+ if (seconds < 0) {
return g_strdup("-");
+ }
hours = seconds / 3600;
seconds -= hours * 3600;
minutes = seconds / 60;
seconds -= minutes * 60;
- if (hours > 0)
- return g_strdup_printf("%u:%02u:%02u", hours, minutes,
+ if (hours > 0) {
+ return g_strdup_printf("%u:%02u:%02u",
+ hours,
+ minutes,
seconds);
- else
+ } else {
return g_strdup_printf("%u:%02u", minutes, seconds);
+ }
}
-static void nsgtk_download_store_update_item (struct gui_download_window *dl)
+
+static void nsgtk_download_store_update_item(struct gui_download_window *dl)
{
gchar *info = nsgtk_download_info_to_string(dl);
char *human = human_friendly_bytesize(dl->speed);
@@ -317,11 +390,11 @@ static void nsgtk_download_store_update_item (struct gui_download_window *dl)
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_model_get_iter(GTK_TREE_MODEL(dl_ctx.store),
+ &dl_ctx.iter,
gtk_tree_row_reference_get_path(dl->row));
- gtk_list_store_set(nsgtk_download_store, &nsgtk_download_iter,
+ gtk_list_store_set(dl_ctx.store, &dl_ctx.iter,
NSGTK_DOWNLOAD_PULSE, pulse ? dl->progress : -1,
NSGTK_DOWNLOAD_PROGRESS, pulse ? 0 : dl->progress,
NSGTK_DOWNLOAD_INFO, info,
@@ -334,20 +407,23 @@ static void nsgtk_download_store_update_item (struct gui_download_window *dl)
g_free(time);
}
+
static gboolean nsgtk_download_update(gboolean force_update)
{
/* Be sure we need to update */
- if (!nsgtk_widget_get_visible(GTK_WIDGET(nsgtk_download_window)))
+ if (!nsgtk_widget_get_visible(GTK_WIDGET(dl_ctx.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;
+ gfloat percent, elapsed = g_timer_elapsed(dl_ctx.timer, NULL);
+
+ dl_ctx.num_active = 0;
- for (list = nsgtk_downloads_list; list != NULL; list = list->next) {
+ for (list = dl_ctx.list; list != NULL; list = list->next) {
struct gui_download_window *dl = list->data;
update = force_update;
@@ -366,10 +442,11 @@ static gboolean nsgtk_download_update(gboolean force_update)
dl->progress = (gfloat)
dl->size_downloaded /
dl->size_total * 100;
- } else
+ } else {
dl->progress++;
+ }
- nsgtk_downloads_num_active++;
+ dl_ctx.num_active++;
update = TRUE;
/* Fall through */
@@ -382,60 +459,66 @@ static gboolean nsgtk_download_update(gboolean force_update)
;//Do nothing
}
- if (update)
+ if (update) {
nsgtk_download_store_update_item(dl);
+ }
}
if (pulse_mode) {
text = g_strdup_printf(
- messages_get(nsgtk_downloads_num_active > 1 ?
+ messages_get(dl_ctx.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);
+ dl_ctx.num_active);
+ gtk_progress_bar_pulse(dl_ctx.progress);
+ gtk_progress_bar_set_text(dl_ctx.progress, 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,
+ gtk_progress_bar_set_fraction(dl_ctx.progress,
percent);
- gtk_progress_bar_set_text(nsgtk_download_progress_bar, text);
+ gtk_progress_bar_set_text(dl_ctx.progress, text);
}
g_free(text);
- if (nsgtk_downloads_num_active == 0)
+ if (dl_ctx.num_active == 0) {
return FALSE; /* Returning FALSE here cancels the g_timeout */
- else
+ } else {
return TRUE;
+ }
}
-static void nsgtk_download_store_clear_item(
- struct gui_download_window *dl,
- void *user_data)
+
+static void
+nsgtk_download_store_clear_item(struct gui_download_window *dl, void *user_data)
{
if (dl->sensitivity & NSGTK_DOWNLOAD_CLEAR) {
- nsgtk_downloads_list = g_list_remove(nsgtk_downloads_list, dl);
+ dl_ctx.list = g_list_remove(dl_ctx.list, dl);
- gtk_tree_model_get_iter(GTK_TREE_MODEL(nsgtk_download_store),
- &nsgtk_download_iter,
+ gtk_tree_model_get_iter(GTK_TREE_MODEL(dl_ctx.store),
+ &dl_ctx.iter,
gtk_tree_row_reference_get_path(dl->row));
- gtk_list_store_remove(nsgtk_download_store,
- &nsgtk_download_iter);
+ gtk_list_store_remove(dl_ctx.store,
+ &dl_ctx.iter);
download_context_destroy(dl->ctx);
g_string_free(dl->name, TRUE);
g_string_free(dl->time_left, TRUE);
g_free(dl);
- nsgtk_download_sensitivity_evaluate(nsgtk_download_selection);
+ nsgtk_download_sensitivity_evaluate(dl_ctx.selection);
nsgtk_download_update(FALSE);
}
}
-static void nsgtk_download_tree_view_row_activated(GtkTreeView *tree,
- GtkTreePath *path, GtkTreeViewColumn *column, gpointer data)
+
+static void
+nsgtk_download_tree_view_row_activated(GtkTreeView *tree,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ gpointer data)
{
GtkTreeModel *model;
GtkTreeIter iter;
@@ -448,31 +531,36 @@ static void nsgtk_download_tree_view_row_activated(GtkTreeView *tree,
}
}
-static void nsgtk_download_change_sensitivity(struct gui_download_window *dl,
- nsgtk_download_actions sensitivity)
+
+static void
+nsgtk_download_change_sensitivity(struct gui_download_window *dl,
+ nsgtk_download_actions sensitivity)
{
dl->sensitivity = sensitivity;
- nsgtk_download_sensitivity_evaluate(nsgtk_download_selection);
+ nsgtk_download_sensitivity_evaluate(dl_ctx.selection);
}
-static void nsgtk_download_change_status (
- struct gui_download_window *dl, nsgtk_download_status status)
+
+static 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_model_get_iter(GTK_TREE_MODEL(dl_ctx.store),
+ &dl_ctx.iter,
gtk_tree_row_reference_get_path(dl->row));
- gtk_list_store_set(nsgtk_download_store, &nsgtk_download_iter,
+ gtk_list_store_set(dl_ctx.store, &dl_ctx.iter,
NSGTK_DOWNLOAD_STATUS,
messages_get(status_messages[status]), -1);
}
}
-static void nsgtk_download_store_cancel_item (
- struct gui_download_window *dl,
- void *user_data)
+
+static void
+nsgtk_download_store_cancel_item(struct gui_download_window *dl,
+ void *user_data)
{
if (dl->sensitivity & NSGTK_DOWNLOAD_CANCEL) {
dl->speed = 0;
@@ -490,148 +578,49 @@ static void nsgtk_download_store_cancel_item (
}
}
+
static gboolean nsgtk_download_hide(GtkWidget *window)
{
gtk_widget_hide(window);
return TRUE;
}
-/* exported interface documented in gtk/download.h */
-nserror nsgtk_download_init(void)
-{
- GtkBuilder* builder;
- nserror res;
-
- res = nsgtk_builder_new_from_resname("downloads", &builder);
- if (res != NSERROR_OK) {
- NSLOG(netsurf, INFO, "Download UI builder init failed");
- return res;
- }
-
- gtk_builder_connect_signals(builder, NULL);
-
- nsgtk_download_button_pause = GTK_BUTTON(gtk_builder_get_object(builder, "buttonPause"));
- nsgtk_download_button_clear = GTK_BUTTON(gtk_builder_get_object(builder, "buttonClear"));
- nsgtk_download_button_cancel = GTK_BUTTON(gtk_builder_get_object(builder, "buttonCancel"));
- nsgtk_download_button_resume = GTK_BUTTON(gtk_builder_get_object(builder, "buttonPlay"));
-
- nsgtk_download_progress_bar = GTK_PROGRESS_BAR(gtk_builder_get_object(builder, "progressBar"));
- nsgtk_download_window = GTK_WINDOW(gtk_builder_get_object(builder, "wndDownloads"));
- nsgtk_download_parent = NULL;
-
- gtk_window_set_transient_for(GTK_WINDOW(nsgtk_download_window),
- nsgtk_download_parent);
- 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(builder);
-
- nsgtk_download_store = gtk_list_store_new(NSGTK_DOWNLOAD_N_COLUMNS,
- G_TYPE_INT, /* % complete */
- 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 =
- gtk_tree_view_get_selection(nsgtk_download_tree);
- gtk_tree_selection_set_mode(nsgtk_download_selection,
- GTK_SELECTION_MULTIPLE);
-
- g_signal_connect(G_OBJECT(nsgtk_download_selection), "changed",
- 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(gtk_builder_get_object(builder, "buttonClear"),
- "clicked",
- G_CALLBACK(nsgtk_download_do),
- nsgtk_download_store_clear_item);
- g_signal_connect_swapped(gtk_builder_get_object(builder, "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);
-
- return NSERROR_OK;
-}
-
-void nsgtk_download_destroy ()
-{
- nsgtk_download_do(nsgtk_download_store_cancel_item);
-}
-
-bool nsgtk_check_for_downloads (GtkWindow *parent)
-{
- 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>%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);
-
- gint response = gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy(dialog);
-
- if (response == GTK_RESPONSE_CANCEL)
- return true;
- }
-
- return false;
-}
-
-void nsgtk_download_show(GtkWindow *parent)
-{
- gtk_window_set_transient_for(nsgtk_download_window,
- nsgtk_download_parent);
- gtk_window_present(nsgtk_download_window);
-}
-static gchar* nsgtk_download_dialog_show (const gchar *filename, const gchar *domain,
- const gchar *size)
+/**
+ * Prompt user for downloaded file name
+ *
+ * \param filename The original name of the file
+ * \param domain the domain the file is being downloaded from
+ * \param size The size of the file being downloaded
+ */
+static gchar*
+nsgtk_download_dialog_show(const gchar *filename,
+ const gchar *domain,
+ const gchar *size)
{
enum { GTK_RESPONSE_DOWNLOAD, GTK_RESPONSE_SAVE_AS };
GtkWidget *dialog;
char *destination = NULL;
- gchar *message = g_strdup(messages_get("gtkStartDownload"));
- gchar *info = g_strdup_printf(messages_get("gtkInfo"), filename,
- domain, size);
-
- dialog = gtk_message_dialog_new_with_markup(nsgtk_download_parent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
- "<span size=\"x-large\" weight=\"ultrabold\">%s</span>"
- "\n\n<small>%s</small>",
- message, info);
-
- gtk_dialog_add_buttons(GTK_DIALOG(dialog), NSGTK_STOCK_SAVE,
- GTK_RESPONSE_DOWNLOAD, NSGTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL, NSGTK_STOCK_SAVE_AS,
- GTK_RESPONSE_SAVE_AS, NULL);
+ gchar *message;
+ gchar *info;
+
+ message = g_strdup(messages_get("gtkStartDownload"));
+ info = g_strdup_printf(messages_get("gtkInfo"), filename, domain, size);
+
+ dialog = gtk_message_dialog_new_with_markup(
+ dl_ctx.parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
+ "<span size=\"x-large\" weight=\"ultrabold\">%s</span>"
+ "\n\n<small>%s</small>",
+ message,
+ info);
+
+ gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+ NSGTK_STOCK_SAVE, GTK_RESPONSE_DOWNLOAD,
+ NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ NSGTK_STOCK_SAVE_AS, GTK_RESPONSE_SAVE_AS,
+ NULL);
gint result = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
@@ -640,13 +629,13 @@ static gchar* nsgtk_download_dialog_show (const gchar *filename, const gchar *do
switch (result) {
case GTK_RESPONSE_SAVE_AS: {
- dialog = gtk_file_chooser_dialog_new
- (messages_get("gtkSave"),
- nsgtk_download_parent,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- NSGTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
+ dialog = gtk_file_chooser_dialog_new(
+ messages_get("gtkSave"),
+ dl_ctx.parent,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ NSGTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
gtk_file_chooser_set_current_name
(GTK_FILE_CHOOSER(dialog), filename);
gtk_file_chooser_set_current_folder
@@ -676,30 +665,32 @@ static gchar* nsgtk_download_dialog_show (const gchar *filename, const gchar *do
* confirmation if needed */
if (g_file_test(destination, G_FILE_TEST_EXISTS) &&
nsoption_bool(request_overwrite)) {
- message = g_strdup_printf(messages_get(
- "gtkOverwrite"), filename);
- info = g_strdup_printf(messages_get(
- "gtkOverwriteInfo"),
+ GtkWidget *button;
+
+ message = g_strdup_printf(messages_get("gtkOverwrite"),
+ filename);
+ info = g_strdup_printf(messages_get("gtkOverwriteInfo"),
nsoption_charp(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);
+ dl_ctx.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),
- "%s", info);
+ GTK_MESSAGE_DIALOG(dialog),
+ "%s",
+ info);
- GtkWidget *button = gtk_dialog_add_button(
- GTK_DIALOG(dialog),
- "_Replace",
- GTK_RESPONSE_DOWNLOAD);
+ button = gtk_dialog_add_button(GTK_DIALOG(dialog),
+ "_Replace",
+ GTK_RESPONSE_DOWNLOAD);
gtk_button_set_image(GTK_BUTTON(button),
nsgtk_image_new_from_stock(
- NSGTK_STOCK_SAVE,
- GTK_ICON_SIZE_BUTTON));
+ NSGTK_STOCK_SAVE,
+ GTK_ICON_SIZE_BUTTON));
gint result = gtk_dialog_run(GTK_DIALOG(dialog));
if (result == GTK_RESPONSE_CANCEL)
@@ -716,20 +707,24 @@ static gchar* nsgtk_download_dialog_show (const gchar *filename, const gchar *do
}
-static gboolean nsgtk_download_handle_error (GError *error)
+static gboolean nsgtk_download_handle_error(GError *error)
{
+ GtkWidget*dialog;
+ gchar *message;
+
if (error != NULL) {
- GtkWidget*dialog;
- gchar *message = g_strdup_printf(messages_get("gtkFileError"),
- error->message);
-
- dialog = gtk_message_dialog_new_with_markup
- (nsgtk_download_parent,
- GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- "<big><b>%s</b></big>\n\n"
- "<small>%s</small>", messages_get("gtkFailed"),
- message);
+ message = g_strdup_printf(messages_get("gtkFileError"),
+ error->message);
+
+ dialog = gtk_message_dialog_new_with_markup(
+ dl_ctx.parent,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "<big><b>%s</b></big>\n\n"
+ "<small>%s</small>",
+ messages_get("gtkFailed"),
+ message);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
@@ -738,14 +733,19 @@ static gboolean nsgtk_download_handle_error (GError *error)
return FALSE;
}
-static void nsgtk_download_store_create_item (struct gui_download_window *dl)
+
+static 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,
- NSGTK_DOWNLOAD, dl, -1);
+ gtk_list_store_set(dl_ctx.store,
+ &dl_ctx.iter,
+ NSGTK_DOWNLOAD,
+ dl,
+ -1);
}
+
/**
* Wrapper to GSourceFunc-ify nsgtk_download_update.
*/
@@ -755,22 +755,31 @@ nsgtk_download_gsourcefunc__nsgtk_download_update(gpointer user_data)
return nsgtk_download_update(FALSE);
}
+
+/**
+ * core callback on creating a new download
+ */
static struct gui_download_window *
gui_download_window_create(download_context *ctx, struct gui_window *gui)
{
- nsurl *url = download_context_get_url(ctx);
- unsigned long total_size = download_context_get_total_length(ctx);
+ nsurl *url;
+ unsigned long total_size;
gchar *domain;
gchar *destination;
- gboolean unknown_size = total_size == 0;
- const char *size = (total_size == 0 ?
- messages_get("gtkUnknownSize") :
- human_friendly_bytesize(total_size));
+ gboolean unknown_size;
+ struct gui_download_window *download;
+ const char *size;
+
+ url = download_context_get_url(ctx);
+ total_size = download_context_get_total_length(ctx);
+ unknown_size = total_size == 0;
+ size = (total_size == 0 ?
+ messages_get("gtkUnknownSize") :
+ human_friendly_bytesize(total_size));
- nsgtk_download_parent =
- nsgtk_scaffolding_window(nsgtk_get_scaffold(gui));
+ dl_ctx.parent = nsgtk_scaffolding_window(nsgtk_get_scaffold(gui));
- struct gui_download_window *download = malloc(sizeof *download);
+ download = malloc(sizeof *download);
if (download == NULL) {
return NULL;
}
@@ -797,12 +806,12 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
/* 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);
+ gtk_list_store_prepend(dl_ctx.store, &dl_ctx.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));
+ GTK_TREE_MODEL(dl_ctx.store),
+ gtk_tree_model_get_path(
+ GTK_TREE_MODEL(dl_ctx.store),
+ &dl_ctx.iter));
download->ctx = ctx;
download->name = g_string_new(download_context_get_filename(ctx));
@@ -810,13 +819,14 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
download->size_total = total_size;
download->size_downloaded = 0;
download->speed = 0;
- download->start_time = g_timer_elapsed(nsgtk_downloads_timer, NULL);
+ download->start_time = g_timer_elapsed(dl_ctx.timer, NULL);
download->time_remaining = -1;
download->status = NSGTK_DOWNLOAD_NONE;
download->progress = 0;
download->error = NULL;
- download->write =
- g_io_channel_new_file(destination, "w", &download->error);
+ download->write = g_io_channel_new_file(destination,
+ "w",
+ &download->error);
if (nsgtk_download_handle_error(download->error)) {
g_string_free(download->name, TRUE);
@@ -829,26 +839,32 @@ gui_download_window_create(download_context *ctx, struct gui_window *gui)
nsgtk_download_change_sensitivity(download, NSGTK_DOWNLOAD_CANCEL);
nsgtk_download_store_create_item(download);
- nsgtk_download_show(nsgtk_download_parent);
+ nsgtk_download_show(dl_ctx.parent);
- if (unknown_size)
+ if (unknown_size) {
nsgtk_download_change_status(download, NSGTK_DOWNLOAD_WORKING);
+ }
- if (nsgtk_downloads_num_active == 0) {
+ if (dl_ctx.num_active == 0) {
g_timeout_add(
UPDATE_RATE,
nsgtk_download_gsourcefunc__nsgtk_download_update,
NULL);
}
- nsgtk_downloads_list = g_list_prepend(nsgtk_downloads_list, download);
+ dl_ctx.list = g_list_prepend(dl_ctx.list, download);
return download;
}
-static nserror gui_download_window_data(struct gui_download_window *dw,
- const char *data, unsigned int size)
+/**
+ * core callback on receipt of data
+ */
+static nserror
+gui_download_window_data(struct gui_download_window *dw,
+ const char *data,
+ unsigned int size)
{
g_io_channel_write_chars(dw->write, data, size, NULL, &dw->error);
if (dw->error != NULL) {
@@ -860,7 +876,7 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
nsgtk_download_update(TRUE);
- gtk_window_present(nsgtk_download_window);
+ gtk_window_present(dl_ctx.window);
return NSERROR_SAVE_FAILED;
}
@@ -870,12 +886,18 @@ static nserror gui_download_window_data(struct gui_download_window *dw,
}
-static void gui_download_window_error(struct gui_download_window *dw,
- const char *error_msg)
+/**
+ * core callback on error
+ */
+static void
+gui_download_window_error(struct gui_download_window *dw, const char *error_msg)
{
}
+/**
+ * core callback when core download is complete
+ */
static void gui_download_window_done(struct gui_download_window *dw)
{
g_io_channel_shutdown(dw->write, TRUE, &dw->error);
@@ -888,10 +910,11 @@ static void gui_download_window_done(struct gui_download_window *dw)
nsgtk_download_change_sensitivity(dw, NSGTK_DOWNLOAD_CLEAR);
nsgtk_download_change_status(dw, NSGTK_DOWNLOAD_COMPLETE);
- if (nsoption_bool(downloads_clear))
+ if (nsoption_bool(downloads_clear)) {
nsgtk_download_store_clear_item(dw, NULL);
- else
+ } else {
nsgtk_download_update(TRUE);
+ }
}
@@ -903,3 +926,146 @@ static struct gui_download_table download_table = {
};
struct gui_download_table *nsgtk_download_table = &download_table;
+
+
+/* exported interface documented in gtk/download.h */
+nserror nsgtk_download_init(void)
+{
+ GtkBuilder* builder;
+ nserror res;
+
+ res = nsgtk_builder_new_from_resname("downloads", &builder);
+ if (res != NSERROR_OK) {
+ NSLOG(netsurf, INFO, "Download UI builder init failed");
+ return res;
+ }
+
+ gtk_builder_connect_signals(builder, NULL);
+
+ dl_ctx.pause = GTK_BUTTON(gtk_builder_get_object(builder,
+ "buttonPause"));
+ dl_ctx.clear = GTK_BUTTON(gtk_builder_get_object(builder,
+ "buttonClear"));
+ dl_ctx.cancel = GTK_BUTTON(gtk_builder_get_object(builder,
+ "buttonCancel"));
+ dl_ctx.resume = GTK_BUTTON(gtk_builder_get_object(builder,
+ "buttonPlay"));
+
+ dl_ctx.progress = GTK_PROGRESS_BAR(gtk_builder_get_object(builder,
+ "progressBar"));
+ dl_ctx.window = GTK_WINDOW(gtk_builder_get_object(builder,
+ "wndDownloads"));
+ dl_ctx.parent = NULL;
+
+ gtk_window_set_transient_for(GTK_WINDOW(dl_ctx.window),
+ dl_ctx.parent);
+ gtk_window_set_destroy_with_parent(GTK_WINDOW(dl_ctx.window),
+ FALSE);
+
+ dl_ctx.timer = g_timer_new();
+
+ dl_ctx.tree = nsgtk_download_tree_view_new(builder);
+
+ dl_ctx.store = gtk_list_store_new(NSGTK_DOWNLOAD_N_COLUMNS,
+ G_TYPE_INT, /* % complete */
+ 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(dl_ctx.tree, GTK_TREE_MODEL(dl_ctx.store));
+
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(dl_ctx.store),
+ NSGTK_DOWNLOAD_STATUS,
+ (GtkTreeIterCompareFunc)nsgtk_download_sort, NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dl_ctx.store),
+ NSGTK_DOWNLOAD_STATUS,
+ GTK_SORT_ASCENDING);
+
+ g_object_unref(dl_ctx.store);
+
+ dl_ctx.selection = gtk_tree_view_get_selection(dl_ctx.tree);
+ gtk_tree_selection_set_mode(dl_ctx.selection, GTK_SELECTION_MULTIPLE);
+
+ g_signal_connect(G_OBJECT(dl_ctx.selection),
+ "changed",
+ G_CALLBACK(nsgtk_download_sensitivity_evaluate),
+ NULL);
+
+ g_signal_connect(dl_ctx.tree,
+ "row-activated",
+ G_CALLBACK(nsgtk_download_tree_view_row_activated),
+ NULL);
+
+ g_signal_connect_swapped(gtk_builder_get_object(builder, "buttonClear"),
+ "clicked",
+ G_CALLBACK(nsgtk_download_do),
+ nsgtk_download_store_clear_item);
+
+ g_signal_connect_swapped(gtk_builder_get_object(builder, "buttonCancel"),
+ "clicked",
+ G_CALLBACK(nsgtk_download_do),
+ nsgtk_download_store_cancel_item);
+
+ g_signal_connect(G_OBJECT(dl_ctx.window),
+ "delete-event",
+ G_CALLBACK(nsgtk_download_hide),
+ NULL);
+
+ return NSERROR_OK;
+}
+
+
+/* exported interface documented in gtk/download.h */
+void nsgtk_download_destroy ()
+{
+ nsgtk_download_do(nsgtk_download_store_cancel_item);
+}
+
+
+/* exported interface documented in gtk/download.h */
+bool nsgtk_check_for_downloads(GtkWindow *parent)
+{
+ GtkWidget *dialog;
+ gint response;
+
+ if (dl_ctx.num_active == 0) {
+ return false;
+ }
+
+ dialog = gtk_message_dialog_new_with_markup(
+ parent,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "<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);
+
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+
+ if (response == GTK_RESPONSE_CANCEL) {
+ return true;
+ }
+
+ return false;
+}
+
+
+/* exported interface documented in gtk/download.h */
+void nsgtk_download_show(GtkWindow *parent)
+{
+ gtk_window_set_transient_for(dl_ctx.window, dl_ctx.parent);
+ gtk_window_present(dl_ctx.window);
+}
diff --git a/frontends/gtk/download.h b/frontends/gtk/download.h
index b720650ca..c6dc187e7 100644
--- a/frontends/gtk/download.h
+++ b/frontends/gtk/download.h
@@ -19,13 +19,12 @@
#ifndef GTK_DOWNLOAD_H
#define GTK_DOWNLOAD_H
-#include <gtk/gtk.h>
-
/**
* download operation table for gtk
*/
extern struct gui_download_table *nsgtk_download_table;
+
/**
* Initialise download window ready for use.
*
@@ -33,9 +32,27 @@ extern struct gui_download_table *nsgtk_download_table;
*/
nserror nsgtk_download_init(void);
-void nsgtk_download_destroy (void);
+
+/**
+ * Destroy download window
+ */
+void nsgtk_download_destroy(void);
+
+
+/**
+ * Check with user if download is in progress they want to complete
+ *
+ * \param parent The parent window for the prompt dialog.
+ * \return true if the user wants to continue else false.
+ */
bool nsgtk_check_for_downloads(GtkWindow *parent);
+
+
+/**
+ * Show the download window
+ *
+ * \param parent The parent window to use for the shown window
+ */
void nsgtk_download_show(GtkWindow *parent);
-void nsgtk_download_add(gchar *url, gchar *destination);
#endif