glade-editable.c 6.75 KB
Newer Older
1
/*
Tristan Van Berkom's avatar
Tristan Van Berkom committed
2
 * glade-editable.c
3 4 5 6 7 8
 *
 * Copyright (C) 2008 Tristan Van Berkom.
 *
 * Authors:
 *   Tristan Van Berkom <tvb@gnome.org>
 *
9
 * This library is free software; you can redistribute it and/or modify it
Tristan Van Berkom's avatar
Tristan Van Berkom committed
10 11 12
 * 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.
13
 *
Tristan Van Berkom's avatar
Tristan Van Berkom committed
14 15 16 17
 * 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.
18
 *
Tristan Van Berkom's avatar
Tristan Van Berkom committed
19 20
 * You should have received a copy of the GNU Lesser General Public 
 * License along with this program; if not, write to the Free Software
21 22 23 24 25 26 27 28 29 30 31 32
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <glib/gi18n-lib.h>

#include <string.h>
#include <stdlib.h>

33
#include "glade-project.h"
34 35 36
#include "glade-widget.h"
#include "glade-editable.h"

37
G_DEFINE_INTERFACE (GladeEditable, glade_editable, GTK_TYPE_WIDGET);
38

39 40
static GQuark glade_editable_project_quark = 0;
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 45 46 47

static void
project_changed (GladeProject  *project,
                 GladeCommand  *command,
                 gboolean       execute, 
48
                 GladeEditable *editable)
49 50 51 52 53 54 55 56 57 58
{
  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,
59
                GladeEditable *editable)
60 61 62 63
{
  glade_editable_load (editable, NULL);
}

64 65 66 67 68 69
static void
editable_destroyed (GladeEditable *editable)
{
  glade_editable_load (editable, NULL);
}

70 71
static void
glade_editable_load_default (GladeEditable  *editable,
72
                             GladeWidget    *widget)
73 74 75 76 77 78 79 80 81 82
{
  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)
83 84 85
        {
          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);
86

87 88 89
          g_object_set_qdata (G_OBJECT (editable), glade_editable_widget_quark, NULL);
          g_object_set_qdata (G_OBJECT (editable), glade_editable_project_quark, NULL);
        }
90 91

      if (widget)
92 93
        {
          GladeProject *project = glade_widget_get_project (widget);
94

95 96
          g_object_set_qdata (G_OBJECT (editable), glade_editable_widget_quark, widget);
          g_object_set_qdata (G_OBJECT (editable), glade_editable_project_quark, project);
97

98 99 100 101 102
          g_signal_connect (project, "changed", 
                            G_CALLBACK (project_changed), editable);
          g_signal_connect (project, "close", 
                            G_CALLBACK (project_closed), editable);
        }
103 104
    }
}
105 106

static void
107
glade_editable_default_init (GladeEditableIface *iface)
108
{
109 110
  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");
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 119 120 121
}

/**
 * glade_editable_load:
 * @editable: A #GladeEditable
 * @widget: the #GladeWidget to load
 *
122 123 124
 * Loads @widget property values into @editable
 * (the editable will watch the widgets properties
 * until its loaded with another widget or %NULL)
125 126
 */
void
127
glade_editable_load (GladeEditable *editable, GladeWidget *widget)
128
{
129 130 131
  GladeEditableIface *iface;
  g_return_if_fail (GLADE_IS_EDITABLE (editable));
  g_return_if_fail (widget == NULL || GLADE_IS_WIDGET (widget));
132

133 134 135 136 137 138 139 140 141
  /* 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));
    }

142
  iface = GLADE_EDITABLE_GET_IFACE (editable);
143

144 145
  g_object_set_qdata (G_OBJECT (editable), glade_editable_loading_quark, GINT_TO_POINTER (TRUE));

146 147 148 149 150
  if (iface->load)
    iface->load (editable, widget);
  else
    g_critical ("No GladeEditable::load() support on type %s",
                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 158 159 160 161 162 163 164 165

/**
 * 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
166
glade_editable_set_show_name (GladeEditable *editable, gboolean show_name)
167
{
168 169
  GladeEditableIface *iface;
  g_return_if_fail (GLADE_IS_EDITABLE (editable));
170

171
  iface = GLADE_EDITABLE_GET_IFACE (editable);
172

173 174
  if (iface->set_show_name)
    iface->set_show_name (editable, show_name);
175
}
176

177 178 179 180 181 182
/**
 * glade_editable_loaded_widget:
 * @editable: A #GladeEditable
 *
 * Returns: (transfer none) (nullable): a #GladeWidget or %NULL if the editable hasn't been loaded
 */
183
GladeWidget *
184
glade_editable_loaded_widget (GladeEditable *editable)
185 186 187
{
  return g_object_get_qdata (G_OBJECT (editable), glade_editable_widget_quark);
}
188

189
gboolean
190
glade_editable_loading (GladeEditable *editable)
191 192 193 194
{
  return GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (editable), glade_editable_loading_quark));
}

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
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);
}