~ubuntu-branches/ubuntu/vivid/liferea/vivid-proposed

« back to all changes in this revision

Viewing changes to src/ui/ui_popup.c

  • Committer: Package Import Robot
  • Author(s): bojo42
  • Date: 2012-03-29 14:17:21 UTC
  • mfrom: (1.3.9) (3.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20120329141721-tbfopcrc5797wxt7
Tags: 1.8.3-0.1ubuntu1
* New upstream release (LP: #290666, #371754, #741543, #716688)
* Merge from Debian unstable (LP: #935147), remaining changes:
* debian/patches:
  - drop gtk-status-icon.patch & notification-append as in upstream
  - drop fix_systray_behavior as mostly upstreamed and rest seems unused
  - 01_ubuntu_feedlists: update & rename, move planets to "Open Source"  
  - add_X-Ubuntu-Gettext-Domain: rebase
  - libunity.patch: rebase, apply before indicator patch (liferea_shell.c)
  - libindicate_increase_version.patch: exclude from libindicate.patch
  - deactivate libindicate.patch, seems partly upstreamed and needs rework
* debian/control: libindicate-dev, libindicate-gtk-dev & libunity-dev
* debian/liferea.indicate & liferea.install: ship indicator desktop file
* debian/rules: enable libindicate

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * @file ui_popup.c popup menus
3
 
 *
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>
7
 
 *
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.
12
 
 *
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.
17
 
 *
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 
21
 
 */
22
 
 
23
 
#include "ui/ui_popup.h"
24
 
 
25
 
#include <string.h>
26
 
 
27
 
#include "common.h"
28
 
#include "feed.h"
29
 
#include "feedlist.h"
30
 
#include "folder.h"
31
 
#include "itemlist.h"
32
 
#include "net.h"
33
 
#include "newsbin.h"
34
 
#include "node.h"
35
 
#include "social.h"
36
 
#include "vfolder.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"
44
 
 
45
 
#define UI_POPUP_ITEM_IS_TOGGLE         1
46
 
 
47
 
static void
48
 
on_popup_quit (void)
49
 
{
50
 
        liferea_shutdown ();
51
 
}
52
 
 
53
 
static void
54
 
on_toggle_visibility (void)
55
 
{
56
 
        liferea_shell_toggle_visibility ();
57
 
}
58
 
 
59
 
static void
60
 
ui_popup_menu_at_pos (GtkWidget *menu, GtkMenuPositionFunc func, guint button, guint32 activate_time, gpointer user_data)
61
 
{
62
 
        g_signal_connect_after (G_OBJECT(menu), "unmap-event", G_CALLBACK(gtk_widget_destroy), NULL);
63
 
 
64
 
        gtk_widget_show_all (menu);
65
 
 
66
 
        gtk_menu_popup (GTK_MENU(menu), NULL, NULL, func, user_data, button, activate_time);
67
 
}
68
 
 
69
 
static void
70
 
ui_popup_menu (GtkWidget *menu, guint button, guint32 activate_time)
71
 
{
72
 
        ui_popup_menu_at_pos(menu, NULL, button, activate_time, NULL);
73
 
}
74
 
 
75
 
static GtkWidget*
76
 
ui_popup_add_menuitem (GtkWidget *menu, const gchar *label, gpointer callback, gpointer data, const gchar *icon, gint toggle)
77
 
{
78
 
        GtkWidget       *item;
79
 
        GtkWidget       *image;
80
 
 
81
 
        if (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);
84
 
        } else {
85
 
                if (icon) {
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);
89
 
                } else {
90
 
                        item = gtk_menu_item_new_with_label (label);
91
 
                }
92
 
        }
93
 
 
94
 
        if (callback)
95
 
                g_signal_connect_swapped (G_OBJECT(item), "activate", G_CALLBACK(callback), data);
96
 
 
97
 
        gtk_menu_item_set_use_underline (GTK_MENU_ITEM(item), TRUE);
98
 
        gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);
99
 
 
100
 
        return item;
101
 
}
102
 
 
103
 
void
104
 
ui_popup_item_menu (itemPtr item, guint button, guint32 activate_time)
105
 
