aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk_main-window-namespace-dropdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk_main-window-namespace-dropdown.c')
-rw-r--r--src/fs/gnunet-fs-gtk_main-window-namespace-dropdown.c261
1 files changed, 119 insertions, 142 deletions
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;
48 * 48 *
49 * @param widget the dropdown widget 49 * @param widget the dropdown widget
50 * @param event the mouse-enter event 50 * @param event the mouse-enter event
51 * @param user_data the builder for the main window 51 * @param user_data the context for the main window
52 */ 52 */
53gboolean 53gboolean
54GNUNET_FS_GTK_search_namespace_dropdown_button_enter_notify_event_cb (GtkWidget *widget, 54GNUNET_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)
85 * window. It will be cancelled if the cursor re-enters the namespace 85 * window. It will be cancelled if the cursor re-enters the namespace
86 * selector window or the toggle button within 100ms 86 * selector window or the toggle button within 100ms
87 * 87 *
88 * @param user_data the builder for the main window 88 * @param user_data the context for the main window
89 */ 89 */
90gboolean 90gboolean
91GNUNET_FS_GTK_search_namespace_selector_window_leave_notify_event_cb (GtkWidget * widget, 91GNUNET_FS_GTK_search_namespace_selector_window_leave_notify_event_cb (GtkWidget * widget,
92 GdkEvent * event, 92 GdkEvent * event,
93 gpointer user_data) 93 gpointer user_data)
94{ 94{
95 GtkBuilder *builder = GTK_BUILDER (user_data); 95 struct GNUNET_GTK_MainWindowContext *main_ctx = user_data;
96 GtkToggleButton *toggle_button;
97 96
98 toggle_button =
99 GTK_TOGGLE_BUTTON (gtk_builder_get_object
100 (builder,
101 "main_window_search_namespace_dropdown_button"));
102 if (namespace_selector_window_leave_timeout_source > 0) 97 if (namespace_selector_window_leave_timeout_source > 0)
103 g_source_remove (namespace_selector_window_leave_timeout_source); 98 g_source_remove (namespace_selector_window_leave_timeout_source);
104 namespace_selector_window_leave_timeout_source 99 namespace_selector_window_leave_timeout_source
105 = g_timeout_add (AUTO_HIDE_TIMEOUT_MS, 100 = g_timeout_add (AUTO_HIDE_TIMEOUT_MS,
106 &namespace_selector_window_leave_timeout_cb, 101 &namespace_selector_window_leave_timeout_cb,
107 toggle_button); 102 main_ctx->ns_dropdown_button);
108 return FALSE; 103 return FALSE;
109} 104}
110 105
@@ -139,51 +134,35 @@ get_selected_row_from_treeview (GtkTreeView * tree)
139 * user clicked to confirm. Hide the drop down and display the 134 * user clicked to confirm. Hide the drop down and display the
140 * selected entry as the new namespace label. 135 * selected entry as the new namespace label.
141 * 136 *
142 * @param builder the builder for the main window 137 * @param main_ctx the context for the main window
143 * @param tv the tree view that was updated 138 * @param tv the tree view that was updated
144 */ 139 */
145static void 140static void
146commit_changes (GtkBuilder *builder, 141commit_changes (struct GNUNET_GTK_MainWindowContext *main_ctx,
147 GtkTreeView *tv) 142 GtkTreeView *tv)
148{ 143{
149 GtkToggleButton *toggle_button;
150 GtkTreeRowReference *ref;
151 GtkTreePath *treepath; 144 GtkTreePath *treepath;
152 gchar *value; 145 gchar *value;
153
154 toggle_button =
155 GTK_TOGGLE_BUTTON (gtk_builder_get_object
156 (builder,
157 "main_window_search_namespace_dropdown_button"));
158 ref = g_object_get_data (G_OBJECT (toggle_button), "selected-row-reference");
159 if (NULL != ref)
160 gtk_tree_row_reference_free (ref);
161 ref = get_selected_row_from_treeview (tv);
162 g_object_set_data (G_OBJECT (toggle_button), "selected-row-reference", ref);
163 146
164 treepath = gtk_tree_row_reference_get_path (ref); 147 if (NULL != main_ctx->selected_ns_row)
148 gtk_tree_row_reference_free (main_ctx->selected_ns_row);
149 main_ctx->selected_ns_row = get_selected_row_from_treeview (tv);
150
151 treepath = gtk_tree_row_reference_get_path (main_ctx->selected_ns_row);
165 if (GNUNET_GTK_get_tree_string (tv, treepath, 0, &value)) 152 if (GNUNET_GTK_get_tree_string (tv, treepath, 0, &value))
166 { 153 {
167 GtkLabel *sel_namespace_label; 154 gtk_label_set_text (main_ctx->search_ns_label, (NULL != value) ? value : "");
168
169 sel_namespace_label =
170 GTK_LABEL (gtk_builder_get_object
171 (builder, "main_window_search_selected_namespace_label"));
172 gtk_label_set_text (sel_namespace_label, (NULL != value) ? value : "");
173 g_free (value); 155 g_free (value);
174 } 156 }
175 if (GNUNET_GTK_get_tree_string (tv, treepath, 2, &value)) 157 if (GNUNET_GTK_get_tree_string (tv, treepath, 2, &value))
176 { 158 {
177 GtkEntry *search_entry; 159 gtk_entry_set_text (main_ctx->search_entry, (NULL != value) ? value : "");
178
179 search_entry = GTK_ENTRY (gtk_builder_get_object (builder, "main_window_search_entry"));
180 gtk_entry_set_text (search_entry, (NULL != value) ? value : "");
181 g_free (value); 160 g_free (value);
182 } 161 }
183 gtk_tree_path_free (treepath); 162 gtk_tree_path_free (treepath);
184 163
185 /* hide the namespace selector */ 164 /* hide the namespace selector */
186 gtk_toggle_button_set_active (toggle_button, FALSE); 165 gtk_toggle_button_set_active (main_ctx->ns_dropdown_button, FALSE);
187} 166}
188 167
189 168
@@ -194,7 +173,7 @@ commit_changes (GtkBuilder *builder,
194 * 173 *
195 * @param widget the tree view widget 174 * @param widget the tree view widget
196 * @param event the push event 175 * @param event the push event
197 * @param user_data the builder for the main window 176 * @param user_data the context for the main window
198 * @return FALSE 177 * @return FALSE
199 */ 178 */
200gboolean 179gboolean
@@ -202,13 +181,11 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_press_event_cb (GtkWidget * wid
202 GdkEvent * event, 181 GdkEvent * event,
203 gpointer user_data) 182 gpointer user_data)
204{ 183{
205 GtkTreeRowReference *ref; 184 struct GNUNET_GTK_MainWindowContext *main_ctx = user_data;
206 gpointer old = g_object_get_data (G_OBJECT (widget), "pushed-rowreference");
207 185
208 if (NULL != old) 186 if (NULL != main_ctx->ns_selector_pushed_row)
209 gtk_tree_row_reference_free (old); 187 gtk_tree_row_reference_free (main_ctx->ns_selector_pushed_row);
210 ref = get_selected_row_from_treeview (GTK_TREE_VIEW (widget)); 188 main_ctx->ns_selector_pushed_row = get_selected_row_from_treeview (GTK_TREE_VIEW (widget));
211 g_object_set_data (G_OBJECT (widget), "pushed-rowreference", ref);
212 return FALSE; 189 return FALSE;
213} 190}
214 191
@@ -216,13 +193,11 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_press_event_cb (GtkWidget * wid
216/** 193/**
217 * User released the button in the treeview. Get the selected entry 194 * User released the button in the treeview. Get the selected entry
218 * and update the cursor accordingly, but only if the user pushed the 195 * and update the cursor accordingly, but only if the user pushed the
219 * button down and released it in the same row. We have stored the 196 * button down and released it in the same row.
220 * row that the user selected when pushing the button down in the
221 * "pushed-rowreference" of the widget.
222 * 197 *
223 * @param widget the tree view widget 198 * @param widget the tree view widget
224 * @param event the release event 199 * @param event the release event
225 * @param user_data the builder for the main window 200 * @param user_data the context for the main window
226 * @return FALSE 201 * @return FALSE
227 */ 202 */
228gboolean 203gboolean
@@ -230,20 +205,19 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_release_event_cb (GtkWidget * w
230 GdkEvent * event, 205 GdkEvent * event,
231 gpointer user_data) 206 gpointer user_data)
232{ 207{
233 GtkBuilder *builder = GTK_BUILDER (user_data); 208 struct GNUNET_GTK_MainWindowContext *main_ctx = user_data;
234 GtkTreeRowReference *ref; 209 GtkTreeRowReference *ref;
235 gpointer old = g_object_get_data (G_OBJECT (widget), "pushed-rowreference");
236 210
237 ref = get_selected_row_from_treeview (GTK_TREE_VIEW (widget)); 211 ref = get_selected_row_from_treeview (GTK_TREE_VIEW (widget));
238 if ( (NULL != ref) && (NULL != old)) 212 if ( (NULL != ref) && (NULL != main_ctx->ns_selector_pushed_row))
239 { 213 {
240 GtkTreePath *path_ref; 214 GtkTreePath *path_ref;
241 GtkTreePath *path_old; 215 GtkTreePath *path_old;
242 216
243 path_ref = gtk_tree_row_reference_get_path (ref); 217 path_ref = gtk_tree_row_reference_get_path (ref);
244 path_old = gtk_tree_row_reference_get_path (old); 218 path_old = gtk_tree_row_reference_get_path (main_ctx->ns_selector_pushed_row);
245 if (0 == gtk_tree_path_compare (path_ref, path_old)) 219 if (0 == gtk_tree_path_compare (path_ref, path_old))
246 commit_changes (builder, GTK_TREE_VIEW (widget)); 220 commit_changes (main_ctx, GTK_TREE_VIEW (widget));
247 if (path_ref) 221 if (path_ref)
248 gtk_tree_path_free (path_ref); 222 gtk_tree_path_free (path_ref);
249 if (path_old) 223 if (path_old)
@@ -251,9 +225,9 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_release_event_cb (GtkWidget * w
251 } 225 }
252 if (NULL != ref) 226 if (NULL != ref)
253 gtk_tree_row_reference_free (ref); 227 gtk_tree_row_reference_free (ref);
254 if (NULL != old) 228 if (NULL != main_ctx->ns_selector_pushed_row)
255 gtk_tree_row_reference_free (old); 229 gtk_tree_row_reference_free (main_ctx->ns_selector_pushed_row);
256 g_object_set_data (G_OBJECT (widget), "pushed-rowreference", NULL); 230 main_ctx->ns_selector_pushed_row = NULL;
257 return FALSE; 231 return FALSE;
258} 232}
259 233
@@ -263,17 +237,15 @@ GNUNET_FS_GTK_namespace_selector_treeview_button_release_event_cb (GtkWidget * w
263 * list was toggled. 237 * list was toggled.
264 * 238 *
265 * @param togglebutton the button that toggles the namespace dropdown list 239 * @param togglebutton the button that toggles the namespace dropdown list
266 * @param user_data the builder for the main window 240 * @param user_data the contexxt for the main window
267 */ 241 */
268void 242void
269GNUNET_FS_GTK_search_namespace_dropdown_button_toggled_cb (GtkToggleButton * 243GNUNET_FS_GTK_search_namespace_dropdown_button_toggled_cb (GtkToggleButton *
270 togglebutton, 244 togglebutton,
271 gpointer user_data) 245 gpointer user_data)
272{ 246{
273 GtkBuilder *builder = GTK_BUILDER (user_data); 247 struct GNUNET_GTK_MainWindowContext *main_ctx = user_data;
274 gboolean active; 248 gboolean active;
275 GtkWidget *namespace_selector_window;
276 GtkWidget *namespace_selector_treeview;
277 GtkAllocation togglebutton_allocation; 249 GtkAllocation togglebutton_allocation;
278 GdkWindow *main_window_gdk; 250 GdkWindow *main_window_gdk;
279 gint mwg_x; 251 gint mwg_x;
@@ -283,19 +255,13 @@ GNUNET_FS_GTK_search_namespace_dropdown_button_toggled_cb (GtkToggleButton *
283 gint popup_x; 255 gint popup_x;
284 gint popup_y; 256 gint popup_y;
285 257
286 namespace_selector_window =
287 GTK_WIDGET (gtk_builder_get_object
288 (builder, "namespace_selector_window"));
289 g_object_get (G_OBJECT (togglebutton), "active", &active, NULL); 258 g_object_get (G_OBJECT (togglebutton), "active", &active, NULL);
290 if (! active) 259 if (! active)
291 { 260 {
292 gtk_widget_hide (namespace_selector_window); 261 gtk_widget_hide (main_ctx->ns_selector_window);
293 gtk_widget_grab_focus (GTK_WIDGET (togglebutton)); 262 gtk_widget_grab_focus (GTK_WIDGET (togglebutton));
294 return; 263 return;
295 } 264 }
296 namespace_selector_treeview =
297 GTK_WIDGET (gtk_builder_get_object
298 (builder, "namespace_selector_treeview"));
299 gtk_widget_get_allocation (GTK_WIDGET (togglebutton), 265 gtk_widget_get_allocation (GTK_WIDGET (togglebutton),
300 &togglebutton_allocation); 266 &togglebutton_allocation);
301 main_window_gdk = gtk_widget_get_window (GTK_WIDGET (togglebutton)); 267 main_window_gdk = gtk_widget_get_window (GTK_WIDGET (togglebutton));
@@ -305,9 +271,9 @@ GNUNET_FS_GTK_search_namespace_dropdown_button_toggled_cb (GtkToggleButton *
305 tgb_y = mwg_y + togglebutton_allocation.y; 271 tgb_y = mwg_y + togglebutton_allocation.y;
306 popup_x = tgb_x; 272 popup_x = tgb_x;
307 popup_y = tgb_y + togglebutton_allocation.height; 273 popup_y = tgb_y + togglebutton_allocation.height;
308 gtk_window_move (GTK_WINDOW (namespace_selector_window), popup_x, popup_y); 274 gtk_window_move (GTK_WINDOW (main_ctx->ns_selector_window), popup_x, popup_y);
309 gtk_widget_show_all (namespace_selector_window); 275 gtk_widget_show_all (main_ctx->ns_selector_window);
310 gtk_widget_grab_focus (namespace_selector_treeview); 276 gtk_widget_grab_focus (GTK_WIDGET (main_ctx->ns_selector_treeview));
311} 277}
312 278
313 279
@@ -370,92 +336,103 @@ add_namespace_to_ts (void *cls, const GNUNET_HashCode * pseudonym,
370 return GNUNET_OK; 336 return GNUNET_OK;
371} 337}
372 338
373
374/**
375 * Startup hook to initialize the namespace dropdown widget.
376 *
377 * @param widget the main window
378 * @param user_data the builder for the main window
379 */
380/* FIXME-STYLE: hang up on 'realize' event of a widget closer to home? */
381void 339void
382GNUNET_GTK_main_window_realize_cb (GtkWidget * widget, gpointer user_data) 340GNUNET_GTK_main_window_refresh_ns_list (struct GNUNET_GTK_MainWindowContext *main_ctx)
383{ 341{
384 GtkBuilder *builder = GTK_BUILDER (user_data);
385 GtkTreeIter iter; 342 GtkTreeIter iter;
386 GtkTreeStore *namespace_treestore; 343 gint i;
387 344
388 /* FIXME-STYLE: can't we do the button initialization when we create the main window? */ 345 GtkTreePath *treepath;
389 /* Make sure button class is realized */ 346 GNUNET_HashCode *key = NULL, *selected_ns_id;
390 g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON));
391 /* GNUnet main window assumes that images on buttons are visible,
392 * override the theme's gtkrc setting
393 */
394 g_object_set (gtk_settings_get_default (), "gtk-button-images", TRUE, NULL);
395 347
396 /* setup namespace treestore */ 348 gboolean found = FALSE;
397 { 349 gchar *value = NULL;
398 namespace_treestore =
399 GTK_TREE_STORE (GNUNET_FS_GTK_get_main_window_object
400 ("main_window_search_namespace_treestore"));
401 350
402 /* FIXME-FEATURE: find a way to manage pseudonyms. 351 if (NULL != main_ctx->selected_ns_row)
403 * Right now the list will be filled with ALL and ANY pseudonyms that we
404 * find, these are held as files in a special directory.
405 * I don't see an easy way to ignore certain pseudonyms in that directory,
406 * and that require for pseudonym management. Also, pseudonyms are presented
407 * in arbitrary order. We must either sort them (by name?) or let the user
408 * drag them around to change the order in which they appear in the list.
409 * All that is not possible with a simple "files in a directory" concept.
410 */
411 gtk_tree_store_insert_with_values (namespace_treestore, &iter, NULL, G_MAXINT,
412 0, "Any", 1, NULL, 2, "", 3,
413 "Do not search in any particular namespace",
414 -1);
415 /* FIXME-BUG-MINOR: when do we unregister? */
416 GNUNET_PSEUDONYM_discovery_callback_register (GNUNET_FS_GTK_get_configuration (),
417 &add_namespace_to_ts,
418 namespace_treestore);
419 }
420
421 /* select the first item and update the label */
422 /* FIXME-STYLE: is this even necessary? If the first item is "Any", we can
423 just have the label have the right default, or not? */
424 if (gtk_tree_model_get_iter_first
425 (GTK_TREE_MODEL (namespace_treestore), &iter))
426 { 352 {
427 gchar *value; 353 GtkTreeModel *model;
428 GtkLabel *sel_namespace_label; 354 treepath = gtk_tree_row_reference_get_path (main_ctx->selected_ns_row);
429 GtkTreePath *treepath = gtk_tree_path_new_first (); 355 model = gtk_tree_view_get_model (main_ctx->ns_selector_treeview);
430 GtkTreeView *namespace_tree; 356 if (model)
431 357 {
432 namespace_tree = 358 if (gtk_tree_model_get_iter (model, &iter, treepath))
433 GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object 359 {
434 ("namespace_selector_treeview")); 360 gtk_tree_model_get (model, &iter, 1, &key, -1);
435 gtk_tree_selection_select_iter (gtk_tree_view_get_selection 361 }
436 (namespace_tree), &iter); 362 }
437 sel_namespace_label =
438 GTK_LABEL (gtk_builder_get_object
439 (builder, "main_window_search_selected_namespace_label"));
440 if (GNUNET_GTK_get_tree_string (namespace_tree, treepath, 0, &value))
441 gtk_label_set_text (sel_namespace_label, value);
442 gtk_tree_path_free (treepath); 363 gtk_tree_path_free (treepath);
364 gtk_tree_row_reference_free (main_ctx->selected_ns_row);
365 main_ctx->selected_ns_row = NULL;
443 } 366 }
444 367 selected_ns_id = NULL;
445 /* show the window (to trigger certain events) and immediately hide it */ 368 if (key != NULL)
446 /* FIXME-STYLE: yuck, can't we trigger these events by other means?
447 CG->LRN: Which events are you even talking about here? I can't find anything
448 that would seem to be needed here. */
449 { 369 {
450 GtkWidget *namespace_selector_window; 370 selected_ns_id = GNUNET_malloc (sizeof (GNUNET_HashCode));
371 memcpy (selected_ns_id, key, sizeof (GNUNET_HashCode));
372 }
451 373
452 namespace_selector_window = 374 if (TRUE == gtk_tree_model_get_iter_first (GTK_TREE_MODEL (
453 GTK_WIDGET (gtk_builder_get_object 375 main_ctx->search_ns_treestore), &iter))
454 (builder, "namespace_selector_window")); 376 {
455 gtk_widget_show (namespace_selector_window); 377 while (TRUE)
456 gtk_widget_hide (namespace_selector_window); 378 {
379 gtk_tree_model_get (GTK_TREE_MODEL (main_ctx->search_ns_treestore), &iter,
380 1, &key,
381 -1);
382 GNUNET_free_non_null (key);
383 if (TRUE != gtk_tree_model_iter_next (GTK_TREE_MODEL (
384 main_ctx->search_ns_treestore), &iter))
385 break;
386 }
387 }
388 gtk_tree_store_clear (main_ctx->search_ns_treestore);
389
390 gtk_tree_store_insert_with_values (main_ctx->search_ns_treestore, &iter, NULL, G_MAXINT,
391 0, "Any", 1, NULL, 2, "", 3,
392 "Do not search in any particular namespace",
393 -1);
394
395 if (GNUNET_YES == main_ctx->ns_callback_registered)
396 GNUNET_PSEUDONYM_discovery_callback_unregister (add_namespace_to_ts,
397 main_ctx->search_ns_treestore);
398 GNUNET_PSEUDONYM_discovery_callback_register (main_ctx->cfg,
399 add_namespace_to_ts, main_ctx->search_ns_treestore);
400 main_ctx->ns_callback_registered = GNUNET_YES;
401
402 if (TRUE == gtk_tree_model_get_iter_first (GTK_TREE_MODEL (
403 main_ctx->search_ns_treestore), &iter))
404 {
405 while (TRUE)
406 {
407 gtk_tree_model_get (GTK_TREE_MODEL (main_ctx->search_ns_treestore), &iter,
408 0, &value,
409 1, &key,
410 -1);
411 if (selected_ns_id == NULL)
412 found = TRUE;
413 else if (key != NULL && memcmp (key, selected_ns_id, sizeof (GNUNET_HashCode)) == 0)
414 found = TRUE;
415 if (found || (TRUE != gtk_tree_model_iter_next (GTK_TREE_MODEL (
416 main_ctx->search_ns_treestore), &iter)))
417 break;
418 else
419 g_free (value);
420 }
457 } 421 }
422 if (!found)
423 {
424 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (
425 main_ctx->search_ns_treestore), &iter);
426 gtk_tree_model_get (GTK_TREE_MODEL (main_ctx->search_ns_treestore), &iter,
427 0, &value, 1, &key, -1);
428 found = TRUE;
429 }
430 gtk_tree_selection_select_iter (gtk_tree_view_get_selection
431 (main_ctx->ns_selector_treeview), &iter);
432 if (value != NULL)
433 gtk_label_set_text (main_ctx->search_ns_label, value);
434 g_free(value);
435 GNUNET_free_non_null (selected_ns_id);
458} 436}
459 437
460
461/* end of gnunet-fs-gtk_main-window-namespace-dropdown.c */ 438/* end of gnunet-fs-gtk_main-window-namespace-dropdown.c */