1 /* 2 * glade-editable.c 3 * 4 * Copyright (C) 2008 Tristan Van Berkom. 5 * 6 * Authors: 7 * Tristan Van Berkom <tvb@gnome.org> 8 * 9 * This library is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU Lesser General Public License as 11 * published by the Free Software Foundation; either version 2.1 of 12 * the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 * 23 */ 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include <glib/gi18n-lib.h> 29 30 #include <string.h> 31 #include <stdlib.h> 32 33 #include "glade-project.h" 34 #include "glade-widget.h" 35 #include "glade-editable.h" 36 37 G_DEFINE_INTERFACE (GladeEditable, glade_editable, GTK_TYPE_WIDGET); 38 39 static GQuark glade_editable_project_quark = 0; 40 static GQuark glade_editable_widget_quark = 0; 41 static GQuark glade_editable_loading_quark = 0; 42 static GQuark glade_editable_destroy_quark = 0; 43 44 static void 45 project_changed (GladeProject *project, 46 GladeCommand *command, 47 gboolean execute, 48 GladeEditable *editable) 49 { 50 GladeWidget *widget; 51 52 widget = g_object_get_qdata (G_OBJECT (editable), glade_editable_widget_quark); 53 54 glade_editable_load (editable, widget); 55 } 56 57 static void 58 project_closed (GladeProject *project, 59 GladeEditable *editable) 60 { 61 glade_editable_load (editable, NULL); 62 } 63 64 static void 65 editable_destroyed (GladeEditable *editable) 66 { 67 glade_editable_load (editable, NULL); 68 } 69 70 static void 71 glade_editable_load_default (GladeEditable *editable, 72 GladeWidget *widget) 73 { 74 GladeWidget *old_widget; 75 GladeProject *old_project; 76 77 old_widget = g_object_get_qdata (G_OBJECT (editable), glade_editable_widget_quark); 78 old_project = g_object_get_qdata (G_OBJECT (editable), glade_editable_project_quark); 79 80 if (old_widget != widget) 81 { 82 if (old_widget) 83 { 84 g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (project_changed), editable); 85 g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (project_closed), editable); 86 87 g_object_set_qdata (G_OBJECT (editable), glade_editable_widget_quark, NULL); 88 g_object_set_qdata (G_OBJECT (editable), glade_editable_project_quark, NULL); 89 } 90 91 if (widget) 92 { 93 GladeProject *project = glade_widget_get_project (widget); 94 95 g_object_set_qdata (G_OBJECT (editable), glade_editable_widget_quark, widget); 96 g_object_set_qdata (G_OBJECT (editable), glade_editable_project_quark, project); 97 98 g_signal_connect (project, "changed", 99 G_CALLBACK (project_changed), editable); 100 g_signal_connect (project, "close", 101 G_CALLBACK (project_closed), editable); 102 } 103 } 104 } 105 106 static void 107 glade_editable_default_init (GladeEditableIface *iface) 108 { 109 glade_editable_project_quark = g_quark_from_static_string ("glade-editable-project-quark"); 110 glade_editable_widget_quark = g_quark_from_static_string ("glade-editable-widget-quark"); 111 glade_editable_loading_quark = g_quark_from_static_string ("glade-editable-loading-quark"); 112 glade_editable_destroy_quark = g_quark_from_static_string ("glade-editable-destroy-quark"); 113 114 iface->load = glade_editable_load_default; 115 } 116 117 /** 118 * glade_editable_load: 119 * @editable: A #GladeEditable 120 * @widget: the #GladeWidget to load 121 * 122 * Loads @widget property values into @editable 123 * (the editable will watch the widgets properties 124 * until its loaded with another widget or %NULL) 125 */ 126 void 127 glade_editable_load (GladeEditable *editable, GladeWidget *widget) 128 { 129 GladeEditableIface *iface; 130 g_return_if_fail (GLADE_IS_EDITABLE (editable)); 131 g_return_if_fail (widget == NULL || GLADE_IS_WIDGET (widget)); 132 133 /* Connect to the destroy signal once, make sure we unload the widget and disconnect 134 * to any signals when destroying 135 */ 136 if (!GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (editable), glade_editable_destroy_quark))) 137 { 138 g_signal_connect (editable, "destroy", G_CALLBACK (editable_destroyed), NULL); 139 g_object_set_qdata (G_OBJECT (editable), glade_editable_destroy_quark, GINT_TO_POINTER (TRUE)); 140 } 141 142 iface = GLADE_EDITABLE_GET_IFACE (editable); 143 144 g_object_set_qdata (G_OBJECT (editable), glade_editable_loading_quark, GINT_TO_POINTER (TRUE)); 145 146 if (iface->load) 147 iface->load (editable, widget); 148 else 149 g_critical ("No GladeEditable::load() support on type %s", 150 G_OBJECT_TYPE_NAME (editable)); 151 152 g_object_set_qdata (G_OBJECT (editable), glade_editable_loading_quark, GINT_TO_POINTER (FALSE)); 153 } 154 155 156 /** 157 * glade_editable_set_show_name: 158 * @editable: A #GladeEditable 159 * @show_name: Whether or not to show the name entry 160 * 161 * This only applies for the general page in the property 162 * editor, editables that embed the #GladeEditorTable implementation 163 * for the general page should use this to forward the message 164 * to its embedded editable. 165 */ 166 void 167 glade_editable_set_show_name (GladeEditable *editable, gboolean show_name) 168 { 169 GladeEditableIface *iface; 170 g_return_if_fail (GLADE_IS_EDITABLE (editable)); 171 172 iface = GLADE_EDITABLE_GET_IFACE (editable); 173 174 if (iface->set_show_name) 175 iface->set_show_name (editable, show_name); 176 } 177 178 GladeWidget * 179 glade_editable_loaded_widget (GladeEditable *editable) 180 { 181 return g_object_get_qdata (G_OBJECT (editable), glade_editable_widget_quark); 182 } 183 184 gboolean 185 glade_editable_loading (GladeEditable *editable) 186 { 187 return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (editable), glade_editable_loading_quark)); 188 } 189 190 void 191 glade_editable_block (GladeEditable *editable) 192 { 193 GladeProject *project; 194 195 g_return_if_fail (GLADE_IS_EDITABLE (editable)); 196 197 project = g_object_get_qdata (G_OBJECT (editable), glade_editable_project_quark); 198 199 g_return_if_fail (GLADE_IS_PROJECT (project)); 200 201 g_signal_handlers_block_by_func (project, G_CALLBACK (project_changed), editable); 202 } 203 204 void 205 glade_editable_unblock (GladeEditable *editable) 206 { 207 GladeProject *project; 208 209 g_return_if_fail (GLADE_IS_EDITABLE (editable)); 210 211 project = g_object_get_qdata (G_OBJECT (editable), glade_editable_project_quark); 212 213 g_return_if_fail (GLADE_IS_PROJECT (project)); 214 215 g_signal_handlers_unblock_by_func (project, G_CALLBACK (project_changed), editable); 216 } 217