diff options
Diffstat (limited to 'liblogdiag/ld-category-view.c')
-rw-r--r-- | liblogdiag/ld-category-view.c | 364 |
1 files changed, 63 insertions, 301 deletions
diff --git a/liblogdiag/ld-category-view.c b/liblogdiag/ld-category-view.c index 707627d..839b099 100644 --- a/liblogdiag/ld-category-view.c +++ b/liblogdiag/ld-category-view.c @@ -2,7 +2,7 @@ * ld-category-view.c * * This file is a part of logdiag. - * Copyright Přemysl Janouch 2011. All rights reserved. + * Copyright Přemysl Janouch 2012. All rights reserved. * * See the file LICENSE for licensing information. * @@ -14,324 +14,86 @@ /** * SECTION:ld-category-view - * @short_description: A category view widget + * @short_description: Interface for objects displaying categories * @see_also: #LdCategory * - * #LdCategoryView enables the user to drag symbols from #LdLibrary - * onto #LdDiagramView. + * #LdCategoryView defines objects displaying contents of #LdCategory + * hierarchies. */ -/* - * LdCategoryViewPrivate: - * @category: a category object assigned as a model. - * @expander_prefix: a string to prepend to subcategory labels in expanders. - */ -struct _LdCategoryViewPrivate -{ - LdCategory *category; - gchar *expander_prefix; -}; - -enum -{ - PROP_0, - PROP_CATEGORY -}; - -static void ld_category_view_get_property (GObject *object, guint property_id, - GValue *value, GParamSpec *pspec); -static void ld_category_view_set_property (GObject *object, guint property_id, - const GValue *value, GParamSpec *pspec); -static void ld_category_view_dispose (GObject *gobject); - -static void ld_category_view_set_category (LdCategoryViewIf *iface, - LdCategory *category); -static LdCategory *ld_category_view_get_category (LdCategoryViewIf *iface); - -static void reload_category (LdCategoryView *self); -static void load_category_cb (gpointer data, gpointer user_data); - - -static void -ld_category_view_if_init (LdCategoryViewIfInterface *iface) -{ - iface->set_category = ld_category_view_set_category; - iface->get_category = ld_category_view_get_category; -} - -G_DEFINE_TYPE_WITH_CODE (LdCategoryView, ld_category_view, GTK_TYPE_VBOX, - G_IMPLEMENT_INTERFACE (LD_TYPE_CATEGORY_VIEW_IF, ld_category_view_if_init)); - -static void -ld_category_view_class_init (LdCategoryViewClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->get_property = ld_category_view_get_property; - object_class->set_property = ld_category_view_set_property; - object_class->dispose = ld_category_view_dispose; - - g_object_class_override_property (object_class, PROP_CATEGORY, "category"); - - g_type_class_add_private (klass, sizeof (LdCategoryViewPrivate)); -} - -static void -ld_category_view_init (LdCategoryView *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE - (self, LD_TYPE_CATEGORY_VIEW, LdCategoryViewPrivate); -} - -static void -ld_category_view_dispose (GObject *gobject) -{ - LdCategoryView *self; - - self = LD_CATEGORY_VIEW (gobject); - ld_category_view_if_set_category (LD_CATEGORY_VIEW_IF (self), NULL); - - g_free (self->priv->expander_prefix); - self->priv->expander_prefix = NULL; - - /* Chain up to the parent class. */ - G_OBJECT_CLASS (ld_category_view_parent_class)->dispose (gobject); -} +G_DEFINE_INTERFACE (LdCategoryView, ld_category_view, 0); static void -ld_category_view_get_property (GObject *object, guint property_id, - GValue *value, GParamSpec *pspec) +ld_category_view_default_init (LdCategoryViewInterface *iface) { - switch (property_id) - { - case PROP_CATEGORY: - g_value_set_object (value, - ld_category_view_if_get_category (LD_CATEGORY_VIEW_IF (object))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -ld_category_view_set_property (GObject *object, guint property_id, - const GValue *value, GParamSpec *pspec) -{ - switch (property_id) - { - case PROP_CATEGORY: - ld_category_view_if_set_category (LD_CATEGORY_VIEW_IF (object), - LD_CATEGORY (g_value_get_object (value))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - + GParamSpec *pspec; /** - * ld_category_view_new: - * @category: (allow-none): a category to be assigned to the widget. + * LdCategoryView::symbol-selected: + * @self: an #LdCategoryView object. + * @symbol: the selected #LdSymbol object. + * @path: location of the symbol within the library. * - * Create an instance. + * A symbol has been selected. */ -GtkWidget * -ld_category_view_new (LdCategory *category) -{ - LdCategoryView *self; - - self = g_object_new (LD_TYPE_CATEGORY_VIEW, NULL); - ld_category_view_if_set_category (LD_CATEGORY_VIEW_IF (self), category); - return GTK_WIDGET (self); -} - -static void -ld_category_view_set_category (LdCategoryViewIf *iface, LdCategory *category) -{ - LdCategoryView *self; - - g_return_if_fail (LD_IS_CATEGORY_VIEW (iface)); - g_return_if_fail (LD_IS_CATEGORY (category) || category == NULL); - - self = LD_CATEGORY_VIEW (iface); - if (self->priv->category) - { - g_signal_handlers_disconnect_by_func (self->priv->category, - reload_category, self); - g_object_unref (self->priv->category); - } - - self->priv->category = category; - - if (category) - { - g_signal_connect_data (category, "children-changed", - G_CALLBACK (reload_category), self, - NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED); - g_signal_connect_data (category, "notify::parent", - G_CALLBACK (reload_category), self, - NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED); - g_object_ref (category); - } - reload_category (self); - g_object_notify (G_OBJECT (self), "category"); -} - -static LdCategory * -ld_category_view_get_category (LdCategoryViewIf *iface) -{ - g_return_val_if_fail (LD_IS_CATEGORY_VIEW (iface), NULL); - return LD_CATEGORY_VIEW (iface)->priv->category; -} + iface->symbol_selected_signal = g_signal_new + ("symbol-selected", G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + ld_marshal_VOID__OBJECT_STRING, + G_TYPE_NONE, 2, LD_TYPE_SYMBOL, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); -static GtkWidget * -create_empty_label (void) -{ - GtkWidget *label; - PangoAttrList *attr; - - label = gtk_label_new (_("Empty")); - gtk_widget_set_sensitive (label, FALSE); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_misc_set_padding (GTK_MISC (label), 5, 0); - - attr = pango_attr_list_new (); - pango_attr_list_change (attr, pango_attr_style_new (PANGO_STYLE_ITALIC)); - gtk_label_set_attributes (GTK_LABEL (label), attr); - pango_attr_list_unref (attr); - - return label; -} - -static void -reconstruct_prefix (LdCategoryView *self) -{ - LdCategory *iter; - gchar *start, *end; - - start = g_strdup (""); - end = g_strdup (""); - - for (iter = self->priv->category; iter; - iter = ld_category_get_parent (iter)) - { - const gchar *name; - gchar *new_start, *new_end, *name_escaped; - - /* Stop at the root category. */ - if (!strcmp (ld_category_get_name (iter), - LD_LIBRARY_IDENTIFIER_SEPARATOR)) - break; - - name = ld_category_get_human_name (iter); - name_escaped = g_markup_escape_text (name, -1); - - new_start = g_strconcat (start, "<small>", NULL); - new_end = g_strconcat (name_escaped, ":</small> ", end, NULL); - - g_free (name_escaped); - g_free (start); - g_free (end); - - start = new_start; - end = new_end; - } - - g_free (self->priv->expander_prefix); - self->priv->expander_prefix = g_strconcat (start, end, NULL); - g_free (start); - g_free (end); -} - -static void -on_symbol_selected (GObject *source, - LdSymbol *symbol, const gchar *path, LdCategoryView *self) -{ - g_signal_emit (self, LD_CATEGORY_VIEW_IF_GET_INTERFACE (self)-> - symbol_selected_signal, 0, symbol, path); -} +/** + * LdCategoryView::symbol-deselected: + * @self: an #LdCategoryView object. + * @symbol: the deselected #LdSymbol object. + * @path: location of the symbol within the library. + * + * A symbol has been deselected. + */ + iface->symbol_deselected_signal = g_signal_new + ("symbol-deselected", G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + ld_marshal_VOID__OBJECT_STRING, + G_TYPE_NONE, 2, LD_TYPE_SYMBOL, + G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE); -static void -on_symbol_deselected (GObject *source, - LdSymbol *symbol, const gchar *path, LdCategoryView *self) -{ - g_signal_emit (self, LD_CATEGORY_VIEW_IF_GET_INTERFACE (self)-> - symbol_deselected_signal, 0, symbol, path); +/** + * LdCategoryView:category: + * + * The #LdCategory this object retrieves content from. + */ + pspec = g_param_spec_object ("category", "Category", + "The symbol category that is shown by this object.", + LD_TYPE_CATEGORY, G_PARAM_READWRITE); + g_object_interface_install_property (iface, pspec); } -static void -reload_category (LdCategoryView *self) +/** + * ld_category_view_set_category: + * @self: an #LdCategorylView object. + * @category: the #LdCategory to be assigned to the view. + * + * Assign an #LdCategory object to the view. + */ +void +ld_category_view_set_category (LdCategoryView *self, + LdCategory *category) { g_return_if_fail (LD_IS_CATEGORY_VIEW (self)); - - /* Clear the container first, if there is already something in it. */ - gtk_container_foreach (GTK_CONTAINER (self), - (GtkCallback) gtk_widget_destroy, NULL); - - /* XXX: We might want to disconnect signal handlers. */ - - if (self->priv->category) - { - GSList *symbols, *children; - - symbols = (GSList *) ld_category_get_symbols (self->priv->category); - children = (GSList *) ld_category_get_children (self->priv->category); - - if (symbols) - { - GtkWidget *symbol_view; - - symbol_view = ld_category_symbol_view_new (self->priv->category); - gtk_box_pack_start (GTK_BOX (self), symbol_view, FALSE, FALSE, 0); - - g_signal_connect_after (symbol_view, "symbol-selected", - G_CALLBACK (on_symbol_selected), self); - g_signal_connect_after (symbol_view, "symbol-deselected", - G_CALLBACK (on_symbol_deselected), self); - } - - if (children) - { - reconstruct_prefix (self); - g_slist_foreach (children, load_category_cb, self); - } - else if (!symbols) - gtk_box_pack_start (GTK_BOX (self), - create_empty_label (), FALSE, FALSE, 0); - } + LD_CATEGORY_VIEW_GET_INTERFACE (self)->set_category (self, category); } -static void -load_category_cb (gpointer data, gpointer user_data) +/** + * ld_category_view_get_category: + * @self: an #LdCategoryView object. + * + * Get the #LdCategory object assigned to this view. + * The reference count on the category is not incremented. + */ +LdCategory * +ld_category_view_get_category (LdCategoryView *self) { - LdCategoryView *self; - LdCategory *cat; - GtkWidget *expander, *child; - gchar *name, *label_markup; - - g_return_if_fail (LD_IS_CATEGORY_VIEW (user_data)); - g_return_if_fail (LD_IS_CATEGORY (data)); - - self = user_data; - cat = data; - - name = g_markup_escape_text (ld_category_get_human_name (cat), -1); - label_markup = g_strconcat (self->priv->expander_prefix, name, NULL); - g_free (name); - - expander = gtk_expander_new (label_markup); - gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE); - gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE); - g_free (label_markup); - - child = ld_category_view_new (cat); - gtk_container_add (GTK_CONTAINER (expander), child); - gtk_box_pack_start (GTK_BOX (self), expander, FALSE, FALSE, 0); - - g_signal_connect_after (child, "symbol-selected", - G_CALLBACK (on_symbol_selected), self); - g_signal_connect_after (child, "symbol-deselected", - G_CALLBACK (on_symbol_deselected), self); + g_return_val_if_fail (LD_IS_CATEGORY_VIEW (self), NULL); + return LD_CATEGORY_VIEW_GET_INTERFACE (self)->get_category (self); } - |