* TRACK_COLUMN="" and ISFILE_COLUMN=FALSE (so that they don't get check boxes,
* lengths, etc).
*
- * TODO We do a period sweep which kills contracted nodes, putting back
- * placeholders, and updating expanded nodes to keep up with server-side
- * changes. (We could trigger the latter off rescan complete notifications?)
- *
* TODO:
- * - sweep up contracted nodes
- * - update when content may have changed (e.g. after a rescan)
+ * - sweep up contracted nodes, replacing their content with a placeholder
*/
#include "disobedience.h"
#include "choose.h"
+#include <gdk/gdkkeysyms.h>
/** @brief The current selection tree */
GtkTreeStore *choose_store;
}
static void choose_dirs_completed(void *v,
- const char *error,
+ const char *err,
int nvec, char **vec) {
- if(error) {
- popup_protocol_error(0, error);
+ if(err) {
+ popup_protocol_error(0, err);
return;
}
choose_populate(v, nvec, vec, 0/*!isfile*/);
}
static void choose_files_completed(void *v,
- const char *error,
+ const char *err,
int nvec, char **vec) {
- if(error) {
- popup_protocol_error(0, error);
+ if(err) {
+ popup_protocol_error(0, err);
return;
}
choose_populate(v, nvec, vec, 1/*isfile*/);
}
void choose_play_completed(void attribute((unused)) *v,
- const char *error) {
- if(error)
- popup_protocol_error(0, error);
+ const char *err) {
+ if(err)
+ popup_protocol_error(0, err);
}
static void choose_state_toggled
//fprintf(stderr, "choose_list_in_flight -> %d+\n", choose_list_in_flight);
}
+/** @brief Called for key-*-event on the main view
+ */
+static gboolean choose_key_event(GtkWidget attribute((unused)) *widget,
+ GdkEventKey *event,
+ gpointer attribute((unused)) user_data) {
+ /*fprintf(stderr, "choose_key_event type=%d state=%#x keyval=%#x\n",
+ event->type, event->state, event->keyval);*/
+ switch(event->keyval) {
+ case GDK_Page_Up:
+ case GDK_Page_Down:
+ case GDK_Up:
+ case GDK_Down:
+ case GDK_Home:
+ case GDK_End:
+ return FALSE; /* We'll take these */
+ case 'f': case 'F':
+ /* ^F is expected to start a search. We implement this by focusing the
+ * search entry box. */
+ if((event->state & ~(GDK_LOCK_MASK|GDK_SHIFT_MASK)) == GDK_CONTROL_MASK
+ && event->type == GDK_KEY_PRESS) {
+ choose_search_new();
+ return TRUE; /* Handled it */
+ }
+ break;
+ case 'g': case 'G':
+ /* ^G is expected to go the next match. We simulate a click on the 'next'
+ * button. */
+ if((event->state & ~(GDK_LOCK_MASK|GDK_SHIFT_MASK)) == GDK_CONTROL_MASK
+ && event->type == GDK_KEY_PRESS) {
+ choose_next_clicked(0, 0);
+ return TRUE; /* Handled it */
+ }
+ break;
+ }
+ gtk_widget_event(user_data, (GdkEvent *)event);
+ return TRUE; /* Handled it */
+}
+
/** @brief Create the choose tab */
GtkWidget *choose_widget(void) {
/* Create the tree store. */
/* Create the view */
choose_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(choose_store));
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(choose_view), TRUE);
- /* Suppress built-in typeahead find, we do our own search support.
- * TODO: ^F still brings up the native search box
- */
+ /* Suppress built-in typeahead find, we do our own search support. */
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(choose_view), FALSE);
/* Create cell renderers and columns */
FALSE/*expand*/, FALSE/*fill*/, 0/*padding*/);
g_object_set_data(G_OBJECT(vbox), "type", (void *)&choose_tabtype);
+
+ /* Redirect keyboard activity to the search widget */
+ g_signal_connect(choose_view, "key-press-event",
+ G_CALLBACK(choose_key_event), choose_search_entry);
+ g_signal_connect(choose_view, "key-release-event",
+ G_CALLBACK(choose_key_event), choose_search_entry);
+
return vbox;
}