/* * glade-editable.c * * Copyright (C) 2008 Tristan Van Berkom. * * Authors: * Tristan Van Berkom * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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. * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "glade-project.h" #include "glade-widget.h" #include "glade-editable.h" G_DEFINE_INTERFACE (GladeEditable, glade_editable, GTK_TYPE_WIDGET); static GQuark glade_editable_project_quark = 0; static GQuark glade_editable_widget_quark = 0; static GQuark glade_editable_loading_quark = 0; static GQuark glade_editable_destroy_quark = 0; static void project_changed (GladeProject *project, GladeCommand *command, gboolean execute, GladeEditable *editable) { GladeWidget *widget; widget = g_object_get_qdata (G_OBJECT (editable), glade_editable_widget_quark); glade_editable_load (editable, widget); } static void project_closed (GladeProject *project, GladeEditable *editable) { glade_editable_load (editable, NULL); } static void editable_destroyed (GladeEditable *editable) { glade_editable_load (editable, NULL); } static void glade_editable_load_default (GladeEditable *editable, GladeWidget *widget) { GladeWidget *old_widget; GladeProject *old_project; old_widget = g_object_get_qdata (G_OBJECT (editable), glade_editable_widget_quark); old_project = g_object_get_qdata (G_OBJECT (editable), glade_editable_project_quark); if (old_widget != widget) { if (old_widget) { g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (project_changed), editable); g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (project_closed), editable); g_object_set_qdata (G_OBJECT (editable), glade_editable_widget_quark, NULL); g_object_set_qdata (G_OBJECT (editable), glade_editable_project_quark, NULL); } if (widget) { GladeProject *project = glade_widget_get_project (widget); g_object_set_qdata (G_OBJECT (editable), glade_editable_widget_quark, widget); g_object_set_qdata (G_OBJECT (editable), glade_editable_project_quark, project); g_signal_connect (project, "changed", G_CALLBACK (project_changed), editable); g_signal_connect (project, "close", G_CALLBACK (project_closed), editable); } } } static void glade_editable_default_init (GladeEditableIface *iface) { glade_editable_project_quark = g_quark_from_static_string ("glade-editable-project-quark"); glade_editable_widget_quark = g_quark_from_static_string ("glade-editable-widget-quark"); glade_editable_loading_quark = g_quark_from_static_string ("glade-editable-loading-quark"); glade_editable_destroy_quark = g_quark_from_static_string ("glade-editable-destroy-quark"); iface->load = glade_editable_load_default; } /** * glade_editable_load: * @editable: A #GladeEditable * @widget: the #GladeWidget to load * * Loads @widget property values into @editable * (the editable will watch the widgets properties * until its loaded with another widget or %NULL) */ void glade_editable_load (GladeEditable *editable, GladeWidget *widget) { GladeEditableIface *iface; g_return_if_fail (GLADE_IS_EDITABLE (editable)); g_return_if_fail (widget == NULL || GLADE_IS_WIDGET (widget)); /* Connect to the destroy signal once, make sure we unload the widget and disconnect * to any signals when destroying */ if (!GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (editable), glade_editable_destroy_quark))) { g_signal_connect (editable, "destroy", G_CALLBACK (editable_destroyed), NULL); g_object_set_qdata (G_OBJECT (editable), glade_editable_destroy_quark, GINT_TO_POINTER (TRUE)); } iface = GLADE_EDITABLE_GET_IFACE (editable); g_object_set_qdata (G_OBJECT (editable), glade_editable_loading_quark, GINT_TO_POINTER (TRUE)); if (iface->load) iface->load (editable, widget); else g_critical ("No GladeEditable::load() support on type %s", G_OBJECT_TYPE_NAME (editable)); g_object_set_qdata (G_OBJECT (editable), glade_editable_loading_quark, GINT_TO_POINTER (FALSE)); } /** * glade_editable_set_show_name: * @editable: A #GladeEditable * @show_name: Whether or not to show the name entry * * This only applies for the general page in the property * editor, editables that embed the #GladeEditorTable implementation * for the general page should use this to forward the message * to its embedded editable. */ void glade_editable_set_show_name (GladeEditable *editable, gboolean show_name) { GladeEditableIface *iface; g_return_if_fail (GLADE_IS_EDITABLE (editable)); iface = GLADE_EDITABLE_GET_IFACE (editable); if (iface->set_show_name) iface->set_show_name (editable, show_name); } GladeWidget * glade_editable_loaded_widget (GladeEditable *editable) { return g_object_get_qdata (G_OBJECT (editable), glade_editable_widget_quark); } gboolean glade_editable_loading (GladeEditable *editable) { return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (editable), glade_editable_loading_quark)); } void glade_editable_block (GladeEditable *editable) { GladeProject *project; g_return_if_fail (GLADE_IS_EDITABLE (editable)); project = g_object_get_qdata (G_OBJECT (editable), glade_editable_project_quark); g_return_if_fail (GLADE_IS_PROJECT (project)); g_signal_handlers_block_by_func (project, G_CALLBACK (project_changed), editable); } void glade_editable_unblock (GladeEditable *editable) { GladeProject *project; g_return_if_fail (GLADE_IS_EDITABLE (editable)); project = g_object_get_qdata (G_OBJECT (editable), glade_editable_project_quark); g_return_if_fail (GLADE_IS_PROJECT (project)); g_signal_handlers_unblock_by_func (project, G_CALLBACK (project_changed), editable); }