From: Richard Kettlewell Date: Sat, 14 Jun 2008 17:15:51 +0000 (+0100) Subject: Update choose screen when a rescan completes (and drive initial fill X-Git-Tag: 4.1~15^2~15 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/00e0c65285bf2e4c345f32bad3ee6b9f72c5c88a Update choose screen when a rescan completes (and drive initial fill off this). --- diff --git a/disobedience/added.c b/disobedience/added.c index e3c41c2..146872f 100644 --- a/disobedience/added.c +++ b/disobedience/added.c @@ -66,7 +66,7 @@ static void added_changed(const char attribute((unused)) *event, /** @brief Called at startup */ static void added_init(void) { - event_register("added-changed", added_changed, 0); + event_register("rescan-complete", added_changed, 0); } /** @brief Columns for the new tracks list */ diff --git a/disobedience/choose.c b/disobedience/choose.c index d25b3e7..228194a 100644 --- a/disobedience/choose.c +++ b/disobedience/choose.c @@ -382,15 +382,15 @@ static void choose_state_toggled } -static void choose_row_expanded(GtkTreeView attribute((unused)) *treeview, - GtkTreeIter *iter, - GtkTreePath *path, - gpointer attribute((unused)) user_data) { - /*fprintf(stderr, "row-expanded path=[%s]\n\n", - gtk_tree_path_to_string(path));*/ - /* We update a node's contents whenever it is expanded, even if it was - * already populated; the effect is that contracting and expanding a node - * suffices to update it to the latest state on the server. */ +/** @brief (Re-)get the children of @p path + * @param path Path to target row + * @param iter Iterator pointing at target row + * + * Called from choose_row_expanded() to make sure that the contents are present + * and from choose_refill_callback() to (re-)synchronize. + */ +static void choose_refill_row(GtkTreePath *path, + GtkTreeIter *iter) { const char *track = choose_get_track(iter); disorder_eclient_files(client, choose_files_completed, track, @@ -404,7 +404,18 @@ static void choose_row_expanded(GtkTreeView attribute((unused)) *treeview, path)); /* The row references are destroyed in the _completed handlers. */ choose_list_in_flight += 2; - //fprintf(stderr, "choose_list_in_flight -> %d+\n", choose_list_in_flight); +} + +static void choose_row_expanded(GtkTreeView attribute((unused)) *treeview, + GtkTreeIter *iter, + GtkTreePath *path, + gpointer attribute((unused)) user_data) { + /*fprintf(stderr, "row-expanded path=[%s]\n\n", + gtk_tree_path_to_string(path));*/ + /* We update a node's contents whenever it is expanded, even if it was + * already populated; the effect is that contracting and expanding a node + * suffices to update it to the latest state on the server. */ + choose_refill_row(path, iter); if(!choose_suppress_set_autocollapse) { if(choose_auto_expanding) { /* This was an automatic expansion; mark it the row for auto-collapse. */ @@ -465,6 +476,35 @@ void choose_auto_collapse(void) { 0); } +/** @brief Called from choose_refill() with each expanded row */ +static void choose_refill_callback(GtkTreeView attribute((unused)) *tree_view, + GtkTreePath *path, + gpointer attribute((unused)) user_data) { + GtkTreeIter it[1]; + + gtk_tree_model_get_iter(GTK_TREE_MODEL(choose_store), it, path); + choose_refill_row(path, it); +} + +/** @brief Synchronize all visible data with the server + * + * Called at startup, when a rescan completes, and via periodic_slow(). + */ +static void choose_refill(const char attribute((unused)) *event, + void attribute((unused)) *eventdata, + void attribute((unused)) *callbackdata) { + //fprintf(stderr, "choose_refill\n"); + /* Update the root */ + disorder_eclient_files(client, choose_files_completed, "", NULL, NULL); + disorder_eclient_dirs(client, choose_dirs_completed, "", NULL, NULL); + choose_list_in_flight += 2; + /* Update all expanded rows */ + gtk_tree_view_map_expanded_rows(GTK_TREE_VIEW(choose_view), + choose_refill_callback, + 0); + //fprintf(stderr, "choose_list_in_flight -> %d+\n", choose_list_in_flight); +} + /** @brief Create the choose tab */ GtkWidget *choose_widget(void) { /* Create the tree store. */ @@ -549,11 +589,9 @@ GtkWidget *choose_widget(void) { event_register("search-results-changed", choose_set_state, 0); event_register("lookups-completed", choose_set_state, 0); - /* Fill the root */ - disorder_eclient_files(client, choose_files_completed, "", NULL, NULL); - disorder_eclient_dirs(client, choose_dirs_completed, "", NULL, NULL); - choose_list_in_flight += 2; - //fprintf(stderr, "choose_list_in_flight -> %d+\n", choose_list_in_flight); + /* After a rescan we update the choose tree. We get a rescan-complete + * automatically at startup and upon connection too. */ + event_register("rescan-complete", choose_refill, 0); /* Make the widget scrollable */ GtkWidget *scrolled = scroll_widget(choose_view); diff --git a/disobedience/control.c b/disobedience/control.c index b62fc06..3ccd7c2 100644 --- a/disobedience/control.c +++ b/disobedience/control.c @@ -351,15 +351,18 @@ static void volume_changed(const char attribute((unused)) *event, static void icon_changed(const char attribute((unused)) *event, void attribute((unused)) *evendata, void *callbackdata) { + //fprintf(stderr, "icon_changed (%s)\n", event); const struct icon *const icon = callbackdata; int on = icon->on ? icon->on() : 1; int sensitive = icon->sensitive ? icon->sensitive() : 1; + //fprintf(stderr, "sensitive->%d\n", sensitive); GtkWidget *child, *newchild; ++suppress_actions; /* If the connection is down nothing is ever usable */ if(!(last_state & DISORDER_CONNECTED)) sensitive = 0; + //fprintf(stderr, "(checked connected) sensitive->%d\n", sensitive); /* Replace the child */ newchild = on ? icon->image_on : icon->image_off; child = gtk_bin_get_child(GTK_BIN(icon->button)); @@ -371,7 +374,7 @@ static void icon_changed(const char attribute((unused)) *event, } /* If you disable play or random play NOT via the icon (for instance, via the * edit menu or via a completely separate command line invocation) then the - * icon shows up as insensitive. Hover the mouse over it and the corrcet + * icon shows up as insensitive. Hover the mouse over it and the correct * state is immediately displayed. sensitive and GTK_WIDGET_SENSITIVE show * it to be in the correct state, so I think this is may be a GTK+ bug. */ if(icon->tip_on) diff --git a/disobedience/disobedience.c b/disobedience/disobedience.c index 80fd389..7225bc8 100644 --- a/disobedience/disobedience.c +++ b/disobedience/disobedience.c @@ -96,7 +96,9 @@ int rtp_supported; /** @brief True if RTP play is enabled */ int rtp_is_running; -static void check_rtp_address(void); +static void check_rtp_address(const char *event, + void *eventdata, + void *callbackdata); /* Window creation --------------------------------------------------------- */ @@ -224,16 +226,8 @@ static gboolean periodic_slow(gpointer attribute((unused)) data) { /* Update everything to be sure that the connection to the server hasn't * mysteriously gone stale on us. */ all_update(); - /* Periodically check what our rights are */ - if(!rights_lookup_in_flight) { - rights_lookup_in_flight = 1; - disorder_eclient_userinfo(client, - userinfo_rights_completed, - config->username, "rights", - 0); - } /* Recheck RTP status too */ - check_rtp_address(); + check_rtp_address(0, 0, 0); return TRUE; /* don't remove me */ } @@ -264,6 +258,14 @@ static gboolean periodic_fast(gpointer attribute((unused)) data) { event_raise("volume-changed", 0); } } + /* Periodically check what our rights are */ + if(!rights_lookup_in_flight) { + rights_lookup_in_flight = 1; + disorder_eclient_userinfo(client, + userinfo_rights_completed, + config->username, "rights", + 0); + } return TRUE; } @@ -311,6 +313,8 @@ static void got_rtp_address(void attribute((unused)) *v, rtp_supported = 1; rtp_is_running = rtp_running(); } + /*fprintf(stderr, "rtp supported->%d, running->%d\n", + rtp_supported, rtp_is_running);*/ if(rtp_supported != rtp_was_supported || rtp_is_running != rtp_was_running) event_raise("rtp-changed", 0); @@ -318,9 +322,13 @@ static void got_rtp_address(void attribute((unused)) *v, } /** @brief Called to check whether RTP play is available */ -static void check_rtp_address(void) { - if(!rtp_address_in_flight) +static void check_rtp_address(const char attribute((unused)) *event, + void attribute((unused)) *eventdata, + void attribute((unused)) *callbackdata) { + if(!rtp_address_in_flight) { + //fprintf(stderr, "checking rtp\n"); disorder_eclient_rtp_address(client, got_rtp_address, NULL); + } } /* main -------------------------------------------------------------------- */ @@ -396,7 +404,7 @@ int main(int argc, char **argv) { || !(logclient = gtkclient())) return 1; /* already reported an error */ /* periodic operations (e.g. expiring the cache, checking local volume) */ - g_timeout_add(10000/*milliseconds*/, periodic_slow, 0); + g_timeout_add(600000/*milliseconds*/, periodic_slow, 0); g_timeout_add(1000/*milliseconds*/, periodic_fast, 0); /* global tooltips */ tips = gtk_tooltips_new(); @@ -413,8 +421,8 @@ int main(int argc, char **argv) { /* Start monitoring the log */ disorder_eclient_log(logclient, &log_callbacks, 0); /* Initiate all the checks */ - periodic_slow(0); periodic_fast(0); + event_register("log-connected", check_rtp_address, 0); suppress_actions = 0; /* If no password is set yet pop up a login box */ if(!config->password) diff --git a/disobedience/log.c b/disobedience/log.c index f0ea7d1..affa449 100644 --- a/disobedience/log.c +++ b/disobedience/log.c @@ -66,7 +66,7 @@ void all_update(void) { event_raise("queue-changed", 0); event_raise("recent-changed", 0); event_raise("volume-changed", 0); - event_raise("added-changed", 0); + event_raise("rescan-complete", 0); --suppress_actions; } @@ -81,6 +81,7 @@ static void log_connected(void attribute((unused)) *v) { * everything. We get this at startup too and this is how we do the initial * state fetch. */ all_update(); + event_raise("log-connected", 0); } /** @brief Called when the current track finishes playing */ @@ -188,7 +189,7 @@ static void log_volume(void attribute((unused)) *v, /** @brief Called when a rescan completes */ static void log_rescanned(void attribute((unused)) *v) { - event_raise("added-changed", 0); + event_raise("rescan-complete", 0); } /*