Major changes

Drop the explicit page and column classes and markup, and create
the necessary structures on the fly. Also drop the custom markup
and just use standard GtkBuilder markup for everything.
This commit is contained in:
Matthias Clasen
2015-10-14 01:15:04 -04:00
parent 337f4e8f95
commit d99f2be837
12 changed files with 967 additions and 1030 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -506,12 +506,10 @@ gtk_private_h_sources = \
gtkselectionprivate.h \
gtksidebarrowprivate.h \
gtksettingsprivate.h \
gtkshortcutscolumnprivate.h \
gtkshortcutsgestureprivate.h \
gtkshortcutsgrouprivate.h \
gtkshortcutlabelprivate.h \
gtkshortcutsshortcutprivate.h \
gtkshortcutspageprivate.h \
gtkshortcutssectionprivate.h \
gtksizegroup-private.h \
gtksizerequestcacheprivate.h \
@@ -813,11 +811,9 @@ gtk_base_c_sources = \
gtkseparatormenuitem.c \
gtkseparatortoolitem.c \
gtksettings.c \
gtkshortcutscolumn.c \
gtkshortcutsgesture.c \
gtkshortcutsgroup.c \
gtkshortcutlabel.c \
gtkshortcutspage.c \
gtkshortcutsshortcut.c \
gtkshortcutssection.c \
gtkshortcutswindow.c \

View File

@@ -1,47 +0,0 @@
/* gtkshortcutscolumn.c
*
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkshortcutscolumnprivate.h"
#include "gtkorientable.h"
struct _GtkShortcutsColumn
{
GtkBox parent_instance;
};
struct _GtkShortcutsColumnClass
{
GtkBoxClass parent_class;
};
G_DEFINE_TYPE (GtkShortcutsColumn, gtk_shortcuts_column, GTK_TYPE_BOX)
static void
gtk_shortcuts_column_class_init (GtkShortcutsColumnClass *klass)
{
}
static void
gtk_shortcuts_column_init (GtkShortcutsColumn *self)
{
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
gtk_box_set_spacing (GTK_BOX (self), 22);
}

View File

@@ -1,42 +0,0 @@
/* gtkshortcutscolumnprivate.h
*
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_SHORTCUTS_COLUMN_H__
#define __GTK_SHORTCUTS_COLUMN_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_SHORTCUTS_COLUMN (gtk_shortcuts_column_get_type ())
#define GTK_SHORTCUTS_COLUMN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_COLUMN, GtkShortcutsColumn))
#define GTK_SHORTCUTS_COLUMN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUTS_COLUMN, GtkShortcutsColumnClass))
#define GTK_IS_COLUMNS_COLUMN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_COLUMN))
#define GTK_IS_COLUMNS_COLUMN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUTS_COLUMN))
#define GTK_SHORTCUTS_COLUMN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUTS_COLUMN, GtkShortcutsColumnClass))
typedef struct _GtkShortcutsColumn GtkShortcutsColumn;
typedef struct _GtkShortcutsColumnClass GtkShortcutsColumnClass;
GType gtk_shortcuts_column_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GTK_SHORTCUTS_COLUMN_H__ */

View File

