diff --git a/demos/gtk-demo/shortcuts.ui b/demos/gtk-demo/shortcuts.ui index b2cefac877..cf413602fc 100644 --- a/demos/gtk-demo/shortcuts.ui +++ b/demos/gtk-demo/shortcuts.ui @@ -53,486 +53,759 @@ window1 1 - -
+ + + 1 + editor Editor Shortcuts - - - - General - + + + 1 + General + + + 1 Global Search <ctrl>period - - + + + + + 1 Preferences <ctrl>comma - - + + + + + 1 Command Bar <ctrl>Return - - + + + + + 1 Terminal <ctrl><shift>t - - + + + + + 1 Keyboard Shortcuts <ctrl><shift>question - - - - Panels - + + + + + + + 1 + Panels + + + 1 Toggle left panel F9 - - + + + + + 1 Toggle right panel <shift>F9 - - + + + + + 1 Toggle bottom panel <ctrl>F9 - - - - Touchpad gestures - + + + + + + + 1 + Touchpad gestures + + + 1 Switch to the next document Two finger swipe right - right-swipe-icon - - + right-swipe-icon + + + + + 1 Switch to the previous document Two finger swipe left - left-swipe-icon - - - - - - Files - + left-swipe-icon + + + + + + + 1 + Files + + + 1 <ctrl>n Create new document - - + + + + + 1 <ctrl>o Open a document - - + + + + + 1 <ctrl>s Save the document - - + + + + + 1 <ctrl>w Close the document - - + + + + + 1 <ctrl><alt>Page_Down Switch to the next document - - + + + + + 1 <ctrl><alt>Page_Up Switch to the previous document - - - <ctrl>k - Show list of open files - - - F4 - Switch to source or header - - - - Find and replace - + + + + + + + 1 + Find and replace + + + 1 <ctrl>f Find - - + + + + + 1 <ctrl>g Find the next match - - + + + + + 1 <ctrl><shift>g Find the previous match - - - + + + + + 1 <ctrl><shift>k Clear highlight - - - - - - - - - Copy and Paste - + + + + + + + 1 + Copy and Paste + + + 1 <ctrl>c Copy selected text to clipboard - - + + + + + 1 <ctrl>x Cut selected text to clipboard - - + + + + + 1 <ctrl>v Paste text from clipboard - - - - Undo and Redo - + + + + + + + 1 + Undo and Redo + + + 1 <ctrl>z Undo previous command - - + + + + + 1 <ctrl><shift>z Redo previous command - - - - Editing - + + + + + + + 1 + Editing + + + 1 <ctrl><shift>a Increment number at cursor - - + + + + + 1 <ctrl><shift>x Decrement number at cursor - - + + + + + 1 <ctrl>j Join selected lines - - + + + + + 1 <ctrl>space Show completion window - - + + + + + 1 Insert Toggle overwrite - - + + + + + 1 <ctrl><alt>i Reindent line - - - - - - Navigation - + + + + + + + 1 + Navigation + + + 1 <alt>n Move to next error in file - - + + + + + 1 <alt>p Move to previous error in file - - + + + + + 1 <shift><alt>Left Move to previous edit location - - + + + + + 1 <shift><alt>Right Move to next edit location - - + + + + + 1 <alt>period Jump to definition of symbol - - + + + + + 1 <alt><shift>Up Move sectionport up within the file - - + + + + + 1 <alt><shift>Down Move sectionport down within the file - - + + + + + 1 <alt><shift>End Move sectionport to end of file - - + + + + + 1 <alt><shift>Home Move sectionport to beginning of file - - + + + + + 1 <ctrl>percent Move to matching bracket - - - - Selections - + + + + + + + 1 + Selections + + + 1 <ctrl>a Select all - - + + + + + 1 <ctrl>backslash Unselect all - - - - - -
+
+
+
+
+
+
+ + + 1 + terminal Terminal Shortcuts - - - - General - + + + 1 + General + + + 1 Global Search <ctrl>period - - + + + + + 1 Preferences <ctrl>comma - - + + + + + 1 Command Bar <ctrl>Return - - + + + + + 1 Terminal <ctrl><shift>t - - + + + + + 1 Keyboard Shortcuts <ctrl><shift>question - - - - - - Copy and Paste - + + + + + + + 1 + Copy and Paste + + + 1 <ctrl><shift>c Copy selected text to clipboard - - + + + + + 1 <ctrl><shift>v Paste text from clipboard - - - - - - + + + + + + window1 1 - -
- - - - General - + + + 1 + shortcuts + + + 1 + General + + + 1 <ctrl>Page_Down Go to the next section - - + + + + + 1 <ctrl>Page_Up Go to the previous section - - + + + + + 1 <alt>Q Quit - - + + + + + 1 <alt>Left Forward - - + + + + + 1 <ctrl>Right Back - - - - World Clocks - + + + + + + + 1 + world + World Clocks + + + 1 <ctrl>N Add a world clock - - + + + + + 1 <ctrl>S Select world clocks - - - - - - Alarm - + + + + + + + 1 + alarm + Alarm + + + 1 <ctrl>N Add an alarm - - + + + + + 1 <ctrl>S Select alarms - - - - Stopwatch - + + + + + + + 1 + stopwatch + Stopwatch + + + 1 Return space Start / Stop / Continue - - + + + + + 1 L Lap - - + + + + + 1 Delete Reset - - - - Timer - + + + + + + + 1 + timer + Timer + + + 1 Return space Start / Stop / Pause - - + + + + + 1 Delete Reset - - - - - - + + + + + +
window1 1 - -
- - - - Touchpad gestures - + + + 1 + shortcuts + 12 + + + 1 + Touchpad gestures + + + 1 Switch to the next document Two finger swipe right - right-swipe-icon - - + right-swipe-icon + + + + + 1 Switch to the previous document Two finger swipe left - left-swipe-icon - - - - Documents - + left-swipe-icon + + + + + + + 1 + Documents + + + 1 <ctrl>N Create new document - - + + + + + 1 <ctrl>O Open a document - - + + + + + 1 <ctrl>S Save the document - - + + + + + 1 <ctrl>W Close the document - - + + + + + 1 <ctrl><Alt>Page_Down Switch to the next document - - + + + + + 1 <ctrl><Alt>Page_Up Switch to the previous document - - - - - - Find and Replace - + + + + + + + 1 + Find and Replace + + + 1 <ctrl>F Find - - + + + + + 1 <ctrl>G Find the next match - - + + + + + 1 <ctrl><Shift>G Find the previous match - - + + + + + 1 <ctrl>H Find and Replace - - + + + + + 1 <ctrl><Shift>K Clear highlight - - + + + + + 1 <ctrl>I Go to line - - - - Tools - + + + + + + + 1 + Tools + + + 1 <shift>F7 Check spelling - - - - - - - - Miscellaneous - + + + + + + + 1 + Miscellaneous + + + 1 F11 Fullscreen on / off - - + + + + + 1 <ctrl>P Print the document - - + + + + + 1 Insert Toggle insert / overwrite - - - - - - + + + + + +
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 921bc26c6c..13ec0ddf36 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -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 \ diff --git a/gtk/gtkshortcutscolumn.c b/gtk/gtkshortcutscolumn.c deleted file mode 100644 index 88f81b8edd..0000000000 --- a/gtk/gtkshortcutscolumn.c +++ /dev/null @@ -1,47 +0,0 @@ -/* gtkshortcutscolumn.c - * - * Copyright (C) 2015 Christian Hergert - * - * 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 . - */ - -#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); -} diff --git a/gtk/gtkshortcutscolumnprivate.h b/gtk/gtkshortcutscolumnprivate.h deleted file mode 100644 index 0ded67d000..0000000000 --- a/gtk/gtkshortcutscolumnprivate.h +++ /dev/null @@ -1,42 +0,0 @@ -/* gtkshortcutscolumnprivate.h - * - * Copyright (C) 2015 Christian Hergert - * - * 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 . - */ - -#ifndef __GTK_SHORTCUTS_COLUMN_H__ -#define __GTK_SHORTCUTS_COLUMN_H__ - -#include - -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__ */ diff --git a/gtk/gtkshortcutsgesture.c b/gtk/gtkshortcutsgesture.c index 8762ee232a..c0c7f527cf 100644 --- a/gtk/gtkshortcutsgesture.c +++ b/gtk/gtkshortcutsgesture.c @@ -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", diff --git a/gtk/gtkshortcutsgroup.c b/gtk/gtkshortcutsgroup.c index ca8f3ebdd8..a7cb08b319 100644 --- a/gtk/gtkshortcutsgroup.c +++ b/gtk/gtkshortcutsgroup.c @@ -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); } diff --git a/gtk/gtkshortcutspage.c b/gtk/gtkshortcutspage.c deleted file mode 100644 index 8208aebefc..0000000000 --- a/gtk/gtkshortcutspage.c +++ /dev/null @@ -1,47 +0,0 @@ -/* gtkshortcutspage.c - * - * Copyright (C) 2015 Christian Hergert - * - * 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 . - */ - -#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); -} diff --git a/gtk/gtkshortcutspageprivate.h b/gtk/gtkshortcutspageprivate.h deleted file mode 100644 index a08ec317b1..0000000000 --- a/gtk/gtkshortcutspageprivate.h +++ /dev/null @@ -1,42 +0,0 @@ -/* gtkshortcutspageprivate.h - * - * Copyright (C) 2015 Christian Hergert - * - * 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 . - */ - -#ifndef __GTK_SHORTCUTS_PAGE_H__ -#define __GTK_SHORTCUTS_PAGE_H__ - -#include - -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__ */ diff --git a/gtk/gtkshortcutssection.c b/gtk/gtkshortcutssection.c index 6830957e24..2a361b468b 100644 --- a/gtk/gtkshortcutssection.c +++ b/gtk/gtkshortcutssection.c @@ -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)); +} diff --git a/gtk/gtkshortcutssectionprivate.h b/gtk/gtkshortcutssectionprivate.h index 776790b3d4..f5d48976ee 100644 --- a/gtk/gtkshortcutssectionprivate.h +++ b/gtk/gtkshortcutssectionprivate.h @@ -20,6 +20,7 @@ #define __GTK_SHORTCUTS_SECTION_H__ #include +#include 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 diff --git a/gtk/gtkshortcutsshortcut.c b/gtk/gtkshortcutsshortcut.c index 78c35ee534..c659674ca7 100644 --- a/gtk/gtkshortcutsshortcut.c +++ b/gtk/gtkshortcutsshortcut.c @@ -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, diff --git a/gtk/gtkshortcutswindow.c b/gtk/gtkshortcutswindow.c index c4c2353e73..f8305d1505 100644 --- a/gtk/gtkshortcutswindow.c +++ b/gtk/gtkshortcutswindow.c @@ -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);