From 0c87c491460125f6fd0bcf74b135cec7ae04c00e Mon Sep 17 00:00:00 2001 From: Helder Martins Date: Wed, 10 Jul 2013 18:29:10 +0100 Subject: [PATCH 1/3] Implemented clear functionality for DCC download manager. Created clear button in DCC downloaded manager interface. --- src/common/dcc.c | 9 +++++ src/common/dcc.h | 1 + src/fe-gtk/dccgui.c | 81 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/common/dcc.c b/src/common/dcc.c index c0527510..57c0d477 100644 --- a/src/common/dcc.c +++ b/src/common/dcc.c @@ -227,6 +227,15 @@ is_dcc (struct DCC *dcc) return FALSE; } +gboolean +is_dcc_fcompleted (struct DCC *dcc) +{ + if (dcc != NULL) + return (dcc->dccstat == STAT_FAILED || dcc->dccstat == STAT_DONE || dcc->dccstat == STAT_ABORTED); + + return FALSE; +} + /* this is called from hexchat.c:hexchat_misc_checks() every 1 second. */ void diff --git a/src/common/dcc.h b/src/common/dcc.h index e3163c8a..6f3b152f 100644 --- a/src/common/dcc.h +++ b/src/common/dcc.h @@ -117,6 +117,7 @@ struct dccstat_info extern struct dccstat_info dccstat[]; gboolean is_dcc (struct DCC *dcc); +gboolean is_dcc_fcompleted (struct DCC *dcc); void dcc_abort (session *sess, struct DCC *dcc); void dcc_get (struct DCC *dcc); int dcc_resume (struct DCC *dcc); diff --git a/src/fe-gtk/dccgui.c b/src/fe-gtk/dccgui.c index 24d3bcbf..e5d1e9cb 100644 --- a/src/fe-gtk/dccgui.c +++ b/src/fe-gtk/dccgui.c @@ -78,6 +78,7 @@ struct dccwindow GtkWidget *accept_button; GtkWidget *resume_button; GtkWidget *open_button; + GtkWidget *clear_button; /* clears aborted and completed requests */ GtkWidget *file_label; GtkWidget *address_label; @@ -380,6 +381,43 @@ dcc_append (struct DCC *dcc, GtkListStore *store, gboolean prepend) dcc_prepare_row_send (dcc, store, &iter, FALSE); } +/* Retrives aborted, sent and received tasks of current view */ +static GSList * +dcc_get_completed (void) +{ + struct DCC *dcc; + GtkTreeIter iter; + GtkTreeModel *model; + GSList *completed = NULL; + + model = GTK_TREE_MODEL (dccfwin.store); + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + gtk_tree_model_get (model, &iter, COL_DCC, &dcc, -1); + if (is_dcc_fcompleted (dcc)) + completed = g_slist_prepend (completed, dcc); + + } while (gtk_tree_model_iter_next (model, &iter)); + } + + return completed; +} + +static gboolean +exists_completed_tasks (void) +{ + gboolean exist; + GSList *comp_list; + + comp_list = dcc_get_completed (); + exist = comp_list != NULL; + + g_slist_free (comp_list); + return exist; +} + static void dcc_fill_window (int flags) { @@ -426,6 +464,10 @@ dcc_fill_window (int flags) gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dccfwin.store), &iter); gtk_tree_selection_select_iter (dccfwin.sel, &iter); } + else + { + gtk_widget_set_sensitive (dccfwin.clear_button, exists_completed_tasks ()); + } } /* return list of selected DCCs */ @@ -460,6 +502,14 @@ dcc_get_selected (void) dccfwin.sel, COL_DCC); } +static void +sensitize_clear_button (void) +{ + gboolean show = (exists_completed_tasks () && !dcc_get_selected ()); + gtk_widget_set_sensitive (dccfwin.clear_button, show); +} + + static void resume_clicked (GtkWidget * wid, gpointer none) { @@ -511,6 +561,9 @@ abort_clicked (GtkWidget * wid, gpointer none) dcc_abort (dcc->serv->front_session, dcc); } g_slist_free (start); + + /* putting it here avoids redudant calls when user presses clear button*/ + sensitize_clear_button (); } static void @@ -529,6 +582,27 @@ accept_clicked (GtkWidget * wid, gpointer none) g_slist_free (start); } + +static void +clear_completed (GtkWidget * wid, gpointer none) +{ + struct DCC *dcc; + GSList *completed = 0; + + /* dcc_abort may change dcc_list structure, so we need to gather the targets + first. This way, we assume nothing about the order of items in the list (after dcc_abort)*/ + completed = dcc_get_completed (); + for (; completed; completed = completed->next) + { + dcc = completed->data; + dcc_abort (dcc->serv->front_session, dcc); + } + + /* The data was freed by dcc_close */ + g_slist_free (completed); + sensitize_clear_button (); +} + static void browse_folder (char *dir) { @@ -590,7 +664,9 @@ dcc_row_cb (GtkTreeSelection *sel, gpointer user_data) dcc_details_populate (NULL); return; } - + + /* there is at least a selection, disable button... similar to banlist semantics*/ + gtk_widget_set_sensitive (dccfwin.clear_button, FALSE); gtk_widget_set_sensitive (dccfwin.abort_button, TRUE); if (list->next) /* multi selection */ @@ -812,6 +888,7 @@ fe_dcc_open_recv_win (int passive) dccfwin.abort_button = gtkutil_button (bbox, GTK_STOCK_CANCEL, 0, abort_clicked, 0, _("Abort")); dccfwin.accept_button = gtkutil_button (bbox, GTK_STOCK_APPLY, 0, accept_clicked, 0, _("Accept")); dccfwin.resume_button = gtkutil_button (bbox, GTK_STOCK_REFRESH, 0, resume_clicked, 0, _("Resume")); + dccfwin.clear_button = gtkutil_button (bbox, GTK_STOCK_CLEAR, 0, clear_completed, 0, _("Clear")); dccfwin.open_button = gtkutil_button (bbox, 0, 0, browse_dcc_folder, 0, _("Open Folder...")); gtk_widget_set_sensitive (dccfwin.accept_button, FALSE); gtk_widget_set_sensitive (dccfwin.resume_button, FALSE); @@ -1055,6 +1132,8 @@ fe_dcc_update (struct DCC *dcc) default: dcc_update_chat (dcc); } + + sensitize_clear_button (); } void From a8abba84bda165d283fad84ea77d59e211629bee Mon Sep 17 00:00:00 2001 From: Helder Martins Date: Wed, 17 Jul 2013 09:20:54 +0100 Subject: [PATCH 2/3] Fixed coding style and clearified some comments, following arnavion suggestions --- src/common/dcc.c | 2 +- src/common/dcc.h | 2 +- src/fe-gtk/dccgui.c | 39 +++++++++++++++++++-------------------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/common/dcc.c b/src/common/dcc.c index 57c0d477..1cd22d97 100644 --- a/src/common/dcc.c +++ b/src/common/dcc.c @@ -228,7 +228,7 @@ is_dcc (struct DCC *dcc) } gboolean -is_dcc_fcompleted (struct DCC *dcc) +is_dcc_completed (struct DCC *dcc) { if (dcc != NULL) return (dcc->dccstat == STAT_FAILED || dcc->dccstat == STAT_DONE || dcc->dccstat == STAT_ABORTED); diff --git a/src/common/dcc.h b/src/common/dcc.h index 6f3b152f..acb87f34 100644 --- a/src/common/dcc.h +++ b/src/common/dcc.h @@ -117,7 +117,7 @@ struct dccstat_info extern struct dccstat_info dccstat[]; gboolean is_dcc (struct DCC *dcc); -gboolean is_dcc_fcompleted (struct DCC *dcc); +gboolean is_dcc_completed (struct DCC *dcc); void dcc_abort (session *sess, struct DCC *dcc); void dcc_get (struct DCC *dcc); int dcc_resume (struct DCC *dcc); diff --git a/src/fe-gtk/dccgui.c b/src/fe-gtk/dccgui.c index e5d1e9cb..6e1024b0 100644 --- a/src/fe-gtk/dccgui.c +++ b/src/fe-gtk/dccgui.c @@ -381,7 +381,7 @@ dcc_append (struct DCC *dcc, GtkListStore *store, gboolean prepend) dcc_prepare_row_send (dcc, store, &iter, FALSE); } -/* Retrives aborted, sent and received tasks of current view */ +/* Returns aborted and completed transfers. */ static GSList * dcc_get_completed (void) { @@ -396,7 +396,7 @@ dcc_get_completed (void) do { gtk_tree_model_get (model, &iter, COL_DCC, &dcc, -1); - if (is_dcc_fcompleted (dcc)) + if (is_dcc_completed (dcc)) completed = g_slist_prepend (completed, dcc); } while (gtk_tree_model_iter_next (model, &iter)); @@ -406,7 +406,7 @@ dcc_get_completed (void) } static gboolean -exists_completed_tasks (void) +dcc_completed_transfer_exists (void) { gboolean exist; GSList *comp_list; @@ -466,7 +466,7 @@ dcc_fill_window (int flags) } else { - gtk_widget_set_sensitive (dccfwin.clear_button, exists_completed_tasks ()); + gtk_widget_set_sensitive (dccfwin.clear_button, dcc_completed_transfer_exists ()); } } @@ -503,13 +503,12 @@ dcc_get_selected (void) } static void -sensitize_clear_button (void) +update_clear_button_sensitivity (void) { - gboolean show = (exists_completed_tasks () && !dcc_get_selected ()); - gtk_widget_set_sensitive (dccfwin.clear_button, show); + gboolean sensitive = dcc_completed_transfer_exists () && !dcc_get_selected (); + gtk_widget_set_sensitive (dccfwin.clear_button, sensitive); } - static void resume_clicked (GtkWidget * wid, gpointer none) { @@ -562,8 +561,8 @@ abort_clicked (GtkWidget * wid, gpointer none) } g_slist_free (start); - /* putting it here avoids redudant calls when user presses clear button*/ - sensitize_clear_button (); + /* Enable the clear button if it wasn't already enabled */ + update_clear_button_sensitivity (); } static void @@ -582,17 +581,17 @@ accept_clicked (GtkWidget * wid, gpointer none) g_slist_free (start); } - static void clear_completed (GtkWidget * wid, gpointer none) { struct DCC *dcc; - GSList *completed = 0; - - /* dcc_abort may change dcc_list structure, so we need to gather the targets - first. This way, we assume nothing about the order of items in the list (after dcc_abort)*/ - completed = dcc_get_completed (); - for (; completed; completed = completed->next) + GSList *completed; + + /* Make a new list of only the completed items and abort each item. + * A new list is made because calling dcc_abort removes items from the original list, + * making it impossible to iterate over that list directly. + */ + for (completed = dcc_get_completed (); completed; completed = completed->next) { dcc = completed->data; dcc_abort (dcc->serv->front_session, dcc); @@ -600,7 +599,7 @@ clear_completed (GtkWidget * wid, gpointer none) /* The data was freed by dcc_close */ g_slist_free (completed); - sensitize_clear_button (); + update_clear_button_sensitivity (); } static void @@ -665,7 +664,7 @@ dcc_row_cb (GtkTreeSelection *sel, gpointer user_data) return; } - /* there is at least a selection, disable button... similar to banlist semantics*/ + /* if a row is selected, the clear button is disabled. */ gtk_widget_set_sensitive (dccfwin.clear_button, FALSE); gtk_widget_set_sensitive (dccfwin.abort_button, TRUE); @@ -1133,7 +1132,7 @@ fe_dcc_update (struct DCC *dcc) dcc_update_chat (dcc); } - sensitize_clear_button (); + update_clear_button_sensitivity (); } void From 78d14a2b1e4c62eee76d707e134a6fd37a8658f8 Mon Sep 17 00:00:00 2001 From: Helder Martins Date: Tue, 23 Jul 2013 23:55:20 +0100 Subject: [PATCH 3/3] Removed restriction that disabled the clear button if at least one transfer item was selected in dcc download manager. --- src/fe-gtk/dccgui.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/fe-gtk/dccgui.c b/src/fe-gtk/dccgui.c index 6e1024b0..a3c2619a 100644 --- a/src/fe-gtk/dccgui.c +++ b/src/fe-gtk/dccgui.c @@ -418,6 +418,13 @@ dcc_completed_transfer_exists (void) return exist; } +static void +update_clear_button_sensitivity (void) +{ + gboolean sensitive = dcc_completed_transfer_exists (); + gtk_widget_set_sensitive (dccfwin.clear_button, sensitive); +} + static void dcc_fill_window (int flags) { @@ -464,10 +471,8 @@ dcc_fill_window (int flags) gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dccfwin.store), &iter); gtk_tree_selection_select_iter (dccfwin.sel, &iter); } - else - { - gtk_widget_set_sensitive (dccfwin.clear_button, dcc_completed_transfer_exists ()); - } + + update_clear_button_sensitivity (); } /* return list of selected DCCs */ @@ -502,13 +507,6 @@ dcc_get_selected (void) dccfwin.sel, COL_DCC); } -static void -update_clear_button_sensitivity (void) -{ - gboolean sensitive = dcc_completed_transfer_exists () && !dcc_get_selected (); - gtk_widget_set_sensitive (dccfwin.clear_button, sensitive); -} - static void resume_clicked (GtkWidget * wid, gpointer none) { @@ -663,9 +661,7 @@ dcc_row_cb (GtkTreeSelection *sel, gpointer user_data) dcc_details_populate (NULL); return; } - - /* if a row is selected, the clear button is disabled. */ - gtk_widget_set_sensitive (dccfwin.clear_button, FALSE); + gtk_widget_set_sensitive (dccfwin.abort_button, TRUE); if (list->next) /* multi selection */