diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-02 06:00:57 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-02 06:00:57 +0000 |
commit | 9ce4c70c81f975f44698506c17747d23ac0ef69a (patch) | |
tree | 0491b2ab12389cef27f75e05bba41952b2a62a8d | |
parent | bf21517c2ccfbf801015c309ac763a98cda6a65d (diff) | |
download | gnunet-gtk-9ce4c70c81f975f44698506c17747d23ac0ef69a.tar.gz gnunet-gtk-9ce4c70c81f975f44698506c17747d23ac0ef69a.zip |
-LRN: Add a proper popup handler (which also works for ctrl+F10 and Menu
keys, not just rightclicks)
-rw-r--r-- | src/fs/gnunet-fs-gtk-event_handler.c | 223 |
1 files changed, 130 insertions, 93 deletions
diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c index 94558630..b420c81b 100644 --- a/src/fs/gnunet-fs-gtk-event_handler.c +++ b/src/fs/gnunet-fs-gtk-event_handler.c | |||
@@ -113,6 +113,122 @@ struct StartDownloadContext | |||
113 | 113 | ||
114 | static struct PublishTab *publish_tab; | 114 | static struct PublishTab *publish_tab; |
115 | 115 | ||
116 | static gboolean | ||
117 | search_list_popup (GtkTreeView *tv, struct SearchTab *tab, GdkEventButton *event_button) | ||
118 | { | ||
119 | GtkMenu *menu; | ||
120 | GtkWidget *child; | ||
121 | GtkTreeSelection *sel; | ||
122 | GtkTreePath *path; | ||
123 | GtkTreeModel *tm; | ||
124 | GtkTreeIter iter; | ||
125 | struct SearchResult *sr; | ||
126 | struct GNUNET_FS_Uri *uri; | ||
127 | gboolean got_selection; | ||
128 | gint init_button; | ||
129 | guint32 event_time; | ||
130 | |||
131 | current_context_search_tab = tab; | ||
132 | if (current_context_row_reference != NULL) | ||
133 | { | ||
134 | gtk_tree_row_reference_free (current_context_row_reference); | ||
135 | current_context_row_reference = NULL; | ||
136 | } | ||
137 | path = NULL; | ||
138 | if (event_button != NULL) | ||
139 | { | ||
140 | got_selection = | ||
141 | gtk_tree_view_get_path_at_pos (tv, event_button->x, event_button->y, | ||
142 | &path, NULL, NULL, NULL); | ||
143 | if (got_selection) | ||
144 | { | ||
145 | tm = gtk_tree_view_get_model (tv); | ||
146 | got_selection = gtk_tree_model_get_iter (tm, &iter, path); | ||
147 | current_context_row_reference = gtk_tree_row_reference_new (tm, path); | ||
148 | gtk_tree_path_free (path); | ||
149 | } | ||
150 | init_button = event_button->button; | ||
151 | event_time = event_button->time; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | sel = gtk_tree_view_get_selection (tv); | ||
156 | got_selection = gtk_tree_selection_get_selected (sel, &tm, &iter); | ||
157 | path = gtk_tree_model_get_path (tm, &iter); | ||
158 | current_context_row_reference = gtk_tree_row_reference_new (tm, path); | ||
159 | gtk_tree_path_free (path); | ||
160 | init_button = 0; | ||
161 | event_time = gtk_get_current_event_time (); | ||
162 | } | ||
163 | if (!got_selection) | ||
164 | { | ||
165 | /* nothing selected or model empty? */ | ||
166 | current_context_search_tab = NULL; | ||
167 | return FALSE; | ||
168 | } | ||
169 | gtk_tree_model_get (tm, &iter, 1, &uri, 9, &sr, -1); | ||
170 | |||
171 | /* | ||
172 | * FIXME: have additional options, depending on status: | ||
173 | * - view full meta data (in new window) | ||
174 | * - copy URI to clipboard | ||
175 | * - start recursive download | ||
176 | * - abort active download (!) | ||
177 | * => need to know download status before creating menu! | ||
178 | */ | ||
179 | menu = GTK_MENU (gtk_menu_new ()); | ||
180 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
181 | "Creating a menu for SR=%p, DE=%p\n", sr, sr->download); | ||
182 | if (sr->download == NULL) | ||
183 | { | ||
184 | if (NULL != uri) | ||
185 | { | ||
186 | /* only display download menus if there is a URI */ | ||
187 | child = gtk_menu_item_new_with_label (_("_Download")); | ||
188 | g_signal_connect (child, "activate", | ||
189 | G_CALLBACK (start_download_ctx_menu), NULL); | ||
190 | gtk_label_set_use_underline (GTK_LABEL | ||
191 | (gtk_bin_get_child (GTK_BIN (child))), | ||
192 | TRUE); | ||
193 | gtk_widget_show (child); | ||
194 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
195 | |||
196 | child = gtk_menu_item_new_with_label (_("Download _recursively")); | ||
197 | g_signal_connect (child, "activate", | ||
198 | G_CALLBACK (start_download_recursively_ctx_menu), NULL); | ||
199 | gtk_label_set_use_underline (GTK_LABEL | ||
200 | (gtk_bin_get_child (GTK_BIN (child))), | ||
201 | TRUE); | ||
202 | gtk_widget_show (child); | ||
203 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
204 | } | ||
205 | } | ||
206 | else | ||
207 | { | ||
208 | child = gtk_menu_item_new_with_label (_("_Abort download")); | ||
209 | g_signal_connect (child, "activate", | ||
210 | G_CALLBACK (abort_download_ctx_menu), sr->download); | ||
211 | gtk_label_set_use_underline (GTK_LABEL | ||
212 | (gtk_bin_get_child (GTK_BIN (child))), | ||
213 | TRUE); | ||
214 | gtk_widget_show (child); | ||
215 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
216 | } | ||
217 | |||
218 | child = gtk_menu_item_new_with_label (_("_Copy URI to Clipboard")); | ||
219 | g_signal_connect (child, "activate", | ||
220 | G_CALLBACK (copy_uri_to_clipboard_ctx_menu), NULL); | ||
221 | gtk_label_set_use_underline (GTK_LABEL | ||
222 | (gtk_bin_get_child (GTK_BIN (child))), TRUE); | ||
223 | gtk_widget_show (child); | ||
224 | |||
225 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
226 | gtk_menu_popup (menu, NULL, NULL, NULL, NULL, init_button, event_time); | ||
227 | /* FIXME: attach some kind of handler to destroy the menu */ | ||
228 | return TRUE; | ||
229 | } | ||
230 | |||
231 | |||
116 | static void | 232 | static void |
117 | closure_notify_free (gpointer data, GClosure *closure) | 233 | closure_notify_free (gpointer data, GClosure *closure) |
118 | { | 234 | { |
@@ -901,6 +1017,17 @@ copy_uri_to_clipboard_ctx_menu (GtkMenuItem *item, gpointer user_data) | |||
901 | GNUNET_free (uris); | 1017 | GNUNET_free (uris); |
902 | } | 1018 | } |
903 | 1019 | ||
1020 | gboolean | ||
1021 | search_list_on_popup (GtkWidget *widget, gpointer user_data) | ||
1022 | { | ||
1023 | GtkTreeView *tv; | ||
1024 | struct SearchTab *tab = user_data; | ||
1025 | |||
1026 | tv = GTK_TREE_VIEW (widget); | ||
1027 | return search_list_popup (tv, tab, NULL); | ||
1028 | } | ||
1029 | |||
1030 | |||
904 | 1031 | ||
905 | /** | 1032 | /** |
906 | * We got a right-click on the search result list. Display the context | 1033 | * We got a right-click on the search result list. Display the context |
@@ -912,13 +1039,6 @@ search_list_on_menu (GtkWidget * widget, GdkEvent * event, gpointer user_data) | |||
912 | GdkEventButton *event_button; | 1039 | GdkEventButton *event_button; |
913 | struct SearchTab *tab = user_data; | 1040 | struct SearchTab *tab = user_data; |
914 | GtkTreeView *tv; | 1041 | GtkTreeView *tv; |
915 | GtkMenu *menu; | ||
916 | GtkWidget *child; | ||
917 | GtkTreePath *path; | ||
918 | GtkTreeModel *tm; | ||
919 | GtkTreeIter iter; | ||
920 | struct SearchResult *sr; | ||
921 | struct GNUNET_FS_Uri *uri; | ||
922 | 1042 | ||
923 | tv = GTK_TREE_VIEW (widget); | 1043 | tv = GTK_TREE_VIEW (widget); |
924 | if (event->type == GDK_BUTTON_PRESS) | 1044 | if (event->type == GDK_BUTTON_PRESS) |
@@ -926,97 +1046,12 @@ search_list_on_menu (GtkWidget * widget, GdkEvent * event, gpointer user_data) | |||
926 | event_button = (GdkEventButton *) event; | 1046 | event_button = (GdkEventButton *) event; |
927 | if (event_button->button == 3) | 1047 | if (event_button->button == 3) |
928 | { | 1048 | { |
929 | current_context_search_tab = tab; | 1049 | return search_list_popup (tv, tab, event_button); |
930 | if (current_context_row_reference != NULL) | ||
931 | { | ||
932 | gtk_tree_row_reference_free (current_context_row_reference); | ||
933 | current_context_row_reference = NULL; | ||
934 | } | ||
935 | path = NULL; | ||
936 | if (FALSE == | ||
937 | gtk_tree_view_get_path_at_pos (tv, event_button->x, event_button->y, | ||
938 | &path, NULL, NULL, NULL)) | ||
939 | { | ||
940 | /* nothing selected */ | ||
941 | current_context_search_tab = NULL; | ||
942 | return FALSE; | ||
943 | } | ||
944 | tm = gtk_tree_view_get_model (tv); | ||
945 | if (TRUE != gtk_tree_model_get_iter (tm, &iter, path)) | ||
946 | { | ||
947 | /* model empty? */ | ||
948 | current_context_search_tab = NULL; | ||
949 | return FALSE; | ||
950 | } | ||
951 | gtk_tree_model_get (tm, &iter, 1, &uri, 9, &sr, -1); | ||
952 | current_context_row_reference = gtk_tree_row_reference_new (tm, path); | ||
953 | gtk_tree_path_free (path); | ||
954 | |||
955 | /* | ||
956 | * FIXME: have additional options, depending on status: | ||
957 | * - view full meta data (in new window) | ||
958 | * - copy URI to clipboard | ||
959 | * - start recursive download | ||
960 | * - abort active download (!) | ||
961 | * => need to know download status before creating menu! | ||
962 | */ | ||
963 | menu = GTK_MENU (gtk_menu_new ()); | ||
964 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
965 | "Creating a menu for SR=%p, DE=%p\n", sr, sr->download); | ||
966 | if (sr->download == NULL) | ||
967 | { | ||
968 | if (NULL != uri) | ||
969 | { | ||
970 | /* only display download menus if there is a URI */ | ||
971 | child = gtk_menu_item_new_with_label (_("_Download")); | ||
972 | g_signal_connect (child, "activate", | ||
973 | G_CALLBACK (start_download_ctx_menu), NULL); | ||
974 | gtk_label_set_use_underline (GTK_LABEL | ||
975 | (gtk_bin_get_child (GTK_BIN (child))), | ||
976 | TRUE); | ||
977 | gtk_widget_show (child); | ||
978 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
979 | |||
980 | child = gtk_menu_item_new_with_label (_("Download _recursively")); | ||
981 | g_signal_connect (child, "activate", | ||
982 | G_CALLBACK (start_download_recursively_ctx_menu), NULL); | ||
983 | gtk_label_set_use_underline (GTK_LABEL | ||
984 | (gtk_bin_get_child (GTK_BIN (child))), | ||
985 | TRUE); | ||
986 | gtk_widget_show (child); | ||
987 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
988 | } | ||
989 | } | ||
990 | else | ||
991 | { | ||
992 | child = gtk_menu_item_new_with_label (_("_Abort download")); | ||
993 | g_signal_connect (child, "activate", | ||
994 | G_CALLBACK (abort_download_ctx_menu), sr->download); | ||
995 | gtk_label_set_use_underline (GTK_LABEL | ||
996 | (gtk_bin_get_child (GTK_BIN (child))), | ||
997 | TRUE); | ||
998 | gtk_widget_show (child); | ||
999 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
1000 | } | ||
1001 | |||
1002 | child = gtk_menu_item_new_with_label (_("_Copy URI to Clipboard")); | ||
1003 | g_signal_connect (child, "activate", | ||
1004 | G_CALLBACK (copy_uri_to_clipboard_ctx_menu), NULL); | ||
1005 | gtk_label_set_use_underline (GTK_LABEL | ||
1006 | (gtk_bin_get_child (GTK_BIN (child))), TRUE); | ||
1007 | gtk_widget_show (child); | ||
1008 | |||
1009 | |||
1010 | |||
1011 | gtk_menu_shell_append (GTK_MENU_SHELL (menu), child); | ||
1012 | gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event_button->button, | ||
1013 | event_button->time); | ||
1014 | } | 1050 | } |
1015 | } | 1051 | } |
1016 | return FALSE; | 1052 | return FALSE; |
1017 | } | 1053 | } |
1018 | 1054 | ||
1019 | |||
1020 | /** | 1055 | /** |
1021 | * Selected row has changed, update preview and metadata | 1056 | * Selected row has changed, update preview and metadata |
1022 | * areas. | 1057 | * areas. |
@@ -1362,6 +1397,8 @@ setup_search (struct GNUNET_FS_SearchContext *sc, | |||
1362 | G_CALLBACK (update_meta_data_views), tab); | 1397 | G_CALLBACK (update_meta_data_views), tab); |
1363 | g_signal_connect (G_OBJECT (tv), "button_press_event", | 1398 | g_signal_connect (G_OBJECT (tv), "button_press_event", |
1364 | G_CALLBACK (search_list_on_menu), tab); | 1399 | G_CALLBACK (search_list_on_menu), tab); |
1400 | g_signal_connect (G_OBJECT (tv), "popup-menu", | ||
1401 | G_CALLBACK (search_list_on_popup), tab); | ||
1365 | 1402 | ||
1366 | 1403 | ||
1367 | /* make visible */ | 1404 | /* make visible */ |