{
106
 
        GtkWidget       *menu;
107
 
        GSList          *iter;
108
 
        gchar           *text;
109
 
 
110
 
        menu = gtk_menu_new ();
111
 
 
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);
114
 
 
115
 
        gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
116
 
 
117
 
        iter = newsbin_get_list ();
118
 
        if (iter) {
119
 
                GtkWidget       *item;
120
 
                GtkWidget       *submenu;
121
 
                int             i = 0;
122
 
 
123
 
                submenu = gtk_menu_new ();
124
 
 
125
 
                item = ui_popup_add_menuitem (menu, _("Copy to News Bin"), NULL, NULL, NULL, 0);
126
 
 
127
 
                while (iter) {
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);
131
 
                        i++;
132
 
                }
133
 
 
134
 
                gtk_menu_item_set_submenu (GTK_MENU_ITEM(item), submenu);
135
 
 
136
 
                gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
137
 
        }
138
 
 
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);
141
 
        g_free (text);
142
 
 
143
 
        ui_popup_add_menuitem (menu, _("Copy Item _URL to Clipboard"), on_popup_copy_URL_clipboard, NULL, NULL, 0);
144
 
        
145
 
        gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
146
 
 
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);
150
 
 
151
 
        ui_popup_menu (menu, button, activate_time);
152
 
}
153
 
 
154
 
void
155
 
ui_popup_enclosure_menu (enclosurePtr enclosure, guint button,
156
 
                         guint32 activate_time)
157
 
{
158
 
        GtkWidget       *menu;
159
 
 
160
 
        menu = gtk_menu_new ();
161
 
 
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);
165
 
 
166
 
        ui_popup_menu (menu, button, activate_time);
167
 
}
168
 
 
169
 
void
170
 
ui_popup_systray_menu (GtkMenuPositionFunc func, guint button, guint32 activate_time, gpointer user_data)
171
 
{
172
 
        GtkWidget       *menu;
173
 
        GtkWidget       *mainwindow = liferea_shell_get_window ();
174
 
 
175
 
        menu = gtk_menu_new ();
176
 
 
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);
180
 
 
181
 
        gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
182
 
 
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);
185
 
 
186
 
        ui_popup_menu_at_pos (menu, func, button, activate_time, user_data);
187
 
}
188
 
 
189
 
/* popup callback wrappers */
190
 
 
191
 
static void
192
 
ui_popup_mark_as_read (gpointer callback_data) 
193
 
{
194
 
        feedlist_mark_all_read ((nodePtr)callback_data);
195
 
}
196
 
 
197
 
static void
198
 
ui_popup_add_feed (void)
199
 
{
200
 
        node_type_request_interactive_add (feed_get_node_type ());
201
 
}
202
 
 
203
 
static void
204
 
ui_popup_add_folder (void)
205
 
{
206
 
        node_type_request_interactive_add (folder_get_node_type ());
207
 
}
208
 
 
209
 
static void
210
 
ui_popup_add_vfolder (void)
211
 
{
212
 
        node_type_request_interactive_add (vfolder_get_node_type ());
213
 
}
214
 
 
215
 
static void
216
 
ui_popup_add_source (void)
217
 
{
218
 
        node_type_request_interactive_add (node_source_get_node_type ());
219
 
}
220
 
 
221
 
static void
222
 
ui_popup_add_newsbin (void)
223
 
{
224
 
        node_type_request_interactive_add (newsbin_get_node_type ());
225
 
}
226
 
 
227
 
static void
228
 
ui_popup_properties (gpointer callback_data)
229
 
{
230
 
        nodePtr node = (nodePtr) callback_data;
231
 
        
232
 
        NODE_TYPE (node)->request_properties (node);
233
 
}
234
 
 
235
 
static void
236
 
ui_popup_delete (gpointer callback_data)
237
 
{
238
 
        ui_feedlist_delete_prompt ((nodePtr)callback_data);
239
 
}
240
 
 
241
 
/** 
242
 
 * Shows popup menus for the feed list depending on the
243
 
 * node type.
244
 
 */
245
 
static void
246
 
ui_popup_node_menu (nodePtr node, gboolean validSelection, guint button, guint32 activate_time)
247
 
