/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Copyright © 2012 Igalia S.L.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "config.h"
#include "ephy-toolbar.h"
#include "ephy-location-entry.h"
#include "ephy-middle-clickable-button.h"
#include "ephy-private.h"
G_DEFINE_TYPE (EphyToolbar, ephy_toolbar, GTK_TYPE_BOX)
#define EPHY_TOOLBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EPHY_TYPE_TOOLBAR, EphyToolbarPrivate))
enum {
PROP_0,
PROP_WINDOW,
N_PROPERTIES
};
static GParamSpec *object_properties[N_PROPERTIES] = { NULL, };
struct _EphyToolbarPrivate {
EphyWindow *window;
GtkWidget *entry;
};
static void
ephy_toolbar_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
EphyToolbarPrivate *priv = EPHY_TOOLBAR (object)->priv;
switch (property_id) {
case PROP_WINDOW:
priv->window = EPHY_WINDOW (g_value_get_object (value));
g_object_notify_by_pspec (object, object_properties[PROP_WINDOW]);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
ephy_toolbar_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
EphyToolbarPrivate *priv = EPHY_TOOLBAR (object)->priv;
switch (property_id) {
case PROP_WINDOW:
g_value_set_object (value, priv->window);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
static void
close_button_clicked (GtkButton *button, gpointer data)
{
GtkWidget *toplevel;
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
gtk_window_close (GTK_WINDOW (toplevel));
}
static void
ephy_toolbar_constructed (GObject *object)
{
EphyToolbarPrivate *priv = EPHY_TOOLBAR (object)->priv;
GtkActionGroup *action_group;
GtkAction *action;
GtkWidget *toolbar, *box, *button, *reload, *separator, *label;
GtkStyleContext *context;
GtkSizeGroup *size;
EphyEmbedShellMode mode;
G_OBJECT_CLASS (ephy_toolbar_parent_class)->constructed (object);
toolbar = GTK_WIDGET (object);
mode = ephy_embed_shell_get_mode (ephy_embed_shell_get_default ());
/* Back and Forward */
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
/* Back */
button = ephy_middle_clickable_button_new ();
/* FIXME: apparently we need an image inside the button for the action
* icon to appear. */
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new ());
action_group = ephy_window_get_toolbar_action_group (priv->window);
action = gtk_action_group_get_action (action_group, "NavigationBack");
gtk_activatable_set_related_action (GTK_ACTIVATABLE (button),
action);
gtk_button_set_label (GTK_BUTTON (button), NULL);
gtk_container_add (GTK_CONTAINER (box), button);
/* Forward */
button = ephy_middle_clickable_button_new ();
/* FIXME: apparently we need an image inside the button for the action
* icon to appear. */
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new ());
action = gtk_action_group_get_action (action_group, "NavigationForward");
gtk_activatable_set_related_action (GTK_ACTIVATABLE (button),
action);
gtk_button_set_label (GTK_BUTTON (button), NULL);
gtk_container_add (GTK_CONTAINER (box), button);
gtk_style_context_add_class (gtk_widget_get_style_context (box),
"raised");
gtk_style_context_add_class (gtk_widget_get_style_context (box),
"linked");
gtk_container_add (GTK_CONTAINER (toolbar), box);
gtk_widget_show_all (box);
if (gtk_widget_get_direction (box) == GTK_TEXT_DIR_RTL)
gtk_widget_set_margin_left (box, 27);
else
gtk_widget_set_margin_right (box, 27);
/* Location and Reload/Stop */
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_size_request (box, 530, -1);
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
/* Location */
priv->entry = ephy_location_entry_new ();
gtk_box_pack_start (GTK_BOX (box), priv->entry, TRUE, TRUE, 0);
gtk_style_context_add_class (gtk_widget_get_style_context (box),
"location-entry");
/* Reload/Stop */
reload = gtk_button_new ();
/* FIXME: apparently we need an image inside the button for the action
* icon to appear. */
gtk_button_set_image (GTK_BUTTON (reload), gtk_image_new ());
gtk_widget_set_valign (reload, GTK_ALIGN_CENTER);
action = gtk_action_group_get_action (action_group, "ViewCombinedStopReload");
gtk_activatable_set_related_action (GTK_ACTIVATABLE (reload),
action);
if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION)
{
gtk_container_add (GTK_CONTAINER (box), reload);
/* Create a GtkSizeGroup to sync the height of the location entry, and
* the stop/reload button. */
size = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
gtk_size_group_add_widget (size, reload);
gtk_size_group_add_widget (size, priv->entry);
g_object_unref (size);
}
gtk_box_pack_start (GTK_BOX (toolbar), box, TRUE, TRUE, 0);
if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION)
gtk_widget_show_all (box);
if (gtk_widget_get_direction (box) == GTK_TEXT_DIR_RTL)
gtk_widget_set_margin_left (box, 12);
else
gtk_widget_set_margin_right (box, 12);
/* New Tab */
button = gtk_button_new ();
/* FIXME: apparently we need an image inside the button for the action
* icon to appear. */
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new ());
action = gtk_action_group_get_action (action_group, "FileNewTab");
gtk_activatable_set_related_action (GTK_ACTIVATABLE (button),
action);
gtk_button_set_label (GTK_BUTTON (button), NULL);
gtk_container_add (GTK_CONTAINER (toolbar), button);
if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION)
gtk_widget_show_all (button);
if (gtk_widget_get_direction (button) == GTK_TEXT_DIR_RTL)
gtk_widget_set_margin_left (button, 6);
else
gtk_widget_set_margin_right (button, 6);
if (gtk_widget_get_direction (button) == GTK_TEXT_DIR_RTL)
gtk_widget_set_margin_right (button, 15);
else
gtk_widget_set_margin_left (button, 15);
/* Page Menu */
button = gtk_button_new ();
gtk_widget_set_name (button, "ephy-page-menu-button");
/* FIXME: apparently we need an image inside the button for the action
* icon to appear. */
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new ());
action = gtk_action_group_get_action (action_group, "PageMenu");
gtk_activatable_set_related_action (GTK_ACTIVATABLE (button),
action);
gtk_container_add (GTK_CONTAINER (toolbar), button);
gtk_widget_show_all (button);
/* Add title only in application mode. */
if (mode == EPHY_EMBED_SHELL_MODE_APPLICATION)
{
/* The title of the window in web application - need
* settings of padding same the location entry. */
label = gtk_label_new (NULL);
context = gtk_widget_get_style_context (label);
gtk_style_context_add_class (context, "title");
gtk_style_context_add_class (context, "dim-label");
gtk_label_set_line_wrap (GTK_LABEL (label), FALSE);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_widget_set_size_request (label, 530, -1);
gtk_box_pack_start (GTK_BOX (toolbar), label, TRUE, TRUE, 0);
gtk_widget_show_all (label);
if (gtk_widget_get_direction (GTK_WIDGET (label)) == GTK_TEXT_DIR_RTL)
gtk_widget_set_margin_left (GTK_WIDGET (label), 12);
else
gtk_widget_set_margin_right (GTK_WIDGET (label), 12);
g_object_bind_property (label, "label",
priv->window, "title",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
/* Reload/Stop for web application. */
gtk_container_add (GTK_CONTAINER (toolbar), reload);
}
/* Separator and Close */
separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
gtk_container_add (GTK_CONTAINER (toolbar), separator);
gtk_widget_show_all (separator);
if (gtk_widget_get_direction (GTK_WIDGET (separator)) == GTK_TEXT_DIR_RTL)
gtk_widget_set_margin_right (GTK_WIDGET (separator), 6);
else
gtk_widget_set_margin_left (GTK_WIDGET (separator), 6);
button = gtk_button_new_from_icon_name ("window-close-symbolic",
GTK_ICON_SIZE_MENU);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
g_signal_connect (button, "clicked",
G_CALLBACK (close_button_clicked), NULL);
gtk_container_add (GTK_CONTAINER (toolbar), button);
gtk_widget_show_all (button);
if (gtk_widget_get_direction (button) == GTK_TEXT_DIR_RTL)
gtk_widget_set_margin_right (button, 6);
else
gtk_widget_set_margin_left (button, 6);
}
static void
ephy_toolbar_class_init (EphyToolbarClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = ephy_toolbar_set_property;
gobject_class->get_property = ephy_toolbar_get_property;
gobject_class->constructed = ephy_toolbar_constructed;
object_properties[PROP_WINDOW] =
g_param_spec_object ("window",
"Window",
"The toolbar's EphyWindow",
EPHY_TYPE_WINDOW,
G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (gobject_class,
N_PROPERTIES,
object_properties);
g_type_class_add_private (klass, sizeof (EphyToolbarPrivate));
}
static void
ephy_toolbar_init (EphyToolbar *toolbar)
{
toolbar->priv = EPHY_TOOLBAR_GET_PRIVATE (toolbar);
}
GtkWidget*
ephy_toolbar_new (EphyWindow *window)
{
g_return_val_if_fail (EPHY_IS_WINDOW (window), NULL);
return GTK_WIDGET (g_object_new (EPHY_TYPE_TOOLBAR,
"window", window,
NULL));
}
GtkWidget *
ephy_toolbar_get_location_entry (EphyToolbar *toolbar)
{
return toolbar->priv->entry;
}