2
* @file ui_popup.c popup menus
4
* Copyright (C) 2003-2008 Lars Lindner <lars.lindner@gmail.com>
5
* Copyright (C) 2004-2006 Nathan J. Conrad <t98502@users.sourceforge.net>
6
* Copyright (C) 2009 Adrian Bunk <bunk@users.sourceforge.net>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
#include "ui/ui_popup.h"
37
#include "ui/enclosure_list_view.h"
38
#include "ui/liferea_shell.h"
39
#include "ui/ui_feedlist.h"
40
#include "ui/ui_itemlist.h"
41
#include "ui/itemview.h"
42
#include "ui/ui_prefs.h"
43
#include "fl_sources/node_source.h"
45
#define UI_POPUP_ITEM_IS_TOGGLE 1
54
on_toggle_visibility (void)
56
liferea_shell_toggle_visibility ();
60
ui_popup_menu_at_pos (GtkWidget *menu, GtkMenuPositionFunc func, guint button, guint32 activate_time, gpointer user_data)
62
g_signal_connect_after (G_OBJECT(menu), "unmap-event", G_CALLBACK(gtk_widget_destroy), NULL);
64
gtk_widget_show_all (menu);
66
gtk_menu_popup (GTK_MENU(menu), NULL, NULL, func, user_data, button, activate_time);
70
ui_popup_menu (GtkWidget *menu, guint button, guint32 activate_time)
72
ui_popup_menu_at_pos(menu, NULL, button, activate_time, NULL);
76
ui_popup_add_menuitem (GtkWidget *menu, const gchar *label, gpointer callback, gpointer data, const gchar *icon, gint toggle)
82
item = gtk_check_menu_item_new_with_label (label);
83
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(item), toggle - UI_POPUP_ITEM_IS_TOGGLE);
86
item = gtk_image_menu_item_new_with_label (label);
87
image = gtk_image_new_from_stock (icon, GTK_ICON_SIZE_MENU);
88
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
90
item = gtk_menu_item_new_with_label (label);
95
g_signal_connect_swapped (G_OBJECT(item), "activate", G_CALLBACK(callback), data);
97
gtk_menu_item_set_use_underline (GTK_MENU_ITEM(item), TRUE);
98
gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);
104
ui_popup_item_menu (itemPtr item, guint button, guint32 activate_time)
110
menu = gtk_menu_new ();
112
ui_popup_add_menuitem (menu, _("Launch Item In _Tab"), on_popup_launchitem_in_tab_selected, NULL, NULL, 0);
113
ui_popup_add_menuitem (menu, _("_Launch Item In Browser"), on_popup_launchitem_selected, NULL, NULL, 0);
115
gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
117
iter = newsbin_get_list ();
123
submenu = gtk_menu_new ();
125
item = ui_popup_add_menuitem (menu, _("Copy to News Bin"), NULL, NULL, NULL, 0);
128
nodePtr node = (nodePtr)iter->data;
129
ui_popup_add_menuitem (submenu, node_get_title (node), on_popup_copy_to_newsbin, GINT_TO_POINTER(i), NULL, 0);
130
iter = g_slist_next (iter);
134
gtk_menu_item_set_submenu (GTK_MENU_ITEM(item), submenu);
136
gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
139
text = g_strdup_printf (_("_Bookmark Link at %s"), social_get_bookmark_site ());
140
ui_popup_add_menuitem (menu, text, on_popup_social_bm_item_selected, NULL, NULL, 0);
143
ui_popup_add_menuitem (menu, _("Copy Item _URL to Clipboard"), on_popup_copy_URL_clipboard, NULL, NULL, 0);
145
gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
147
ui_popup_add_menuitem (menu, _("Toggle _Read Status"), on_popup_toggle_read, NULL, GTK_STOCK_APPLY, 0);
148
ui_popup_add_menuitem (menu, _("Toggle Item _Flag"), on_popup_toggle_flag, NULL, NULL, 0);
149
ui_popup_add_menuitem (menu, _("R_emove Item"), on_popup_remove_selected, NULL, GTK_STOCK_DELETE, 0);
151
ui_popup_menu (menu, button, activate_time);
155
ui_popup_enclosure_menu (enclosurePtr enclosure, guint button,
156
guint32 activate_time)
160
menu = gtk_menu_new ();
162
ui_popup_add_menuitem (menu, _("Open Enclosure..."), on_popup_open_enclosure, enclosure, NULL, 0);
163
ui_popup_add_menuitem (menu, _("Save As..."), on_popup_save_enclosure, enclosure, NULL, 0);
164
ui_popup_add_menuitem (menu, _("Copy Link Location"), on_popup_copy_enclosure, enclosure, NULL, 0);
166
ui_popup_menu (menu, button, activate_time);
170
ui_popup_systray_menu (GtkMenuPositionFunc func, guint button, guint32 activate_time, gpointer user_data)
173
GtkWidget *mainwindow = liferea_shell_get_window ();
175
menu = gtk_menu_new ();
177
ui_popup_add_menuitem (menu, _("_Work Offline"), on_onlinebtn_clicked, NULL, NULL, (!network_is_online ()) + UI_POPUP_ITEM_IS_TOGGLE);
178
ui_popup_add_menuitem (menu, _("_Update All"), on_menu_update_all, NULL, GTK_STOCK_REFRESH, 0);
179
ui_popup_add_menuitem (menu, _("_Preferences"), on_prefbtn_clicked, NULL, GTK_STOCK_PREFERENCES, 0);
181
gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
183
ui_popup_add_menuitem (menu, _("_Show Liferea"), on_toggle_visibility, NULL, NULL, (!(gdk_window_get_state (mainwindow->window) & GDK_WINDOW_STATE_ICONIFIED) && GTK_WIDGET_VISIBLE (mainwindow)) + UI_POPUP_ITEM_IS_TOGGLE);
184
ui_popup_add_menuitem (menu, _("_Quit"), on_popup_quit, NULL, GTK_STOCK_QUIT, 0);
186
ui_popup_menu_at_pos (menu, func, button, activate_time, user_data);
189
/* popup callback wrappers */
192
ui_popup_mark_as_read (gpointer callback_data)
194
feedlist_mark_all_read ((nodePtr)callback_data);
198
ui_popup_add_feed (void)
200
node_type_request_interactive_add (feed_get_node_type ());
204
ui_popup_add_folder (void)
206
node_type_request_interactive_add (folder_get_node_type ());
210
ui_popup_add_vfolder (void)
212
node_type_request_interactive_add (vfolder_get_node_type ());
216
ui_popup_add_source (void)
218
node_type_request_interactive_add (node_source_get_node_type ());
222
ui_popup_add_newsbin (void)
224
node_type_request_interactive_add (newsbin_get_node_type ());
228
ui_popup_properties (gpointer callback_data)
230
nodePtr node = (nodePtr) callback_data;
232
NODE_TYPE (node)->request_properties (node);
236
ui_popup_delete (gpointer callback_data)
238
ui_feedlist_delete_prompt ((nodePtr)callback_data);
242
* Shows popup menus for the feed list depending on the
246
ui_popup_node_menu (nodePtr node, gboolean validSelection, guint button, guint32 activate_time)
249
gboolean writeableFeedlist, isRoot, isHierarchic;
251
menu = gtk_menu_new ();
254
writeableFeedlist = NODE_SOURCE_TYPE (node->parent->source->root)->capabilities & NODE_SOURCE_CAPABILITY_WRITABLE_FEEDLIST;
255
isRoot = NODE_SOURCE_TYPE (node->parent->source->root)->capabilities & NODE_SOURCE_CAPABILITY_IS_ROOT;
256
isHierarchic = NODE_SOURCE_TYPE (node->parent->source->root)->capabilities & NODE_SOURCE_CAPABILITY_HIERARCHIC_FEEDLIST;
258
/* if we have no parent then we have the root node... */
259
writeableFeedlist = TRUE;
264
if (validSelection) {
265
if (NODE_TYPE (node)->capabilities & NODE_CAPABILITY_UPDATE)
266
ui_popup_add_menuitem (menu, _("_Update"), on_menu_update, node, GTK_STOCK_REFRESH, 0);
267
else if (NODE_TYPE (node)->capabilities & NODE_CAPABILITY_UPDATE_CHILDS)
268
ui_popup_add_menuitem (menu, _("_Update Folder"), on_menu_update, node, GTK_STOCK_REFRESH, 0);
270
ui_popup_add_menuitem (menu, _("_Mark All As Read"), ui_popup_mark_as_read, node, GTK_STOCK_APPLY, 0);
273
if (writeableFeedlist) {
274
if (NODE_TYPE (node->source->root)->capabilities & NODE_CAPABILITY_ADD_CHILDS) {
278
submenu = gtk_menu_new ();
280
item = ui_popup_add_menuitem (menu, _("_New"), NULL, NULL, NULL, 0);
282
ui_popup_add_menuitem (submenu, _("New _Subscription..."), ui_popup_add_feed, NULL, NULL, 0);
285
ui_popup_add_menuitem (submenu, _("New _Folder..."), ui_popup_add_folder, NULL, NULL, 0);
288
ui_popup_add_menuitem (submenu, _("New S_earch Folder..."), ui_popup_add_vfolder, NULL, NULL, 0);
289
ui_popup_add_menuitem (submenu, _("New S_ource..."), ui_popup_add_source, NULL, NULL, 0);
290
ui_popup_add_menuitem (submenu, _("New _News Bin..."), ui_popup_add_newsbin, NULL, NULL, 0);
293
gtk_menu_item_set_submenu (GTK_MENU_ITEM(item), submenu);
297
if (validSelection) {
298
if (writeableFeedlist) {
299
ui_popup_add_menuitem (menu, _("_Delete"), ui_popup_delete, node, GTK_STOCK_DELETE, 0);
300
ui_popup_add_menuitem (menu, _("_Properties..."), ui_popup_properties, node, GTK_STOCK_PROPERTIES, 0);
304
ui_popup_menu (menu, button, activate_time);
307
/*------------------------------------------------------------------------------*/
308
/* mouse button handler */
309
/*------------------------------------------------------------------------------*/
312
on_mainfeedlist_button_press_event (GtkWidget *widget,
313
GdkEventButton *event,
321
gboolean selected = TRUE;
324
treeview = liferea_shell_lookup ("feedlist");
327
if (event->type != GDK_BUTTON_PRESS)
330
eb = (GdkEventButton*)event;
333
if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview), event->x, event->y, &path, NULL, NULL, NULL)) {
335
node = feedlist_get_root ();
337
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
338
gtk_tree_model_get_iter (model, &iter, path);
339
gtk_tree_path_free (path);
340
gtk_tree_model_get (model, &iter, FS_PTR, &node, -1);
344
switch (eb->button) {
346
/* Shouldn't happen... */
351
feedlist_mark_all_read (node);
352
itemview_update_node_info (node);
358
ui_feedlist_select (node);
360
/* This happens when an "empty" node or nothing (feed list root) is clicked */
362
node = feedlist_get_root ();
365
ui_popup_node_menu (node, selected, eb->button, eb->time);