{
248
 
        GtkWidget       *menu;
249
 
        gboolean        writeableFeedlist, isRoot, isHierarchic;
250
 
 
251
 
        menu = gtk_menu_new ();
252
 
        
253
 
        if (node->parent) {
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;
257
 
        } else {
258
 
                /* if we have no parent then we have the root node... */
259
 
                writeableFeedlist = TRUE;
260
 
                isRoot = TRUE;
261
 
                isHierarchic = TRUE;
262
 
        }
263
 
 
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);
269
 
 
270
 
                ui_popup_add_menuitem (menu, _("_Mark All As Read"), ui_popup_mark_as_read, node, GTK_STOCK_APPLY, 0);
271
 
        }
272
 
 
273
 
        if (writeableFeedlist) {
274
 
                if (NODE_TYPE (node->source->root)->capabilities & NODE_CAPABILITY_ADD_CHILDS) {
275
 
                        GtkWidget       *item;
276
 
                        GtkWidget       *submenu;
277
 
 
278
 
                        submenu = gtk_menu_new ();
279
 
 
280
 
                        item = ui_popup_add_menuitem (menu, _("_New"), NULL, NULL, NULL, 0);
281
 
 
282
 
                        ui_popup_add_menuitem (submenu, _("New _Subscription..."), ui_popup_add_feed, NULL, NULL, 0);
283
 
                        
284
 
                        if (isHierarchic)
285
 
                                ui_popup_add_menuitem (submenu, _("New _Folder..."), ui_popup_add_folder, NULL, NULL, 0);
286
 
                                
287
 
                        if (isRoot) {
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);
291
 
                        }
292
 
 
293
 
                        gtk_menu_item_set_submenu (GTK_MENU_ITEM(item), submenu);
294
 
                }
295
 
        }
296
 
 
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);
301
 
                }
302
 
        }
303
 
 
304
 
        ui_popup_menu (menu, button, activate_time);
305
 
}
306
 
 
307
 
/*------------------------------------------------------------------------------*/
308
 
/* mouse button handler                                                         */
309
 
/*------------------------------------------------------------------------------*/
310
 
 
311
 
gboolean
312
 
on_mainfeedlist_button_press_event (GtkWidget *widget,
313
 
                                    GdkEventButton *event,
314
 
                                    gpointer user_data)
315
 
{
316
 
        GdkEventButton  *eb;
317
 
        GtkWidget       *treeview;
318
 
        GtkTreeModel    *model;
319
 
        GtkTreePath     *path;
320
 
        GtkTreeIter     iter;
321
 
        gboolean        selected = TRUE;
322
 
        nodePtr         node = NULL;
323
 
 
324
 
        treeview = liferea_shell_lookup ("feedlist");
325
 
        g_assert (treeview);
326
 
 
327
 
        if (event->type != GDK_BUTTON_PRESS)
328
 
                return FALSE;
329
 
 
330
 
        eb = (GdkEventButton*)event;
331
 
 
332
 
        /* determine node */    
333
 
        if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview), event->x, event->y, &path, NULL, NULL, NULL)) {
334
 
                selected = FALSE;
335
 
                node = feedlist_get_root ();
336
 
        } else {
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);
341
 
        }
342
 
        
343
 
        /* apply action */
344
 
        switch (eb->button) {
345
 
                default:
346
 
                        /* Shouldn't happen... */
347
 
                        return FALSE;
348
 
                        break;
349
 
                case 2:
350
 
                        if (node) {
351
 
                                feedlist_mark_all_read (node);
352
 
                                itemview_update_node_info (node);
353
 
                                itemview_update ();
354
 
                        }
355
 
                        break;
356
 
                case 3:
357
 
                        if (node) {
358
 
                                ui_feedlist_select (node);
359
 
                        } else {
360
 
                                /* This happens when an "empty" node or nothing (feed list root) is clicked */
361
 
                                selected = FALSE;
362
 
                                node = feedlist_get_root ();
363
 
                        }
364
 
 
365
 
                        ui_popup_node_menu (node, selected, eb->button, eb->time);
366
 
                        break;
367
 
        }
368
 
                        
369
 
        return TRUE;
370
 
}