From 566a2506418b17631f101fb81a320616bde0fdaa Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 1 Mar 2012 11:54:40 +0000 Subject: LRN: add main window context; apply pseudonym rank filtering --- contrib/gnunet_fs_gtk_main_window.glade | 1 - src/fs/gnunet-fs-gtk.c | 92 +++++--- src/fs/gnunet-fs-gtk.h | 30 +++ ...net-fs-gtk_main-window-meta-data-context-menu.c | 23 +- .../gnunet-fs-gtk_main-window-namespace-dropdown.c | 261 ++++++++++----------- src/fs/gnunet-fs-gtk_main-window-search.c | 25 +- src/fs/gnunet-fs-gtk_namespace_manager.c | 7 +- src/include/gnunet_gtk.h | 12 + src/lib/eventloop.c | 28 ++- 9 files changed, 269 insertions(+), 210 deletions(-) diff --git a/contrib/gnunet_fs_gtk_main_window.glade b/contrib/gnunet_fs_gtk_main_window.glade index 710c7697..fd46bceb 100644 --- a/contrib/gnunet_fs_gtk_main_window.glade +++ b/contrib/gnunet_fs_gtk_main_window.glade @@ -161,7 +161,6 @@ 700 500 gnunet-gtk - diff --git a/src/fs/gnunet-fs-gtk.c b/src/fs/gnunet-fs-gtk.c index ccc05c15..7cee7ac3 100644 --- a/src/fs/gnunet-fs-gtk.c +++ b/src/fs/gnunet-fs-gtk.c @@ -23,6 +23,7 @@ * @brief Main function of gnunet-fs-gtk * @author Christian Grothoff */ +#include "gnunet-fs-gtk.h" #include "gnunet-fs-gtk_common.h" #include "gnunet-fs-gtk_event-handler.h" #include @@ -172,14 +173,14 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) void GNUNET_GTK_quit_cb (GObject * object, gpointer user_data) { - GtkWidget *main_window = GTK_WIDGET (GNUNET_FS_GTK_get_main_window_object ( - "GNUNET_GTK_main_window")); + struct GNUNET_GTK_MainWindowContext *main_context; - main_window_save_position (main_window); + main_window_save_position (main_context->main_window); GNUNET_GTK_tray_icon_destroy (); GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, &shutdown_task, NULL); + GNUNET_free (main_context); } @@ -193,72 +194,97 @@ GNUNET_GTK_quit_cb (GObject * object, gpointer user_data) static void run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - GtkWidget *main_window; - GtkTreeView *metadata_tree; unsigned long long dl_parallel, req_parallel, window_x, window_y, window_width, window_height; int maximized; - const struct GNUNET_CONFIGURATION_Handle *cfg; + + struct GNUNET_GTK_MainWindowContext *main_context; + + main_context = GNUNET_malloc (sizeof (struct GNUNET_GTK_MainWindowContext)); ml = cls; + /* setup main context */ + if (GNUNET_OK != GNUNET_GTK_main_loop_build_window (cls, main_context)) + { + GNUNET_free (main_context); + return; + } + + main_context->builder = GNUNET_GTK_main_loop_get_builder (cls); + main_context->cfg = GNUNET_GTK_main_loop_get_configuration (cls); + main_context->search_ns_treestore = GTK_TREE_STORE (GNUNET_FS_GTK_get_main_window_object ("main_window_search_namespace_treestore")); + main_context->main_window = GTK_WIDGET (GNUNET_FS_GTK_get_main_window_object ("GNUNET_GTK_main_window")); + main_context->ns_selector_treeview = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object ("namespace_selector_treeview")); + main_context->ns_selector_window = GTK_WIDGET (GNUNET_FS_GTK_get_main_window_object ("namespace_selector_window")); + main_context->ns_dropdown_button = GTK_TOGGLE_BUTTON (GNUNET_FS_GTK_get_main_window_object ("main_window_search_namespace_dropdown_button")); + main_context->search_ns_label = GTK_LABEL (GNUNET_FS_GTK_get_main_window_object ("main_window_search_selected_namespace_label")); + + main_context->search_entry = GTK_ENTRY (GNUNET_FS_GTK_get_main_window_object ("main_window_search_entry")); + + main_context->anonymity_combo = GTK_COMBO_BOX (GNUNET_FS_GTK_get_main_window_object ("main_window_search_anonymity_combobox")); + main_context->anonymity_level_liststore = GTK_LIST_STORE (GNUNET_FS_GTK_get_main_window_object ("anonymity_level_liststore")); + + main_context->preview_image = GTK_IMAGE (GNUNET_FS_GTK_get_main_window_object ("GNUNET_GTK_main_window_preview_image")); + main_context->md_liststore = GTK_LIST_STORE (GNUNET_FS_GTK_get_main_window_object ("GNUNET_GTK_meta_data_list_store")); + main_context->md_treeview = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object ("GNUNET_GTK_main_window_metadata_treeview")); + main_context->ns_callback_registered = GNUNET_NO; + GNUNET_GTK_set_icon_search_path (); GNUNET_GTK_setup_nls (); - /* setup main window */ - main_window = - GTK_WIDGET (GNUNET_FS_GTK_get_main_window_object - ("GNUNET_GTK_main_window")); - - cfg = GNUNET_GTK_main_loop_get_configuration (ml); + /* Make sure button class is realized */ + g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON)); + /* GNUnet main window assumes that images on buttons are visible, + * override the theme's gtkrc setting + */ + g_object_set (gtk_settings_get_default (), "gtk-button-images", TRUE, NULL); - maximized = GNUNET_CONFIGURATION_get_value_yesno (cfg, + /* setup main window */ + maximized = GNUNET_CONFIGURATION_get_value_yesno (main_context->cfg, "gnunet-gtk", "MAIN_WINDOW_MAXIMIZED"); if (GNUNET_SYSERR == maximized) maximized = GNUNET_YES; if ( (GNUNET_NO == maximized) && - (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "gnunet-gtk", + (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (main_context->cfg, "gnunet-gtk", "MAIN_WINDOW_X", &window_x)) && - (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "gnunet-gtk", + (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (main_context->cfg, "gnunet-gtk", "MAIN_WINDOW_Y", &window_y)) && - (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "gnunet-gtk", + (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (main_context->cfg, "gnunet-gtk", "MAIN_WINDOW_WIDTH", &window_width)) && - (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "gnunet-gtk", + (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (main_context->cfg, "gnunet-gtk", "MAIN_WINDOW_HEIGHT", &window_height)) ) { - gtk_window_move (GTK_WINDOW (main_window), window_x, window_y); - gtk_window_resize (GTK_WINDOW (main_window), window_width, window_height); + gtk_window_move (GTK_WINDOW (main_context->main_window), window_x, window_y); + gtk_window_resize (GTK_WINDOW (main_context->main_window), window_width, window_height); } else { /* If anything is wrong - play safe and show it maximized */ - gtk_window_maximize (GTK_WINDOW (main_window)); + gtk_window_maximize (GTK_WINDOW (main_context->main_window)); } /* Allow multiple selection in metadata view; */ /* FIXME-GTK3: this can be done within (modern versions of) glade */ - metadata_tree = - GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object - ("GNUNET_GTK_main_window_metadata_treeview")); - gtk_tree_selection_set_mode (gtk_tree_view_get_selection (metadata_tree), + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (main_context->md_treeview), GTK_SELECTION_MULTIPLE); - GNUNET_GTK_tray_icon_create (GTK_WINDOW (main_window), + GNUNET_GTK_tray_icon_create (GTK_WINDOW (main_context->main_window), "gnunet-fs-gtk", "gnunet-fs-gtk"); /* FIXME: should these '1's be here? Maybe better to put them into * default config files? */ - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "gnunet-gtk", + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (main_context->cfg, "gnunet-gtk", "MAX_PARALLEL_DOWNLOADS", &dl_parallel)) dl_parallel = 1; - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "gnunet-gtk", + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (main_context->cfg, "gnunet-gtk", "MAX_PARALLEL_REQUESTS", &req_parallel)) req_parallel = 1; /* initialize file-sharing */ - fs = GNUNET_FS_start (cfg, "gnunet-fs-gtk", + fs = GNUNET_FS_start (main_context->cfg, "gnunet-fs-gtk", &GNUNET_GTK_fs_event_handler, NULL, GNUNET_FS_FLAGS_NONE | GNUNET_FS_FLAGS_PERSISTENCE /* | GNUNET_FS_FLAGS_DO_PROBES */ , @@ -269,14 +295,18 @@ run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_FS_OPTIONS_END); if (NULL == fs) { - GNUNET_GTK_main_loop_quit (ml); + GNUNET_GTK_main_loop_quit (cls); + GNUNET_free (main_context); return; } + + GNUNET_GTK_main_window_refresh_ns_list (main_context); + /* make GUI visible */ if (!tray_only) { - gtk_widget_show (main_window); - gtk_window_present (GTK_WINDOW (main_window)); + gtk_widget_show (main_context->main_window); + gtk_window_present (GTK_WINDOW (main_context->main_window)); } } diff --git a/src/fs/gnunet-fs-gtk.h b/src/fs/gnunet-fs-gtk.h index 4f5c7476..af533fad 100644 --- a/src/fs/gnunet-fs-gtk.h +++ b/src/fs/gnunet-fs-gtk.h @@ -30,6 +30,33 @@ #include #include +struct GNUNET_GTK_MainWindowContext +{ + GtkBuilder *builder; + + const struct GNUNET_CONFIGURATION_Handle *cfg; + + GtkTreeStore *search_ns_treestore; + GtkTreeView *ns_selector_treeview; + GtkWidget *ns_selector_window; + GtkToggleButton *ns_dropdown_button; + GtkLabel *search_ns_label; + + GtkEntry *search_entry; + + GtkComboBox *anonymity_combo; + GtkListStore *anonymity_level_liststore; + + GtkImage *preview_image; + GtkListStore *md_liststore; + GtkTreeView *md_treeview; + + GtkWidget *main_window; + + GtkTreeRowReference *ns_selector_pushed_row; + GtkTreeRowReference *selected_ns_row; + int ns_callback_registered; +}; /** * Get our configuration. @@ -114,5 +141,8 @@ GNUNET_GTK_select_anonymity_level (GtkBuilder * builder, gchar * combo_name, gboolean GNUNET_GTK_select_anonymity_combo_level (GtkComboBox *combo, guint sel_level); +void +GNUNET_GTK_main_window_refresh_ns_list (struct GNUNET_GTK_MainWindowContext *main_ctx); + #endif /* end of gnunet-fs-gtk.h */ diff --git a/src/fs/gnunet-fs-gtk_main-window-meta-data-context-menu.c b/src/fs/gnunet-fs-gtk_main-window-meta-data-context-menu.c index bf3421ee..f209415d 100644 --- a/src/fs/gnunet-fs-gtk_main-window-meta-data-context-menu.c +++ b/src/fs/gnunet-fs-gtk_main-window-meta-data-context-menu.c @@ -64,7 +64,7 @@ void GNUNET_GTK_FS_metadata_copy_selection_activated (GtkMenuItem * menuitem, gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; GtkTreeView *tree; GtkClipboard *cb; GList *pairs; @@ -75,9 +75,7 @@ GNUNET_GTK_FS_metadata_copy_selection_activated (GtkMenuItem * menuitem, gchar *s; gchar *p; - tree = - GTK_TREE_VIEW (gtk_builder_get_object - (builder, "GNUNET_GTK_main_window_metadata_treeview")); + tree = main_ctx->md_treeview; pairs = NULL; gtk_tree_selection_selected_foreach (gtk_tree_view_get_selection (tree), ©_metadata_to_clipboard, &pairs); @@ -129,17 +127,18 @@ GNUNET_GTK_FS_metadata_copy_selection_activated (GtkMenuItem * menuitem, * * @param button which button caused the event (0 for none) * @param event_time time of the event (current time or 'event->time') - * @param user_data the gtk builder of the main window + * @param user_data the context of the main window */ static void do_metadata_popup_menu (int button, int event_time, - GtkBuilder *builder) + gpointer user_data) { GtkMenu *menu; + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; - menu = GTK_MENU (gtk_builder_get_object (builder, "metadata_popup_menu")); - gtk_menu_popup (menu, NULL, NULL, NULL, builder, button, event_time); + menu = GTK_MENU (gtk_builder_get_object (main_ctx->builder, "metadata_popup_menu")); + gtk_menu_popup (menu, NULL, NULL, NULL, main_ctx, button, event_time); } @@ -158,14 +157,12 @@ GNUNET_GTK_main_window_metadata_treeview_button_press_event_cb (GtkWidget * gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); - /* Ignore double-clicks and triple-clicks */ if ( (event->button != 3) || (event->type != GDK_BUTTON_PRESS) ) return FALSE; do_metadata_popup_menu (event->button, event->time, - builder); + user_data); return TRUE; } @@ -182,11 +179,9 @@ gboolean GNUNET_GTK_main_window_metadata_treeview_popup_menu_cb (GtkWidget * widget, gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); - do_metadata_popup_menu (0 /* no button */, gtk_get_current_event_time (), - builder); + user_data); return TRUE; } diff --git a/src/fs/gnunet-fs-gtk_main-window-namespace-dropdown.c b/src/fs/gnunet-fs-gtk_main-window-namespace-dropdown.c index 818caa6c..f5697ef1 100644 --- a/src/fs/gnunet-fs-gtk_main-window-namespace-dropdown.c +++ b/src/fs/gnunet-fs-gtk_main-window-namespace-dropdown.c @@ -48,7 +48,7 @@ static guint namespace_selector_window_leave_timeout_source; * * @param widget the dropdown widget * @param event the mouse-enter event - * @param user_data the builder for the main window + * @param user_data the context for the main window */ gboolean GNUNET_FS_GTK_search_namespace_dropdown_button_enter_notify_event_cb (GtkWidget *widget, @@ -85,26 +85,21 @@ namespace_selector_window_leave_timeout_cb (gpointer user_data) * window. It will be cancelled if the cursor re-enters the namespace * selector window or the toggle button within 100ms * - * @param user_data the builder for the main window + * @param user_data the context for the main window */ gboolean GNUNET_FS_GTK_search_namespace_selector_window_leave_notify_event_cb (GtkWidget * widget, GdkEvent * event, gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); - GtkToggleButton *toggle_button; + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; - toggle_button = - GTK_TOGGLE_BUTTON (gtk_builder_get_object - (builder, - "main_window_search_namespace_dropdown_button")); if (namespace_selector_window_leave_timeout_source > 0) g_source_remove (namespace_selector_window_leave_timeout_source); namespace_selector_window_leave_timeout_source = g_timeout_add (AUTO_HIDE_TIMEOUT_MS, &namespace_selector_window_leave_timeout_cb, - toggle_button); + main_ctx->ns_dropdown_button); return FALSE; } @@ -139,51 +134,35 @@ get_selected_row_from_treeview (GtkTreeView * tree) * user clicked to confirm. Hide the drop down and display the * selected entry as the new namespace label. * - * @param builder the builder for the main window + * @param main_ctx the context for the main window * @param tv the tree view that was updated */ static void -commit_changes (GtkBuilder *builder, +commit_changes (struct GNUNET_GTK_MainWindowContext *main_ctx, GtkTreeView *tv) { - GtkToggleButton *toggle_button; - GtkTreeRowReference *ref; GtkTreePath *treepath; gchar *value; - - toggle_button = - GTK_TOGGLE_BUTTON (gtk_builder_get_object - (builder, - "main_window_search_namespace_dropdown_button")); - ref = g_object_get_data (G_OBJECT (toggle_button), "selected-row-reference"); - if (NULL != ref) - gtk_tree_row_reference_free (ref); - ref = get_selected_row_from_treeview (tv); - g_object_set_data (G_OBJECT (toggle_button), "selected-row-reference", ref); - treepath = gtk_tree_row_reference_get_path (ref); + if (NULL != main_ctx->selected_ns_row) + gtk_tree_row_reference_free (main_ctx->selected_ns_row); + main_ctx->selected_ns_row = get_selected_row_from_treeview (tv); + + treepath = gtk_tree_row_reference_get_path (main_ctx->selected_ns_row); if (GNUNET_GTK_get_tree_string (tv, treepath, 0, &value)) { - GtkLabel *sel_namespace_label; - - sel_namespace_label = - GTK_LABEL (gtk_builder_get_object - (builder, "main_window_search_selected_namespace_label")); - gtk_label_set_text (sel_namespace_label, (NULL != value) ? value : ""); + gtk_label_set_text (main_ctx->search_ns_label, (NULL != value) ? value : ""); g_free (value); } if (GNUNET_GTK_get_tree_string (tv, treepath, 2, &value)) { - GtkEntry *search_entry; - - search_entry = GTK_ENTRY (gtk_builder_get_object (builder, "main_window_search_entry")); - gtk_entry_set_text (search_entry, (NULL != value) ? value : ""); + gtk_entry_set_text (main_ctx->search_entry, (NULL != value) ? value : ""); g_free (value); } gtk_tree_path_free (treepath); /* hide the namespace selector */ - gtk_toggle_button_set_active (toggle_button, FALSE); + gtk_toggle_button_set_active (main_ctx->ns_dropdown_button, FALSE); } @@ -194,7 +173,7 @@ commit_changes (GtkBuilder *builder, * * @param widget the tree view widget * @param event the push event - * @param user_data the builder for the main window + * @param user_data the context for the main window * @return FALSE */ gboolean @@ -202,13 +181,11 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_press_event_cb (GtkWidget * wid GdkEvent * event, gpointer user_data) { - GtkTreeRowReference *ref; - gpointer old = g_object_get_data (G_OBJECT (widget), "pushed-rowreference"); + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; - if (NULL != old) - gtk_tree_row_reference_free (old); - ref = get_selected_row_from_treeview (GTK_TREE_VIEW (widget)); - g_object_set_data (G_OBJECT (widget), "pushed-rowreference", ref); + if (NULL != main_ctx->ns_selector_pushed_row) + gtk_tree_row_reference_free (main_ctx->ns_selector_pushed_row); + main_ctx->ns_selector_pushed_row = get_selected_row_from_treeview (GTK_TREE_VIEW (widget)); return FALSE; } @@ -216,13 +193,11 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_press_event_cb (GtkWidget * wid /** * User released the button in the treeview. Get the selected entry * and update the cursor accordingly, but only if the user pushed the - * button down and released it in the same row. We have stored the - * row that the user selected when pushing the button down in the - * "pushed-rowreference" of the widget. + * button down and released it in the same row. * * @param widget the tree view widget * @param event the release event - * @param user_data the builder for the main window + * @param user_data the context for the main window * @return FALSE */ gboolean @@ -230,20 +205,19 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_release_event_cb (GtkWidget * w GdkEvent * event, gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; GtkTreeRowReference *ref; - gpointer old = g_object_get_data (G_OBJECT (widget), "pushed-rowreference"); ref = get_selected_row_from_treeview (GTK_TREE_VIEW (widget)); - if ( (NULL != ref) && (NULL != old)) + if ( (NULL != ref) && (NULL != main_ctx->ns_selector_pushed_row)) { GtkTreePath *path_ref; GtkTreePath *path_old; path_ref = gtk_tree_row_reference_get_path (ref); - path_old = gtk_tree_row_reference_get_path (old); + path_old = gtk_tree_row_reference_get_path (main_ctx->ns_selector_pushed_row); if (0 == gtk_tree_path_compare (path_ref, path_old)) - commit_changes (builder, GTK_TREE_VIEW (widget)); + commit_changes (main_ctx, GTK_TREE_VIEW (widget)); if (path_ref) gtk_tree_path_free (path_ref); if (path_old) @@ -251,9 +225,9 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_release_event_cb (GtkWidget * w } if (NULL != ref) gtk_tree_row_reference_free (ref); - if (NULL != old) - gtk_tree_row_reference_free (old); - g_object_set_data (G_OBJECT (widget), "pushed-rowreference", NULL); + if (NULL != main_ctx->ns_selector_pushed_row) + gtk_tree_row_reference_free (main_ctx->ns_selector_pushed_row); + main_ctx->ns_selector_pushed_row = NULL; return FALSE; } @@ -263,17 +237,15 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_release_event_cb (GtkWidget * w * list was toggled. * * @param togglebutton the button that toggles the namespace dropdown list - * @param user_data the builder for the main window + * @param user_data the contexxt for the main window */ void GNUNET_FS_GTK_search_namespace_dropdown_button_toggled_cb (GtkToggleButton * togglebutton, gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; gboolean active; - GtkWidget *namespace_selector_window; - GtkWidget *namespace_selector_treeview; GtkAllocation togglebutton_allocation; GdkWindow *main_window_gdk; gint mwg_x; @@ -283,19 +255,13 @@ GNUNET_FS_GTK_search_namespace_dropdown_button_toggled_cb (GtkToggleButton * gint popup_x; gint popup_y; - namespace_selector_window = - GTK_WIDGET (gtk_builder_get_object - (builder, "namespace_selector_window")); g_object_get (G_OBJECT (togglebutton), "active", &active, NULL); if (! active) { - gtk_widget_hide (namespace_selector_window); + gtk_widget_hide (main_ctx->ns_selector_window); gtk_widget_grab_focus (GTK_WIDGET (togglebutton)); return; } - namespace_selector_treeview = - GTK_WIDGET (gtk_builder_get_object - (builder, "namespace_selector_treeview")); gtk_widget_get_allocation (GTK_WIDGET (togglebutton), &togglebutton_allocation); main_window_gdk = gtk_widget_get_window (GTK_WIDGET (togglebutton)); @@ -305,9 +271,9 @@ GNUNET_FS_GTK_search_namespace_dropdown_button_toggled_cb (GtkToggleButton * tgb_y = mwg_y + togglebutton_allocation.y; popup_x = tgb_x; popup_y = tgb_y + togglebutton_allocation.height; - gtk_window_move (GTK_WINDOW (namespace_selector_window), popup_x, popup_y); - gtk_widget_show_all (namespace_selector_window); - gtk_widget_grab_focus (namespace_selector_treeview); + gtk_window_move (GTK_WINDOW (main_ctx->ns_selector_window), popup_x, popup_y); + gtk_widget_show_all (main_ctx->ns_selector_window); + gtk_widget_grab_focus (GTK_WIDGET (main_ctx->ns_selector_treeview)); } @@ -370,92 +336,103 @@ add_namespace_to_ts (void *cls, const GNUNET_HashCode * pseudonym, return GNUNET_OK; } - -/** - * Startup hook to initialize the namespace dropdown widget. - * - * @param widget the main window - * @param user_data the builder for the main window - */ -/* FIXME-STYLE: hang up on 'realize' event of a widget closer to home? */ void -GNUNET_GTK_main_window_realize_cb (GtkWidget * widget, gpointer user_data) +GNUNET_GTK_main_window_refresh_ns_list (struct GNUNET_GTK_MainWindowContext *main_ctx) { - GtkBuilder *builder = GTK_BUILDER (user_data); GtkTreeIter iter; - GtkTreeStore *namespace_treestore; + gint i; - /* FIXME-STYLE: can't we do the button initialization when we create the main window? */ - /* Make sure button class is realized */ - g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON)); - /* GNUnet main window assumes that images on buttons are visible, - * override the theme's gtkrc setting - */ - g_object_set (gtk_settings_get_default (), "gtk-button-images", TRUE, NULL); + GtkTreePath *treepath; + GNUNET_HashCode *key = NULL, *selected_ns_id; - /* setup namespace treestore */ - { - namespace_treestore = - GTK_TREE_STORE (GNUNET_FS_GTK_get_main_window_object - ("main_window_search_namespace_treestore")); + gboolean found = FALSE; + gchar *value = NULL; - /* FIXME-FEATURE: find a way to manage pseudonyms. - * Right now the list will be filled with ALL and ANY pseudonyms that we - * find, these are held as files in a special directory. - * I don't see an easy way to ignore certain pseudonyms in that directory, - * and that require for pseudonym management. Also, pseudonyms are presented - * in arbitrary order. We must either sort them (by name?) or let the user - * drag them around to change the order in which they appear in the list. - * All that is not possible with a simple "files in a directory" concept. - */ - gtk_tree_store_insert_with_values (namespace_treestore, &iter, NULL, G_MAXINT, - 0, "Any", 1, NULL, 2, "", 3, - "Do not search in any particular namespace", - -1); - /* FIXME-BUG-MINOR: when do we unregister? */ - GNUNET_PSEUDONYM_discovery_callback_register (GNUNET_FS_GTK_get_configuration (), - &add_namespace_to_ts, - namespace_treestore); - } - - /* select the first item and update the label */ - /* FIXME-STYLE: is this even necessary? If the first item is "Any", we can - just have the label have the right default, or not? */ - if (gtk_tree_model_get_iter_first - (GTK_TREE_MODEL (namespace_treestore), &iter)) + if (NULL != main_ctx->selected_ns_row) { - gchar *value; - GtkLabel *sel_namespace_label; - GtkTreePath *treepath = gtk_tree_path_new_first (); - GtkTreeView *namespace_tree; - - namespace_tree = - GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object - ("namespace_selector_treeview")); - gtk_tree_selection_select_iter (gtk_tree_view_get_selection - (namespace_tree), &iter); - sel_namespace_label = - GTK_LABEL (gtk_builder_get_object - (builder, "main_window_search_selected_namespace_label")); - if (GNUNET_GTK_get_tree_string (namespace_tree, treepath, 0, &value)) - gtk_label_set_text (sel_namespace_label, value); + GtkTreeModel *model; + treepath = gtk_tree_row_reference_get_path (main_ctx->selected_ns_row); + model = gtk_tree_view_get_model (main_ctx->ns_selector_treeview); + if (model) + { + if (gtk_tree_model_get_iter (model, &iter, treepath)) + { + gtk_tree_model_get (model, &iter, 1, &key, -1); + } + } gtk_tree_path_free (treepath); + gtk_tree_row_reference_free (main_ctx->selected_ns_row); + main_ctx->selected_ns_row = NULL; } - - /* show the window (to trigger certain events) and immediately hide it */ - /* FIXME-STYLE: yuck, can't we trigger these events by other means? - CG->LRN: Which events are you even talking about here? I can't find anything - that would seem to be needed here. */ + selected_ns_id = NULL; + if (key != NULL) { - GtkWidget *namespace_selector_window; + selected_ns_id = GNUNET_malloc (sizeof (GNUNET_HashCode)); + memcpy (selected_ns_id, key, sizeof (GNUNET_HashCode)); + } - namespace_selector_window = - GTK_WIDGET (gtk_builder_get_object - (builder, "namespace_selector_window")); - gtk_widget_show (namespace_selector_window); - gtk_widget_hide (namespace_selector_window); + if (TRUE == gtk_tree_model_get_iter_first (GTK_TREE_MODEL ( + main_ctx->search_ns_treestore), &iter)) + { + while (TRUE) + { + gtk_tree_model_get (GTK_TREE_MODEL (main_ctx->search_ns_treestore), &iter, + 1, &key, + -1); + GNUNET_free_non_null (key); + if (TRUE != gtk_tree_model_iter_next (GTK_TREE_MODEL ( + main_ctx->search_ns_treestore), &iter)) + break; + } + } + gtk_tree_store_clear (main_ctx->search_ns_treestore); + + gtk_tree_store_insert_with_values (main_ctx->search_ns_treestore, &iter, NULL, G_MAXINT, + 0, "Any", 1, NULL, 2, "", 3, + "Do not search in any particular namespace", + -1); + + if (GNUNET_YES == main_ctx->ns_callback_registered) + GNUNET_PSEUDONYM_discovery_callback_unregister (add_namespace_to_ts, + main_ctx->search_ns_treestore); + GNUNET_PSEUDONYM_discovery_callback_register (main_ctx->cfg, + add_namespace_to_ts, main_ctx->search_ns_treestore); + main_ctx->ns_callback_registered = GNUNET_YES; + + if (TRUE == gtk_tree_model_get_iter_first (GTK_TREE_MODEL ( + main_ctx->search_ns_treestore), &iter)) + { + while (TRUE) + { + gtk_tree_model_get (GTK_TREE_MODEL (main_ctx->search_ns_treestore), &iter, + 0, &value, + 1, &key, + -1); + if (selected_ns_id == NULL) + found = TRUE; + else if (key != NULL && memcmp (key, selected_ns_id, sizeof (GNUNET_HashCode)) == 0) + found = TRUE; + if (found || (TRUE != gtk_tree_model_iter_next (GTK_TREE_MODEL ( + main_ctx->search_ns_treestore), &iter))) + break; + else + g_free (value); + } } + if (!found) + { + gtk_tree_model_get_iter_first (GTK_TREE_MODEL ( + main_ctx->search_ns_treestore), &iter); + gtk_tree_model_get (GTK_TREE_MODEL (main_ctx->search_ns_treestore), &iter, + 0, &value, 1, &key, -1); + found = TRUE; + } + gtk_tree_selection_select_iter (gtk_tree_view_get_selection + (main_ctx->ns_selector_treeview), &iter); + if (value != NULL) + gtk_label_set_text (main_ctx->search_ns_label, value); + g_free(value); + GNUNET_free_non_null (selected_ns_id); } - /* end of gnunet-fs-gtk_main-window-namespace-dropdown.c */ diff --git a/src/fs/gnunet-fs-gtk_main-window-search.c b/src/fs/gnunet-fs-gtk_main-window-search.c index fdab7b94..ff43ff62 100644 --- a/src/fs/gnunet-fs-gtk_main-window-search.c +++ b/src/fs/gnunet-fs-gtk_main-window-search.c @@ -34,7 +34,7 @@ * @param builder the main dialog builder */ static void -start_search (GtkBuilder *builder) +start_search (struct GNUNET_GTK_MainWindowContext *main_ctx) { guint anonymity_level; gchar *keywords; @@ -44,7 +44,7 @@ start_search (GtkBuilder *builder) /* get anonymity level */ if (!GNUNET_GTK_get_selected_anonymity_level - (builder, "main_window_search_anonymity_combobox", &anonymity_level)) + (main_ctx->builder, "main_window_search_anonymity_combobox", &anonymity_level)) { GNUNET_break (0); return; @@ -73,15 +73,10 @@ start_search (GtkBuilder *builder) /* get selected namespace */ { GtkTreeRowReference *ref; - GtkToggleButton *toggle_button; GtkTreeIter iter; nsid = NULL; - toggle_button = - GTK_TOGGLE_BUTTON (gtk_builder_get_object - (builder, - "main_window_search_namespace_dropdown_button")); - ref = g_object_get_data (G_OBJECT (toggle_button), "selected-row-reference"); + ref = g_object_get_data (G_OBJECT (main_ctx->ns_dropdown_button), "selected-row-reference"); if (NULL != ref) { GtkTreePath *namespace_treepath; @@ -97,12 +92,9 @@ start_search (GtkBuilder *builder) /* get keywords and compose keyword string */ { - GtkEntry *query_entry; const char *entry_keywords; - query_entry = GTK_ENTRY (gtk_builder_get_object (builder, - "main_window_search_entry")); - entry_keywords = gtk_entry_get_text (query_entry); + entry_keywords = gtk_entry_get_text (main_ctx->search_entry); if (NULL != mime_keyword) { keywords = g_strdup_printf ("%s +%s", @@ -156,9 +148,8 @@ void main_window_search_button_clicked_cb (GtkButton * button, gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); - - start_search (builder); + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; + start_search (main_ctx); } @@ -176,11 +167,11 @@ main_window_search_entry_key_press_event_cb (GtkWidget * widget, GdkEventKey * event, gpointer user_data) { - GtkBuilder *builder = GTK_BUILDER (user_data); + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; if (event->keyval == GDK_KEY_Return) { - start_search (builder); + start_search (main_ctx); return TRUE; } return FALSE; diff --git a/src/fs/gnunet-fs-gtk_namespace_manager.c b/src/fs/gnunet-fs-gtk_namespace_manager.c index 772d3339..95763aef 100644 --- a/src/fs/gnunet-fs-gtk_namespace_manager.c +++ b/src/fs/gnunet-fs-gtk_namespace_manager.c @@ -47,6 +47,7 @@ struct GNUNET_GTK_NamespaceManagerContext GtkWidget *details_delete_button; int sort_direction; struct GNUNET_CONTAINER_MetaData *uneditable_md; + struct GNUNET_GTK_MainWindowContext *main_ctx; }; /** @@ -747,6 +748,7 @@ GNUNET_GTK_namespace_manager_dialog_response_cb (GtkDialog *dialog, case GTK_RESPONSE_APPLY: case GTK_RESPONSE_OK: apply_known_ns_changes (ctx); + GNUNET_GTK_main_window_refresh_ns_list (ctx->main_ctx); break; default: break; @@ -902,7 +904,8 @@ void GNUNET_GTK_main_menu_file_manage_pseudonyms_activate_cb (GtkMenuItem *menuitem, gpointer user_data) { - struct GNUNET_GTK_NamespaceManagerContext *ctx; + struct GNUNET_GTK_MainWindowContext *main_ctx = user_data; + struct GNUNET_GTK_NamespaceManagerContext *ctx; if (ns_manager != NULL) return; @@ -916,6 +919,8 @@ GNUNET_GTK_main_menu_file_manage_pseudonyms_activate_cb (GtkMenuItem *menuitem, return; } + ctx->main_ctx = main_ctx; + /* initialize widget references */ ctx->known_ns = GTK_WIDGET (gtk_builder_get_object (ctx->builder, "GNUNET_GTK_namespace_manager_known_treeview")); diff --git a/src/include/gnunet_gtk.h b/src/include/gnunet_gtk.h index c1528759..2d53806d 100644 --- a/src/include/gnunet_gtk.h +++ b/src/include/gnunet_gtk.h @@ -208,6 +208,18 @@ GObject * GNUNET_GTK_main_loop_get_object (struct GNUNET_GTK_MainLoop *ml, const char *name); +/** + * Get the builder from the main window. + * + * @param ml handle to the main loop + * @return NULL on error, otherwise the builder + */ +GtkBuilder * +GNUNET_GTK_main_loop_get_builder (struct GNUNET_GTK_MainLoop *ml); + +int +GNUNET_GTK_main_loop_build_window (struct GNUNET_GTK_MainLoop *ml, + gpointer data); /** diff --git a/src/lib/eventloop.c b/src/lib/eventloop.c index 60bd1faa..aef8d966 100644 --- a/src/lib/eventloop.c +++ b/src/lib/eventloop.c @@ -191,6 +191,30 @@ GNUNET_GTK_main_loop_quit (struct GNUNET_GTK_MainLoop *ml) } } +/** + * Get the builder from the main window. + * + * @param ml handle to the main loop + * @return NULL on error, otherwise the builder + */ +GtkBuilder * +GNUNET_GTK_main_loop_get_builder (struct GNUNET_GTK_MainLoop *ml) +{ + return ml->builder; +} + +int +GNUNET_GTK_main_loop_build_window (struct GNUNET_GTK_MainLoop *ml, gpointer data) +{ + ml->builder = GNUNET_GTK_get_new_builder (ml->main_window_file, data); + if (ml->builder == NULL) + { + GNUNET_GTK_main_loop_quit (ml); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + /** * Obtain the name of the configuration file that is being used. @@ -841,10 +865,6 @@ run_main_loop (void *cls, char *const *args, const char *cfgfile, argc++; gtk_init (&argc, (char ***) &args); - /* setup main context */ - ml->builder = GNUNET_GTK_get_new_builder (ml->main_window_file, NULL); - if (ml->builder == NULL) - return; ml->rs = GNUNET_NETWORK_fdset_create (); ml->ws = GNUNET_NETWORK_fdset_create (); ml->gml = g_main_loop_new (NULL, TRUE); -- cgit v1.2.3