-/** @brief Called BY GTK+ to tell us the search entry box has changed */
-static void searchentry_changed(GtkEditable attribute((unused)) *editable,
- gpointer attribute((unused)) user_data) {
- initiate_search();
-}
-
-/* Track menu items -------------------------------------------------------- */
-
-/** @brief Recursive step for gather_selected() */
-static void recurse_selected(struct choosenode *cn, struct vector *v) {
- int n;
-
- if(cn->flags & CN_EXPANDABLE) {
- if(cn->flags & CN_EXPANDED)
- for(n = 0; n < cn->children.nvec; ++n)
- recurse_selected(cn->children.vec[n], v);
- } else {
- if((cn->flags & CN_SELECTED) && cn->path)
- vector_append(v, (char *)cn->path);
- }
-}
-
-/*** @brief Get a list of all the selected tracks */
-static const char **gather_selected(int *ntracks) {
- struct vector v;
-
- vector_init(&v);
- recurse_selected(root, &v);
- vector_terminate(&v);
- if(ntracks) *ntracks = v.nvec;
- return (const char **)v.vec;
-}
-
-/** @brief Called when the track menu's play option is activated */
-static void activate_track_play(GtkMenuItem attribute((unused)) *menuitem,
- gpointer attribute((unused)) user_data) {
- const char **tracks = gather_selected(0);
- int n;
-
- gtk_label_set_text(GTK_LABEL(report_label), "adding track to queue");
- for(n = 0; tracks[n]; ++n)
- disorder_eclient_play(client, tracks[n], play_completed, 0);
-}
-
-/** @brief Called when the menu's properties option is activated */
-static void activate_track_properties(GtkMenuItem attribute((unused)) *menuitem,
- gpointer attribute((unused)) user_data) {
- int ntracks;
- const char **tracks = gather_selected(&ntracks);
-
- properties(ntracks, tracks);
-}
-
-/** @brief Determine whether the menu's play option should be sensitive */
-static gboolean sensitive_track_play(struct choosenode attribute((unused)) *cn) {
- return (!!files_selected
- && (disorder_eclient_state(client) & DISORDER_CONNECTED)
- && (last_rights & RIGHT_PLAY));
-}
-
-/** @brief Determine whether the menu's properties option should be sensitive */
-static gboolean sensitive_track_properties(struct choosenode attribute((unused)) *cn) {
- return (!!files_selected
- && (disorder_eclient_state(client) & DISORDER_CONNECTED)
- && (last_rights & RIGHT_PREFS));
-}
-
-/* Directory menu items ---------------------------------------------------- */
-
-/** @brief Return the file children of @p cn
- *
- * The list is terminated by a null pointer.
- */
-static const char **dir_files(struct choosenode *cn, int *nfiles) {
- const char **files = xcalloc(cn->children.nvec + 1, sizeof (char *));
- int n, m;
-
- for(n = m = 0; n < cn->children.nvec; ++n)
- if(!(cn->children.vec[n]->flags & CN_EXPANDABLE))
- files[m++] = cn->children.vec[n]->path;
- files[m] = 0;
- if(nfiles) *nfiles = m;
- return files;
-}
-
-static void play_dir(struct choosenode *cn,
- void attribute((unused)) *wfu) {
- int ntracks, n;
- const char **tracks = dir_files(cn, &ntracks);
-
- gtk_label_set_text(GTK_LABEL(report_label), "adding track to queue");
- for(n = 0; n < ntracks; ++n)
- disorder_eclient_play(client, tracks[n], play_completed, 0);
-}
-
-static void properties_dir(struct choosenode *cn,
- void attribute((unused)) *wfu) {
- int ntracks;
- const char **tracks = dir_files(cn, &ntracks);
-
- properties(ntracks, tracks);
-}
-
-static void select_dir(struct choosenode *cn,
- void attribute((unused)) *wfu) {
- int n;
-
- clear_selection(root);
- for(n = 0; n < cn->children.nvec; ++n)
- set_selection(cn->children.vec[n], 1);
-}
-
-/** @brief Ensure @p cn is expanded and then call @p callback */
-static void call_with_dir(struct choosenode *cn,
- when_filled_callback *whenfilled,
- void *wfu) {
- if(!(cn->flags & CN_EXPANDABLE))
- return; /* something went wrong */
- if(cn->flags & CN_EXPANDED)
- /* @p cn is already open */
- whenfilled(cn, wfu);
- else {
- /* @p cn is not open, arrange for the callback to go off when it is
- * opened */
- cn->whenfilled = whenfilled;
- cn->wfu = wfu;
- expand_node(cn, 0/*not contingnet upon search*/);
- }
-}
-
-/** @brief Called when the directory menu's play option is activated */
-static void activate_dir_play(GtkMenuItem attribute((unused)) *menuitem,
- gpointer user_data) {
- struct choosenode *const cn = (struct choosenode *)user_data;
-
- call_with_dir(cn, play_dir, 0);
-}
-
-/** @brief Called when the directory menu's properties option is activated */
-static void activate_dir_properties(GtkMenuItem attribute((unused)) *menuitem,
- gpointer user_data) {
- struct choosenode *const cn = (struct choosenode *)user_data;
-
- call_with_dir(cn, properties_dir, 0);
-}
-
-/** @brief Called when the directory menu's select option is activated */
-static void activate_dir_select(GtkMenuItem attribute((unused)) *menuitem,
- gpointer user_data) {
- struct choosenode *const cn = (struct choosenode *)user_data;
-
- call_with_dir(cn, select_dir, 0);
-}
-
-/** @brief Determine whether the directory menu's play option should be sensitive */
-static gboolean sensitive_dir_play(struct choosenode attribute((unused)) *cn) {
- return !!(disorder_eclient_state(client) & DISORDER_CONNECTED);
-}
-
-/** @brief Determine whether the directory menu's properties option should be sensitive */
-static gboolean sensitive_dir_properties(struct choosenode attribute((unused)) *cn) {
- return !!(disorder_eclient_state(client) & DISORDER_CONNECTED);
-}
-
-/** @brief Determine whether the directory menu's select option should be sensitive */
-static gboolean sensitive_dir_select(struct choosenode attribute((unused)) *cn) {
- return TRUE;
-}
-
-
-
-/* Main menu plumbing ------------------------------------------------------ */
-
-/** @brief Determine whether the edit menu's properties option should be sensitive */
-static int choose_properties_sensitive(GtkWidget attribute((unused)) *w) {
- return !!files_selected && (disorder_eclient_state(client) & DISORDER_CONNECTED);
-}
-
-/** @brief Determine whether the edit menu's select all option should be sensitive
- *
- * TODO not implemented, see also choose_selectall_activate()
- */
-static int choose_selectall_sensitive(GtkWidget attribute((unused)) *w) {
- return FALSE;
-}
-
-/** @brief Determine whether the edit menu's select none option should be sensitive
- *
- * TODO not implemented, see also choose_selectnone_activate()
- */
-static int choose_selectnone_sensitive(GtkWidget attribute((unused)) *w) {
- return FALSE;
-}
-
-/** @brief Called when the edit menu's properties option is activated */
-static void choose_properties_activate(GtkWidget attribute((unused)) *w) {
- activate_track_properties(0, 0);
-}
-
-/** @brief Called when the edit menu's select all option is activated
- *
- * TODO not implemented, see choose_selectall_sensitive() */
-static void choose_selectall_activate(GtkWidget attribute((unused)) *w) {
-}
-
-/** @brief Called when the edit menu's select none option is activated
- *
- * TODO not implemented, see choose_selectnone_sensitive() */
-static void choose_selectnone_activate(GtkWidget attribute((unused)) *w) {
-}
-
-/** @brief Main menu callbacks for Choose screen */
-static const struct tabtype tabtype_choose = {
- choose_properties_sensitive,
- choose_selectall_sensitive,
- choose_selectnone_sensitive,
- choose_properties_activate,
- choose_selectall_activate,
- choose_selectnone_activate,
-};
-
-/* Public entry points ----------------------------------------------------- */
-
-/** @brief Called when we have just logged in
- *
- * Entirely resets the choose tab.
- */
-static void choose_logged_in(const char attribute((unused)) *event,
- void attribute((unused)) *eventdata,
- void attribute((unused)) *callbackdata) {
- if(root)
- undisplay_tree(root);
- root = newnode(0/*parent*/, "<root>", "All files", "",
- CN_EXPANDABLE, fill_root_node);
- expand_node(root, 0); /* will call redisplay_tree */
-}
-
-/** @brief Create a track choice widget */