aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk-main_window_namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk-main_window_namespace.c')
-rw-r--r--src/fs/gnunet-fs-gtk-main_window_namespace.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/src/fs/gnunet-fs-gtk-main_window_namespace.c b/src/fs/gnunet-fs-gtk-main_window_namespace.c
new file mode 100644
index 00000000..b2ca9b42
--- /dev/null
+++ b/src/fs/gnunet-fs-gtk-main_window_namespace.c
@@ -0,0 +1,349 @@
1/*
2 This file is part of GNUnet
3 (C) 2011, 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/fs/gnunet-fs-gtk-main_window_namespace.c
23 * @author Christian Grothoff
24 * @brief event handlers for the namespace selection dropdown box in the main window
25 */
26#include "gnunet-fs-gtk-common.h"
27#include <gdk/gdk.h>
28
29
30void
31main_window_search_namespace_dropdown_button_toggled_cb (GtkToggleButton *
32 togglebutton,
33 gpointer user_data)
34{
35 GtkBuilder *builder = GTK_BUILDER (user_data);
36 gboolean active;
37 GtkWidget *namespace_selector_window;
38 GtkWidget *namespace_selector_treeview;
39
40 namespace_selector_window =
41 GTK_WIDGET (gtk_builder_get_object
42 (builder, "namespace_selector_window"));
43 namespace_selector_treeview =
44 GTK_WIDGET (gtk_builder_get_object
45 (builder, "namespace_selector_treeview"));
46 g_object_get (G_OBJECT (togglebutton), "active", &active, NULL);
47 if (active)
48 {
49 GtkAllocation togglebutton_allocation;
50 GdkWindow *main_window_gdk;
51 gint mwg_x, mwg_y, tgb_x, tgb_y, popup_x, popup_y;
52
53 gtk_widget_get_allocation (GTK_WIDGET (togglebutton),
54 &togglebutton_allocation);
55
56 main_window_gdk = gtk_widget_get_window (GTK_WIDGET (togglebutton));
57
58 gdk_window_get_origin (main_window_gdk, &mwg_x, &mwg_y);
59
60 /* FIXME: this might become a problem in other window managers,
61 * where reference point is not in the top-left corner.
62 * We want to show the window below the button.
63 */
64 tgb_x = mwg_x + togglebutton_allocation.x;
65 tgb_y = mwg_y + togglebutton_allocation.y;
66 popup_x = tgb_x;
67 popup_y = tgb_y + togglebutton_allocation.height;
68
69 gtk_window_move (GTK_WINDOW (namespace_selector_window), popup_x, popup_y);
70
71 gtk_widget_show_all (namespace_selector_window);
72 gtk_widget_grab_focus (namespace_selector_treeview);
73 }
74 else
75 {
76 gtk_widget_hide (namespace_selector_window);
77 gtk_widget_grab_focus (GTK_WIDGET (togglebutton));
78 }
79}
80
81
82gboolean
83namespace_selector_window_leave_timeout_cb (gpointer user_data)
84{
85 GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (user_data);
86
87 /* This will eventually hide the namespace selector */
88 gtk_toggle_button_set_active (toggle_button, FALSE);
89 return FALSE;
90}
91
92
93gboolean
94main_window_search_namespace_dropdown_button_enter_notify_event_cb (GtkWidget *
95 widget,
96 GdkEvent *
97 event,
98 gpointer
99 user_data)
100{
101 if (namespace_selector_window_leave_timeout_source > 0)
102 g_source_remove (namespace_selector_window_leave_timeout_source);
103 return FALSE;
104}
105
106
107gboolean
108namespace_selector_window_leave_notify_event_cb (GtkWidget * widget,
109 GdkEvent * event,
110 gpointer user_data)
111{
112 GtkBuilder *builder;
113 GtkToggleButton *toggle_button;
114 guint timeout_id;
115
116 builder = GTK_BUILDER (user_data);
117
118 toggle_button =
119 GTK_TOGGLE_BUTTON (gtk_builder_get_object
120 (builder,
121 "main_window_search_namespace_dropdown_button"));
122
123 /* Place a timeout to hide the window. It will be cancelled if the cursor
124 * enters the namespace selector window or the toggle button within 100ms.
125 */
126 timeout_id =
127 g_timeout_add (100, &namespace_selector_window_leave_timeout_cb,
128 toggle_button);
129 if (namespace_selector_window_leave_timeout_source > 0)
130 g_source_remove (namespace_selector_window_leave_timeout_source);
131 namespace_selector_window_leave_timeout_source = timeout_id;
132
133 return FALSE;
134}
135
136
137static gboolean
138GNUNET_GTK_get_tree_string (GtkTreeView * treeview, GtkTreePath * treepath,
139 guint column, gchar ** value)
140{
141 gboolean ok;
142 GtkTreeModel *model;
143
144 model = gtk_tree_view_get_model (treeview);
145 if (!model)
146 return FALSE;
147
148 GtkTreeIter iter;
149
150 ok = gtk_tree_model_get_iter (model, &iter, treepath);
151 if (!ok)
152 return FALSE;
153
154 *value = NULL;
155 gtk_tree_model_get (model, &iter, column, value, -1);
156 if (*value == NULL)
157 return FALSE;
158 return TRUE;
159}
160
161
162
163gboolean
164get_selected_namespace_treepath_iter_model_widget (GtkBuilder * builder,
165 GtkTreePath ** p_treepath,
166 GtkTreeIter * p_iter,
167 GtkTreeModel ** p_model,
168 GtkWidget ** p_widget)
169{
170 GtkTreeSelection *selection;
171 GtkTreeModel *model;
172 GList *selected;
173 GtkTreePath *treepath;
174 GtkWidget *widget;
175
176 widget =
177 GTK_WIDGET (gtk_builder_get_object
178 (builder, "namespace_selector_treeview"));
179 if (!widget)
180 return FALSE;
181
182 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
183 model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
184 if (!selection || !model)
185 return FALSE;
186
187 selected = gtk_tree_selection_get_selected_rows (selection, NULL);
188 if (!selected)
189 return FALSE;
190 if (selected->data == NULL)
191 {
192 g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
193 g_list_free (selected);
194 return FALSE;
195 }
196 /* Free everything except the first path, keep it */
197 treepath = (GtkTreePath *) selected->data;
198 selected = g_list_remove (selected, selected->data);
199 g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
200 g_list_free (selected);
201
202 if (p_iter && !gtk_tree_model_get_iter (model, p_iter, treepath))
203 {
204 gtk_tree_path_free (treepath);
205 return FALSE;
206 }
207 *p_treepath = treepath;
208 if (p_model)
209 *p_model = model;
210 if (p_widget)
211 *p_widget = widget;
212 return TRUE;
213}
214
215void
216namespace_selector_treeview_cursor_changed_cb (GtkWidget * widget,
217 gpointer user_data)
218{
219 GtkBuilder *builder;
220 GtkToggleButton *toggle_button;
221 GtkLabel *sel_namespace_label;
222 GtkTreeModel *model;
223 gchar *value;
224 GtkTreePath *treepath;
225 GtkEntry *search_entry;
226 GtkTreeRowReference *ref, *old;
227
228 builder = GTK_BUILDER (user_data);
229
230 toggle_button =
231 GTK_TOGGLE_BUTTON (gtk_builder_get_object
232 (builder,
233 "main_window_search_namespace_dropdown_button"));
234 if (!toggle_button)
235 return;
236
237 search_entry =
238 GTK_ENTRY (gtk_builder_get_object (builder, "main_window_search_entry"));
239 if (!search_entry)
240 return;
241
242 if (!get_selected_namespace_treepath_iter_model_widget
243 (builder, &treepath, NULL, &model, NULL))
244 return;
245 ref = gtk_tree_row_reference_new (model, treepath);
246 old = g_object_get_data (G_OBJECT (toggle_button), "selected-row-reference");
247 if (old)
248 gtk_tree_row_reference_free (old);
249 g_object_set_data (G_OBJECT (toggle_button), "selected-row-reference", ref);
250
251
252 sel_namespace_label =
253 GTK_LABEL (gtk_builder_get_object
254 (builder, "main_window_search_selected_namespace_label"));
255 if (!sel_namespace_label)
256 return;
257
258 if (GNUNET_GTK_get_tree_string (GTK_TREE_VIEW (widget), treepath, 0, &value)
259 && value != NULL)
260 {
261 gtk_label_set_text (sel_namespace_label, value);
262 g_free (value);
263 }
264 if (GNUNET_GTK_get_tree_string (GTK_TREE_VIEW (widget), treepath, 2, &value)
265 && value != NULL)
266 {
267 gtk_entry_set_text (search_entry, value);
268 g_free (value);
269 }
270
271 gtk_tree_path_free (treepath);
272
273 /* This will eventually hide the namespace selector */
274 gtk_toggle_button_set_active (toggle_button, FALSE);
275}
276
277GtkTreeRowReference *
278get_ns_selected_row (GtkTreeView * tree)
279{
280 GtkTreeSelection *sel;
281 GList *rows, *row;
282 GtkTreeModel *model;
283 GtkTreeRowReference *ref = NULL;
284
285 sel = gtk_tree_view_get_selection (tree);
286 rows = gtk_tree_selection_get_selected_rows (sel, &model);
287 for (row = rows; row; row = row->next)
288 {
289 ref = gtk_tree_row_reference_new (model, row->data);
290 if (ref != NULL)
291 break;
292 }
293 g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
294 g_list_free (rows);
295 return ref;
296}
297
298gboolean
299namespace_selector_treeview_button_press_event_cb (GtkWidget * widget,
300 GdkEvent * event,
301 gpointer user_data)
302{
303 GtkTreeRowReference *ref = NULL;
304
305 ref = get_ns_selected_row (GTK_TREE_VIEW (widget));
306 if (ref != NULL)
307 {
308 gpointer old = g_object_get_data (G_OBJECT (widget), "pushed-rowreference");
309
310 if (old)
311 gtk_tree_row_reference_free (old);
312 g_object_set_data (G_OBJECT (widget), "pushed-rowreference", ref);
313 }
314 return FALSE;
315}
316
317gboolean
318namespace_selector_treeview_button_release_event_cb (GtkWidget * widget,
319 GdkEvent * event,
320 gpointer user_data)
321{
322 GtkTreeRowReference *ref = NULL;
323 gpointer old = g_object_get_data (G_OBJECT (widget), "pushed-rowreference");
324
325 ref = get_ns_selected_row (GTK_TREE_VIEW (widget));
326 if (ref && old)
327 {
328 GtkTreePath *path_ref, *path_old;
329
330 path_ref = gtk_tree_row_reference_get_path (ref);
331 path_old = gtk_tree_row_reference_get_path (old);
332 if (gtk_tree_path_compare (path_ref, path_old) == 0)
333 namespace_selector_treeview_cursor_changed_cb (widget, user_data);
334 if (path_ref)
335 gtk_tree_path_free (path_ref);
336 if (path_old)
337 gtk_tree_path_free (path_old);
338 }
339 if (ref)
340 gtk_tree_row_reference_free (ref);
341 if (old)
342 gtk_tree_row_reference_free (old);
343 g_object_set_data (G_OBJECT (widget), "pushed-rowreference", NULL);
344 return FALSE;
345}
346
347
348
349/* end of gnunet-fs-gtk-main_window_namespace.c */