diff options
author | Tristan Van Berkom <tvb@src.gnome.org> | 2008-10-23 17:30:14 +0000 |
---|---|---|
committer | Tristan Van Berkom <tvb@src.gnome.org> | 2008-10-23 17:30:14 +0000 |
commit | d38ad3ce787368276e84a00a4991be72a02b6bee (patch) | |
tree | ee37d0105d9c2bf16509401ab2e8bb91eb23a59a /gladeui/glade-editor-table.c | |
parent | d8cb7c328b884faab22294036d1aae77ba755599 (diff) | |
download | glade-d38ad3ce787368276e84a00a4991be72a02b6bee.tar.gz |
- Added GladeEditable interface used as pages by GladeEditor - Added
* gladeui/Makefile.am, gladeui/glade-editable.[ch], gladeui/glade-editor-table.[ch]:
- Added GladeEditable interface used as pages by GladeEditor
- Added GladeEditorTable widget to implmenemt the editable as the traditional table
with sorted properties
* gladeui/glade-editor.[ch]: Removed lots of code, now uses GladeEditables returned
by thier adaptors.
* gladeui/glade-editor-property.c: Removed obsolete doc-search signal.
* gladeui/glade-widget-adaptor.[ch]: Added GladeCreateEditableFunc to allow backends
to define layouts of pages in the editor.
svn path=/trunk/; revision=1990
Diffstat (limited to 'gladeui/glade-editor-table.c')
-rw-r--r-- | gladeui/glade-editor-table.c | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/gladeui/glade-editor-table.c b/gladeui/glade-editor-table.c new file mode 100644 index 00000000..93f7411b --- /dev/null +++ b/gladeui/glade-editor-table.c @@ -0,0 +1,371 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2008 Tristan Van Berkom. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Authors: + * Tristan Van Berkom <tvb@gnome.org> + */ + +#include <config.h> +#include <gladeui/glade.h> +#include <glib/gi18n-lib.h> + +#include "glade-editor-table.h" + +static void glade_editor_table_init (GladeEditorTable *self); +static void glade_editor_table_class_init (GladeEditorTableClass *klass); +static void glade_editor_table_finalize (GObject *object); +static void glade_editor_table_editable_init (GladeEditableIface *iface); +static void glade_editor_table_grab_focus (GtkWidget *widget); +static void append_packing_items (GladeEditorTable *table, + GladeWidget *widget); + +G_DEFINE_TYPE_WITH_CODE (GladeEditorTable, glade_editor_table, GTK_TYPE_TABLE, + G_IMPLEMENT_INTERFACE (GLADE_TYPE_EDITABLE, + glade_editor_table_editable_init)); + +static void +glade_editor_table_class_init (GladeEditorTableClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = glade_editor_table_finalize; + widget_class->grab_focus = glade_editor_table_grab_focus; +} + +static void +glade_editor_table_init (GladeEditorTable *self) +{ + +} + +static void +glade_editor_table_finalize (GObject *object) +{ + GladeEditorTable *table = GLADE_EDITOR_TABLE (object); + + table->properties = + (g_list_free (table->properties), NULL); + glade_editable_load (GLADE_EDITABLE (table), NULL); + + G_OBJECT_CLASS (glade_editor_table_parent_class)->finalize (object); +} + +static void +glade_editor_table_grab_focus (GtkWidget *widget) +{ + GladeEditorTable *editor_table = GLADE_EDITOR_TABLE (widget); + + if (editor_table->name_entry) + gtk_widget_grab_focus (editor_table->name_entry); + else if (editor_table->properties) + gtk_widget_grab_focus (GTK_WIDGET (editor_table->properties->data)); + else + GTK_WIDGET_CLASS (glade_editor_table_parent_class)->grab_focus (widget); +} + + +static void +widget_name_changed (GladeWidget *widget, + GParamSpec *pspec, + GladeEditorTable *table) +{ + table->loading = TRUE; + if (table->name_entry) + gtk_entry_set_text (GTK_ENTRY (table->name_entry), table->loaded_widget->name); + table->loading = FALSE; + +} + +static void +widget_finalized (GladeEditorTable *table, + GladeWidget *where_widget_was) +{ + table->loaded_widget = NULL; + + glade_editable_load (GLADE_EDITABLE (table), NULL); +} + + +static void +glade_editor_table_load (GladeEditable *editable, + GladeWidget *widget) +{ + GladeEditorTable *table = GLADE_EDITOR_TABLE (editable); + GladeEditorProperty *property; + GList *list; + + /* abort mission */ + if ((!table->loaded_widget && !widget) || + (table->loaded_widget && widget && table->loaded_widget == widget)) + return; + + table->loading = TRUE; + + if (table->loaded_widget && table->name_entry) + { + g_signal_handlers_disconnect_by_func (G_OBJECT (table->loaded_widget), + G_CALLBACK (widget_name_changed), table); + + /* The widget could die unexpectedly... */ + g_object_weak_unref (G_OBJECT (table->loaded_widget), + (GWeakNotify)widget_finalized, + table); + } + + table->loaded_widget = widget; + + if (table->loaded_widget && table->name_entry) + { + g_signal_connect (G_OBJECT (table->loaded_widget), "notify::name", + G_CALLBACK (widget_name_changed), table); + + /* The widget could die unexpectedly... */ + g_object_weak_ref (G_OBJECT (table->loaded_widget), + (GWeakNotify)widget_finalized, + table); + + gtk_entry_set_text (GTK_ENTRY (table->name_entry), widget->name); + + + } + else if (table->name_entry) + gtk_entry_set_text (GTK_ENTRY (table->name_entry), ""); + + /* If this is a packing page, we need to generate the properties here... */ + if (table->loaded_widget && table->type == GLADE_PAGE_PACKING) + append_packing_items (table, table->loaded_widget); + + /* Sync up properties, even if widget is NULL */ + for (list = table->properties; list; list = list->next) + { + property = list->data; + glade_editor_property_load_by_widget (property, widget); + } + + table->loading = FALSE; +} + +static void +glade_editor_table_editable_init (GladeEditableIface *iface) +{ + iface->load = glade_editor_table_load; +} + +static void +glade_editor_table_attach (GladeEditorTable *table, + GtkWidget *child, + gint pos, gint row) +{ + gtk_table_attach (GTK_TABLE (table), child, + pos, pos+1, row, row +1, + GTK_EXPAND | GTK_FILL, + GTK_EXPAND | GTK_FILL, + 3, 1); +} + +static gint +property_class_comp (gconstpointer a, gconstpointer b) +{ + const GladePropertyClass *ca = a, *cb = b; + + if (ca->pspec->owner_type == cb->pspec->owner_type) + { + gdouble result = ca->weight - cb->weight; + /* Avoid cast to int */ + if (result < 0.0) return -1; + else if (result > 0.0) return 1; + else return 0; + } + else + { + if (g_type_is_a (ca->pspec->owner_type, cb->pspec->owner_type)) + return (ca->common || ca->packing) ? 1 : -1; + else + return (ca->common || ca->packing) ? -1 : 1; + } +} + +static GList * +get_sorted_properties (GladeWidgetAdaptor *adaptor, + GladeEditorPageType type) +{ + GList *l, *list = NULL; + + for (l = adaptor->properties; l && l->data; l = g_list_next (l)) + { + GladePropertyClass *klass = l->data; + + /* Collect properties in our domain, query dialogs are allowed editor invisible properties */ + if (GLADE_PROPERTY_CLASS_IS_TYPE (klass, type) && + (glade_property_class_is_visible (klass) || type != GLADE_PAGE_QUERY)) + list = g_list_prepend (list, klass); + + } + return g_list_sort (list, property_class_comp); +} + +static GladeEditorProperty * +append_item (GladeEditorTable *table, + GladePropertyClass *klass, + gboolean from_query_dialog) +{ + GladeEditorProperty *property; + + if (!(property = glade_widget_adaptor_create_eprop + (GLADE_WIDGET_ADAPTOR (klass->handle), + klass, from_query_dialog == FALSE))) + { + g_critical ("Unable to create editor for property '%s' of class '%s'", + klass->id, GLADE_WIDGET_ADAPTOR (klass->handle)->name); + return NULL; + } + + gtk_widget_show (GTK_WIDGET (property)); + gtk_widget_show_all (property->item_label); + + glade_editor_table_attach (table, property->item_label, 0, table->rows); + glade_editor_table_attach (table, GTK_WIDGET (property), 1, table->rows); + + table->rows++; + + return property; +} + + +static void +append_items (GladeEditorTable *table, + GladeWidgetAdaptor *adaptor, + GladeEditorPageType type) +{ + GladeEditorProperty *property; + GladePropertyClass *property_class; + GList *list, *sorted_list; + + sorted_list = get_sorted_properties (adaptor, type); + for (list = sorted_list; list != NULL; list = list->next) + { + property_class = (GladePropertyClass *) list->data; + + property = append_item (table, property_class, type == GLADE_PAGE_QUERY); + table->properties = g_list_prepend (table->properties, property); + } + g_list_free (sorted_list); + + table->properties = g_list_reverse (table->properties); +} + +static void +append_packing_items (GladeEditorTable *table, + GladeWidget *widget) +{ + GladeEditorProperty *eprop; + GladeProperty *property; + GList *list; + + for (list = widget->packing_properties; list != NULL; list = list->next) + { + property = list->data; + + eprop = append_item (table, property->klass, FALSE); + table->properties = g_list_prepend (table->properties, eprop); + } + + table->properties = g_list_reverse (table->properties); +} + + +static void +widget_name_edited (GtkWidget *editable, GladeEditorTable *table) +{ + GladeWidget *widget; + gchar *new_name; + + g_return_if_fail (GTK_IS_EDITABLE (editable)); + g_return_if_fail (GLADE_IS_EDITOR_TABLE (table)); + + if (table->loading) return; + + widget = table->loaded_widget; + new_name = gtk_editable_get_chars (GTK_EDITABLE (editable), 0, -1); + + if (glade_project_available_widget_name (widget->project, widget, new_name)) + glade_command_set_name (widget, new_name); + g_free (new_name); +} + + +static void +append_name_field (GladeEditorTable *table) +{ + GtkWidget *label; + gchar *text = _("The Object's name"); + + /* Name */ + label = gtk_label_new (_("Name:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + + table->name_entry = gtk_entry_new (); + gtk_widget_show (table->name_entry); + + gtk_widget_set_tooltip_text (label, text); + gtk_widget_set_tooltip_text (table->name_entry, text); + + g_signal_connect (G_OBJECT (table->name_entry), "activate", + G_CALLBACK (widget_name_edited), table); + g_signal_connect (G_OBJECT (table->name_entry), "changed", + G_CALLBACK (widget_name_edited), table); + + glade_editor_table_attach (table, label, 0, table->rows); + glade_editor_table_attach (table, table->name_entry, 1, table->rows); + + table->rows++; +} + +/** + * glade_editor_table_new: + * @adaptor: A #GladeWidgetAdaptor + * @type: The #GladeEditorPageType + * + * Creates a new #GladeEditorTable. + * + * Returns: a new #GladeEditorTable + * + */ +GtkWidget * +glade_editor_table_new (GladeWidgetAdaptor *adaptor, + GladeEditorPageType type) +{ + GladeEditorTable *table; + + g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL); + + table = g_object_new (GLADE_TYPE_EDITOR_TABLE, NULL); + table->adaptor = adaptor; + table->type = type; + + if (type == GLADE_PAGE_GENERAL) + append_name_field (table); + + append_items (table, adaptor, type); + + gtk_widget_show (GTK_WIDGET (table)); + + return GTK_WIDGET (table); +} |