@@ -35,6 +35,9 @@ struct _GtkShortcutsGesture
GtkLabel *title;
GtkLabel *subtitle;
GtkBox *desc_box;
GtkSizeGroup *desc_size_group;
GtkSizeGroup *icon_size_group;
};
struct _GtkShortcutsGestureClass
@@ -47,7 +50,7 @@ G_DEFINE_TYPE (GtkShortcutsGesture, gtk_shortcuts_gesture, GTK_TYPE_BOX)
enum {
PROP_0,
PROP_DESC_SIZE_GROUP,
PROP_GICON,
PROP_ICON,
PROP_ICON_SIZE_GROUP,
PROP_SUBTITLE,
PROP_TITLE,
@@ -57,8 +60,32 @@ enum {
static GParamSpec *properties[LAST_PROP];
static void
gtk_shortcuts_gesture_set_gicon (GtkShortcutsGesture *self,
GIcon *gicon)
gtk_shortcuts_gesture_set_desc_size_group (GtkShortcutsGesture *self,
GtkSizeGroup *group)
{
if (self->desc_size_group)
gtk_size_group_remove_widget (self->desc_size_group, GTK_WIDGET (self->desc_box));
if (group)
gtk_size_group_add_widget (group, GTK_WIDGET (self->desc_box));
g_set_object (&self->desc_size_group, group);
}
static void
gtk_shortcuts_gesture_set_icon_size_group (GtkShortcutsGesture *self,
GtkSizeGroup *group)
{
if (self->icon_size_group)
gtk_size_group_remove_widget (self->icon_size_group, GTK_WIDGET (self->image));
if (group)
gtk_size_group_add_widget (group, GTK_WIDGET (self->image));
g_set_object (&self->icon_size_group, group);
}
static void
gtk_shortcuts_gesture_set_icon (GtkShortcutsGesture *self,
GIcon *gicon)
{
gtk_image_set_from_gicon (self->image, gicon, GTK_ICON_SIZE_DIALOG);
}
@@ -81,6 +108,15 @@ gtk_shortcuts_gesture_get_property (GObject *object,
g_value_set_string (value, gtk_label_get_label (self->title));
break;
case PROP_ICON:
{
GIcon *icon;
gtk_image_get_gicon (self->image, &icon, NULL);
g_value_set_object (value, icon);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -97,26 +133,16 @@ gtk_shortcuts_gesture_set_property (GObject *object,
switch (prop_id)
{
case PROP_DESC_SIZE_GROUP:
{
GtkSizeGroup *group = g_value_get_object (value);
gtk_shortcuts_gesture_set_desc_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
break;
if (group != NULL)
gtk_size_group_add_widget (group, GTK_WIDGET (self->desc_box));
break;
}
case PROP_GICON:
gtk_shortcuts_gesture_set_gicon (self, g_value_get_object (value));
case PROP_ICON:
gtk_shortcuts_gesture_set_icon (self, g_value_get_object (value));
break;
case PROP_ICON_SIZE_GROUP:
{
GtkSizeGroup *group = g_value_get_object (value);
if (group != NULL)
gtk_size_group_add_widget (group, GTK_WIDGET (self->image));
break;
}
gtk_shortcuts_gesture_set_icon_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
break;
case PROP_SUBTITLE:
gtk_label_set_label (self->subtitle, g_value_get_string (value));
@@ -131,11 +157,23 @@ gtk_shortcuts_gesture_set_property (GObject *object,
}
}
static void
gtk_shortcuts_gesture_finalize (GObject *object)
{
GtkShortcutsGesture *self = GTK_SHORTCUTS_GESTURE (object);
g_clear_object (&self->desc_size_group);
g_clear_object (&self->icon_size_group);
G_OBJECT_CLASS (gtk_shortcuts_gesture_parent_class)->finalize (object);
}
static void
gtk_shortcuts_gesture_class_init (GtkShortcutsGestureClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gtk_shortcuts_gesture_finalize;
object_class->get_property = gtk_shortcuts_gesture_get_property;
object_class->set_property = gtk_shortcuts_gesture_set_property;
@@ -146,12 +184,12 @@ gtk_shortcuts_gesture_class_init (GtkShortcutsGestureClass *klass)
GTK_TYPE_SIZE_GROUP,
(G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_GICON] =
g_param_spec_object ("gicon",
P_("GIcon"),
P_("GIcon"),
properties[PROP_ICON] =
g_param_spec_object ("icon",
P_("Icon"),
P_("Icon"),
G_TYPE_ICON,
(G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_ICON_SIZE_GROUP] =
g_param_spec_object ("icon-size-group",

View File

@@ -20,8 +20,11 @@
#include "gtkshortcutsgroupprivate.h"
#include "gtkshortcutsshortcutprivate.h"
#include "gtkshortcutsgestureprivate.h"
#include "gtklabel.h"
#include "gtkorientable.h"
#include "gtksizegroup.h"
#include "gtkprivate.h"
#include "gtkintl.h"
@@ -30,7 +33,8 @@ struct _GtkShortcutsGroup
GtkBox parent_instance;
GtkLabel *title;
gchar *view;
gchar *view;
guint height;
};
struct _GtkShortcutsGroupClass
@@ -44,11 +48,69 @@ enum {
PROP_0,
PROP_TITLE,
PROP_VIEW,
PROP_ACCEL_SIZE_GROUP,
PROP_TITLE_SIZE_GROUP,
PROP_HEIGHT,
LAST_PROP
};
static GParamSpec *properties[LAST_PROP];
static void
gtk_shortcuts_group_set_accel_size_group (GtkShortcutsGroup *group,
GtkSizeGroup *size_group)
{
GList *children, *l;
children = gtk_container_get_children (GTK_CONTAINER (group));
for (l = children; l; l = l->next)
{
if (GTK_IS_SHORTCUTS_SHORTCUT (l->data))
g_object_set (l->data, "accel-size-group", size_group, NULL);
else if (GTK_IS_SHORTCUTS_GESTURE (l->data))
g_object_set (l->data, "icon-size-group", size_group, NULL);
}
g_list_free (children);
}
static void
gtk_shortcuts_group_set_title_size_group (GtkShortcutsGroup *group,
GtkSizeGroup *size_group)
{
GList *children, *l;
children = gtk_container_get_children (GTK_CONTAINER (group));
for (l = children; l; l = l->next)
{
if (GTK_IS_SHORTCUTS_SHORTCUT (l->data))
g_object_set (l->data, "title-size-group", size_group, NULL);
else if (GTK_IS_SHORTCUTS_GESTURE (l->data))
g_object_set (l->data, "desc-size-group", size_group, NULL);
}
g_list_free (children);
}
static guint
gtk_shortcuts_group_get_height (GtkShortcutsGroup *group)
{
GList *children, *l;
guint height;
height = 1;
children = gtk_container_get_children (GTK_CONTAINER (group));
for (l = children; l; l = l->next)
{
if (GTK_IS_SHORTCUTS_SHORTCUT (l->data))
height += 1;
else if (GTK_IS_SHORTCUTS_GESTURE (l->data))
height += 2;
}
g_list_free (children);
return height;
}
static void
gtk_shortcuts_group_get_property (GObject *object,
guint prop_id,
@@ -67,6 +129,10 @@ gtk_shortcuts_group_get_property (GObject *object,
g_value_set_string (value, self->view);
break;
case PROP_HEIGHT:
g_value_set_uint (value, gtk_shortcuts_group_get_height (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -91,6 +157,14 @@ gtk_shortcuts_group_set_property (GObject *object,
self->view = g_value_dup_string (value);
break;
case PROP_ACCEL_SIZE_GROUP:
gtk_shortcuts_group_set_accel_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
break;
case PROP_TITLE_SIZE_GROUP:
gtk_shortcuts_group_set_title_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -124,6 +198,25 @@ gtk_shortcuts_group_class_init (GtkShortcutsGroupClass *klass)
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_ACCEL_SIZE_GROUP] =
g_param_spec_object ("accel-size-group",
P_("Accelerator Size Group"),
P_("Accelerator Size Group"),
GTK_TYPE_SIZE_GROUP,
(G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_TITLE_SIZE_GROUP] =
g_param_spec_object ("title-size-group",
P_("Title Size Group"),
P_("Title Size Group"),
GTK_TYPE_SIZE_GROUP,
(G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
properties[PROP_HEIGHT] =
g_param_spec_uint ("height", P_("Height"), P_("Height"),
0, G_MAXUINT, 0,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, LAST_PROP, properties);
}

View File

@@ -1,47 +0,0 @@
/* gtkshortcutspage.c
*
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkshortcutspageprivate.h"
#include "gtkorientable.h"
struct _GtkShortcutsPage
{
GtkBox parent_instance;
};
struct _GtkShortcutsPageClass
{
GtkBoxClass parent_class;
};
G_DEFINE_TYPE (GtkShortcutsPage, gtk_shortcuts_page, GTK_TYPE_BOX)
static void
gtk_shortcuts_page_class_init (GtkShortcutsPageClass *klass)
{
}
static void
gtk_shortcuts_page_init (GtkShortcutsPage *self)
{
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL);
gtk_box_set_spacing (GTK_BOX (self), 22);
}

View File

@@ -1,42 +0,0 @@
/* gtkshortcutspageprivate.h
*
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_SHORTCUTS_PAGE_H__
#define __GTK_SHORTCUTS_PAGE_H__
#include <gtk/gtkbox.h>
G_BEGIN_DECLS
#define GTK_TYPE_SHORTCUTS_PAGE (gtk_shortcuts_page_get_type ())
#define GTK_SHORTCUTS_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_PAGE, GtkShortcutsPage))
#define GTK_SHORTCUTS_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUTS_PAGE, GtkShortcutsPageClass))
#define GTK_IS_SHORTCUTS_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_PAGE))
#define GTK_IS_SHORTCUTS_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUTS_PAGE))
#define GTK_SHORTCUTS_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUTS_PAGE, GtkShortcutsPageClass))
typedef struct _GtkShortcutsPage GtkShortcutsPage;
typedef struct _GtkShortcutsPageClass GtkShortcutsPageClass;
GType gtk_shortcuts_page_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GTK_SHORTCUTS_PAGE_H__ */

View File

@@ -20,13 +20,13 @@
#include "gtkshortcutssectionprivate.h"
#include "gtkshortcutspageprivate.h"
#include "gtkshortcutsgroupprivate.h"
#include "gtktogglebutton.h"
#include "gtkstack.h"
#include "gtkstackswitcher.h"
#include "gtkstylecontext.h"
#include "gtkorientable.h"
#include "gtksizegroup.h"
#include "gtkprivate.h"
#include "gtkintl.h"
@@ -37,6 +37,7 @@ struct _GtkShortcutsSection
gchar *name;
gchar *title;
gchar *view_name;
guint max_height;
GtkStack *stack;
GtkStackSwitcher *switcher;
@@ -44,6 +45,11 @@ struct _GtkShortcutsSection
gboolean has_filtered_group;
guint last_page_num;
GtkWidget *current_page;
GtkWidget *current_column;
guint n_columns;
guint n_rows;
};
struct _GtkShortcutsSectionClass
@@ -58,6 +64,7 @@ enum {
PROP_TITLE,
PROP_SECTION_NAME,
PROP_VIEW_NAME,
PROP_MAX_HEIGHT,
LAST_PROP
};
@@ -85,26 +92,10 @@ gtk_shortcuts_section_add (GtkContainer *container,
{
GtkShortcutsSection *self = (GtkShortcutsSection *)container;
if (GTK_IS_SHORTCUTS_PAGE (child))
{
gchar *title = NULL;
guint count = 0;
title = g_strdup_printf ("%u", ++self->last_page_num);
gtk_container_add_with_properties (GTK_CONTAINER (self->stack), child,
"title", title,
NULL);
gtk_container_foreach (GTK_CONTAINER (self->switcher), adjust_page_buttons, &count);
gtk_widget_set_visible (GTK_WIDGET (self->switcher), (count > 1));
if (count > 1)
gtk_widget_show (gtk_widget_get_parent (GTK_WIDGET (self->switcher)));
g_free (title);
}
if (GTK_IS_SHORTCUTS_GROUP (child))
gtk_shortcuts_section_add_group (self, GTK_SHORTCUTS_GROUP (child));
else
{
GTK_CONTAINER_CLASS (gtk_shortcuts_section_parent_class)->add (container, child);
}
GTK_CONTAINER_CLASS (gtk_shortcuts_section_parent_class)->add (container, child);
}
static void
@@ -140,6 +131,10 @@ gtk_shortcuts_section_get_property (GObject *object,
g_value_set_string (value, self->title);
break;
case PROP_MAX_HEIGHT:
g_value_set_uint (value, self->max_height);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -169,6 +164,10 @@ gtk_shortcuts_section_set_property (GObject *object,
self->title = g_value_dup_string (value);
break;
case PROP_MAX_HEIGHT:
self->max_height = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -201,6 +200,11 @@ gtk_shortcuts_section_class_init (GtkShortcutsSectionClass *klass)
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_MAX_HEIGHT] =
g_param_spec_uint ("max-height", P_("Maximum Height"), P_("Maximum Height"),
0, G_MAXUINT, 15,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, LAST_PROP, properties);
}
@@ -245,6 +249,8 @@ gtk_shortcuts_section_init (GtkShortcutsSection *self)
{
GtkWidget *box;
self->max_height = 15;
gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
gtk_box_set_homogeneous (GTK_BOX (self), FALSE);
gtk_box_set_spacing (GTK_BOX (self), 22);
@@ -309,3 +315,61 @@ gtk_shortcuts_section_set_view_name (GtkShortcutsSection *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VIEW_NAME]);
}
void
gtk_shortcuts_section_add_group (GtkShortcutsSection *self,
GtkShortcutsGroup *group)
{
guint height;
g_return_if_fail (GTK_IS_SHORTCUTS_SECTION (self));
g_return_if_fail (GTK_IS_SHORTCUTS_GROUP (group));
g_object_get (group, "height", &height, NULL);
if (self->n_rows == 0 || self->n_rows + height > self->max_height)
{
GtkWidget *column;
column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22);
gtk_widget_show (column);
g_object_set_data_full (G_OBJECT (column), "accel-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
g_object_set_data_full (G_OBJECT (column), "title-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref);
if (self->n_columns % 2 == 0)
{
GtkWidget *page;
gchar *title = NULL;
guint count = 0;
page = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 22);
gtk_widget_show (page);
title = g_strdup_printf ("%u", ++self->last_page_num);
gtk_container_add_with_properties (GTK_CONTAINER (self->stack), page,
"title", title,
NULL);
gtk_container_foreach (GTK_CONTAINER (self->switcher), adjust_page_buttons, &count);
gtk_widget_set_visible (GTK_WIDGET (self->switcher), (count > 1));
if (count > 1)
gtk_widget_show (gtk_widget_get_parent (GTK_WIDGET (self->switcher)));
g_free (title);
self->current_page = page;
}
gtk_container_add (GTK_CONTAINER (self->current_page), column);
self->current_column = column;
self->n_columns += 1;
self->n_rows = 0;
}
self->n_rows += height;
g_object_set (group, "accel-size-group", g_object_get_data (G_OBJECT (self->current_column), "accel-size-group"), NULL);
g_object_set (group, "title-size-group", g_object_get_data (G_OBJECT (self->current_column), "title-size-group"), NULL);
gtk_container_add (GTK_CONTAINER (self->current_column), GTK_WIDGET (group));
}

View File

@@ -20,6 +20,7 @@
#define __GTK_SHORTCUTS_SECTION_H__
#include <gtk/gtkbox.h>
#include <gtk/gtkshortcutsgroupprivate.h>
G_BEGIN_DECLS
@@ -41,6 +42,8 @@ const gchar *gtk_shortcuts_section_get_section_name (GtkShortcutsSection *self);
const gchar *gtk_shortcuts_section_get_title (GtkShortcutsSection *self);
void gtk_shortcuts_section_set_view_name (GtkShortcutsSection *self,
const gchar *view_name);
void gtk_shortcuts_section_add_group (GtkShortcutsSection *self,
GtkShortcutsGroup *group);
G_END_DECLS

View File

@@ -31,6 +31,9 @@ struct _GtkShortcutsShortcut
GtkShortcutLabel *accelerator;
GtkLabel *title;
GtkSizeGroup *accel_size_group;
GtkSizeGroup *title_size_group;
};
struct _GtkShortcutsShortcutClass
@@ -43,7 +46,7 @@ G_DEFINE_TYPE (GtkShortcutsShortcut, gtk_shortcuts_shortcut, GTK_TYPE_BOX)
enum {
PROP_0,
PROP_ACCELERATOR,
PROP_ACCELERATOR_SIZE_GROUP,
PROP_ACCEL_SIZE_GROUP,
PROP_TITLE,
PROP_TITLE_SIZE_GROUP,
LAST_PROP
@@ -51,6 +54,30 @@ enum {
static GParamSpec *properties[LAST_PROP];
static void
gtk_shortcuts_shortcut_set_accel_size_group (GtkShortcutsShortcut *self,
GtkSizeGroup *group)
{
if (self->accel_size_group)
gtk_size_group_remove_widget (self->accel_size_group, GTK_WIDGET (self->accelerator));
if (group)
gtk_size_group_add_widget (group, GTK_WIDGET (self->accelerator));
g_set_object (&self->accel_size_group, group);
}
static void
gtk_shortcuts_shortcut_set_title_size_group (GtkShortcutsShortcut *self,
GtkSizeGroup *group)
{
if (self->title_size_group)
gtk_size_group_remove_widget (self->title_size_group, GTK_WIDGET (self->accelerator));
if (group)
gtk_size_group_add_widget (group, GTK_WIDGET (self->title));
g_set_object (&self->title_size_group, group);
}
static void
gtk_shortcuts_shortcut_get_property (GObject *object,
guint prop_id,
@@ -88,38 +115,41 @@ gtk_shortcuts_shortcut_set_property (GObject *object,
gtk_shortcut_label_set_accelerator (self->accelerator, g_value_get_string (value));
break;
case PROP_ACCELERATOR_SIZE_GROUP:
{
GtkSizeGroup *group = g_value_get_object (value);
if (group != NULL)
gtk_size_group_add_widget (group, GTK_WIDGET (self->accelerator));
break;
}
case PROP_ACCEL_SIZE_GROUP:
gtk_shortcuts_shortcut_set_accel_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
break;
case PROP_TITLE:
gtk_label_set_label (self->title, g_value_get_string (value));
break;
case PROP_TITLE_SIZE_GROUP:
{
GtkSizeGroup *group = g_value_get_object (value);
if (group != NULL)
gtk_size_group_add_widget (group, GTK_WIDGET (self->title));
break;
}
gtk_shortcuts_shortcut_set_title_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shortcuts_shortcut_finalize (GObject *object)
{
GtkShortcutsShortcut *self = GTK_SHORTCUTS_SHORTCUT (object);
g_clear_object (&self->accel_size_group);
g_clear_object (&self->title_size_group);
G_OBJECT_CLASS (gtk_shortcuts_shortcut_parent_class)->finalize (object);
}
static void
gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gtk_shortcuts_shortcut_finalize;
object_class->get_property = gtk_shortcuts_shortcut_get_property;
object_class->set_property = gtk_shortcuts_shortcut_set_property;
@@ -130,8 +160,8 @@ gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass)
NULL,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
properties[PROP_ACCELERATOR_SIZE_GROUP] =
g_param_spec_object ("accelerator-size-group",
properties[PROP_ACCEL_SIZE_GROUP] =
g_param_spec_object ("accel-size-group",
P_("Accelerator Size Group"),
P_("Accelerator Size Group"),
GTK_TYPE_SIZE_GROUP,

View File

@@ -20,10 +20,8 @@
#include "gtkshortcutswindow.h"
#include "gtkscrolledwindow.h"
#include "gtkshortcutscolumnprivate.h"
#include "gtkshortcutsgestureprivate.h"
#include "gtkshortcutsgroupprivate.h"
#include "gtkshortcutspageprivate.h"
#include "gtkshortcutsshortcutprivate.h"
#include "gtkshortcutssectionprivate.h"
#include "gtkprivate.h"
@@ -69,18 +67,13 @@ typedef struct
GtkShortcutsWindow *self;
GtkBuilder *builder;
GQueue *stack;
GtkWidget *search_item;
GQueue *column_image_size_groups;
GQueue *column_desc_size_groups;
gchar *property_name;
guint translatable : 1;
} ViewsParserData;
static void gtk_buildable_iface_init (GtkBuildableIface *iface);
G_DEFINE_TYPE_EXTENDED (GtkShortcutsWindow, gtk_shortcuts_window, GTK_TYPE_WINDOW, 0,
G_ADD_PRIVATE (GtkShortcutsWindow)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gtk_buildable_iface_init))
G_DEFINE_TYPE_WITH_PRIVATE (GtkShortcutsWindow, gtk_shortcuts_window, GTK_TYPE_WINDOW)
enum {
CLOSE,
@@ -139,6 +132,102 @@ update_title_stack (GtkShortcutsWindow *self)
}
}
static void
gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data)
{
GtkShortcutsWindow *self = data;
GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
GtkWidget *item;
gchar *subtitle = NULL;
gchar *accelerator = NULL;
gchar *title = NULL;
gchar *hash_key = NULL;
GIcon *icon = NULL;
gchar *str;
gchar *keywords;
if (GTK_IS_SHORTCUTS_SHORTCUT (child))
{
g_object_get (child,
"accelerator", &accelerator,
"title", &title,
NULL);
hash_key = g_strdup_printf ("%s-%s", title, accelerator);
if (g_hash_table_contains (priv->search_items_hash, hash_key))
{
g_free (hash_key);
g_free (title);
g_free (accelerator);
return;
}
g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
item = g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT,
"visible", TRUE,
"accelerator", accelerator,
"title", title,
"accel-size-group", priv->search_image_group,
"title-size-group", priv->search_text_group,
NULL);
str = g_strdup_printf ("%s %s", accelerator, title);
keywords = g_utf8_strdown (str, -1);
g_hash_table_insert (priv->keywords, item, keywords);
gtk_container_add (GTK_CONTAINER (priv->search_shortcuts), item);
g_free (title);
g_free (accelerator);
g_free (str);
}
else if (GTK_IS_SHORTCUTS_GESTURE (child))
{
g_object_get (child,
"title", &title,
"subtitle", &subtitle,
"icon", &icon,
NULL);
hash_key = g_strdup_printf ("%s-%s", title, subtitle);
if (g_hash_table_contains (priv->search_items_hash, hash_key))
{
g_free (subtitle);
g_free (title);
g_free (hash_key);
g_clear_object (&icon);
return;
}
g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
item = g_object_new (GTK_TYPE_SHORTCUTS_GESTURE,
"visible", TRUE,
"title", title,
"subtitle", subtitle,
"icon", icon,
"icon-size-group", priv->search_image_group,
"desc-size-group", priv->search_text_group,
NULL);
str = g_strdup_printf ("%s %s", title, subtitle);
keywords = g_utf8_strdown (str, -1);
g_hash_table_insert (priv->keywords, item, keywords);
gtk_container_add (GTK_CONTAINER (priv->search_gestures), item);
g_free (subtitle);
g_free (title);
g_clear_object (&icon);
g_free (str);
}
else if (GTK_IS_CONTAINER (child))
{
gtk_container_foreach (GTK_CONTAINER (child), gtk_shortcuts_window_add_search_item, self);
}
}
static void
gtk_shortcuts_window_add_section (GtkShortcutsWindow *self,
GtkShortcutsSection *section)
@@ -150,6 +239,8 @@ gtk_shortcuts_window_add_section (GtkShortcutsWindow *self,
const gchar *visible_section;
GtkWidget *label;
gtk_container_foreach (GTK_CONTAINER (section), gtk_shortcuts_window_add_search_item, self);
name = gtk_shortcuts_section_get_section_name (section);
title = gtk_shortcuts_section_get_title (section);
@@ -237,92 +328,6 @@ gtk_shortcuts_window__list_box__row_activated (GtkShortcutsWindow *self,
gtk_widget_hide (GTK_WIDGET (priv->popover));
}
static void
gtk_shortcuts_window_add_search_item (GtkShortcutsWindow *self,
GtkWidget *search_item)
{
GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self);
GString *str;
gchar *downcase;
str = g_string_new (NULL);
if (GTK_IS_SHORTCUTS_SHORTCUT (search_item))
{
gchar *accelerator = NULL;
gchar *title = NULL;
gchar *hash_key = NULL;
g_object_get (search_item,
"accelerator", &accelerator,
"title", &title,
NULL);
hash_key = g_strdup_printf ("%s-%s", title, accelerator);
if (g_hash_table_contains (priv->search_items_hash, hash_key))
{
g_free (hash_key);
g_free (title);
g_free (accelerator);
return;
}
g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
g_object_set (search_item,
"accelerator-size-group", priv->search_image_group,
"title-size-group", priv->search_text_group,
NULL);
g_string_append_printf (str, "%s %s", accelerator, title);
gtk_container_add (GTK_CONTAINER (priv->search_shortcuts), search_item);
g_free (title);
g_free (accelerator);
}
else if (GTK_IS_SHORTCUTS_GESTURE (search_item))
{
gchar *subtitle = NULL;
gchar *title = NULL;
gchar *hash_key = NULL;
g_object_get (search_item,
"subtitle", &subtitle,
"title", &title,
NULL);
hash_key = g_strdup_printf ("%s-%s", title, subtitle);
if (g_hash_table_contains (priv->search_items_hash, hash_key))
{
g_free (subtitle);
g_free (title);
g_free (hash_key);
return;
}
g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1));
g_object_set (search_item,
"icon-size-group", priv->search_image_group,
"desc-size-group", priv->search_text_group,
NULL);
g_string_append_printf (str, "%s %s", title, subtitle);
gtk_container_add (GTK_CONTAINER (priv->search_gestures), search_item);
g_free (subtitle);
g_free (title);
}
downcase = g_utf8_strdown (str->str, str->len);
g_hash_table_insert (priv->keywords, search_item, downcase);
g_string_free (str, TRUE);
}
static void
gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self,
GtkSearchEntry *search_entry)
@@ -388,385 +393,7 @@ gtk_shortcuts_window__search_mode__changed (GtkShortcutsWindow *self)
if (!gtk_search_bar_get_search_mode (priv->search_bar))
{
if (priv->last_section_name != NULL)
{
gtk_stack_set_visible_child_name (priv->stack, priv->last_section_name);
return;
}
}
}
static gboolean
check_parent (GMarkupParseContext *context,
const gchar *element_name,
GError **error)
{
const GSList *stack;
const gchar *parent_name;
const gchar *our_name;
stack = g_markup_parse_context_get_element_stack (context);
our_name = stack->data;
parent_name = stack->next ? stack->next->data : "";
if (g_strcmp0 (parent_name, element_name) != 0)
{
gint line;
gint col;
g_markup_parse_context_get_position (context, &line, &col);
g_set_error (error,
GTK_BUILDER_ERROR,
GTK_BUILDER_ERROR_INVALID_TAG,
"%d:%d: Element <%s> found in <%s>, expected <%s>.",
line, col, our_name, parent_name, element_name);
return FALSE;
}
return TRUE;
}
static void
sections_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
ViewsParserData *parser_data = user_data;
GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (parser_data->self);
GtkWidget *item;
if (g_strcmp0 (element_name, "sections") == 0)
{
}
else if (g_strcmp0 (element_name, "section") == 0)
{
const gchar *name = NULL;
if (!check_parent (context, "sections", error))
return;
if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
G_MARKUP_COLLECT_STRING, "name", &name,
G_MARKUP_COLLECT_INVALID))
return;
item = g_object_new (GTK_TYPE_SHORTCUTS_SECTION,
"section-name", name,
"visible", TRUE,
"view-name", priv->view_name,
NULL);
g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
}
else if (g_strcmp0 (element_name, "page") == 0)
{
if (!check_parent (context, "section", error))
return;
item = g_object_new (GTK_TYPE_SHORTCUTS_PAGE,
"visible", TRUE,
NULL);
g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
}
else if (g_strcmp0 (element_name, "column") == 0)
{
GtkSizeGroup *size_group;
if (!check_parent (context, "page", error))
return;
size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
g_queue_push_head (parser_data->column_image_size_groups, size_group);
size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
g_queue_push_head (parser_data->column_desc_size_groups, size_group);
item = g_object_new (GTK_TYPE_SHORTCUTS_COLUMN,
"visible", TRUE,
NULL);
g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
}
else if (g_strcmp0 (element_name, "group") == 0)
{
const gchar *view = NULL;
if (!check_parent (context, "column", error))
return;
if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "view", &view,
G_MARKUP_COLLECT_INVALID))
return;
item = g_object_new (GTK_TYPE_SHORTCUTS_GROUP,
"visible", TRUE,
"view", view,
NULL);
g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
}
else if (g_strcmp0 (element_name, "shortcut") == 0)
{
GtkSizeGroup *accel_size_group;
GtkSizeGroup *desc_size_group;
if (!check_parent (context, "group", error))
return;
accel_size_group = g_queue_peek_head (parser_data->column_image_size_groups);
desc_size_group = g_queue_peek_head (parser_data->column_desc_size_groups);
parser_data->search_item = g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT,
"visible", TRUE,
NULL);
item = g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT,
"accelerator-size-group", accel_size_group,
"title-size-group", desc_size_group,
"visible", TRUE,
NULL);
g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
}
else if (g_strcmp0 (element_name, "gesture") == 0)
{
GtkSizeGroup *accel_size_group;
GtkSizeGroup *desc_size_group;
if (!check_parent (context, "group", error))
return;
accel_size_group = g_queue_peek_head (parser_data->column_image_size_groups);
desc_size_group = g_queue_peek_head (parser_data->column_desc_size_groups);
parser_data->search_item = g_object_new (GTK_TYPE_SHORTCUTS_GESTURE,
"visible", TRUE,
NULL);
item = g_object_new (GTK_TYPE_SHORTCUTS_GESTURE,
"desc-size-group", desc_size_group,
"icon-size-group", accel_size_group,
"visible", TRUE,
NULL);
g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
}
else if (g_strcmp0 (element_name, "property") == 0)
{
const gchar *name = NULL;
const gchar *translatable = NULL;
item = g_queue_peek_head (parser_data->stack);
if (item == NULL)
{
g_set_error (error,
GTK_BUILDER_ERROR,
GTK_BUILDER_ERROR_INVALID_TAG,
"Property called without a parent object");
return;
}
if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
G_MARKUP_COLLECT_STRING, "name", &name,
G_MARKUP_COLLECT_OPTIONAL | G_MARKUP_COLLECT_STRING, "translatable", &translatable,
G_MARKUP_COLLECT_INVALID))
return;
g_free (parser_data->property_name);
parser_data->property_name = g_strdup (name);
parser_data->translatable = (g_strcmp0 (translatable, "yes") == 0);
}
else
{
const GSList *stack;
const gchar *parent_name;
const gchar *our_name;
gint line;
gint col;
stack = g_markup_parse_context_get_element_stack (context);
our_name = stack->data;
parent_name = stack->next ? stack->next->data : "";
g_markup_parse_context_get_position (context, &line, &col);
g_set_error (error,
GTK_BUILDER_ERROR,
GTK_BUILDER_ERROR_INVALID_TAG,
"%d:%d: Unknown element <%s> found in <%s>.",
line, col, our_name, parent_name);
}
}
static void
sections_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
{
ViewsParserData *parser_data = user_data;
GtkWidget *item;
if (g_strcmp0 (element_name, "section") == 0)
{
item = g_queue_pop_head (parser_data->stack);
gtk_shortcuts_window_add_section (parser_data->self, GTK_SHORTCUTS_SECTION (item));
g_object_unref (item);
}
else if ((g_strcmp0 (element_name, "page") == 0) ||
(g_strcmp0 (element_name, "column") == 0) ||
(g_strcmp0 (element_name, "group") == 0) ||
(g_strcmp0 (element_name, "shortcut") == 0) ||
(g_strcmp0 (element_name, "gesture") == 0))
{
GtkWidget *parent;
item = g_queue_pop_head (parser_data->stack);
parent = g_queue_peek_head (parser_data->stack);
if (item != NULL && parent != NULL)
gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (item));
g_clear_object (&item);
if ((g_strcmp0 (element_name, "shortcut") == 0) ||
(g_strcmp0 (element_name, "gesture") == 0))
{
gtk_shortcuts_window_add_search_item (parser_data->self, parser_data->search_item);
parser_data->search_item = NULL;
}
if (g_strcmp0 (element_name, "column") == 0)
{
GtkSizeGroup *size_group;
size_group = g_queue_pop_head (parser_data->column_image_size_groups);
g_clear_object (&size_group);
size_group = g_queue_pop_head (parser_data->column_desc_size_groups);
g_clear_object (&size_group);
}
}
else if (g_strcmp0 (element_name, "property") == 0)
{
g_clear_pointer (&parser_data->property_name, g_free);
}
}
static void
sections_parser_text (GMarkupParseContext *context,
const gchar *text,
gsize text_len,
gpointer user_data,
GError **error)
{
ViewsParserData *parser_data = user_data;
GParamSpec *pspec;
GtkWidget *item;
GValue value = { 0 };
if (parser_data->property_name == NULL)
return;
item = g_queue_peek_head (parser_data->stack);
if (item == NULL)
return;
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (item), parser_data->property_name);
if (pspec == NULL)
{
g_set_error (error,
GTK_BUILDER_ERROR,
GTK_BUILDER_ERROR_INVALID_PROPERTY,
"No such property: %s",
parser_data->property_name);
return;
}
if (parser_data->translatable)
text = _(text);
if (g_type_is_a (pspec->value_type, G_TYPE_OBJECT))
{
GObject *relative;
relative = gtk_builder_get_object (parser_data->builder, text);
if (relative == NULL)
{
g_set_error (error,
GTK_BUILDER_ERROR,
GTK_BUILDER_ERROR_INVALID_VALUE,
"Unknown object for property '%s': %s",
parser_data->property_name,
text);
return;
}
g_value_init (&value, pspec->value_type);
g_value_set_object (&value, relative);
}
else if (!gtk_builder_value_from_string (parser_data->builder,
pspec, text, &value, error))
return;
if (parser_data->search_item != NULL)
g_object_set_property (G_OBJECT (parser_data->search_item),
parser_data->property_name,
&value);
g_object_set_property (G_OBJECT (item), parser_data->property_name, &value);
g_value_unset (&value);
}
static GMarkupParser ViewsParser = {
sections_parser_start_element,
sections_parser_end_element,
sections_parser_text,
};
static gboolean
gtk_shortcuts_window_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
GMarkupParser *parser,
gpointer *data)
{
if (g_strcmp0 (tagname, "sections") == 0)
{
ViewsParserData *parser_data;
parser_data = g_slice_new0 (ViewsParserData);
parser_data->self = g_object_ref (buildable);
parser_data->builder = g_object_ref (builder);
parser_data->stack = g_queue_new ();
parser_data->column_image_size_groups = g_queue_new ();
parser_data->column_desc_size_groups = g_queue_new ();
*parser = ViewsParser;
*data = parser_data;
return TRUE;
}
return FALSE;
}
static void
gtk_shortcuts_window_custom_finished (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
gpointer user_data)
{
if (g_strcmp0 (tagname, "sections") == 0)
{
ViewsParserData *parser_data = user_data;
g_object_unref (parser_data->self);
g_object_unref (parser_data->builder);
g_queue_free_full (parser_data->stack, (GDestroyNotify)g_object_unref);
g_queue_free_full (parser_data->column_image_size_groups, (GDestroyNotify)g_object_unref);
g_queue_free_full (parser_data->column_desc_size_groups, (GDestroyNotify)g_object_unref);
g_slice_free (ViewsParserData, parser_data);
gtk_stack_set_visible_child_name (priv->stack, priv->last_section_name);
}
}
@@ -806,13 +433,6 @@ gtk_shortcuts_window_finalize (GObject *object)
G_OBJECT_CLASS (gtk_shortcuts_window_parent_class)->finalize (object);
}
static void
gtk_buildable_iface_init (GtkBuildableIface *iface)
{
iface->custom_tag_start = gtk_shortcuts_window_custom_tag_start;
iface->custom_finished = gtk_shortcuts_window_custom_finished;
}
static void
gtk_shortcuts_window_get_property (GObject *object,
guint prop_id,
@@ -908,8 +528,6 @@ gtk_shortcuts_window_class_init (GtkShortcutsWindowClass *klass)
0);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
g_type_ensure (GTK_TYPE_SHORTCUTS_PAGE);
g_type_ensure (GTK_TYPE_SHORTCUTS_COLUMN);
g_type_ensure (GTK_TYPE_SHORTCUTS_GROUP);
g_type_ensure (GTK_TYPE_SHORTCUTS_GESTURE);
g_type_ensure (GTK_TYPE_SHORTCUTS_SHORTCUT);