Merge lp:~kalikiana/midori/mfs into lp:midori

Proposed by Cris Dywan
Status: Merged
Approved by: André Stösel
Approved revision: 6289
Merged at revision: 6305
Proposed branch: lp:~kalikiana/midori/mfs
Merge into: lp:midori
Diff against target: 1877 lines (+599/-903)
8 files modified
midori/midori-browser.c (+119/-236)
midori/midori-contextaction.vala (+112/-0)
midori/midori-locationaction.c (+4/-1)
midori/midori-panel.c (+0/-19)
midori/midori-tab.vala (+3/-0)
midori/midori-view.c (+361/-570)
midori/sokoke.c (+0/-74)
midori/sokoke.h (+0/-3)
To merge this branch: bzr merge lp:~kalikiana/midori/mfs
Reviewer Review Type Date Requested Status
André Stösel Approve
Review via email: mp+177286@code.launchpad.net

Commit message

Introduce Midori.ContextAction and refactor page menu from scratch

To post a comment you must log in.
Revision history for this message
André Stösel (ivaldi) wrote :

If you select some text and right click the entry for "Search the Web" is missing.

review: Needs Fixing
Revision history for this message
André Stösel (ivaldi) wrote :

"Search the Web" works fine now, but if I use "Search with" -> some search engine, it opens two new tabs.

Revision history for this message
André Stösel (ivaldi) wrote :

I used this branch the whole day - the "normal" mode works fine, but the "app" mode has still some issues.

