1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3 * Copyright © 2018 Purism SPC
4 * Copyright © 2018 Adrien Plazas <kekun.plazas@laposte.net>
5 *
6 * This file is part of Epiphany.
7 *
8 * Epiphany 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 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Epiphany 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 Epiphany. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "ephy-action-bar-start.h"
23
24 #include "ephy-desktop-utils.h"
25 #include "ephy-embed.h"
26 #include "ephy-embed-container.h"
27 #include "ephy-embed-prefs.h"
28 #include "ephy-embed-utils.h"
29 #include "ephy-favicon-helpers.h"
30 #include "ephy-file-helpers.h"
31 #include "ephy-gui.h"
32 #include "ephy-settings.h"
33 #include "ephy-shell.h"
34 #include "ephy-window.h"
35
36 /* Translators: tooltip for the refresh button */
37 static const char *REFRESH_BUTTON_TOOLTIP = N_("Reload the current page");
38
39 struct _EphyActionBarStart {
40 GtkBox parent_instance;
41
42 GtkWidget *navigation_box;
43 GtkWidget *navigation_back;
44 GtkWidget *navigation_forward;
45 GtkWidget *combined_stop_reload_button;
46 GtkWidget *combined_stop_reload_image;
47 GtkWidget *homepage_button;
48 GtkWidget *new_tab_button;
49 GtkWidget *placeholder;
50
51 guint navigation_buttons_menu_timeout;
52 };
53
54 G_DEFINE_TYPE (EphyActionBarStart, ephy_action_bar_start, GTK_TYPE_BOX)
55
56 typedef enum {
57 EPHY_NAVIGATION_HISTORY_DIRECTION_BACK,
58 EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD
59 } EphyNavigationHistoryDirection;
60
61 typedef enum {
62 WEBKIT_HISTORY_BACKWARD,
63 WEBKIT_HISTORY_FORWARD
64 } WebKitHistoryType;
65
66 typedef struct {
67 GtkWidget *button;
68 EphyWindow *window;
69 EphyNavigationHistoryDirection direction;
70 GdkEventButton *event;
71 } PopupData;
72
73 #define MAX_LABEL_LENGTH 48
74 #define HISTORY_ITEM_DATA_KEY "history-item-data-key"
75
76 static gboolean
item_enter_notify_event_cb(GtkWidget * widget,GdkEvent * event,EphyWebView * view)77 item_enter_notify_event_cb (GtkWidget *widget,
78 GdkEvent *event,
79 EphyWebView *view)
80 {
81 char *text;
82
83 text = g_object_get_data (G_OBJECT (widget), "link-message");
84 ephy_web_view_set_link_message (view, text);
85
86 return GDK_EVENT_PROPAGATE;
87 }
88
89 static gboolean
item_leave_notify_event_cb(GtkWidget * widget,GdkEvent * event,EphyWebView * view)90 item_leave_notify_event_cb (GtkWidget *widget,
91 GdkEvent *event,
92 EphyWebView *view)
93 {
94 ephy_web_view_set_link_message (view, NULL);
95 return GDK_EVENT_PROPAGATE;
96 }
97
98 static void
icon_loaded_cb(GObject * source,GAsyncResult * result,GtkWidget * image)99 icon_loaded_cb (GObject *source,
100 GAsyncResult *result,
101 GtkWidget *image)
102 {
103 WebKitFaviconDatabase *database = WEBKIT_FAVICON_DATABASE (source);
104 GdkPixbuf *favicon = NULL;
105 cairo_surface_t *icon_surface = webkit_favicon_database_get_favicon_finish (database, result, NULL);
106
107 if (icon_surface) {
108 gint scale = gtk_widget_get_scale_factor (image);
109
110 favicon = ephy_pixbuf_get_from_surface_scaled (icon_surface, FAVICON_SIZE * scale, FAVICON_SIZE * scale);
111 cairo_surface_destroy (icon_surface);
112 }
113
114 if (favicon)
115 gtk_image_set_from_gicon (GTK_IMAGE (image), G_ICON (favicon), GTK_ICON_SIZE_MENU);
116
117 g_object_unref (image);
118 }
119
120 static GtkWidget *
new_history_menu_item(EphyWebView * view,const char * origtext,const char * address)121 new_history_menu_item (EphyWebView *view,
122 const char *origtext,
123 const char *address)
124 {
125 GtkWidget *menu_item;
126 GtkWidget *box;
127 GtkWidget *image;
128 GtkWidget *label;
129 WebKitFaviconDatabase *database;
130 EphyEmbedShell *shell = ephy_embed_shell_get_default ();
131
132 g_assert (address != NULL && origtext != NULL);
133
134 box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
135
136 image = gtk_image_new ();
137 gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
138
139 label = gtk_label_new (origtext);
140 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
141 gtk_label_set_max_width_chars (GTK_LABEL (label), MAX_LABEL_LENGTH);
142 gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
143 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 6);
144
145 menu_item = gtk_menu_item_new ();
146 gtk_container_add (GTK_CONTAINER (menu_item), box);
147
148 database = webkit_web_context_get_favicon_database (ephy_embed_shell_get_web_context (shell));
149 webkit_favicon_database_get_favicon (database, address,
150 NULL,
151 (GAsyncReadyCallback)icon_loaded_cb,
152 g_object_ref (image));
153
154 g_object_set_data_full (G_OBJECT (menu_item), "link-message", g_strdup (address), (GDestroyNotify)g_free);
155
156 g_signal_connect (menu_item, "enter-notify-event",
157 G_CALLBACK (item_enter_notify_event_cb), view);
158 g_signal_connect (menu_item, "leave-notify-event",
159 G_CALLBACK (item_leave_notify_event_cb), view);
160
161 gtk_widget_show_all (menu_item);
162
163 return menu_item;
164 }
165
166 static void
middle_click_handle_on_history_menu_item(EphyEmbed * embed,WebKitBackForwardListItem * item)167 middle_click_handle_on_history_menu_item (EphyEmbed *embed,
168 WebKitBackForwardListItem *item)
169 {
170 EphyEmbed *new_embed = NULL;
171 const gchar *url;
172
173 new_embed = ephy_shell_new_tab (ephy_shell_get_default (),
174 EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (embed))),
175 embed,
176 0);
177 g_assert (new_embed != NULL);
178
179 /* Load the new URL */
180 url = webkit_back_forward_list_item_get_original_uri (item);
181 ephy_web_view_load_url (ephy_embed_get_web_view (new_embed), url);
182 }
183
184 static gboolean
navigation_menu_item_pressed_cb(GtkWidget * menuitem,GdkEvent * event,gpointer user_data)185 navigation_menu_item_pressed_cb (GtkWidget *menuitem,
186 GdkEvent *event,
187 gpointer user_data)
188 {
189 EphyWindow *window = EPHY_WINDOW (user_data);
190 WebKitBackForwardListItem *item;
191 EphyEmbed *embed;
192
193 embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
194
195 item = (WebKitBackForwardListItem *)g_object_get_data (G_OBJECT (menuitem), HISTORY_ITEM_DATA_KEY);
196
197 if (((GdkEventButton *)event)->button == GDK_BUTTON_MIDDLE) {
198 middle_click_handle_on_history_menu_item (embed, item);
199 } else {
200 WebKitWebView *web_view;
201
202 web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
203 webkit_web_view_go_to_back_forward_list_item (web_view, item);
204 }
205
206 return GDK_EVENT_STOP;
207 }
208
209 static GList *
construct_webkit_history_list(WebKitWebView * web_view,WebKitHistoryType hist_type,int limit)210 construct_webkit_history_list (WebKitWebView *web_view,
211 WebKitHistoryType hist_type,
212 int limit)
213 {
214 WebKitBackForwardList *back_forward_list;
215
216 back_forward_list = webkit_web_view_get_back_forward_list (web_view);
217 return hist_type == WEBKIT_HISTORY_FORWARD ?
218 g_list_reverse (webkit_back_forward_list_get_forward_list_with_limit (back_forward_list, limit)) :
219 webkit_back_forward_list_get_back_list_with_limit (back_forward_list, limit);
220 }
221
222 static GtkWidget *
build_dropdown_menu(EphyWindow * window,EphyNavigationHistoryDirection direction)223 build_dropdown_menu (EphyWindow *window,
224 EphyNavigationHistoryDirection direction)
225 {
226 GtkMenuShell *menu;
227 EphyEmbed *embed;
228 GList *list, *l;
229 WebKitWebView *web_view;
230
231 embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
232 g_assert (embed != NULL);
233
234 menu = GTK_MENU_SHELL (gtk_menu_new ());
235
236 web_view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (embed);
237
238 if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_BACK)
239 list = construct_webkit_history_list (web_view,
240 WEBKIT_HISTORY_BACKWARD, 10);
241 else
242 list = construct_webkit_history_list (web_view,
243 WEBKIT_HISTORY_FORWARD, 10);
244
245 for (l = list; l != NULL; l = l->next) {
246 GtkWidget *item;
247 WebKitBackForwardListItem *hitem;
248 const char *uri;
249 char *title;
250
251 hitem = (WebKitBackForwardListItem *)l->data;
252 uri = webkit_back_forward_list_item_get_uri (hitem);
253 title = g_strdup (webkit_back_forward_list_item_get_title (hitem));
254
255 if (title == NULL || g_strstrip (title)[0] == '\0')
256 item = new_history_menu_item (EPHY_WEB_VIEW (web_view), uri, uri);
257 else
258 item = new_history_menu_item (EPHY_WEB_VIEW (web_view), title, uri);
259
260 g_free (title);
261
262 g_object_set_data_full (G_OBJECT (item), HISTORY_ITEM_DATA_KEY,
263 g_object_ref (hitem), g_object_unref);
264
265 g_signal_connect (item, "button-release-event",
266 G_CALLBACK (navigation_menu_item_pressed_cb), window);
267
268 gtk_menu_shell_append (menu, item);
269 gtk_widget_show_all (item);
270 }
271
272 g_list_free (list);
273
274 return GTK_WIDGET (menu);
275 }
276
277 static void
popup_history_menu(GtkWidget * widget,EphyWindow * window,EphyNavigationHistoryDirection direction,GdkEventButton * event)278 popup_history_menu (GtkWidget *widget,
279 EphyWindow *window,
280 EphyNavigationHistoryDirection direction,
281 GdkEventButton *event)
282 {
283 GtkWidget *menu;
284
285 menu = build_dropdown_menu (window, direction);
286 gtk_menu_popup_at_widget (GTK_MENU (menu),
287 widget,
288 GDK_GRAVITY_SOUTH_WEST,
289 GDK_GRAVITY_NORTH_WEST,
290 (GdkEvent *)event);
291 }
292
293 static gboolean
menu_timeout_cb(PopupData * data)294 menu_timeout_cb (PopupData *data)
295 {
296 if (data != NULL && data->window)
297 popup_history_menu (data->button, data->window, data->direction, data->event);
298
299 return G_SOURCE_REMOVE;
300 }
301
302 static gboolean
navigation_button_press_event_cb(GtkButton * button,GdkEvent * event,gpointer user_data)303 navigation_button_press_event_cb (GtkButton *button,
304 GdkEvent *event,
305 gpointer user_data)
306 {
307 EphyActionBarStart *action_bar_start = EPHY_ACTION_BAR_START (user_data);
308 EphyNavigationHistoryDirection direction;
309 PopupData *data;
310 gboolean is_back = FALSE;
311
312 is_back = (GTK_WIDGET (button) == action_bar_start->navigation_back);
313
314 direction = is_back ? EPHY_NAVIGATION_HISTORY_DIRECTION_BACK
315 : EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD;
316
317 switch (((GdkEventButton *)event)->button) {
318 case GDK_BUTTON_SECONDARY:
319 popup_history_menu (GTK_WIDGET (button), EPHY_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (action_bar_start), EPHY_TYPE_WINDOW)),
320 direction, (GdkEventButton *)event);
321 return GDK_EVENT_STOP;
322 case GDK_BUTTON_MIDDLE:
323 /* If a desktop-wide middle-click titlebar action is enabled, we want to
324 * prevent that action from occurring because we handle middle click in
325 * navigation_button_release_event_cb().
326 */
327 return GDK_EVENT_STOP;
328 default:
329 break;
330 }
331
332 data = g_new (PopupData, 1);
333 data->button = GTK_WIDGET (button);
334 data->window = EPHY_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (action_bar_start), EPHY_TYPE_WINDOW));
335 data->direction = direction;
336 data->event = (GdkEventButton *)event;
337
338 action_bar_start->navigation_buttons_menu_timeout = g_timeout_add_full (G_PRIORITY_DEFAULT, 500,
339 (GSourceFunc)menu_timeout_cb,
340 data,
341 (GDestroyNotify)g_free);
342 g_source_set_name_by_id (action_bar_start->navigation_buttons_menu_timeout, "[epiphany] menu_timeout_cb");
343
344 return GDK_EVENT_PROPAGATE;
345 }
346
347 static gboolean
navigation_button_release_event_cb(GtkButton * button,GdkEvent * event,gpointer user_data)348 navigation_button_release_event_cb (GtkButton *button,
349 GdkEvent *event,
350 gpointer user_data)
351 {
352 EphyActionBarStart *action_bar_start = EPHY_ACTION_BAR_START (user_data);
353 GActionGroup *action_group;
354 GAction *action;
355 EphyNavigationHistoryDirection direction;
356 gboolean is_back = FALSE;
357 gboolean open_in_new_tab = FALSE;
358 gboolean open_in_current_tab = FALSE;
359 GdkEventType type = GDK_NOTHING;
360 guint state = 0, button_val = (guint) - 1, keyval = (guint) - 1;
361
362 ephy_gui_get_current_event (&type, &state, &button_val, &keyval);
363 is_back = (GTK_WIDGET (button) == action_bar_start->navigation_back);
364
365 g_clear_handle_id (&action_bar_start->navigation_buttons_menu_timeout, g_source_remove);
366
367 action_group = gtk_widget_get_action_group (gtk_widget_get_ancestor (GTK_WIDGET (action_bar_start), EPHY_TYPE_WINDOW), "toolbar");
368
369 direction = is_back ? EPHY_NAVIGATION_HISTORY_DIRECTION_BACK
370 : EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD;
371
372 open_in_new_tab = (((GdkEventButton *)event)->button == GDK_BUTTON_MIDDLE) || (state == GDK_CONTROL_MASK);
373 open_in_current_tab = ((GdkEventButton *)event)->button == GDK_BUTTON_PRIMARY;
374
375 if (open_in_new_tab) {
376 if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_BACK) {
377 action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
378 "navigation-back-new-tab");
379 g_action_activate (action, NULL);
380 } else if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD) {
381 action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
382 "navigation-forward-new-tab");
383 g_action_activate (action, NULL);
384 }
385
386 /* Don't propagate the event to avoid other middle-click actions. */
387 return GDK_EVENT_STOP;
388 }
389
390 if (open_in_current_tab) {
391 if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_BACK) {
392 action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
393 "navigation-back");
394 g_action_activate (action, NULL);
395 } else if (direction == EPHY_NAVIGATION_HISTORY_DIRECTION_FORWARD) {
396 action = g_action_map_lookup_action (G_ACTION_MAP (action_group),
397 "navigation-forward");
398 g_action_activate (action, NULL);
399 }
400
401 /* Propagate the event to allow the button to correctly reset its internal
402 * state. */
403 return GDK_EVENT_PROPAGATE;
404 }
405
406 /* Propagate other unhandled events. */
407 return GDK_EVENT_PROPAGATE;
408 }
409
410 static gboolean
homepage_button_release_event_cb(GtkButton * button,GdkEvent * event,gpointer user_data)411 homepage_button_release_event_cb (GtkButton *button,
412 GdkEvent *event,
413 gpointer user_data)
414 {
415 EphyActionBarStart *action_bar_start = EPHY_ACTION_BAR_START (user_data);
416 GActionGroup *action_group;
417 GAction *action;
418
419 action_group = gtk_widget_get_action_group (gtk_widget_get_ancestor (GTK_WIDGET (action_bar_start), EPHY_TYPE_WINDOW), "toolbar");
420
421 switch (((GdkEventButton *)event)->button) {
422 case GDK_BUTTON_MIDDLE:
423 action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "homepage-new-tab");
424 g_action_activate (action, NULL);
425 return GDK_EVENT_STOP;
426 default:
427 break;
428 }
429
430 return GDK_EVENT_PROPAGATE;
431 }
432
433 static gboolean
new_tab_button_release_event_cb(GtkButton * button,GdkEvent * event,gpointer user_data)434 new_tab_button_release_event_cb (GtkButton *button,
435 GdkEvent *event,
436 gpointer user_data)
437 {
438 EphyActionBarStart *action_bar_start = EPHY_ACTION_BAR_START (user_data);
439 GActionGroup *action_group;
440 GAction *action;
441
442 action_group = gtk_widget_get_action_group (gtk_widget_get_ancestor (GTK_WIDGET (action_bar_start), EPHY_TYPE_WINDOW), "toolbar");
443
444 switch (((GdkEventButton *)event)->button) {
445 case GDK_BUTTON_MIDDLE:
446 action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "new-tab-from-clipboard");
447 g_action_activate (action, NULL);
448 return GDK_EVENT_STOP;
449 default:
450 break;
451 }
452
453 return GDK_EVENT_PROPAGATE;
454 }
455
456 static gboolean
navigation_leave_notify_event_cb(GtkButton * button,GdkEvent * event,gpointer user_data)457 navigation_leave_notify_event_cb (GtkButton *button,
458 GdkEvent *event,
459 gpointer user_data)
460 {
461 EphyActionBarStart *action_bar_start = EPHY_ACTION_BAR_START (user_data);
462
463 g_clear_handle_id (&action_bar_start->navigation_buttons_menu_timeout, g_source_remove);
464
465 return GDK_EVENT_PROPAGATE;
466 }
467
468 static void
homepage_url_changed(GSettings * settings,const char * key,GtkWidget * button)469 homepage_url_changed (GSettings *settings,
470 const char *key,
471 GtkWidget *button)
472 {
473 char *setting;
474 gboolean show_button;
475
476 setting = g_settings_get_string (settings, key);
477 if (setting && setting[0])
478 show_button = g_strcmp0 (setting, "about:blank") != 0;
479 else
480 show_button = is_desktop_pantheon ();
481
482 gtk_widget_set_visible (button, show_button);
483 g_free (setting);
484 }
485
486 static void
ephy_action_bar_start_dispose(GObject * object)487 ephy_action_bar_start_dispose (GObject *object)
488 {
489 EphyActionBarStart *action_bar_start = EPHY_ACTION_BAR_START (object);
490
491 g_clear_handle_id (&action_bar_start->navigation_buttons_menu_timeout, g_source_remove);
492
493 G_OBJECT_CLASS (ephy_action_bar_start_parent_class)->dispose (object);
494 }
495
496 static void
update_new_tab_button_visibility(EphyActionBarStart * action_bar_start)497 update_new_tab_button_visibility (EphyActionBarStart *action_bar_start)
498 {
499 EphyEmbedShell *embed_shell;
500
501 embed_shell = ephy_embed_shell_get_default ();
502
503 gtk_widget_set_visible (action_bar_start->new_tab_button,
504 (ephy_embed_shell_get_mode (embed_shell) != EPHY_EMBED_SHELL_MODE_APPLICATION) &&
505 !is_desktop_pantheon ());
506 }
507
508 static void
ephy_action_bar_start_constructed(GObject * object)509 ephy_action_bar_start_constructed (GObject *object)
510 {
511 EphyActionBarStart *action_bar_start = EPHY_ACTION_BAR_START (object);
512 EphyEmbedShell *embed_shell;
513
514 G_OBJECT_CLASS (ephy_action_bar_start_parent_class)->constructed (object);
515
516 gtk_widget_init_template (GTK_WIDGET (action_bar_start));
517
518 /* Back */
519 g_signal_connect (action_bar_start->navigation_back, "button-press-event",
520 G_CALLBACK (navigation_button_press_event_cb), action_bar_start);
521 g_signal_connect (action_bar_start->navigation_back, "button-release-event",
522 G_CALLBACK (navigation_button_release_event_cb), action_bar_start);
523 g_signal_connect (action_bar_start->navigation_back, "leave-notify-event",
524 G_CALLBACK (navigation_leave_notify_event_cb), action_bar_start);
525
526 /* Forward */
527 g_signal_connect (action_bar_start->navigation_forward, "button-press-event",
528 G_CALLBACK (navigation_button_press_event_cb), action_bar_start);
529 g_signal_connect (action_bar_start->navigation_forward, "button-release-event",
530 G_CALLBACK (navigation_button_release_event_cb), action_bar_start);
531 g_signal_connect (action_bar_start->navigation_forward, "leave-notify-event",
532 G_CALLBACK (navigation_leave_notify_event_cb), action_bar_start);
533
534 /* Combined_stop_reload */
535 gtk_widget_set_tooltip_text (action_bar_start->combined_stop_reload_button, _(REFRESH_BUTTON_TOOLTIP));
536
537 /* Homepage */
538 embed_shell = ephy_embed_shell_get_default ();
539 if (ephy_embed_shell_get_mode (embed_shell) != EPHY_EMBED_SHELL_MODE_APPLICATION) {
540 homepage_url_changed (EPHY_SETTINGS_MAIN, EPHY_PREFS_HOMEPAGE_URL, action_bar_start->homepage_button);
541 g_signal_connect_object (EPHY_SETTINGS_MAIN,
542 "changed::" EPHY_PREFS_HOMEPAGE_URL,
543 G_CALLBACK (homepage_url_changed),
544 action_bar_start->homepage_button,
545 0);
546 } else {
547 gtk_widget_set_visible (action_bar_start->homepage_button, FALSE);
548 }
549 g_signal_connect (action_bar_start->homepage_button, "button-release-event",
550 G_CALLBACK (homepage_button_release_event_cb), action_bar_start);
551
552 /* New Tab Button */
553 update_new_tab_button_visibility (action_bar_start);
554
555 g_signal_connect (action_bar_start->new_tab_button, "button-release-event",
556 G_CALLBACK (new_tab_button_release_event_cb), action_bar_start);
557
558 if (is_desktop_pantheon ()) {
559 gtk_button_set_image (GTK_BUTTON (action_bar_start->navigation_back),
560 gtk_image_new_from_icon_name ("go-previous-symbolic",
561 get_icon_size ()));
562 gtk_button_set_image (GTK_BUTTON (action_bar_start->navigation_forward),
563 gtk_image_new_from_icon_name ("go-next-symbolic",
564 get_icon_size ()));
565 gtk_button_set_image (GTK_BUTTON (action_bar_start->homepage_button),
566 gtk_image_new_from_icon_name ("go-home-symbolic",
567 get_icon_size ()));
568 }
569
570 if (ephy_profile_dir_is_web_application ()) {
571 GtkWidget *navigation_box = ephy_action_bar_start_get_navigation_box (action_bar_start);
572
573 g_settings_bind (EPHY_SETTINGS_WEB_APP, EPHY_PREFS_WEB_APP_SHOW_NAVIGATION_BUTTONS, navigation_box, "visible", G_SETTINGS_BIND_GET | G_SETTINGS_BIND_INVERT_BOOLEAN);
574 }
575 }
576
577 static void
ephy_action_bar_start_class_init(EphyActionBarStartClass * klass)578 ephy_action_bar_start_class_init (EphyActionBarStartClass *klass)
579 {
580 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
581 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
582
583 gobject_class->dispose = ephy_action_bar_start_dispose;
584 gobject_class->constructed = ephy_action_bar_start_constructed;
585
586 gtk_widget_class_set_template_from_resource (widget_class,
587 "/org/gnome/epiphany/gtk/action-bar-start.ui");
588
589 gtk_widget_class_bind_template_child (widget_class,
590 EphyActionBarStart,
591 navigation_box);
592 gtk_widget_class_bind_template_child (widget_class,
593 EphyActionBarStart,
594 navigation_back);
595 gtk_widget_class_bind_template_child (widget_class,
596 EphyActionBarStart,
597 navigation_forward);
598 gtk_widget_class_bind_template_child (widget_class,
599 EphyActionBarStart,
600 combined_stop_reload_button);
601 gtk_widget_class_bind_template_child (widget_class,
602 EphyActionBarStart,
603 combined_stop_reload_image);
604 gtk_widget_class_bind_template_child (widget_class,
605 EphyActionBarStart,
606 homepage_button);
607 gtk_widget_class_bind_template_child (widget_class,
608 EphyActionBarStart,
609 new_tab_button);
610 gtk_widget_class_bind_template_child (widget_class,
611 EphyActionBarStart,
612 placeholder);
613 }
614
615 static void
ephy_action_bar_start_init(EphyActionBarStart * action_bar_start)616 ephy_action_bar_start_init (EphyActionBarStart *action_bar_start)
617 {
618 }
619
620 EphyActionBarStart *
ephy_action_bar_start_new(void)621 ephy_action_bar_start_new (void)
622 {
623 return g_object_new (EPHY_TYPE_ACTION_BAR_START,
624 NULL);
625 }
626
627 GtkWidget *
ephy_action_bar_start_get_navigation_box(EphyActionBarStart * action_bar_start)628 ephy_action_bar_start_get_navigation_box (EphyActionBarStart *action_bar_start)
629 {
630 return action_bar_start->navigation_box;
631 }
632
633 void
ephy_action_bar_start_change_combined_stop_reload_state(EphyActionBarStart * action_bar_start,gboolean loading)634 ephy_action_bar_start_change_combined_stop_reload_state (EphyActionBarStart *action_bar_start,
635 gboolean loading)
636 {
637 if (loading) {
638 gtk_image_set_from_icon_name (GTK_IMAGE (action_bar_start->combined_stop_reload_image),
639 "process-stop-symbolic",
640 get_icon_size ());
641 /* Translators: tooltip for the stop button */
642 gtk_widget_set_tooltip_text (action_bar_start->combined_stop_reload_button,
643 _("Stop loading the current page"));
644 } else {
645 gtk_image_set_from_icon_name (GTK_IMAGE (action_bar_start->combined_stop_reload_image),
646 "view-refresh-symbolic",
647 get_icon_size ());
648 gtk_widget_set_tooltip_text (action_bar_start->combined_stop_reload_button,
649 _(REFRESH_BUTTON_TOOLTIP));
650 }
651 }
652
653 GtkWidget *
ephy_action_bar_start_get_placeholder(EphyActionBarStart * action_bar_start)654 ephy_action_bar_start_get_placeholder (EphyActionBarStart *action_bar_start)
655 {
656 return action_bar_start->placeholder;
657 }
658
659 void
ephy_action_bar_start_set_adaptive_mode(EphyActionBarStart * action_bar,EphyAdaptiveMode adaptive_mode)660 ephy_action_bar_start_set_adaptive_mode (EphyActionBarStart *action_bar,
661 EphyAdaptiveMode adaptive_mode)
662 {
663 GValue val = G_VALUE_INIT;
664
665 g_value_init (&val, G_TYPE_INT);
666
667 gtk_widget_set_visible (action_bar->new_tab_button, adaptive_mode == EPHY_ADAPTIVE_MODE_NORMAL);
668 gtk_widget_set_visible (action_bar->combined_stop_reload_button, adaptive_mode == EPHY_ADAPTIVE_MODE_NORMAL);
669
670 if (adaptive_mode == EPHY_ADAPTIVE_MODE_NARROW)
671 g_value_set_int (&val, 42);
672 else
673 g_value_set_int (&val, -1);
674
675 g_object_set_property (G_OBJECT (action_bar->navigation_back), "width-request", &val);
676 g_object_set_property (G_OBJECT (action_bar->navigation_forward), "width-request", &val);
677
678 g_value_unset (&val);
679 }
680