(In app mode searching and stuff like that doesn't work.)

Revision history for this message
Cris Dywan (kalikiana) wrote :

I had accidentally removed the condition to only show SearchWith if engines are there - which isn't the case in app mode in trunk. I fixed that.
Search still may not work - I didn't change the callback, it's the same in trunk, please file a bug report and I will investigate that further.

lp:~kalikiana/midori/mfs updated
6289. By Cris Dywan

Re-instate enforced update of edit actions

There's no reliable global hook that ensures the actions
are sensitive when they should be.

Revision history for this message
André Stösel (ivaldi) wrote :

The menu in private mode works (searching, opening links,...), but it's throws g-critical-errors.

Revision history for this message
André Stösel (ivaldi) wrote :

Since the g-criticals-error issue is actually a bug in midori trunk, I'll add bug reports and approve this patch.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'midori/midori-browser.c'
2--- midori/midori-browser.c 2013-07-30 17:01:11 +0000
3+++ midori/midori-browser.c 2013-08-01 19:47:33 +0000
4@@ -189,11 +189,6 @@
5 _midori_browser_set_toolbar_style (MidoriBrowser* browser,
6 MidoriToolbarStyle toolbar_style);
7
8-GtkWidget*
9-midori_panel_construct_menu_item (MidoriPanel* panel,
10- MidoriViewable* viewable,
11- gboolean popup);
12-
13 static void
14 midori_browser_settings_notify (MidoriWebSettings* web_settings,
15 GParamSpec* pspec,
16@@ -3084,26 +3079,16 @@
17 gint button,
18 MidoriBrowser* browser)
19 {
20- GtkWidget* menu;
21- GtkWidget* menuitem;
22-
23- menu = gtk_menu_new ();
24- menuitem = sokoke_action_create_popup_menu_item (
25- _action_by_name (browser, "Menubar"));
26- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
27- menuitem = sokoke_action_create_popup_menu_item (
28- _action_by_name (browser, "Navigationbar"));
29- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
30- menuitem = sokoke_action_create_popup_menu_item (
31- _action_by_name (browser, "Bookmarkbar"));
32- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
33- menuitem = sokoke_action_create_popup_menu_item (
34- _action_by_name (browser, "Statusbar"));
35- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
36-
37- g_signal_emit (browser, signals[POPULATE_TOOLBAR_MENU], 0, menu);
38-
39- katze_widget_popup (widget, GTK_MENU (menu), NULL,
40+ MidoriContextAction* menu = midori_context_action_new ("ToolbarContextMenu", NULL, NULL, NULL);
41+ midori_context_action_add_action_group (menu, browser->action_group);
42+ midori_context_action_add_by_name (menu, "Menubar");
43+ midori_context_action_add_by_name (menu, "Navigationbar");
44+ midori_context_action_add_by_name (menu, "Bookmarkbar");
45+ midori_context_action_add_by_name (menu, "Statusbar");
46+
47+ GtkMenu* context_menu = midori_context_action_create_menu (menu, NULL, FALSE);
48+ g_signal_emit (browser, signals[POPULATE_TOOLBAR_MENU], 0, context_menu);
49+ katze_widget_popup (widget, GTK_MENU (context_menu), NULL,
50 button == -1 ? KATZE_MENU_POSITION_LEFT : KATZE_MENU_POSITION_CURSOR);
51 return TRUE;
52 }
53@@ -3203,57 +3188,25 @@
54
55 static void
56 _action_tools_populate_popup (GtkAction* action,
57- GtkMenu* menu,
58+ GtkMenu* default_menu,
59 MidoriBrowser* browser)
60 {
61- static const GtkActionEntry actions[] =
62- {
63- { "ManageSearchEngines" },
64- { "ClearPrivateData" },
65- { "InspectPage" },
66- { "-" },
67- { NULL },
68- { "p" },
69- #ifdef G_OS_WIN32
70- { NULL },
71- { "Preferences" },
72- #endif
73- };
74- guint i;
75-
76- for (i = 0; i < G_N_ELEMENTS (actions); i++)
77- {
78- GtkWidget* menuitem;
79- if (actions[i].name != NULL)
80- {
81- if (actions[i].name[0] == '-')
82- {
83- g_signal_emit (browser, signals[POPULATE_TOOL_MENU], 0, menu);
84- continue;
85- }
86- else if (actions[i].name[0] == 'p')
87- {
88- MidoriPanel* panel;
89- gsize j;
90- GtkWidget* widget;
91-
92- panel = MIDORI_PANEL (browser->panel);
93- j = 0;
94- while ((widget = midori_panel_get_nth_page (panel, j++)))
95- {
96- menuitem = midori_panel_construct_menu_item (panel, MIDORI_VIEWABLE (widget), FALSE);
97- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
98- }
99- continue;
100- }
101- menuitem = sokoke_action_create_popup_menu_item (
102- _action_by_name (browser, actions[i].name));
103- }
104- else
105- menuitem = gtk_separator_menu_item_new ();
106- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
107- gtk_widget_show (menuitem);
108- }
109+ MidoriContextAction* menu = midori_context_action_new ("ToolsMenu", NULL, NULL, NULL);
110+ midori_context_action_add_action_group (menu, browser->action_group);
111+ midori_context_action_add_by_name (menu, "ManageSearchEngines");
112+ midori_context_action_add_by_name (menu, "ClearPrivateData");
113+ midori_context_action_add_by_name (menu, "InspectPage");
114+ g_signal_emit (browser, signals[POPULATE_TOOL_MENU], 0, default_menu);
115+ midori_context_action_add (menu, NULL);
116+ gsize j = 0;
117+ GtkWidget* widget;
118+ while ((widget = midori_panel_get_nth_page (MIDORI_PANEL (browser->panel), j++)))
119+ midori_context_action_add (menu, g_object_get_data (G_OBJECT (widget), "midori-panel-action"));
120+ #ifdef G_OS_WIN32
121+ midori_context_action_add (menu, NULL);
122+ midori_context_action_add_by_name (menu, "Preferences");
123+ #endif
124+ midori_context_action_create_menu (menu, default_menu, TRUE);
125 }
126
127 static void
128@@ -3320,34 +3273,18 @@
129
130 static void
131 _action_window_populate_popup (GtkAction* action,
132- GtkMenu* menu,
133+ GtkMenu* default_menu,
134 MidoriBrowser* browser)
135 {
136- GtkWidget* menuitem;
137-
138- menuitem = gtk_separator_menu_item_new ();
139- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
140- gtk_widget_show (menuitem);
141- menuitem = gtk_action_create_menu_item (
142- _action_by_name (browser, "LastSession"));
143- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
144- gtk_widget_show (menuitem);
145- menuitem = gtk_action_create_menu_item (
146- _action_by_name (browser, "TabCurrent"));
147- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
148- gtk_widget_show (menuitem);
149- menuitem = gtk_action_create_menu_item (
150- _action_by_name (browser, "NextView"));
151- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
152- gtk_widget_show (menuitem);
153- menuitem = gtk_action_create_menu_item (
154- _action_by_name (browser, "TabNext"));
155- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
156- gtk_widget_show (menuitem);
157- menuitem = gtk_action_create_menu_item (
158- _action_by_name (browser, "TabPrevious"));
159- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menuitem);
160- gtk_widget_show (menuitem);
161+ MidoriContextAction* menu = midori_context_action_new ("WindowMenu", NULL, NULL, NULL);
162+ midori_context_action_add_action_group (menu, browser->action_group);
163+ midori_context_action_add (menu, NULL);
164+ midori_context_action_add_by_name (menu, "LastSession");
165+ midori_context_action_add_by_name (menu, "TabCurrent");
166+ midori_context_action_add_by_name (menu, "NextView");
167+ midori_context_action_add_by_name (menu, "TabNext");
168+ midori_context_action_add_by_name (menu, "TabPrevious");
169+ midori_context_action_create_menu (menu, default_menu, TRUE);
170 }
171
172 static void
173@@ -3361,70 +3298,36 @@
174
175 static void
176 _action_compact_menu_populate_popup (GtkAction* action,
177- GtkWidget* menu,
178+ GtkMenu* default_menu,
179 MidoriBrowser* browser)
180 {
181- static const GtkActionEntry actions[] = {
182- { "TabNew" },
183- { "WindowNew" },
184- { "PrivateBrowsing" },
185- { NULL },
186- { "Find" },
187- { "Print" },
188- { "Fullscreen" },
189- { NULL },
190- { "p" },
191- { NULL },
192- { "BookmarksImport" },
193- { "BookmarksExport" },
194- { "ClearPrivateData" },
195- { "-" },
196- { NULL },
197- #ifndef HAVE_GRANITE
198- { "HelpFAQ" },
199- { "HelpBugs"},
200- #endif
201- { "About" },
202- { "Preferences" },
203- };
204-
205- guint i;
206-
207- for (i = 0; i < G_N_ELEMENTS (actions); i++)
208- {
209- GtkWidget* menuitem;
210- if (actions[i].name != NULL)
211- {
212- if (actions[i].name[0] == '-')
213- {
214- g_signal_emit (browser, signals[POPULATE_TOOL_MENU], 0, menu);
215- continue;
216- }
217- else if (actions[i].name[0] == 'p')
218- {
219- MidoriPanel* panel;
220- gsize j;
221- GtkWidget* widget;
222-
223- panel = MIDORI_PANEL (browser->panel);
224- j = 0;
225- while ((widget = midori_panel_get_nth_page (panel, j++)))
226- {
227- menuitem = midori_panel_construct_menu_item (panel, MIDORI_VIEWABLE (widget), TRUE);
228- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
229- }
230- continue;
231- }
232- menuitem = sokoke_action_create_popup_menu_item (
233- _action_by_name (browser, actions[i].name));
234- }
235- else
236- {
237- menuitem = gtk_separator_menu_item_new ();
238- gtk_widget_show (menuitem);
239- }
240- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
241- }
242+ MidoriContextAction* menu = midori_context_action_new ("CompactMenu", NULL, NULL, NULL);
243+ midori_context_action_add_action_group (menu, browser->action_group);
244+ midori_context_action_add_by_name (menu, "TabNew");
245+ midori_context_action_add_by_name (menu, "WindowNew");
246+ midori_context_action_add_by_name (menu, "PrivateBrowsing");
247+ midori_context_action_add (menu, NULL);
248+ midori_context_action_add_by_name (menu, "Find");
249+ midori_context_action_add_by_name (menu, "Print");
250+ midori_context_action_add_by_name (menu, "Fullscreen");
251+ midori_context_action_add (menu, NULL);
252+ gsize j = 0;
253+ GtkWidget* widget;
254+ while ((widget = midori_panel_get_nth_page (MIDORI_PANEL (browser->panel), j++)))
255+ midori_context_action_add (menu, g_object_get_data (G_OBJECT (widget), "midori-panel-action"));
256+ midori_context_action_add (menu, NULL);
257+ midori_context_action_add_by_name (menu, "BookmarksImport");
258+ midori_context_action_add_by_name (menu, "BookmarksExport");
259+ midori_context_action_add_by_name (menu, "ClearPrivateData");
260+ g_signal_emit (browser, signals[POPULATE_TOOL_MENU], 0, default_menu);
261+ midori_context_action_add (menu, NULL);
262+ #ifndef HAVE_GRANITE
263+ midori_context_action_add_by_name (menu, "HelpFAQ");
264+ midori_context_action_add_by_name (menu, "HelpBugs");
265+ #endif
266+ midori_context_action_add_by_name (menu, "About");
267+ midori_context_action_add_by_name (menu, "Preferences");
268+ midori_context_action_create_menu (menu, default_menu, FALSE);
269 }
270
271 static void
272@@ -4287,37 +4190,6 @@
273 }
274
275 static void
276-midori_browser_bookmark_popup_item (GtkWidget* menu,
277- const gchar* stock_id,
278- const gchar* label,
279- KatzeItem* item,
280- gpointer callback,
281- gpointer userdata)
282-{
283- const gchar* uri;
284- GtkWidget* menuitem;
285-
286- uri = katze_item_get_uri (item);
287-
288- menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
289- if (label)
290- gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (
291- GTK_BIN (menuitem))), label);
292- if (!strcmp (stock_id, GTK_STOCK_EDIT))
293- gtk_widget_set_sensitive (menuitem,
294- KATZE_IS_ARRAY (item) || uri != NULL);
295- else if (!KATZE_IS_ARRAY (item) && strcmp (stock_id, GTK_STOCK_DELETE))
296- gtk_widget_set_sensitive (menuitem, uri != NULL);
297- g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
298- if (callback)
299- g_signal_connect (menuitem, "activate", G_CALLBACK (callback), userdata);
300- else
301- gtk_widget_set_sensitive (menuitem, FALSE);
302- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
303- gtk_widget_show (menuitem);
304-}
305-
306-static void
307 midori_browser_bookmark_open_activate_cb (GtkWidget* menuitem,
308 MidoriBrowser* browser)
309 {
310@@ -4398,42 +4270,56 @@
311 KatzeItem* item,
312 MidoriBrowser* browser)
313 {
314- GtkWidget* menu;
315- GtkWidget* menuitem;
316-
317- menu = gtk_menu_new ();
318+ MidoriContextAction* menu = midori_context_action_new ("BookmarkContextMenu", NULL, NULL, NULL);
319 if (KATZE_ITEM_IS_FOLDER (item))
320 {
321 gint child_bookmarks_count = midori_array_count_recursive (browser->bookmarks,
322 "uri <> ''", NULL, item, FALSE);
323
324- midori_browser_bookmark_popup_item (menu,
325- STOCK_TAB_NEW, _("Open all in _Tabs"), item,
326- (!child_bookmarks_count ? NULL : midori_browser_bookmark_open_in_tab_activate_cb),
327- browser);
328+ GtkAction* action = gtk_action_new ("BookmarkOpenAllTabs", _("Open all in _Tabs"), NULL, STOCK_TAB_NEW);
329+ gtk_action_set_sensitive (action, child_bookmarks_count > 0);
330+ g_object_set_data (G_OBJECT (action), "KatzeItem", item);
331+ g_signal_connect (action, "activate",
332+ G_CALLBACK (midori_browser_bookmark_open_in_tab_activate_cb), browser);
333+ midori_context_action_add (menu, action);
334 }
335 else
336 {
337- midori_browser_bookmark_popup_item (menu, GTK_STOCK_OPEN, NULL,
338- item, midori_browser_bookmark_open_activate_cb, browser);
339- midori_browser_bookmark_popup_item (menu,
340- STOCK_TAB_NEW, _("Open in New _Tab"),
341- item, midori_browser_bookmark_open_in_tab_activate_cb, browser);
342- midori_browser_bookmark_popup_item (menu,
343- STOCK_WINDOW_NEW, _("Open in New _Window"),
344- item, midori_browser_bookmark_open_in_window_activate_cb, browser);
345+ GtkAction* action = gtk_action_new ("BookmarkOpen", NULL, NULL, GTK_STOCK_OPEN);
346+ gtk_action_set_sensitive (action, katze_item_get_uri (item) != NULL);
347+ g_object_set_data (G_OBJECT (action), "KatzeItem", item);
348+ g_signal_connect (action, "activate",
349+ G_CALLBACK (midori_browser_bookmark_open_activate_cb), browser);
350+ midori_context_action_add (menu, action);
351+ action = gtk_action_new ("BookmarkOpenTab", NULL, NULL, STOCK_TAB_NEW);
352+ gtk_action_set_sensitive (action, katze_item_get_uri (item) != NULL);
353+ g_object_set_data (G_OBJECT (action), "KatzeItem", item);
354+ g_signal_connect (action, "activate",
355+ G_CALLBACK (midori_browser_bookmark_open_in_tab_activate_cb), browser);
356+ midori_context_action_add (menu, action);
357+ action = gtk_action_new ("BookmarkOpenWindow", _("Open in New _Window"), NULL, STOCK_WINDOW_NEW);
358+ gtk_action_set_sensitive (action, katze_item_get_uri (item) != NULL);
359+ g_object_set_data (G_OBJECT (action), "KatzeItem", item);
360+ g_signal_connect (action, "activate",
361+ G_CALLBACK (midori_browser_bookmark_open_in_window_activate_cb), browser);
362+ midori_context_action_add (menu, action);
363 }
364
365- menuitem = gtk_separator_menu_item_new ();
366- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
367- gtk_widget_show (menuitem);
368-
369- midori_browser_bookmark_popup_item (menu, GTK_STOCK_EDIT, NULL,
370- item, midori_browser_bookmark_edit_activate_cb, widget);
371- midori_browser_bookmark_popup_item (menu, GTK_STOCK_DELETE, NULL,
372- item, midori_browser_bookmark_delete_activate_cb, browser);
373-
374- katze_widget_popup (widget, GTK_MENU (menu), event, KATZE_MENU_POSITION_CURSOR);
375+ midori_context_action_add (menu, NULL);
376+ GtkAction* action = gtk_action_new ("BookmarkEdit", NULL, NULL, GTK_STOCK_EDIT);
377+ gtk_action_set_sensitive (action, !KATZE_ITEM_IS_SEPARATOR (item));
378+ g_object_set_data (G_OBJECT (action), "KatzeItem", item);
379+ g_signal_connect (action, "activate",
380+ G_CALLBACK (midori_browser_bookmark_edit_activate_cb), browser);
381+ midori_context_action_add (menu, action);
382+ action = gtk_action_new ("BookmarkDelete", NULL, NULL, GTK_STOCK_DELETE);
383+ g_object_set_data (G_OBJECT (action), "KatzeItem", item);
384+ g_signal_connect (action, "activate",
385+ G_CALLBACK (midori_browser_bookmark_delete_activate_cb), browser);
386+ midori_context_action_add (menu, action);
387+
388+ GtkMenu* context_menu = midori_context_action_create_menu (menu, NULL, FALSE);
389+ katze_widget_popup (widget, context_menu, event, KATZE_MENU_POSITION_CURSOR);
390 }
391
392 static gboolean
393@@ -5339,32 +5225,29 @@
394 }
395 else if (event->type == GDK_BUTTON_PRESS && MIDORI_EVENT_CONTEXT_MENU (event))
396 {
397- GtkWidget* menu = gtk_menu_new ();
398+ MidoriContextAction* menu = midori_context_action_new ("NotebookContextMenu", NULL, NULL, NULL);
399+ midori_context_action_add_action_group (menu, browser->action_group);
400 GList* tabs = midori_browser_get_tabs (browser);
401- GtkWidget* menuitem = sokoke_action_create_popup_menu_item (
402- gtk_action_group_get_action (browser->action_group, "TabNew"));
403+ midori_context_action_add_by_name (menu, "TabNew");
404+ midori_context_action_add_by_name (menu, "UndoTabClose");
405+ midori_context_action_add (menu, NULL);
406 gint i = 0;
407- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
408- menuitem = sokoke_action_create_popup_menu_item (
409- gtk_action_group_get_action (browser->action_group, "UndoTabClose"));
410- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
411- menuitem = gtk_separator_menu_item_new ();
412- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
413 for (; tabs != NULL; tabs = g_list_next (tabs))
414 {
415 const gchar* title = midori_view_get_display_title (tabs->data);
416- menuitem = katze_image_menu_item_new_ellipsized (title);
417- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
418- gtk_image_new_from_pixbuf (midori_view_get_icon (tabs->data)));
419- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
420- g_object_set_data (G_OBJECT (menuitem), "index", GINT_TO_POINTER (i));
421- g_signal_connect (menuitem, "activate",
422+ gchar* tab_option = g_strdup_printf ("Tab%u", i);
423+ GtkAction* action = gtk_action_new (tab_option, title, NULL, NULL);
424+ g_free (tab_option);
425+ gtk_action_set_gicon (GTK_ACTION (action), G_ICON (midori_view_get_icon (tabs->data)));
426+ g_object_set_data (G_OBJECT (action), "index", GINT_TO_POINTER (i));
427+ g_signal_connect (action, "activate",
428 G_CALLBACK (midori_browser_menu_item_switch_tab_cb), browser);
429+ midori_context_action_add (menu, action);
430 i++;
431 }
432 g_list_free (tabs);
433- gtk_widget_show_all (menu);
434- katze_widget_popup (GTK_WIDGET (notebook), GTK_MENU (menu), NULL,
435+ GtkMenu* context_menu = midori_context_action_create_menu (menu, NULL, FALSE);
436+ katze_widget_popup (GTK_WIDGET (notebook), context_menu, NULL,
437 KATZE_MENU_POSITION_CURSOR);
438 }
439
440
441=== added file 'midori/midori-contextaction.vala'
442--- midori/midori-contextaction.vala 1970-01-01 00:00:00 +0000
443+++ midori/midori-contextaction.vala 2013-08-01 19:47:33 +0000
444@@ -0,0 +1,112 @@
445+/*
446+ Copyright (C) 2013 Christian Dywan <christian@twotoasts.de>
447+
448+ This library is free software; you can redistribute it and/or
449+ modify it under the terms of the GNU Lesser General Public
450+ License as published by the Free Software Foundation; either
451+ version 2.1 of the License, or (at your option) any later version.
452+
453+ See the file COPYING for the full license text.
454+*/
455+
456+namespace Midori {
457+ /* A context action represents an item that can be shown in a menu
458+ or toolbar. Context actions can be nested as needed.
459+ Since: 0.5.5 */
460+ public class ContextAction : Gtk.Action {
461+ List<Gtk.ActionGroup> action_groups;
462+ List<Gtk.Action> children;
463+ public ContextAction (string name, string? label, string? tooltip, string? stock_id) {
464+ GLib.Object (name: name, label: label, tooltip: tooltip, stock_id: stock_id);
465+ action_groups = new List<Gtk.ActionGroup> ();
466+ children = new List<ContextAction> ();
467+ }
468+
469+ public delegate void ActionActivateCallback (Gtk.Action action);
470+ public void add_simple (string name, string? label, string? tooltip, string? stock_id, ActionActivateCallback callback) {
471+ var action = new ContextAction (name, label, tooltip, stock_id);
472+ action.activate.connect (() => { callback (action); });
473+ add (action);
474+ }
475+
476+ public void add (Gtk.Action? action) {
477+ if (action == null) {
478+ add (new SeparatorContextAction ());
479+ return;
480+ }
481+
482+ children.append (action);
483+ if (action is ContextAction) {
484+ foreach (var action_group in action_groups)
485+ (action as ContextAction).add_action_group (action_group);
486+ }
487+ }
488+
489+ public void add_action_group (Gtk.ActionGroup action_group) {
490+ action_groups.append (action_group);
491+ }
492+
493+ public void add_by_name (string name) {
494+ foreach (var action_group in action_groups) {
495+ var action = action_group.get_action (name);
496+ if (action != null) {
497+ add (action);
498+ return;
499+ }
500+ }
501+ warning ("Action %s not known to ContextAction", name);
502+ }
503+
504+#if HAVE_WEBKIT2
505+ public WebKit.ContextMenu create_webkit_context_menu (WebKit.ContextMenu? default_menu) {
506+ var menu = default_menu ?? new WebKit.ContextMenu ();
507+ foreach (var action in children) {
508+ WebKit.ContextMenuItem menuitem;
509+ if (action is SeparatorContextAction)
510+ menuitem = new WebKit.ContextMenuItem.separator ();
511+ else if (action is ContextAction
512+ && (action as ContextAction).children.nth_data (0) != null) {
513+ menuitem = new WebKit.ContextMenuItem (action);
514+ menuitem.set_submenu ((action as ContextAction).create_webkit_context_menu (null));
515+ }
516+ else
517+ menuitem = new WebKit.ContextMenuItem (action);
518+ menu.append (menuitem);
519+ }
520+ return menu;
521+ }
522+#endif
523+
524+ public new Gtk.Menu create_menu (Gtk.Menu? default_menu, bool accels) {
525+ var menu = default_menu ?? new Gtk.Menu ();
526+ foreach (var action in children) {
527+ Gtk.MenuItem menuitem;
528+ if (action is SeparatorContextAction) {
529+ menuitem = new Gtk.SeparatorMenuItem ();
530+ menuitem.show ();
531+ }
532+ else if (action is ContextAction
533+ && (action as ContextAction).children.nth_data (0) != null) {
534+ menuitem = action.create_menu_item () as Gtk.MenuItem;
535+ menuitem.submenu = (action as ContextAction).create_menu (null, accels);
536+ }
537+ else
538+ menuitem = action.create_menu_item () as Gtk.MenuItem;
539+ /* Disable accels from the action in context menus */
540+ if (!accels) {
541+ var accel_label = menuitem.get_child () as Gtk.AccelLabel;
542+ if (accel_label != null)
543+ accel_label.accel_closure = null;
544+ }
545+ menu.append (menuitem);
546+ }
547+ return menu;
548+ }
549+ }
550+
551+ public class SeparatorContextAction : ContextAction {
552+ public SeparatorContextAction () {
553+ GLib.Object (name: "SeparatorContextAction", label: null, tooltip: null, stock_id: null);
554+ }
555+ }
556+}
557
558=== modified file 'midori/midori-locationaction.c'
559--- midori/midori-locationaction.c 2013-07-16 14:20:37 +0000
560+++ midori/midori-locationaction.c 2013-08-01 19:47:33 +0000
561@@ -1539,8 +1539,11 @@
562 menuitem = gtk_separator_menu_item_new ();
563 gtk_widget_show (menuitem);
564 gtk_menu_shell_append (menu, menuitem);
565- menuitem = sokoke_action_create_popup_menu_item (
566+ menuitem = gtk_action_create_menu_item (
567 gtk_action_group_get_action (actions, "ManageSearchEngines"));
568+ GtkWidget* accel_label = gtk_bin_get_child (GTK_BIN (menuitem));
569+ if (accel_label != NULL)
570+ gtk_accel_label_set_accel_closure (GTK_ACCEL_LABEL (accel_label), NULL);
571 gtk_menu_shell_append (menu, menuitem);
572 /* i18n: Right-click on Location, Open an URL from the clipboard */
573 menuitem = gtk_menu_item_new_with_mnemonic (_("Paste and p_roceed"));
574
575=== modified file 'midori/midori-panel.c'
576--- midori/midori-panel.c 2013-06-21 23:18:01 +0000
577+++ midori/midori-panel.c 2013-08-01 19:47:33 +0000
578@@ -485,25 +485,6 @@
579 g_object_notify (G_OBJECT (panel), "right-aligned");
580 }
581
582-/* Private function, used by MidoriBrowser */
583-/* static */ GtkWidget*
584-midori_panel_construct_menu_item (MidoriPanel* panel,
585- MidoriViewable* viewable,
586- gboolean popup)
587-{
588- GtkAction* action;
589- GtkWidget* menuitem;
590-
591- action = g_object_get_data (G_OBJECT (viewable), "midori-panel-action");
592- menuitem = popup ? sokoke_action_create_popup_menu_item (action)
593- : gtk_action_create_menu_item (action);
594- g_object_set_data (G_OBJECT (menuitem), "page", viewable);
595-
596- if (gtk_widget_get_visible (GTK_WIDGET (viewable)))
597- gtk_widget_show (menuitem);
598- return menuitem;
599-}
600-
601 static void
602 midori_panel_viewable_destroy_cb (GtkWidget* viewable,
603 MidoriPanel* panel)
604
605=== modified file 'midori/midori-tab.vala'
606--- midori/midori-tab.vala 2013-06-21 23:23:12 +0000
607+++ midori/midori-tab.vala 2013-08-01 19:47:33 +0000
608@@ -89,6 +89,9 @@
609 /* Allow the browser to provide the find bar */
610 public signal void search_text (bool found, string typing);
611
612+ /* Since: 0.5.5 */
613+ public signal void context_menu (WebKit.HitTestResult hit_test_result, ContextAction menu);
614+
615 public bool is_blank () {
616 return URI.is_blank (uri);
617 }
618
619=== modified file 'midori/midori-view.c'
620--- midori/midori-view.c 2013-07-30 17:43:22 +0000
621+++ midori/midori-view.c 2013-08-01 19:47:33 +0000
622@@ -1972,20 +1972,22 @@
623 }
624
625 static void
626-midori_web_view_menu_new_window_activate_cb (GtkWidget* widget,
627- MidoriView* view)
628+midori_web_view_menu_new_window_activate_cb (GtkAction* action,
629+ gpointer user_data)
630 {
631+ MidoriView* view = user_data;
632 g_signal_emit (view, signals[NEW_WINDOW], 0, view->link_uri);
633 }
634
635 static void
636-midori_web_view_menu_link_copy_activate_cb (GtkWidget* widget,
637- MidoriView* view)
638+midori_web_view_menu_link_copy_activate_cb (GtkAction* widget,
639+ gpointer user_data)
640 {
641+ MidoriView* view = user_data;
642 if (g_str_has_prefix (view->link_uri, "mailto:"))
643- sokoke_widget_copy_clipboard (widget, view->link_uri + 7, NULL, NULL);
644+ sokoke_widget_copy_clipboard (view->web_view, view->link_uri + 7, NULL, NULL);
645 else
646- sokoke_widget_copy_clipboard (widget, view->link_uri, NULL, NULL);
647+ sokoke_widget_copy_clipboard (view->web_view, view->link_uri, NULL, NULL);
648 }
649
650 static void
651@@ -2006,16 +2008,18 @@
652 }
653
654 static void
655-midori_web_view_menu_save_activate_cb (GtkWidget* widget,
656- MidoriView* view)
657+midori_web_view_menu_save_activate_cb (GtkAction* action,
658+ gpointer user_data)
659 {
660+ MidoriView* view = user_data;
661 midori_view_download_uri (view, MIDORI_DOWNLOAD_SAVE_AS, view->link_uri);
662 }
663
664 static void
665-midori_web_view_menu_image_new_tab_activate_cb (GtkWidget* widget,
666- MidoriView* view)
667+midori_web_view_menu_image_new_tab_activate_cb (GtkAction* action,
668+ gpointer user_data)
669 {
670+ MidoriView* view = user_data;
671 gchar* uri = katze_object_get_string (view->hit_test, "image-uri");
672 if (view->open_new_pages_in == MIDORI_NEW_PAGE_WINDOW)
673 g_signal_emit (view, signals[NEW_WINDOW], 0, uri);
674@@ -2103,66 +2107,72 @@
675 }
676
677 static void
678-midori_web_view_menu_image_copy_activate_cb (GtkWidget* widget,
679- MidoriView* view)
680+midori_web_view_menu_image_copy_activate_cb (GtkAction* action,
681+ gpointer user_data)
682 {
683+ MidoriView* view = user_data;
684 gchar* uri = katze_object_get_string (view->hit_test, "image-uri");
685 g_object_set_data (G_OBJECT (view->hit_test), "view", view);
686- sokoke_widget_copy_clipboard (widget,
687+ sokoke_widget_copy_clipboard (view->web_view,
688 uri, midori_view_clipboard_get_image_cb, view->hit_test);
689 g_free (uri);
690 }
691
692 static void
693-midori_web_view_menu_image_save_activate_cb (GtkWidget* widget,
694- MidoriView* view)
695+midori_web_view_menu_image_save_activate_cb (GtkAction* action,
696+ gpointer user_data)
697 {
698+ MidoriView* view = user_data;
699 gchar* uri = katze_object_get_string (view->hit_test, "image-uri");
700 midori_view_download_uri (view, MIDORI_DOWNLOAD_SAVE_AS, uri);
701 g_free (uri);
702 }
703
704 static void
705-midori_web_view_open_in_viewer_cb (GtkWidget* widget,
706- MidoriView* view)
707+midori_web_view_open_in_viewer_cb (GtkAction* action,
708+ gpointer user_data)
709 {
710+ MidoriView* view = user_data;
711 gchar* uri = katze_object_get_string (view->hit_test, "image-uri");
712 midori_view_download_uri (view, MIDORI_DOWNLOAD_OPEN_IN_VIEWER, uri);
713 g_free (uri);
714 }
715
716 static void
717-midori_web_view_menu_video_copy_activate_cb (GtkWidget* widget,
718- MidoriView* view)
719+midori_web_view_menu_video_copy_activate_cb (GtkAction* action,
720+ gpointer user_data)
721 {
722+ MidoriView* view = user_data;
723 gchar* uri = katze_object_get_string (view->hit_test, "media-uri");
724- sokoke_widget_copy_clipboard (widget, uri, NULL, NULL);
725+ sokoke_widget_copy_clipboard (view->web_view, uri, NULL, NULL);
726 g_free (uri);
727 }
728
729 static void
730-midori_web_view_menu_video_save_activate_cb (GtkWidget* widget,
731- MidoriView* view)
732+midori_web_view_menu_video_save_activate_cb (GtkAction* action,
733+ gpointer user_data)
734 {
735+ MidoriView* view = user_data;
736 gchar* uri = katze_object_get_string (view->hit_test, "media-uri");
737 midori_view_download_uri (view, MIDORI_DOWNLOAD_SAVE_AS, uri);
738 g_free (uri);
739 }
740
741 static void
742-midori_web_view_menu_new_tab_activate_cb (GtkWidget* widget,
743- MidoriView* view)
744+midori_web_view_menu_new_tab_activate_cb (GtkAction* action,
745+ gpointer user_data)
746 {
747+ MidoriView* view = user_data;
748 if (view->link_uri)
749 g_signal_emit (view, signals[NEW_TAB], 0, view->link_uri,
750 view->open_tabs_in_the_background);
751 else
752 {
753- gchar* data = (gchar*)g_object_get_data (G_OBJECT (widget), "uri");
754+ gchar* data = (gchar*)g_object_get_data (G_OBJECT (action), "uri");
755 if (strchr (data, '@'))
756 {
757 gchar* uri = g_strconcat ("mailto:", data, NULL);
758- sokoke_show_uri (gtk_widget_get_screen (widget),
759+ sokoke_show_uri (gtk_widget_get_screen (view->web_view),
760 uri, GDK_CURRENT_TIME, NULL);
761 g_free (uri);
762 }
763@@ -2179,18 +2189,21 @@
764 }
765
766 static void
767-midori_web_view_menu_background_tab_activate_cb (GtkWidget* widget,
768- MidoriView* view)
769+midori_web_view_menu_background_tab_activate_cb (GtkAction* action,
770+ gpointer user_data)
771 {
772+ MidoriView* view = user_data;
773 g_signal_emit (view, signals[NEW_TAB], 0, view->link_uri,
774 !view->open_tabs_in_the_background);
775 }
776
777+#ifndef HAVE_WEBKIT2
778 static void
779-midori_web_view_menu_search_web_activate_cb (GtkWidget* widget,
780- MidoriView* view)
781+midori_web_view_menu_search_web_activate_cb (GtkAction* action,
782+ gpointer user_data)
783 {
784- const gchar* search = g_object_get_data (G_OBJECT (widget), "search");
785+ MidoriView* view = user_data;
786+ const gchar* search = g_object_get_data (G_OBJECT (action), "search");
787 if (search == NULL)
788 search = midori_settings_get_location_entry_search (MIDORI_SETTINGS (view->settings));
789 gchar* uri = midori_uri_for_search (search, view->selected_text);
790@@ -2206,52 +2219,47 @@
791
792 g_free (uri);
793 }
794-
795-static void
796-midori_web_view_menu_copy_activate_cb (GtkWidget* widget,
797- MidoriView* view)
798-{
799- sokoke_widget_copy_clipboard (widget, view->selected_text, NULL, NULL);
800-}
801-
802-static void
803-midori_view_tab_label_menu_window_new_cb (GtkWidget* menuitem,
804- GtkWidget* view)
805-{
806+#endif
807+
808+static void
809+midori_view_tab_label_menu_window_new_cb (GtkAction* action,
810+ gpointer user_data)
811+{
812+ MidoriView* view = user_data;
813 g_signal_emit (view, signals[NEW_WINDOW], 0,
814 midori_view_get_display_uri (MIDORI_VIEW (view)));
815 }
816
817+#ifndef HAVE_WEBKIT2
818 static void
819-midori_web_view_open_frame_in_new_tab_cb (GtkWidget* widget,
820- MidoriView* view)
821+midori_web_view_open_frame_in_new_tab_cb (GtkAction* action,
822+ gpointer user_data)
823 {
824-#ifndef HAVE_WEBKIT2
825+ MidoriView* view = user_data;
826 WebKitWebFrame* web_frame = webkit_web_view_get_focused_frame (WEBKIT_WEB_VIEW (view->web_view));
827 g_signal_emit (view, signals[NEW_TAB], 0,
828 webkit_web_frame_get_uri (web_frame), view->open_tabs_in_the_background);
829+}
830 #endif
831-}
832
833 static void
834-midori_web_view_menu_inspect_element_activate_cb (GtkWidget* widget,
835- MidoriView* view)
836+midori_view_inspect_element_activate_cb (GtkAction* action,
837+ gpointer user_data)
838 {
839-#ifndef HAVE_WEBKIT2
840- WebKitWebInspector* inspector;
841- gint x, y;
842-
843- inspector = webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (view->web_view));
844- x = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "x"));
845- y = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "y"));
846+ MidoriView* view = user_data;
847+ WebKitWebInspector* inspector = webkit_web_view_get_inspector (WEBKIT_WEB_VIEW (view->web_view));
848+ #ifndef HAVE_WEBKIT2
849+ WebKitHitTestResult* hit_test_result = view->hit_test;
850+ gint x = katze_object_get_int (hit_test_result, "x");
851+ gint y = katze_object_get_int (hit_test_result, "y");
852 webkit_web_inspector_inspect_coordinates (inspector, x, y);
853+ #endif
854 webkit_web_inspector_show (inspector);
855-#endif
856 }
857
858 static void
859-midori_view_menu_add_search_engine_cb (GtkWidget* widget,
860- MidoriView* view)
861+midori_view_add_search_engine_cb (GtkWidget* widget,
862+ MidoriView* view)
863 {
864 MidoriBrowser* browser = midori_browser_get_for_widget (view->web_view);
865 GtkActionGroup* actions = midori_browser_get_action_group (browser);
866@@ -2260,500 +2268,301 @@
867 midori_search_action_get_editor (MIDORI_SEARCH_ACTION (action), item, TRUE);
868 }
869
870-static GtkWidget*
871-midori_view_insert_menu_item (GtkMenuShell* menu,
872- gint position,
873- const gchar* label,
874- const gchar* stock_id,
875- GCallback callback,
876- GtkWidget* widget)
877-{
878- GtkWidget* menuitem;
879-
880- if (label)
881- {
882- menuitem = gtk_image_menu_item_new_with_mnemonic (label);
883- if (stock_id)
884- {
885- GdkScreen* screen = gtk_widget_get_screen (widget);
886- GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
887- if (gtk_icon_theme_has_icon (icon_theme, stock_id))
888- {
889- GtkWidget* icon = gtk_image_new_from_stock (stock_id,
890- GTK_ICON_SIZE_MENU);
891- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
892- icon);
893- }
894- }
895- }
896- else
897- menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
898- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, position);
899- if (callback)
900- g_signal_connect (menuitem, "activate", callback, widget);
901- else
902- gtk_widget_set_sensitive (menuitem, FALSE);
903- return menuitem;
904-}
905-
906 /**
907- * midori_view_populate_popup:
908+ * midori_view_get_page_context_action:
909 * @view: a #MidoriView
910- * @menu: a #GtkMenu
911- * @manual: %TRUE if this a manually created popup
912- *
913- * Populates the given @menu with context menu items
914- * according to the position of the mouse pointer. This
915- * can be used in situations where a custom hotkey
916- * opens the context menu or the default behaviour
917- * needs to be intercepted.
918- *
919- * @manual should usually be %TRUE, except for the
920- * case where @menu was created by the #WebKitWebView.
921- *
922- * Since: 0.2.5
923+ * @hit_test_result: a #WebKitHitTestResult
924+ *
925+ * Populates actions depending on the hit test result.
926+ *
927+ * Since: 0.5.5
928 */
929-void
930-midori_view_populate_popup (MidoriView* view,
931- GtkWidget* menu,
932- gboolean manual)
933+MidoriContextAction*
934+midori_view_get_page_context_action (MidoriView* view,
935+ WebKitHitTestResult* hit_test_result)
936 {
937-#ifndef HAVE_WEBKIT2
938- g_return_if_fail (MIDORI_IS_VIEW (view));
939- g_return_if_fail (GTK_IS_MENU_SHELL (menu));
940+ g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
941+ g_return_val_if_fail (hit_test_result != NULL, NULL);
942
943- WebKitWebView* web_view = WEBKIT_WEB_VIEW (view->web_view);
944- GtkWidget* widget = GTK_WIDGET (view);
945- MidoriBrowser* browser = midori_browser_get_for_widget (widget);
946+ MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (view));
947 GdkWindowState state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (browser)));
948+ WebKitHitTestResultContext context = katze_object_get_int (hit_test_result, "context");
949 GtkActionGroup* actions = midori_browser_get_action_group (browser);
950- GtkMenuShell* menu_shell = GTK_MENU_SHELL (menu);
951- GtkWidget* menuitem;
952- GtkWidget* icon;
953- gchar* stock_id;
954- GList* items;
955- gboolean has_selection;
956- gboolean is_editable;
957- gboolean is_document;
958- GtkWidget* label;
959- guint i;
960-
961- gint x, y;
962- WebKitHitTestResultContext context;
963- gboolean is_image;
964- gboolean is_media;
965-
966- GdkEvent* event = gtk_get_current_event();
967- midori_view_ensure_link_uri (view, &x, &y, (GdkEventButton *)event);
968- gdk_event_free (event);
969-
970- context = katze_object_get_int (view->hit_test, "context");
971- has_selection = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;
972- /* Ensure view->selected_text */
973- if (!midori_view_has_selection (view))
974- has_selection = false;
975- is_editable = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
976- is_image = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;
977- is_media = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA;
978- is_document = !view->link_uri && !has_selection && !is_image && !is_media;
979-
980- if (is_editable)
981- {
982- menuitem = gtk_separator_menu_item_new ();
983- gtk_menu_shell_prepend (menu_shell, menuitem);
984- gtk_widget_show (menuitem);
985- menuitem = sokoke_action_create_popup_menu_item (
986- gtk_action_group_get_action (actions, "Redo"));
987- gtk_widget_set_sensitive (menuitem,
988- webkit_web_view_can_redo (web_view));
989- gtk_menu_shell_prepend (menu_shell, menuitem);
990- menuitem = sokoke_action_create_popup_menu_item (
991- gtk_action_group_get_action (actions, "Undo"));
992- gtk_widget_set_sensitive (menuitem,
993- webkit_web_view_can_undo (web_view));
994- gtk_menu_shell_prepend (menu_shell, menuitem);
995-
996- {
997- KatzeItem* item = midori_search_action_get_engine_for_form (
998- WEBKIT_WEB_VIEW (view->web_view), view->ellipsize);
999- if (item != NULL)
1000- {
1001- menuitem = midori_view_insert_menu_item (menu_shell, -1,
1002- _("Add _search engine..."), NULL,
1003- G_CALLBACK (midori_view_menu_add_search_engine_cb), widget);
1004- g_object_set_data (G_OBJECT (menuitem), "item", item);
1005- gtk_widget_show (menuitem);
1006- }
1007- }
1008-
1009- if (manual)
1010- {
1011- menuitem = sokoke_action_create_popup_menu_item (
1012- gtk_action_group_get_action (actions, "Cut"));
1013- gtk_widget_set_sensitive (menuitem,
1014- webkit_web_view_can_cut_clipboard (web_view));
1015- gtk_menu_shell_append (menu_shell, menuitem);
1016- menuitem = sokoke_action_create_popup_menu_item (
1017- gtk_action_group_get_action (actions, "Copy"));
1018- gtk_widget_set_sensitive (menuitem,
1019- webkit_web_view_can_copy_clipboard (web_view));
1020- gtk_menu_shell_append (menu_shell, menuitem);
1021- menuitem = sokoke_action_create_popup_menu_item (
1022- gtk_action_group_get_action (actions, "Paste"));
1023- gtk_widget_set_sensitive (menuitem,
1024- webkit_web_view_can_paste_clipboard (web_view));
1025- gtk_menu_shell_append (menu_shell, menuitem);
1026- menuitem = sokoke_action_create_popup_menu_item (
1027- gtk_action_group_get_action (actions, "Delete"));
1028- gtk_widget_set_sensitive (menuitem,
1029- webkit_web_view_can_cut_clipboard (web_view));
1030- gtk_menu_shell_append (menu_shell, menuitem);
1031- menuitem = gtk_separator_menu_item_new ();
1032- gtk_widget_show (menuitem);
1033- gtk_menu_shell_append (menu_shell, menuitem);
1034- menuitem = sokoke_action_create_popup_menu_item (
1035- gtk_action_group_get_action (actions, "SelectAll"));
1036- gtk_menu_shell_append (menu_shell, menuitem);
1037- /* FIXME: We are missing Font, Input Methods and Insert Character */
1038- if (katze_object_get_boolean (view->settings, "enable-developer-extras"))
1039- {
1040- menuitem = gtk_separator_menu_item_new ();
1041- gtk_widget_show (menuitem);
1042- gtk_menu_shell_append (menu_shell, menuitem);
1043- menuitem = midori_view_insert_menu_item (menu_shell, -1,
1044- _("Inspect _Element"), NULL,
1045- G_CALLBACK (midori_web_view_menu_inspect_element_activate_cb),
1046- widget);
1047- gtk_widget_show (menuitem);
1048- g_object_set_data (G_OBJECT (menuitem), "x", GINT_TO_POINTER (x));
1049- g_object_set_data (G_OBJECT (menuitem), "y", GINT_TO_POINTER (y));
1050- }
1051- }
1052- return;
1053- }
1054-
1055- items = gtk_container_get_children (GTK_CONTAINER (menu));
1056- menuitem = (GtkWidget*)g_list_nth_data (items, 0);
1057- /* Form control: no items */
1058- if (!manual && !menuitem)
1059- {
1060- g_list_free (items);
1061- return;
1062- }
1063- /* Form control: separator and Inspect element */
1064- if (!manual && GTK_IS_SEPARATOR_MENU_ITEM (menuitem) && g_list_length (items) == 2)
1065- {
1066- gtk_widget_destroy (menuitem);
1067- g_list_free (items);
1068- return;
1069- }
1070- g_list_free (items);
1071- /* Link and/ or image, but falsely reported as document */
1072- if (is_document)
1073- {
1074- if (GTK_IS_IMAGE_MENU_ITEM (menuitem))
1075- {
1076- icon = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menuitem));
1077- gtk_image_get_stock (GTK_IMAGE (icon), &stock_id, NULL);
1078- if (stock_id && !strcmp (stock_id, GTK_STOCK_OPEN))
1079- return;
1080- }
1081- }
1082-
1083- if (!is_document)
1084- {
1085- items = gtk_container_get_children (GTK_CONTAINER (menu));
1086- i = 0;
1087- while ((menuitem = g_list_nth_data (items, i++)))
1088- gtk_widget_destroy (menuitem);
1089- g_list_free (items);
1090- }
1091- if (view->link_uri)
1092+ MidoriContextAction* menu = midori_context_action_new ("PageContextMenu", NULL, NULL, NULL);
1093+ midori_context_action_add_action_group (menu, actions);
1094+
1095+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)
1096+ {
1097+ /* Enforce update of actions - there's no "selection-changed" signal */
1098+ #ifndef HAVE_WEBKIT2
1099+ gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Redo"),
1100+ webkit_web_view_can_undo (WEBKIT_WEB_VIEW (view->web_view)));
1101+ gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Undo"),
1102+ webkit_web_view_can_redo (WEBKIT_WEB_VIEW (view->web_view)));
1103+ gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Cut"),
1104+ webkit_web_view_can_cut_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
1105+ gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Copy"),
1106+ webkit_web_view_can_copy_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
1107+ gtk_action_set_sensitive (gtk_action_group_get_action (actions, "Paste"),
1108+ webkit_web_view_can_paste_clipboard (WEBKIT_WEB_VIEW (view->web_view)));
1109+ gtk_action_set_sensitive (gtk_action_group_get_action (actions, "SelectAll"), TRUE);
1110+ #endif
1111+ midori_context_action_add_by_name (menu, "Redo");
1112+ midori_context_action_add_by_name (menu, "Undo");
1113+ midori_context_action_add (menu, NULL);
1114+ midori_context_action_add_by_name (menu, "Cut");
1115+ midori_context_action_add_by_name (menu, "Copy");
1116+ midori_context_action_add_by_name (menu, "Paste");
1117+ midori_context_action_add_by_name (menu, "Delete");
1118+ midori_context_action_add (menu, NULL);
1119+ midori_context_action_add_by_name (menu, "SelectAll");
1120+ midori_context_action_add (menu, NULL);
1121+ KatzeItem* item = midori_search_action_get_engine_for_form (
1122+ WEBKIT_WEB_VIEW (view->web_view), view->ellipsize);
1123+ if (item != NULL)
1124+ {
1125+ GtkAction* action = gtk_action_new ("AddSearchEngine", _("Add _search engine..."), NULL, NULL);
1126+ g_object_set_data (G_OBJECT (action), "item", item);
1127+ g_signal_connect (action, "activate",
1128+ G_CALLBACK (midori_view_add_search_engine_cb), view);
1129+ midori_context_action_add (menu, action);
1130+ }
1131+ /* FIXME: input methods, font, spelling, insert unicode character */
1132+ }
1133+
1134+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
1135 {
1136 if (midori_paths_get_runtime_mode () == MIDORI_RUNTIME_MODE_APP)
1137 {
1138- midori_view_insert_menu_item (menu_shell, -1,
1139- _("Open _Link"), STOCK_TAB_NEW,
1140- G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), widget);
1141+ midori_context_action_add_simple (menu, "OpenLinkTab", _("Open _Link"), NULL, STOCK_TAB_NEW,
1142+ midori_web_view_menu_new_tab_activate_cb, view);
1143 }
1144 else if (!midori_view_always_same_tab (view->link_uri))
1145 {
1146- midori_view_insert_menu_item (menu_shell, -1,
1147- _("Open Link in New _Tab"), STOCK_TAB_NEW,
1148- G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), widget);
1149- midori_view_insert_menu_item (menu_shell, -1,
1150+ midori_context_action_add_simple (menu, "OpenLinkTab", _("Open Link in New _Tab"), NULL, STOCK_TAB_NEW,
1151+ midori_web_view_menu_new_tab_activate_cb, view);
1152+ midori_context_action_add_simple (menu, "OpenLinkForegroundTab",
1153 view->open_tabs_in_the_background
1154- ? _("Open Link in _Foreground Tab")
1155- : _("Open Link in _Background Tab"), NULL,
1156- G_CALLBACK (midori_web_view_menu_background_tab_activate_cb), widget);
1157- midori_view_insert_menu_item (menu_shell, -1,
1158- _("Open Link in New _Window"), STOCK_WINDOW_NEW,
1159- G_CALLBACK (midori_web_view_menu_new_window_activate_cb), widget);
1160+ ? _("Open Link in _Foreground Tab") : _("Open Link in _Background Tab"), NULL, NULL,
1161+ midori_web_view_menu_background_tab_activate_cb, view);
1162+ midori_context_action_add_simple (menu, "OpenLinkWindow", _("Open Link in New _Window"), NULL, STOCK_WINDOW_NEW,
1163+ midori_web_view_menu_new_window_activate_cb, view);
1164 }
1165
1166- midori_view_insert_menu_item (menu_shell, -1,
1167- _("Copy Link de_stination"), NULL,
1168- G_CALLBACK (midori_web_view_menu_link_copy_activate_cb), widget);
1169+ midori_context_action_add_simple (menu, "CopyLinkDestination", _("Copy Link de_stination"), NULL, NULL,
1170+ midori_web_view_menu_link_copy_activate_cb, view);
1171
1172 if (!midori_view_always_same_tab (view->link_uri))
1173+ {
1174 /* GTK_STOCK_SAVE_AS is lacking the underline */
1175- midori_view_insert_menu_item (menu_shell, -1,
1176- _("Save _As…"), GTK_STOCK_SAVE_AS,
1177- G_CALLBACK (midori_web_view_menu_save_activate_cb), widget);
1178+ midori_context_action_add_simple (menu, "SaveLinkAs", _("Save _As…"), NULL, GTK_STOCK_SAVE_AS,
1179+ midori_web_view_menu_save_activate_cb, view);
1180+ }
1181 }
1182
1183- if (is_image)
1184+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE)
1185 {
1186- if (view->link_uri)
1187- gtk_menu_shell_append (menu_shell, gtk_separator_menu_item_new ());
1188- midori_view_insert_menu_item (menu_shell, -1,
1189+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
1190+ midori_context_action_add (menu, NULL);
1191+
1192+ midori_context_action_add_simple (menu, "OpenImageNewTab",
1193 view->open_new_pages_in == MIDORI_NEW_PAGE_WINDOW
1194- ? _("Open _Image in New Window")
1195- : _("Open _Image in New Tab")
1196- , STOCK_TAB_NEW,
1197- G_CALLBACK (midori_web_view_menu_image_new_tab_activate_cb), widget);
1198- midori_view_insert_menu_item (menu_shell, -1,
1199- _("Copy Im_age"), NULL,
1200- G_CALLBACK (midori_web_view_menu_image_copy_activate_cb), widget);
1201- midori_view_insert_menu_item (menu_shell, -1,
1202- _("Save I_mage"), GTK_STOCK_SAVE,
1203- G_CALLBACK (midori_web_view_menu_image_save_activate_cb), widget);
1204- midori_view_insert_menu_item (menu_shell, -1,
1205- _("Open in Image _Viewer"), GTK_STOCK_OPEN,
1206- G_CALLBACK (midori_web_view_open_in_viewer_cb), widget);
1207- }
1208-
1209- if (is_media)
1210- {
1211- midori_view_insert_menu_item (menu_shell, -1,
1212- _("Copy Video _Address"), NULL,
1213- G_CALLBACK (midori_web_view_menu_video_copy_activate_cb), widget);
1214- midori_view_insert_menu_item (menu_shell, -1,
1215- FALSE ? _("Save _Video") : _("Download _Video"), GTK_STOCK_SAVE,
1216- G_CALLBACK (midori_web_view_menu_video_save_activate_cb), widget);
1217- }
1218-
1219- if (has_selection)
1220- {
1221- gtk_menu_shell_append (menu_shell, gtk_separator_menu_item_new ());
1222- midori_view_insert_menu_item (menu_shell, -1, NULL, GTK_STOCK_COPY,
1223- G_CALLBACK (midori_web_view_menu_copy_activate_cb), widget);
1224- }
1225-
1226- if (!view->link_uri && has_selection)
1227- {
1228- GtkWidget* window;
1229- KatzeArray* search_engines = NULL;
1230-
1231- window = gtk_widget_get_toplevel (GTK_WIDGET (web_view));
1232- i = 0;
1233- if (MIDORI_IS_BROWSER (window))
1234- search_engines = katze_object_get_object (window, "search-engines");
1235-
1236+ ? _("Open _Image in New Window") : _("Open _Image in New Tab")
1237+ , NULL, STOCK_TAB_NEW,
1238+ midori_web_view_menu_image_new_tab_activate_cb, view);
1239+ midori_context_action_add_simple (menu, "CopyImage", _("Copy Im_age"), NULL, NULL,
1240+ midori_web_view_menu_image_copy_activate_cb, view);
1241+ midori_context_action_add_simple (menu, "SaveImage", _("Save I_mage"), NULL, GTK_STOCK_SAVE,
1242+ midori_web_view_menu_image_save_activate_cb, view);
1243+ midori_context_action_add_simple (menu, "OpenImageInViewer", _("Open in Image _Viewer"), NULL, GTK_STOCK_OPEN,
1244+ midori_web_view_open_in_viewer_cb, view);
1245+ }
1246+
1247+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA)
1248+ {
1249+ midori_context_action_add_simple (menu, "CopyVideoAddress", _("Copy Video _Address"), NULL, NULL,
1250+ midori_web_view_menu_video_copy_activate_cb, view);
1251+ midori_context_action_add_simple (menu, "DownloadVideo", _("Download _Video"), NULL, GTK_STOCK_SAVE,
1252+ midori_web_view_menu_video_save_activate_cb, view);
1253+ }
1254+
1255+ #ifndef HAVE_WEBKIT2
1256+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION)
1257+ {
1258+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
1259+ midori_context_action_add (menu, NULL);
1260+
1261+ /* No need to have Copy twice, which is already in the editable menu */
1262+ if (!(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE))
1263+ midori_context_action_add_by_name (menu, "Copy");
1264+
1265+ /* Ensure view->selected_text */
1266+ midori_view_has_selection (view);
1267+ if (midori_uri_is_valid (view->selected_text))
1268+ {
1269+ /* :// and @ together would mean login credentials */
1270+ if (g_str_has_prefix (view->selected_text, "mailto:")
1271+ || (strchr (view->selected_text, '@') != NULL
1272+ && strstr (view->selected_text, "://") == NULL))
1273+ {
1274+ gchar* text = g_strdup_printf (_("Send a message to %s"), view->selected_text);
1275+ GtkAction* action = gtk_action_new ("SendMessage", text, NULL, GTK_STOCK_JUMP_TO);
1276+ g_object_set_data (G_OBJECT (action), "uri", view->selected_text);
1277+ g_signal_connect (action, "activate", G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), view);
1278+ midori_context_action_add (menu, action);
1279+ g_free (text);
1280+ }
1281+ else
1282+ {
1283+ GtkAction* action = gtk_action_new ("OpenAddressInNewTab", _("Open Address in New _Tab"), NULL, GTK_STOCK_JUMP_TO);
1284+ g_object_set_data (G_OBJECT (action), "uri", view->selected_text);
1285+ g_signal_connect (action, "activate", G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), view);
1286+ midori_context_action_add (menu, action);
1287+ }
1288+ }
1289+
1290+ KatzeArray* search_engines = katze_object_get_object (browser, "search-engines");
1291 if (search_engines != NULL)
1292 {
1293+ MidoriContextAction* searches = midori_context_action_new ("SearchWith", _("Search _with"), NULL, NULL);
1294+ midori_context_action_add (menu, GTK_ACTION (searches));
1295+
1296 KatzeItem* item;
1297- GtkWidget* sub_menu = gtk_menu_new ();
1298-
1299- menuitem = gtk_image_menu_item_new_with_mnemonic (_("Search _with"));
1300- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), sub_menu);
1301- gtk_menu_shell_insert (menu_shell, menuitem, 1);
1302-
1303+ guint i = 0;
1304 KATZE_ARRAY_FOREACH_ITEM (item, search_engines)
1305 {
1306 GdkPixbuf* pixbuf;
1307-
1308- menuitem = gtk_image_menu_item_new_with_mnemonic (katze_item_get_name (item));
1309- if ((pixbuf = katze_item_get_pixbuf (item, GTK_WIDGET (web_view))))
1310+ gchar* search_option = g_strdup_printf ("SearchWith%u", i);
1311+ GtkAction* action = gtk_action_new (search_option, katze_item_get_name (item), NULL, STOCK_EDIT_FIND);
1312+ g_free (search_option);
1313+ midori_context_action_add (searches, action);
1314+ if ((pixbuf = katze_item_get_pixbuf (item, view->web_view)))
1315 {
1316- icon = gtk_image_new_from_pixbuf (pixbuf);
1317+ gtk_action_set_gicon (GTK_ACTION (action), G_ICON (pixbuf));
1318 g_object_unref (pixbuf);
1319 }
1320- else
1321- icon = gtk_image_new_from_icon_name (STOCK_EDIT_FIND, GTK_ICON_SIZE_MENU);
1322- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
1323- gtk_image_menu_item_set_always_show_image (
1324- GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
1325- gtk_menu_shell_insert (GTK_MENU_SHELL (sub_menu), menuitem, i);
1326- g_object_set_data (G_OBJECT (menuitem), "search",
1327- (gchar*)katze_item_get_uri (item));
1328- g_signal_connect (menuitem, "activate",
1329+ gtk_action_set_always_show_image (GTK_ACTION (action), TRUE);
1330+ g_object_set_data (G_OBJECT (action), "search", (gchar*)katze_item_get_uri (item));
1331+ g_signal_connect (action, "activate",
1332 G_CALLBACK (midori_web_view_menu_search_web_activate_cb), view);
1333 i++;
1334 }
1335 g_object_unref (search_engines);
1336 }
1337- midori_view_insert_menu_item (menu_shell, 0,
1338- _("_Search the Web"), GTK_STOCK_FIND,
1339- G_CALLBACK (midori_web_view_menu_search_web_activate_cb), widget);
1340- /* FIXME: choose 3 most frequently */
1341-
1342- g_strstrip (view->selected_text);
1343- if (midori_uri_is_valid (view->selected_text))
1344- {
1345- /* :// and @ together would mean login credentials */
1346- if (g_str_has_prefix (view->selected_text, "mailto:")
1347- || (strchr (view->selected_text, '@') != NULL
1348- && strstr (view->selected_text, "://") == NULL))
1349- {
1350- gchar* text = g_strdup_printf (_("Send a message to %s"), view->selected_text);
1351- menuitem = midori_view_insert_menu_item (menu_shell, -1,
1352- text, GTK_STOCK_JUMP_TO,
1353- G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), widget);
1354- g_free (text);
1355- }
1356- else
1357- menuitem = midori_view_insert_menu_item (menu_shell, -1,
1358- _("Open Address in New _Tab"), GTK_STOCK_JUMP_TO,
1359- G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), widget);
1360- g_object_set_data (G_OBJECT (menuitem), "uri", view->selected_text);
1361- }
1362+ midori_context_action_add_simple (menu, "SearchWeb", _("_Search the Web"), NULL, GTK_STOCK_FIND,
1363+ midori_web_view_menu_search_web_activate_cb, view);
1364 }
1365+ #endif
1366
1367- if (is_document)
1368+ if (context == WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT)
1369 {
1370- if (manual)
1371- {
1372- menuitem = sokoke_action_create_popup_menu_item (
1373- gtk_action_group_get_action (actions, "Back"));
1374- gtk_menu_shell_append (menu_shell, menuitem);
1375- menuitem = sokoke_action_create_popup_menu_item (
1376- gtk_action_group_get_action (actions, "Forward"));
1377- gtk_menu_shell_append (menu_shell, menuitem);
1378- menuitem = sokoke_action_create_popup_menu_item (
1379- gtk_action_group_get_action (actions, "Stop"));
1380- gtk_menu_shell_append (menu_shell, menuitem);
1381- menuitem = sokoke_action_create_popup_menu_item (
1382- gtk_action_group_get_action (actions, "Reload"));
1383- gtk_menu_shell_append (menu_shell, menuitem);
1384- }
1385- else
1386- {
1387- items = gtk_container_get_children (GTK_CONTAINER (menu));
1388- menuitem = (GtkWidget*)g_list_nth_data (items, 3);
1389- /* hack to localize menu item */
1390- if (GTK_IS_BIN (menuitem))
1391- {
1392- GtkStockItem stock_item;
1393- if (gtk_stock_lookup (GTK_STOCK_REFRESH, &stock_item))
1394- {
1395- label = gtk_bin_get_child (GTK_BIN (menuitem));
1396- gtk_label_set_label (GTK_LABEL (label), stock_item.label);
1397- }
1398- }
1399- g_list_free (items);
1400- }
1401-
1402- gtk_menu_shell_append (menu_shell, gtk_separator_menu_item_new ());
1403- menuitem = sokoke_action_create_popup_menu_item (
1404- gtk_action_group_get_action (actions, "UndoTabClose"));
1405- gtk_menu_shell_append (menu_shell, menuitem);
1406-
1407+ midori_context_action_add_by_name (menu, "Back");
1408+ midori_context_action_add_by_name (menu, "Forward");
1409+ midori_context_action_add_by_name (menu, "Stop");
1410+ midori_context_action_add_by_name (menu, "Reload");
1411+ midori_context_action_add (menu, NULL);
1412+ midori_context_action_add_by_name (menu, "UndoTabClose");
1413+
1414+ #ifndef HAVE_WEBKIT2
1415+ WebKitWebView* web_view = WEBKIT_WEB_VIEW (view->web_view);
1416 if (webkit_web_view_get_focused_frame (web_view) != webkit_web_view_get_main_frame (web_view))
1417- midori_view_insert_menu_item (menu_shell, -1,
1418- _("Open _Frame in New Tab"), NULL,
1419- G_CALLBACK (midori_web_view_open_frame_in_new_tab_cb), widget);
1420-
1421- menuitem = gtk_image_menu_item_new_from_stock (STOCK_WINDOW_NEW, NULL);
1422- gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), _("Open in New _Window"));
1423- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1424- g_signal_connect (menuitem, "activate",
1425- G_CALLBACK (midori_view_tab_label_menu_window_new_cb), view);
1426-
1427- menuitem = sokoke_action_create_popup_menu_item (
1428- gtk_action_group_get_action (actions, "ZoomIn"));
1429- gtk_menu_shell_append (menu_shell, menuitem);
1430- menuitem = sokoke_action_create_popup_menu_item (
1431- gtk_action_group_get_action (actions, "ZoomOut"));
1432- gtk_menu_shell_append (menu_shell, menuitem);
1433-
1434- menuitem = sokoke_action_create_popup_menu_item (
1435- gtk_action_group_get_action (actions, "Encoding"));
1436- gtk_menu_shell_append (menu_shell, menuitem);
1437- if (gtk_widget_get_sensitive (menuitem))
1438- {
1439- GtkWidget* sub_menu;
1440- static const GtkActionEntry encodings[] = {
1441- { "EncodingAutomatic" },
1442- { "EncodingChinese" },
1443- { "EncodingChineseSimplified" },
1444- { "EncodingJapanese" },
1445- { "EncodingKorean" },
1446- { "EncodingRussian" },
1447- { "EncodingUnicode" },
1448- { "EncodingWestern" },
1449- { "EncodingCustom" },
1450- };
1451-
1452- sub_menu = gtk_menu_new ();
1453- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), sub_menu);
1454-
1455- for (i = 0; i < G_N_ELEMENTS (encodings); i++)
1456- {
1457- menuitem = sokoke_action_create_popup_menu_item (
1458- gtk_action_group_get_action (actions, encodings[i].name));
1459- gtk_menu_shell_append (GTK_MENU_SHELL (sub_menu), menuitem);
1460- }
1461- }
1462-
1463- gtk_menu_shell_append (menu_shell, gtk_separator_menu_item_new ());
1464- menuitem = sokoke_action_create_popup_menu_item (
1465- gtk_action_group_get_action (actions, "BookmarkAdd"));
1466- gtk_menu_shell_append (menu_shell, menuitem);
1467-
1468+ midori_context_action_add_simple (menu, "OpenFrameInNewTab", _("Open _Frame in New Tab"), NULL, NULL,
1469+ midori_web_view_open_frame_in_new_tab_cb, view);
1470+ #endif
1471+
1472+ midori_context_action_add_simple (menu, "OpenInNewWindow", _("Open in New _Window"), NULL, NULL,
1473+ midori_view_tab_label_menu_window_new_cb, view);
1474+ midori_context_action_add_by_name (menu, "ZoomIn");
1475+ midori_context_action_add_by_name (menu, "ZoomOut");
1476+
1477+ MidoriContextAction* encodings = midori_context_action_new ("Encoding", _("_Encoding"), NULL, NULL);
1478+ midori_context_action_add (menu, GTK_ACTION (encodings));
1479+ midori_context_action_add_by_name (encodings, "EncodingAutomatic");
1480+ midori_context_action_add_by_name (encodings, "EncodingChinese");
1481+ midori_context_action_add_by_name (encodings, "EncodingChineseSimplified");
1482+ midori_context_action_add_by_name (encodings, "EncodingJapanese");
1483+ midori_context_action_add_by_name (encodings, "EncodingKorean");
1484+ midori_context_action_add_by_name (encodings, "EncodingRussian");
1485+ midori_context_action_add_by_name (encodings, "EncodingUnicode");
1486+ midori_context_action_add_by_name (encodings, "EncodingWestern");
1487+ midori_context_action_add_by_name (encodings, "EncodingCustom");
1488+
1489+ midori_context_action_add (menu, NULL);
1490+ midori_context_action_add_by_name (menu, "BookmarkAdd");
1491 if (!midori_view_is_blank (view) && !midori_paths_is_readonly ())
1492- {
1493- menuitem = sokoke_action_create_popup_menu_item (
1494- gtk_action_group_get_action (actions, "AddSpeedDial"));
1495- gtk_menu_shell_append (menu_shell, menuitem);
1496- }
1497-
1498- menuitem = sokoke_action_create_popup_menu_item (
1499- gtk_action_group_get_action (actions, "SaveAs"));
1500- gtk_menu_shell_append (menu_shell, menuitem);
1501- menuitem = sokoke_action_create_popup_menu_item (
1502- gtk_action_group_get_action (actions, "SourceView"));
1503- gtk_menu_shell_append (menu_shell, menuitem);
1504-
1505+ midori_context_action_add_by_name (menu, "AddSpeedDial");
1506+ midori_context_action_add_by_name (menu, "SaveAs");
1507+ midori_context_action_add_by_name (menu, "SourceView");
1508 if (!g_object_get_data (G_OBJECT (browser), "midori-toolbars-visible"))
1509- {
1510- menuitem = sokoke_action_create_popup_menu_item (
1511- gtk_action_group_get_action (actions, "Navigationbar"));
1512- gtk_menu_shell_append (menu_shell, menuitem);
1513- }
1514- }
1515-
1516- if ((!is_document || manual)
1517- && katze_object_get_boolean (view->settings, "enable-developer-extras"))
1518- {
1519- gtk_menu_shell_append (menu_shell, gtk_separator_menu_item_new ());
1520- menuitem = midori_view_insert_menu_item (menu_shell, -1,
1521- _("Inspect _Element"), NULL,
1522- G_CALLBACK (midori_web_view_menu_inspect_element_activate_cb), widget);
1523- g_object_set_data (G_OBJECT (menuitem), "x", GINT_TO_POINTER (x));
1524- g_object_set_data (G_OBJECT (menuitem), "y", GINT_TO_POINTER (y));
1525- }
1526-
1527- if (state & GDK_WINDOW_STATE_FULLSCREEN)
1528- {
1529- menuitem = sokoke_action_create_popup_menu_item (
1530- gtk_action_group_get_action (actions, "Fullscreen"));
1531-
1532- gtk_image_menu_item_set_use_stock (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
1533- gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), GTK_STOCK_LEAVE_FULLSCREEN);
1534- gtk_menu_shell_append (menu_shell, menuitem);
1535- }
1536-
1537- gtk_widget_show_all (menu);
1538-#endif
1539-}
1540-
1541-static void
1542-webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
1543- GtkWidget* menu,
1544- MidoriView* view)
1545-{
1546- midori_view_populate_popup (view, menu, FALSE);
1547+ midori_context_action_add_by_name (menu, "Navigationbar");
1548+ if (katze_object_get_boolean (view->settings, "enable-developer-extras"))
1549+ midori_context_action_add_by_name (menu, "InspectPage");
1550+ if (state & GDK_WINDOW_STATE_FULLSCREEN)
1551+ midori_context_action_add_by_name (menu, "Fullscreen");
1552+ }
1553+ else if (katze_object_get_boolean (view->settings, "enable-developer-extras"))
1554+ midori_context_action_add_simple (menu, "InspectElement", _("Inspect _Element"), NULL, NULL,
1555+ midori_view_inspect_element_activate_cb, view);
1556+
1557+ g_signal_emit_by_name (view, "context-menu", hit_test_result, menu);
1558+ return menu;
1559+}
1560+
1561+/**
1562+ * midori_view_populate_popup:
1563+ * @view: a #MidoriView
1564+ * @menu: a #GtkMenu
1565+ * @manual: %TRUE if this a manually created popup
1566+ *
1567+ * Populates the given @menu with context menu items
1568+ * according to the position of the mouse pointer. This
1569+ * can be used in situations where a custom hotkey
1570+ * opens the context menu or the default behaviour
1571+ * needs to be intercepted.
1572+ *
1573+ * @manual should usually be %TRUE, except for the
1574+ * case where @menu was created by the #WebKitWebView.
1575+ *
1576+ * Since: 0.2.5
1577+ * Deprecated: 0.5.5: Use midori_view_get_page_context_action().
1578+ */
1579+void
1580+midori_view_populate_popup (MidoriView* view,
1581+ GtkWidget* menu,
1582+ gboolean manual)
1583+{
1584+ g_return_if_fail (MIDORI_IS_VIEW (view));
1585+ g_return_if_fail (GTK_IS_MENU_SHELL (menu));
1586+
1587+ GdkEvent* event = gtk_get_current_event();
1588+ midori_view_ensure_link_uri (view, NULL, NULL, (GdkEventButton *)event);
1589+ gdk_event_free (event);
1590+ MidoriContextAction* context_action = midori_view_get_page_context_action (view, view->hit_test);
1591+ midori_context_action_create_menu (context_action, GTK_MENU (menu), FALSE);
1592+}
1593+
1594+static gboolean
1595+midori_view_web_view_context_menu_cb (WebKitWebView* web_view,
1596+ #ifdef HAVE_WEBKIT2
1597+ WebKitContextMenu* context_menu,
1598+ GdkEvent* event,
1599+ WebKitHitTestResult* hit_test_result,
1600+ #else
1601+ GtkMenu* default_menu,
1602+ WebKitHitTestResult* hit_test_result,
1603+ gboolean keyboard,
1604+ #endif
1605+ MidoriView* view)
1606+{
1607+ MidoriContextAction* menu = midori_view_get_page_context_action (view, hit_test_result);
1608+ #ifdef HAVE_WEBKIT2
1609+ webkit_context_menu_remove_all (context_menu);
1610+ midori_context_action_create_webkit_context_menu (menu, context_menu);
1611+ #else
1612+ gtk_container_foreach (GTK_CONTAINER (default_menu), (GtkCallback) gtk_widget_destroy, NULL);
1613+ midori_context_action_create_menu (menu, default_menu, FALSE);
1614+ #endif
1615+ return FALSE;
1616 }
1617
1618 static gboolean
1619@@ -3641,6 +3450,8 @@
1620 midori_view_web_view_navigation_decision_cb, view,
1621 "signal::permission-request",
1622 midori_view_web_view_permission_request_cb, view,
1623+ "signal::context-menu",
1624+ midori_view_web_view_context_menu_cb, view,
1625 #else
1626 "signal::notify::load-status",
1627 midori_view_web_view_notify_load_status_cb, view,
1628@@ -3672,8 +3483,8 @@
1629 webkit_web_view_hovering_over_link_cb, view,
1630 "signal::status-bar-text-changed",
1631 webkit_web_view_statusbar_text_changed_cb, view,
1632- "signal::populate-popup",
1633- webkit_web_view_populate_popup_cb, view,
1634+ "signal::context-menu",
1635+ midori_view_web_view_context_menu_cb, view,
1636 "signal::console-message",
1637 webkit_web_view_console_message_cb, view,
1638 "signal::download-requested",
1639@@ -4454,7 +4265,7 @@
1640 g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
1641
1642 if (midori_view_has_selection (view))
1643- return view->selected_text;
1644+ return g_strstrip (view->selected_text);
1645 return NULL;
1646 }
1647
1648@@ -4494,9 +4305,10 @@
1649 }
1650
1651 static void
1652-midori_view_tab_label_menu_duplicate_tab_cb (GtkWidget* menuitem,
1653- MidoriView* view)
1654+midori_view_tab_label_menu_duplicate_tab_cb (GtkAction* action,
1655+ gpointer user_data)
1656 {
1657+ MidoriView* view = user_data;
1658 midori_view_duplicate (view);
1659 }
1660
1661@@ -4513,9 +4325,10 @@
1662 }
1663
1664 static void
1665-midori_view_tab_label_menu_close_other_tabs_cb (GtkWidget* menuitem,
1666- GtkWidget* view)
1667+midori_view_tab_label_menu_close_other_tabs_cb (GtkAction* action,
1668+ gpointer user_data)
1669 {
1670+ GtkWidget* view = user_data;
1671 MidoriBrowser* browser = midori_browser_get_for_widget (view);
1672 GList* tabs = midori_browser_get_tabs (browser);
1673 for (; tabs; tabs = g_list_next (tabs))
1674@@ -4527,16 +4340,18 @@
1675 }
1676
1677 static void
1678-midori_view_tab_label_menu_minimize_tab_cb (GtkWidget* menuitem,
1679- MidoriView* view)
1680+midori_view_tab_label_menu_minimize_tab_cb (GtkAction* action,
1681+ gpointer user_data)
1682 {
1683+ MidoriView* view = user_data;
1684 g_object_set (view, "minimized", !view->minimized, NULL);
1685 }
1686
1687 static void
1688-midori_view_tab_label_menu_close_cb (GtkWidget* menuitem,
1689- GtkWidget* view)
1690+midori_view_tab_label_menu_close_cb (GtkAction* action,
1691+ gpointer user_data)
1692 {
1693+ GtkWidget* view = user_data;
1694 midori_browser_close_tab (midori_browser_get_for_widget (view), view);
1695 }
1696
1697@@ -4554,57 +4369,33 @@
1698 GtkWidget*
1699 midori_view_get_tab_menu (MidoriView* view)
1700 {
1701- MidoriBrowser* browser;
1702- GtkActionGroup* actions;
1703- gint pages;
1704- GtkWidget* menu;
1705- GtkWidget* menuitem;
1706-
1707 g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
1708
1709- browser = midori_browser_get_for_widget (GTK_WIDGET (view));
1710- g_return_val_if_fail (browser != NULL, NULL);
1711- actions = midori_browser_get_action_group (browser);
1712- pages = midori_browser_get_n_pages (browser);
1713-
1714- menu = gtk_menu_new ();
1715- menuitem = sokoke_action_create_popup_menu_item (
1716- gtk_action_group_get_action (actions, "TabNew"));
1717- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1718- menuitem = sokoke_action_create_popup_menu_item (
1719- gtk_action_group_get_action (actions, "UndoTabClose"));
1720- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1721- menuitem = gtk_separator_menu_item_new ();
1722- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1723- menuitem = gtk_image_menu_item_new_from_stock (STOCK_WINDOW_NEW, NULL);
1724- gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), _("Open in New _Window"));
1725- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1726- g_signal_connect (menuitem, "activate",
1727- G_CALLBACK (midori_view_tab_label_menu_window_new_cb), view);
1728- menuitem = gtk_menu_item_new_with_mnemonic (_("_Duplicate Tab"));
1729- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1730- g_signal_connect (menuitem, "activate",
1731- G_CALLBACK (midori_view_tab_label_menu_duplicate_tab_cb), view);
1732- menuitem = gtk_menu_item_new_with_mnemonic (
1733- view->minimized ? _("Show Tab _Label") : _("Show Tab _Icon Only"));
1734- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1735- g_signal_connect (menuitem, "activate",
1736- G_CALLBACK (midori_view_tab_label_menu_minimize_tab_cb), view);
1737- menuitem = gtk_separator_menu_item_new ();
1738- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1739- menuitem = gtk_menu_item_new_with_mnemonic (
1740- g_dngettext (NULL, "Close Ot_her Tab", "Close Ot_her Tabs", pages - 1));
1741- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1742- g_signal_connect (menuitem, "activate",
1743- G_CALLBACK (midori_view_tab_label_menu_close_other_tabs_cb), view);
1744- gtk_widget_set_sensitive (menuitem, pages > 1);
1745- menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLOSE, NULL);
1746- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1747- g_signal_connect (menuitem, "activate",
1748- G_CALLBACK (midori_view_tab_label_menu_close_cb), view);
1749- gtk_widget_show_all (menu);
1750-
1751- return menu;
1752+ MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (view));
1753+ GtkActionGroup* actions = midori_browser_get_action_group (browser);
1754+ MidoriContextAction* menu = midori_context_action_new ("TabContextMenu", NULL, NULL, NULL);
1755+ midori_context_action_add_action_group (menu, actions);
1756+ gint pages = midori_browser_get_n_pages (browser);
1757+
1758+ midori_context_action_add_by_name (menu, "TabNew");
1759+ midori_context_action_add_by_name (menu, "UndoTabClose");
1760+ midori_context_action_add (menu, NULL);
1761+ midori_context_action_add_simple (menu, "TabWindowNew", _("Open in New _Window"), NULL, STOCK_WINDOW_NEW,
1762+ midori_view_tab_label_menu_window_new_cb, view);
1763+ midori_context_action_add_simple (menu, "TabDuplicate", _("_Duplicate Tab"), NULL, NULL,
1764+ midori_view_tab_label_menu_duplicate_tab_cb, view);
1765+ midori_context_action_add_simple (menu, "TabMinimize",
1766+ view->minimized ? _("Show Tab _Label") : _("Show Tab _Icon Only"), NULL, NULL,
1767+ midori_view_tab_label_menu_minimize_tab_cb, view);
1768+ midori_context_action_add (menu, NULL);
1769+ GtkAction* action = gtk_action_new ("TabCloseOther", g_dngettext (NULL, "Close Ot_her Tab", "Close Ot_her Tabs", pages - 1), NULL, NULL);
1770+ g_signal_connect (action, "activate", G_CALLBACK (midori_view_tab_label_menu_close_other_tabs_cb), view);
1771+ gtk_action_set_sensitive (action, pages > 1);
1772+ midori_context_action_add (menu, action);
1773+ midori_context_action_add_simple (menu, "TabClose", NULL, NULL, GTK_STOCK_CLOSE,
1774+ midori_view_tab_label_menu_close_cb, view);
1775+
1776+ return GTK_WIDGET (midori_context_action_create_menu (menu, NULL, FALSE));
1777 }
1778
1779 #ifdef HAVE_GRANITE
1780
1781=== modified file 'midori/sokoke.c'
1782--- midori/sokoke.c 2013-07-16 14:20:37 +0000
1783+++ midori/sokoke.c 2013-08-01 19:47:33 +0000
1784@@ -720,80 +720,6 @@
1785 }
1786
1787 /**
1788- * sokoke_action_create_popup_menu_item:
1789- * @action: a #GtkAction
1790- *
1791- * Creates a menu item from an action, just like
1792- * gtk_action_create_menu_item(), but it won't
1793- * display an accelerator.
1794- *
1795- * Note: This menu item is not a proxy and will
1796- * not reflect any changes to the action.
1797- *
1798- * Return value: a new #GtkMenuItem
1799- **/
1800-GtkWidget*
1801-sokoke_action_create_popup_menu_item (GtkAction* action)
1802-{
1803- GtkWidget* menuitem;
1804- GtkWidget* icon;
1805- gchar* label;
1806- gchar* stock_id;
1807- gchar* icon_name;
1808- gboolean sensitive;
1809- gboolean visible;
1810-
1811- g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1812-
1813- if (KATZE_IS_ARRAY_ACTION (action))
1814- return gtk_action_create_menu_item (action);
1815-
1816- g_object_get (action,
1817- "label", &label,
1818- "stock-id", &stock_id,
1819- "icon-name", &icon_name,
1820- "sensitive", &sensitive,
1821- "visible", &visible,
1822- NULL);
1823- if (GTK_IS_TOGGLE_ACTION (action))
1824- {
1825- menuitem = gtk_check_menu_item_new_with_mnemonic (label);
1826- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
1827- gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
1828- if (GTK_IS_RADIO_ACTION (action))
1829- gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menuitem),
1830- TRUE);
1831- }
1832- else if (stock_id)
1833- {
1834- if (label)
1835- {
1836- menuitem = gtk_image_menu_item_new_with_mnemonic (label);
1837- icon = gtk_action_create_icon (action, GTK_ICON_SIZE_MENU);
1838- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
1839- }
1840- else
1841- menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
1842- }
1843- else
1844- {
1845- menuitem = gtk_image_menu_item_new_with_mnemonic (label);
1846- if (icon_name)
1847- {
1848- icon = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
1849- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
1850- }
1851- }
1852- gtk_widget_set_sensitive (menuitem, sensitive);
1853- sokoke_widget_set_visible (menuitem, visible);
1854- gtk_widget_set_no_show_all (menuitem, TRUE);
1855- g_signal_connect_swapped (menuitem, "activate",
1856- G_CALLBACK (gtk_action_activate), action);
1857-
1858- return menuitem;
1859-}
1860-
1861-/**
1862 * sokoke_time_t_to_julian:
1863 * @timestamp: a time_t timestamp value
1864 *
1865
1866=== modified file 'midori/sokoke.h'
1867--- midori/sokoke.h 2013-07-04 19:57:07 +0000
1868+++ midori/sokoke.h 2013-08-01 19:47:33 +0000
1869@@ -90,9 +90,6 @@
1870 gint* width,
1871 gint* height);
1872
1873-GtkWidget*
1874-sokoke_action_create_popup_menu_item (GtkAction* action);
1875-
1876 gint64
1877 sokoke_time_t_to_julian (const time_t* timestamp);
1878

Subscribers

People subscribed via source and target branches

to all changes: