Added functionality for GtkFixed (also replaced some ints with gints and

2004-10-22  Tristan Van Berkom  <tristan.van.berkom@gmail.com>

	* src/glade-gtk.c: Added functionality for GtkFixed (also replaced some
	  ints with gints and chopped down some lines).

	* src/glade-plugin.h: Added some headers for the plugin (needed for
	  GtkFixed)

	* src/glade-popup.c,src/glade-project.c: Replaced reference to
	  GLADE_WIDGET_IS_TOPLEVEL (support for deprication of flags on
	  GladeWidgetClass).

	* src/glade-project-view.c: Replaced reference to
	  GLADE_WIDGET_IS_TOPLEVEL (support for deprication of flags on
	  GladeWidgetClass).

	* src/glade-project-window.[ch]: Replace gpw->project with
	  gpw->active_project and added
	  glade_project_window_get_active_project() for clarity's sake.

	* src/glade-property-class.h: Added construct_only as a quick reference
	  (to G_PARAM_CONSTRUCT_ONLY).

	* src/glade-property.c: glade_property_set() will now check for
	  construct_only and call glade_widget_rebuild_instance() if needed.

	* src/glade-utils.c: fixed the queue_nodes code to add a reference on
	  the GladeWidget pertaining to the expose event, since the code
	  depends on the existance of the GladeWidget, the GtkWidget and the
	  GdkWindow as opposed to only the GdkWindow

	* src/glade-widget-class.c: Update construct_only tab upon construction
	  of GladePropertyClass structs. Removed set of depricated flags on
	  GladeWidgetClass.

	* src/glade-widget-class.h: Removed depricated flag macro definitions
	  (and removed the flags)

	* src/glade-widget.c:
	- Fixed Segfaults (Removed glade_widget_class_free() in finalize)
	- Objects are now built with thier properties as paramaters of
	  g_object_newv
	- Added glade_widget_rebuild_instance for the purpose of changing
	  properties that are flagged as G_PARAM_CONSTRUCT_ONLY.

	* pixmaps/fixed_bg.xpm: New picture for background of GtkFixed.

	* widgets/gtkfixed.xml,widgets/Makefile.am: Add definition of GtkFixed.
This commit is contained in:
Tristan Van Berkom 2004-10-22 16:19:39 +00:00 committed by David Hoover
parent bca2011ad7
commit 36e15441e2
20 changed files with 872 additions and 389 deletions

View File

@ -1,3 +1,52 @@
2004-10-22 Tristan Van Berkom <tristan.van.berkom@gmail.com>
* src/glade-gtk.c: Added functionality for GtkFixed (also replaced some
ints with gints and chopped down some lines).
* src/glade-plugin.h: Added some headers for the plugin (needed for
GtkFixed)
* src/glade-popup.c,src/glade-project.c: Replaced reference to
GLADE_WIDGET_IS_TOPLEVEL (support for deprication of flags on
GladeWidgetClass).
* src/glade-project-view.c: Replaced reference to
GLADE_WIDGET_IS_TOPLEVEL (support for deprication of flags on
GladeWidgetClass).
* src/glade-project-window.[ch]: Replace gpw->project with
gpw->active_project and added
glade_project_window_get_active_project() for clarity's sake.
* src/glade-property-class.h: Added construct_only as a quick reference
(to G_PARAM_CONSTRUCT_ONLY).
* src/glade-property.c: glade_property_set() will now check for
construct_only and call glade_widget_rebuild_instance() if needed.
* src/glade-utils.c: fixed the queue_nodes code to add a reference on
the GladeWidget pertaining to the expose event, since the code
depends on the existance of the GladeWidget, the GtkWidget and the
GdkWindow as opposed to only the GdkWindow
* src/glade-widget-class.c: Update construct_only tab upon construction
of GladePropertyClass structs. Removed set of depricated flags on
GladeWidgetClass.
* src/glade-widget-class.h: Removed depricated flag macro definitions
(and removed the flags)
* src/glade-widget.c:
- Fixed Segfaults (Removed glade_widget_class_free() in finalize)
- Objects are now built with thier properties as paramaters of
g_object_newv
- Added glade_widget_rebuild_instance for the purpose of changing
properties that are flagged as G_PARAM_CONSTRUCT_ONLY.
* pixmaps/fixed_bg.xpm: New picture for background of GtkFixed.
* widgets/gtkfixed.xml,widgets/Makefile.am: Add definition of GtkFixed.
2004-10-06 Morten Welinder <terra@gnome.org>
* widgets/gtkradiobutton.xml: Define the group property.

17
pixmaps/fixed_bg.xpm Normal file
View File

@ -0,0 +1,17 @@
/* XPM */
static char *fixed_bg_xpm[] = {
/* columns rows colors chars-per-pixel */
"8 8 2 1",
". c #bbbbbb",
" c #d6d6d6",
/* pixels */
" ",
" ",
" ",
" ",
" ",
" ",
" ..",
" ..",
" "
};

View File

@ -408,8 +408,6 @@ glade_command_set_property (GladeProperty *property, const GValue* pvalue)
g_assert (cmd->description);
g_free (value_name);
g_debug(("Pushing: %s\n", cmd->description));
glade_command_set_property_execute (GLADE_COMMAND (me));
glade_command_push_undo (gwidget->project, GLADE_COMMAND (me));
}
@ -552,6 +550,8 @@ typedef struct {
GladeWidget *widget;
GladePlaceholder *placeholder;
gboolean create;
gulong handler_id;
} GladeCommandCreateDelete;
GLADE_MAKE_COMMAND (GladeCommandCreateDelete, glade_command_create_delete);
@ -619,7 +619,7 @@ glade_command_delete_execute (GladeCommandCreateDelete *me)
static gboolean
glade_command_create_delete_execute (GladeCommand *cmd)
{
GladeCommandCreateDelete* me = (GladeCommandCreateDelete*) cmd;
GladeCommandCreateDelete *me = (GladeCommandCreateDelete*) cmd;
gboolean retval;
if (me->create)
@ -643,7 +643,7 @@ glade_command_create_delete_finalize (GObject *obj)
g_object_unref (cmd->placeholder);
g_object_unref (cmd->widget);
glade_command_finalize (obj);
}
@ -673,18 +673,16 @@ glade_command_create_delete_common (GladeWidget *widget,
me = g_object_new (GLADE_COMMAND_CREATE_DELETE_TYPE, NULL);
cmd = GLADE_COMMAND (me);
me->widget = widget;
me->create = create;
me->placeholder = placeholder;
cmd->description = g_strdup_printf (_("%s %s"), create ? "Create" : "Delete", widget->name);
g_object_ref (G_OBJECT (widget->widget));
me->widget = g_object_ref(widget);
me->create = create;
me->placeholder = placeholder;
cmd->description =
g_strdup_printf (_("%s %s"), create ?
"Create" : "Delete", widget->name);
if (placeholder)
g_object_ref (G_OBJECT (placeholder));
g_debug(("Pushing: %s\n", cmd->description));
if (glade_command_create_delete_execute (GLADE_COMMAND (me)));
glade_command_push_undo (widget->project, GLADE_COMMAND (me));
}
@ -906,13 +904,10 @@ glade_command_cut_paste_common (GladeWidget *widget,
gpw = glade_project_window_get ();
me->cut = cut;
me->widget = widget;
me->cut = cut;
me->widget = g_object_ref(widget);
me->placeholder = placeholder;
me->clipboard = gpw->clipboard;
if (me->widget)
g_object_ref (G_OBJECT (widget->widget));
me->clipboard = gpw->clipboard;
if (me->placeholder)
g_object_ref (G_OBJECT (me->placeholder));
@ -993,7 +988,7 @@ typedef struct {
gboolean add;
GladeSignal *signal;
GtkWidget *widget;
GladeWidget *widget;
} GladeCommandAddSignal;
/* standard macros */
@ -1009,6 +1004,7 @@ glade_command_add_signal_finalize (GObject *obj)
{
GladeCommandAddSignal *cmd = GLADE_COMMAND_ADD_SIGNAL (obj);
glade_signal_free (cmd->signal);
g_object_unref (cmd->widget);
glade_command_finalize (obj);
}
@ -1025,9 +1021,9 @@ glade_command_add_signal_execute (GladeCommand *this)
GladeCommandAddSignal *cmd = GLADE_COMMAND_ADD_SIGNAL (this);
if (cmd->add)
glade_widget_add_signal_handler (glade_widget_get_from_gtk_widget (cmd->widget), cmd->signal);
glade_widget_add_signal_handler (cmd->widget, cmd->signal);
else
glade_widget_remove_signal_handler (glade_widget_get_from_gtk_widget (cmd->widget), cmd->signal);
glade_widget_remove_signal_handler (cmd->widget, cmd->signal);
cmd->add = !cmd->add;
return TRUE;
@ -1050,20 +1046,22 @@ glade_command_add_remove_signal (GladeWidget *glade_widget, const GladeSignal *s
{
GladeCommandAddSignal *me = GLADE_COMMAND_ADD_SIGNAL (g_object_new (GLADE_COMMAND_ADD_SIGNAL_TYPE, NULL));
GladeCommand *cmd = GLADE_COMMAND (me);
GtkWidget *widget = glade_widget_get_widget (glade_widget);
/* we can only add/remove a signal to a widget that has been wrapped by a GladeWidget */
g_assert (glade_widget != NULL);
g_assert (glade_widget->project != NULL);
g_object_ref (widget);
me->widget = widget;
me->add = add;
me->signal = glade_signal_clone (signal);
me->widget = g_object_ref(glade_widget);
me->add = add;
me->signal = glade_signal_clone (signal);
if (add)
cmd->description = g_strdup_printf (_("Add signal handler %s"), signal->handler);
cmd->description =
g_strdup_printf (_("Add signal handler %s"),
signal->handler);
else
cmd->description = g_strdup_printf (_("Remove signal handler %s"), signal->handler);
cmd->description =
g_strdup_printf (_("Remove signal handler %s"),
signal->handler);
if (glade_command_add_signal_execute (cmd))
glade_command_push_undo (glade_widget->project, cmd);

View File

@ -26,6 +26,8 @@
#include <gtk/gtk.h>
#include "glade-plugin.h"
#include "../pixmaps/fixed_bg.xpm"
/* Borrow from libgnome/libgnome.h */
#ifdef ENABLE_NLS
# include <libintl.h>
@ -57,6 +59,11 @@
#define GLADEGTK_API
#endif
/* ------------------------------------ Constants ------------------------------ */
#define FIXED_DEFAULT_CHILD_WIDTH 100
#define FIXED_DEFAULT_CHILD_HEIGHT 60
/* ------------------------------------ Custom Properties ------------------------------ */
/**
* glade_gtk_option_menu_set_items:
* @object:
@ -108,7 +115,7 @@ glade_gtk_option_menu_set_items (GObject *object, GValue *value)
*
* TODO: write me
*/
int GLADEGTK_API
gint GLADEGTK_API
glade_gtk_widget_condition (GladeWidgetClass *klass)
{
GtkObject *object = (GtkObject*)g_object_new (klass->type, NULL);
@ -326,7 +333,8 @@ glade_gtk_box_set_size (GObject *object, GValue *value)
/* The box has grown. Add placeholders */
while (new_size > old_size)
{
GladePlaceholder *placeholder = GLADE_PLACEHOLDER (glade_placeholder_new ());
GladePlaceholder *placeholder =
GLADE_PLACEHOLDER (glade_placeholder_new ());
gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (placeholder));
old_size++;
}
@ -344,7 +352,8 @@ glade_gtk_box_set_size (GObject *object, GValue *value)
glade_widget = glade_widget_get_from_gtk_widget (child_widget);
if (glade_widget) /* it may be NULL, e.g a placeholder */
glade_project_remove_widget (glade_widget->project, child_widget);
glade_project_remove_widget
(glade_widget->project, child_widget);
gtk_container_remove (GTK_CONTAINER (box), child_widget);
@ -418,7 +427,8 @@ glade_gtk_toolbar_set_size (GObject *object, GValue *value)
glade_widget = glade_widget_get_from_gtk_widget (child_widget);
if (glade_widget)
glade_project_remove_widget (glade_widget->project, child_widget);
glade_project_remove_widget
(glade_widget->project, child_widget);
gtk_container_remove (GTK_CONTAINER (toolbar), child_widget);
@ -478,7 +488,8 @@ glade_gtk_notebook_set_n_pages (GObject *object, GValue *value)
if (new_size > old_size) {
/* The notebook has grown. Add a page. */
while (new_size > old_size) {
GladePlaceholder *placeholder = GLADE_PLACEHOLDER (glade_placeholder_new ());
GladePlaceholder *placeholder =
GLADE_PLACEHOLDER (glade_placeholder_new ());
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
GTK_WIDGET (placeholder),
NULL);
@ -504,7 +515,8 @@ glade_gtk_notebook_set_n_pages (GObject *object, GValue *value)
* from project.
*/
if (child_gwidget)
glade_project_remove_widget (child_gwidget->project, child_widget);
glade_project_remove_widget
(child_gwidget->project, child_widget);
gtk_notebook_remove_page (notebook, old_size-1);
old_size--;
@ -524,9 +536,9 @@ glade_gtk_table_set_n_common (GObject *object, GValue *value, gboolean for_rows)
{
GladeWidget *widget;
GtkTable *table;
int new_size;
int old_size;
int i, j;
gint new_size;
gint old_size;
gint i, j;
table = GTK_TABLE (object);
g_return_if_fail (GTK_IS_TABLE (table));
@ -548,19 +560,22 @@ glade_gtk_table_set_n_common (GObject *object, GValue *value, gboolean for_rows)
for (i = 0; i < table->ncols; i++)
for (j = old_size; j < table->nrows; j++)
gtk_table_attach_defaults (table, glade_placeholder_new (),
gtk_table_attach_defaults
(table, glade_placeholder_new (),
i, i + 1, j, j + 1);
} else {
gtk_table_resize (table, table->nrows, new_size);
for (i = old_size; i < table->ncols; i++)
for (j = 0; j < table->nrows; j++)
gtk_table_attach_defaults (table, glade_placeholder_new (),
gtk_table_attach_defaults
(table, glade_placeholder_new (),
i, i + 1, j, j + 1);
}
} else {
/* Remove from the bottom up */
GList *list = g_list_reverse (gtk_container_get_children (GTK_CONTAINER (table)));
GList *list = g_list_reverse
(g_list_copy (gtk_container_get_children (GTK_CONTAINER (table))));
GList *freeme = list;
for (; list; list = list->next) {
GtkTableChild *child = list->data;
@ -574,11 +589,13 @@ glade_gtk_table_set_n_common (GObject *object, GValue *value, gboolean for_rows)
continue;
}
/* If the widget spans beyond the new border, we should resize it to fit on the new table */
/* If the widget spans beyond the new border,
* we should resize it to fit on the new table */
if (end > new_size)
gtk_container_child_set (GTK_CONTAINER (table), GTK_WIDGET (child),
for_rows ? "bottom_attach" : "right_attach",
new_size, NULL);
gtk_container_child_set
(GTK_CONTAINER (table), GTK_WIDGET (child),
for_rows ? "bottom_attach" : "right_attach",
new_size, NULL);
}
g_list_free (freeme);
@ -587,7 +604,9 @@ glade_gtk_table_set_n_common (GObject *object, GValue *value, gboolean for_rows)
for_rows ? table->ncols : new_size);
}
g_object_set_data (object, "glade_nb_placeholders", GINT_TO_POINTER (new_size * (for_rows ? table->ncols : table->nrows)));
g_object_set_data (object, "glade_nb_placeholders",
GINT_TO_POINTER
(new_size * (for_rows ? table->ncols : table->nrows)));
}
/**
@ -790,22 +809,25 @@ glade_gtk_tree_view_pre_create (GObject *object)
g_object_unref (G_OBJECT (store));
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Column 1", renderer, "text", 0, NULL);
column = gtk_tree_view_column_new_with_attributes
("Column 1", renderer, "text", 0, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Column 2", renderer, "text", 1, NULL);
column = gtk_tree_view_column_new_with_attributes
("Column 2", renderer, "text", 1, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
}
/* ------------------------- Post Create functions ------------------------- */
static int
ask_for_number (const char *title, const char *name, int min, int max, int def)
static gint
ask_for_number (const gchar *title, const gchar *name, gint min, gint max, gint def)
{
int number;
GtkWidget *dialog = gtk_dialog_new_with_buttons (title, NULL,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
gint number;
GtkWidget *dialog = gtk_dialog_new_with_buttons
(title, NULL,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
GtkWidget *label = gtk_label_new (name);
GtkWidget *spin_button = gtk_spin_button_new_with_range ((double) min, (double) max, 1.0);
GtkWidget *hbox = gtk_hbox_new (FALSE, 4);
@ -826,7 +848,9 @@ ask_for_number (const char *title, const char *name, int min, int max, int def)
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 4);
gtk_widget_show_all (hbox);
/* even if the user destroys the dialog box, we retrieve the number and we accept it. I.e., this function never fails */
/* even if the user destroys the dialog box, we retrieve the number and we accept it.
* I.e., this function never fails */
gtk_dialog_run (GTK_DIALOG (dialog));
number = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_button));
@ -845,11 +869,14 @@ ask_for_number (const char *title, const char *name, int min, int max, int def)
void GLADEGTK_API
glade_gtk_box_post_create (GObject *object)
{
GladeProperty *property = glade_widget_get_property (glade_widget_get_from_gtk_widget (object), "size");
GladeProperty *property =
glade_widget_get_property
(glade_widget_get_from_gtk_widget (object), "size");
GValue value = {0,};
g_value_init (&value, G_TYPE_INT);
g_value_set_int (&value, ask_for_number(_("Create a box"), _("Number of items:"), 0, 10000, 3));
g_value_set_int (&value, ask_for_number(_("Create a box"),
_("Number of items:"), 0, 10000, 3));
glade_property_set (property, &value);
}
@ -863,13 +890,90 @@ glade_gtk_box_post_create (GObject *object)
void GLADEGTK_API
glade_gtk_notebook_post_create (GObject *object)
{
GladeProperty *property = glade_widget_get_property (glade_widget_get_from_gtk_widget (object), "size");
GValue value = {0,};
g_value_init (&value, G_TYPE_INT);
g_value_set_int (&value, ask_for_number(_("Create a notebook"), _("Number of pages:"), 0, 100, 3));
g_value_set_int (&value, ask_for_number(_("Create a notebook"),
_("Number of pages:"), 0, 100, 3));
}
glade_property_set (property, &value);
static gboolean
glade_gtk_fixed_button_press (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
GladeProjectWindow *gpw;
if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
{
gpw = glade_project_window_get ();
if (gpw->add_class != NULL)
{
GtkWidget *placeholder = glade_placeholder_new ();
GList *selection;
/* A widget type is selected in the palette.
* Create a placeholder at the mouse position and
* add a new widget of that type with a default
* size request.
*/
gtk_fixed_put(GTK_FIXED(widget), placeholder,
(gint)event->x, (gint)event->y);
glade_command_create (gpw->add_class,
GLADE_PLACEHOLDER(placeholder), NULL);
selection = glade_project_selection_get
(glade_project_window_get_active_project(gpw));
gtk_widget_set_size_request(GTK_WIDGET(selection->data),
FIXED_DEFAULT_CHILD_WIDTH,
FIXED_DEFAULT_CHILD_HEIGHT);
}
return TRUE;
}
return FALSE;
}
void
glade_gtk_fixed_finalize(GdkPixmap *backing)
{
g_object_unref(backing);
}
void
glade_gtk_fixed_realize (GtkWidget *widget)
{
GdkPixmap *backing =
gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (widget),
NULL, NULL, fixed_bg_xpm);
gdk_window_set_back_pixmap (widget->window, backing, FALSE);
/* For cleanup later
*/
g_object_weak_ref(G_OBJECT(widget), (GWeakNotify)glade_gtk_fixed_finalize, backing);
}
void GLADEGTK_API
glade_gtk_fixed_post_create (GObject *object)
{
/* Only widgets with windows can recieve
* mouse events
*/
GTK_WIDGET_UNSET_FLAGS(object, GTK_NO_WINDOW);
gtk_widget_add_events(GTK_WIDGET(object),
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK);
/* For backing pixmap
*/
g_signal_connect_after(object, "realize",
G_CALLBACK(glade_gtk_fixed_realize), NULL);
/* Menu will be activated on mouse clicks
*/
g_signal_connect(object, "button-press-event",
G_CALLBACK(glade_gtk_fixed_button_press), NULL);
}
/**
@ -886,9 +990,12 @@ glade_gtk_table_post_create (GObject *object)
GladeProperty *property_cols = glade_widget_get_property (widget, "n-columns");
GValue gvrows = {0,};
GValue gvcols = {0,};
GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Create a table"), NULL,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
GtkWidget *dialog =
gtk_dialog_new_with_buttons (_("Create a table"), NULL,
GTK_DIALOG_MODAL |
GTK_DIALOG_DESTROY_WITH_PARENT |
GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
GtkWidget *label_rows = gtk_label_new (_("Number of rows:"));
GtkWidget *label_cols = gtk_label_new (_("Number of columns:"));
GtkWidget *spin_button_rows = gtk_spin_button_new_with_range (0.0, 10000.0, 1.0);
@ -922,11 +1029,14 @@ glade_gtk_table_post_create (GObject *object)
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);
gtk_widget_show_all (table);
/* even if the user destroys the dialog box, we retrieve the number and we accept it. I.e., this function never fails */
/* even if the user destroys the dialog box, we retrieve the number and we accept it.
* I.e., this function never fails */
gtk_dialog_run (GTK_DIALOG (dialog));
g_value_set_int (&gvrows, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_button_rows)));
g_value_set_int (&gvcols, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_button_cols)));
g_value_set_int (&gvrows, gtk_spin_button_get_value_as_int
(GTK_SPIN_BUTTON (spin_button_rows)));
g_value_set_int (&gvcols, gtk_spin_button_get_value_as_int
(GTK_SPIN_BUTTON (spin_button_cols)));
glade_property_set (property_rows, &gvrows);
glade_property_set (property_cols, &gvcols);
@ -984,9 +1094,13 @@ glade_gtk_dialog_post_create (GObject *object)
if (!child_class)
return;
gtk_box_pack_start (GTK_BOX (dialog->action_area), GTK_WIDGET (glade_placeholder_new ()), TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (dialog->action_area), GTK_WIDGET (glade_placeholder_new ()), TRUE, TRUE, 0);
actionarea_widget = glade_widget_new_for_internal_child (child_class, vbox_widget, dialog->action_area, "action_area");
gtk_box_pack_start (GTK_BOX (dialog->action_area),
GTK_WIDGET (glade_placeholder_new ()), TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (dialog->action_area),
GTK_WIDGET (glade_placeholder_new ()), TRUE, TRUE, 0);
actionarea_widget =
glade_widget_new_for_internal_child
(child_class, vbox_widget, dialog->action_area, "action_area");
if (!actionarea_widget)
return;
@ -1056,30 +1170,35 @@ glade_gtk_container_replace_child (GtkWidget *current,
if (current->parent != container)
return;
param_spec = gtk_container_class_list_child_properties (G_OBJECT_GET_CLASS (container), &nproperties);
value = calloc (nproperties, sizeof (GValue));
if (nproperties != 0 && (param_spec == 0 || value == 0))
// TODO: Signal the not enough memory condition
return;
param_spec = gtk_container_class_list_child_properties
(G_OBJECT_GET_CLASS (container), &nproperties);
value = g_malloc0 (sizeof(GValue) * nproperties);
for (i = 0; i < nproperties; i++) {
g_value_init (&value[i], param_spec[i]->value_type);
gtk_container_child_get_property (GTK_CONTAINER (container), current, param_spec[i]->name, &value[i]);
gtk_container_child_get_property
(GTK_CONTAINER (container), current, param_spec[i]->name, &value[i]);
}
gtk_container_remove (GTK_CONTAINER (container), current);
gtk_container_add (GTK_CONTAINER (container), new);
for (i = 0; i < nproperties; i++)
gtk_container_child_set_property (GTK_CONTAINER (container), new, param_spec[i]->name, &value[i]);
for (i = 0; i < nproperties; i++) {
gtk_container_child_set_property
(GTK_CONTAINER (container), new, param_spec[i]->name, &value[i]);
}
for (i = 0; i < nproperties; i++)
g_value_unset (&value[i]);
g_free (param_spec);
free (value);
g_free (value);
#if 0
/* If there is still no reason to keep this around come release
* time, kill it.
*/
gtk_widget_unparent (child_info->widget);
child_info->widget = new;
gtk_widget_set_parent (child_info->widget, GTK_WIDGET (container));
@ -1156,10 +1275,18 @@ void GLADEGTK_API
glade_gtk_container_fill_empty (GObject *container)
{
g_return_if_fail (GTK_IS_CONTAINER (container));
gtk_container_add (GTK_CONTAINER (container), glade_placeholder_new ());
}
void GLADEGTK_API
glade_gtk_fixed_fill_empty (GObject *fixed)
{
/* This is here purly to override `glade_gtk_container_fill_empty()'
* there is to be no placeholder by default.
*/
}
/**
* glade_gtk_dialog_fill_empty:
* @dialog:
@ -1238,7 +1365,8 @@ glade_gtk_dialog_child_property_applies (GtkWidget *ancestor,
if (strcmp(property_id, "response-id") == 0)
{
if (GTK_IS_HBUTTON_BOX (widget->parent) && GTK_IS_VBOX (widget->parent->parent) &&
if (GTK_IS_HBUTTON_BOX (widget->parent) &&
GTK_IS_VBOX (widget->parent->parent) &&
widget->parent->parent->parent == ancestor)
return TRUE;
}

View File

@ -5,6 +5,8 @@
#include "glade-widget-class.h"
#include "glade-widget.h"
#include "glade-project.h"
#include "glade-project-window.h"
#include "glade-command.h"
#include "glade-property.h"
#include "glade-property-class.h"
#include "glade-choice.h"

View File

@ -147,7 +147,8 @@ glade_popup_create_menu (GladeWidget *widget, gboolean add_childs)
glade_popup_append_item (popup_menu, GTK_STOCK_DELETE, NULL, TRUE,
glade_popup_delete_cb, widget);
if (add_childs && !GLADE_WIDGET_IS_TOPLEVEL (widget)) {
if (add_childs &&
!g_type_is_a (widget->widget_class->type, GTK_TYPE_WINDOW)) {
GladeWidget *parent = glade_widget_get_parent (widget);
g_return_val_if_fail (GLADE_IS_WIDGET (parent), popup_menu);
glade_popup_populate_childs(popup_menu, parent);

View File

@ -153,7 +153,8 @@ glade_project_view_widget_name_changed (GladeProjectView *view,
GtkTreeIter *iter;
GtkTreePath *path;
if (view->is_list && !GLADE_WIDGET_IS_TOPLEVEL (findme))
if (view->is_list &&
!g_type_is_a (findme->widget_class->type, GTK_TYPE_WINDOW))
return;
model = GTK_TREE_MODEL (view->model);
@ -252,8 +253,8 @@ glade_project_view_add_item (GladeProjectView *view,
g_return_if_fail (widget != NULL);
class = glade_widget_get_class (widget);
if (view->is_list && !GLADE_WIDGET_CLASS_TOPLEVEL (class))
if (view->is_list && !g_type_is_a (class->type, GTK_TYPE_WINDOW))
return;
model = view->model;
@ -283,7 +284,7 @@ glade_project_view_remove_item (GladeProjectView *view,
class = glade_widget_get_class (widget);
if (view->is_list && !GLADE_WIDGET_CLASS_TOPLEVEL (class))
if (view->is_list && !g_type_is_a (class->type, GTK_TYPE_WINDOW))
return;
model = GTK_TREE_MODEL (view->model);
@ -327,7 +328,7 @@ glade_project_view_selection_update (GladeProjectView *view,
class = glade_widget_get_class (widget);
if (view->is_list && !GLADE_WIDGET_CLASS_TOPLEVEL (class))
if (view->is_list && !g_type_is_a (class->type, GTK_TYPE_WINDOW))
return;
model = GTK_TREE_MODEL (view->model);

View File

@ -51,8 +51,8 @@ gpw_refresh_title (GladeProjectWindow *gpw)
{
gchar *title;
if (gpw->project)
title = g_strdup_printf ("glade3 - %s", gpw->project->name);
if (gpw->active_project)
title = g_strdup_printf ("glade3 - %s", gpw->active_project->name);
else
title = g_strdup_printf ("glade3");
@ -90,7 +90,7 @@ glade_project_window_set_project (GladeProject *project)
gpw = glade_project_window_get ();
if (gpw->project == project)
if (gpw->active_project == project)
return;
if (!g_list_find (gpw->projects, project))
@ -101,10 +101,10 @@ glade_project_window_set_project (GladeProject *project)
}
/* clear the selection in the previous project */
if (gpw->project)
glade_project_selection_clear (gpw->project, FALSE);
if (gpw->active_project)
glade_project_selection_clear (gpw->active_project, FALSE);
gpw->project = project;
gpw->active_project = project;
gpw_refresh_title (gpw);
for (list = gpw->views; list; list = list->next)
@ -178,7 +178,7 @@ gpw_save_cb (void)
const gchar *path = NULL;
gpw = glade_project_window_get ();
project = gpw->project;
project = gpw->active_project;
if (project->path != NULL) {
if (glade_project_save (project, project->path)) {
@ -222,7 +222,7 @@ gpw_save_as_cb (void)
const gchar *path = NULL;
gpw = glade_project_window_get ();
project = gpw->project;
project = gpw->active_project;
filechooser = glade_util_file_chooser_new (_("Save as ..."), GTK_WINDOW (gpw->window),
GTK_FILE_CHOOSER_ACTION_SAVE);
@ -349,7 +349,7 @@ gpw_close_cb (void)
gboolean close;
gpw = glade_project_window_get ();
project = gpw->project;
project = gpw->active_project;
if (!project)
return;
@ -365,7 +365,7 @@ gpw_close_cb (void)
/* this is needed to prevent clearing the selection of a closed project
*/
gpw->project = NULL;
gpw->active_project = NULL;
/* If no more projects */
if (gpw->projects == NULL)
@ -422,7 +422,7 @@ gpw_copy_cb (void)
GList *list;
gpw = glade_project_window_get ();
list = glade_project_selection_get (gpw->project);
list = glade_project_selection_get (gpw->active_project);
/* TODO: support multiple selected items */
if (list != NULL && list->next == NULL)
{
@ -440,7 +440,7 @@ gpw_cut_cb (void)
GList *list;
gpw = glade_project_window_get ();
list = glade_project_selection_get (gpw->project);
list = glade_project_selection_get (gpw->active_project);
/* TODO: support multiple selected items */
if (list != NULL && list->next == NULL)
{
@ -459,7 +459,7 @@ gpw_paste_cb (void)
gpw = glade_project_window_get ();
selection = glade_project_selection_get (gpw->project);
selection = glade_project_selection_get (gpw->active_project);
if (selection != NULL && selection->next == NULL && GLADE_IS_PLACEHOLDER (selection->data))
glade_command_paste (GLADE_PLACEHOLDER (selection->data));
}
@ -470,16 +470,15 @@ gpw_delete_cb (void)
GladeProjectWindow *gpw;
gpw = glade_project_window_get ();
if (!gpw->project)
if (!gpw->active_project)
{
g_warning ("delete should not be sensitive: we don't have a project");
return;
}
/* glade_util_delete_selection performs a glade_command_delete
* on each of the selected widgets
*/
glade_util_delete_selection (gpw->project);
* on each of the selected widgets */
glade_util_delete_selection (gpw->active_project);
}
static void
@ -488,13 +487,13 @@ gpw_undo_cb (void)
GladeProjectWindow *gpw;
gpw = glade_project_window_get ();
if (!gpw->project)
if (!gpw->active_project)
{
g_warning ("undo should not be sensitive: we don't have a project");
return;
}
glade_command_undo (gpw->project);
glade_command_undo (gpw->active_project);
glade_project_window_refresh_undo_redo ();
}
@ -505,13 +504,13 @@ gpw_redo_cb (void)
GladeProjectWindow *gpw;
gpw = glade_project_window_get ();
if (!gpw->project)
if (!gpw->active_project)
{
g_warning ("redo should not be sensitive: we don't have a project");
return;
}
glade_command_redo (gpw->project);
glade_command_redo (gpw->active_project);
glade_project_window_refresh_undo_redo ();
}
@ -543,9 +542,9 @@ gpw_palette_button_clicked (GladePalette *palette, gpointer not_used)
class = palette->current;
/* class may be NULL if the selector was pressed */
if (class && GLADE_WIDGET_CLASS_TOPLEVEL (class))
if (class && g_type_is_a (class->type, GTK_TYPE_WINDOW))
{
glade_command_create (class, NULL, gpw->project);
glade_command_create (class, NULL, gpw->active_project);
gpw->add_class = NULL;
}
else
@ -719,7 +718,7 @@ gpw_create_widget_tree (GladeProjectWindow *gpw)
view = glade_project_view_new (GLADE_PROJECT_VIEW_TREE);
gpw->views = g_list_prepend (gpw->views, view);
glade_project_view_set_project (view, gpw->project);
glade_project_view_set_project (view, gpw->active_project);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
GTK_POLICY_NEVER, GTK_POLICY_NEVER);
@ -1139,8 +1138,10 @@ gpw_construct_statusbar (GladeProjectWindow *gpw)
statusbar = gtk_statusbar_new ();
gpw->statusbar = statusbar;
gpw->statusbar_menu_context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar), "menu");
gpw->statusbar_actions_context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar), "actions");
gpw->statusbar_menu_context_id =
gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar), "menu");
gpw->statusbar_actions_context_id =
gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar), "actions");
return statusbar;
}
@ -1301,7 +1302,7 @@ gpw_project_selection_changed_cb (GladeProject *project,
g_return_if_fail (GLADE_IS_PROJECT (project));
g_return_if_fail (GLADE_IS_PROJECT_WINDOW (gpw));
if (gpw->project != project)
if (gpw->active_project != project)
{
glade_project_window_set_project (project);
return;
@ -1312,7 +1313,9 @@ gpw_project_selection_changed_cb (GladeProject *project,
list = glade_project_selection_get (project);
num = g_list_length (list);
if (num == 1 && !GLADE_IS_PLACEHOLDER (list->data))
glade_editor_load_widget (gpw->editor, glade_widget_get_from_gtk_widget (GTK_WIDGET (list->data)));
glade_editor_load_widget (gpw->editor,
glade_widget_get_from_gtk_widget
(GTK_WIDGET (list->data)));
else
glade_editor_load_widget (gpw->editor, NULL);
}
@ -1486,7 +1489,7 @@ glade_project_window_refresh_undo_redo (void)
gpw = glade_project_window_get ();
project = gpw->project;
project = gpw->active_project;
if (!project)
{
undo_item = NULL;
@ -1526,3 +1529,9 @@ glade_project_window_show_all (void)
gpw_show_palette (gpw);
gpw_show_editor (gpw);
}
GladeProject *
glade_project_window_get_active_project (GladeProjectWindow *gpw)
{
return gpw->active_project;
}

View File

@ -25,7 +25,8 @@ struct _GladeProjectWindow
* We need it to be able to later add
* items to the Project submenu
*/
GladeProject *project; /* See glade-project */
GladeProject *active_project; /* Currently active project (if there is at least one
* project; then this is always valid) */
GtkWidget *widget_tree; /* The widget tree window*/
GtkWindow *palette_window; /* The window that will contain the palette */
GladePalette *palette; /* See glade-palette */
@ -60,6 +61,7 @@ void glade_project_window_open_project (const gchar *path);
void glade_project_window_refresh_undo_redo (void);
GladeProject *glade_project_window_get_active_project (GladeProjectWindow *gpw);
G_END_DECLS

View File

@ -700,7 +700,8 @@ glade_project_write (GladeXmlContext *context, const GladeProject *project)
* Append toplevel widgets. Each widget then takes
* care of appending its children.
*/
if (GLADE_WIDGET_IS_TOPLEVEL (widget)) {
if (g_type_is_a
(widget->widget_class->type, GTK_TYPE_WINDOW)) {
child = glade_widget_write (widget, context);
if (!child)
return NULL;

View File

@ -144,6 +144,8 @@ struct _GladePropertyClass
*/
gboolean optional_default; /* For optional values, what the default is */
gboolean construct_only; /* Whether this property is G_PARAM_CONSTRUCT_ONLY or not */
GladeWidgetClass *child; /* A GladeWidgetClass pointer of objects
* that we need to set for this widget
* for example : GtkSpinButton has a Adjustment inside
@ -194,7 +196,6 @@ gboolean glade_property_class_update_from_node (GladeXmlNode *node,
GladeWidgetClass *widget_class,
GladePropertyClass **property_class);
G_END_DECLS
#endif /* __GLADE_PROPERTY_CLASS_H__ */

View File

@ -162,7 +162,7 @@ glade_property_set (GladeProperty *property, const GValue *value)
{
g_return_if_fail (GLADE_IS_PROPERTY (property));
g_return_if_fail (value != NULL);
if (!g_value_type_compatible (G_VALUE_TYPE (property->value), G_VALUE_TYPE (value)))
{
g_warning ("Trying to assign an incompatible value to property %s\n",
@ -178,15 +178,21 @@ glade_property_set (GladeProperty *property, const GValue *value)
property->loading = TRUE;
/* if there is a custom set_property, use it */
if (property->class->set_function)
/* Assign property first so that; if the object need be
* rebuilt, it will reflect the new value
*/
g_value_reset (property->value);
g_value_copy (value, property->value);
if (property->class->construct_only)
/* if we cant set it, rebuild it */
glade_widget_rebuild (property->widget);
else if (property->class->set_function)
/* if there is a custom set_property, use it */
(*property->class->set_function) (G_OBJECT (property->widget->widget), value);
else
glade_property_set_property (property, value);
g_value_reset (property->value);
g_value_copy (value, property->value);
property->loading = FALSE;
}

View File

@ -51,6 +51,8 @@ glade_util_widget_set_tooltip (GtkWidget *widget, const gchar *str)
GtkTooltips *tooltips;
tooltips = gtk_tooltips_new ();
g_object_ref (G_OBJECT (tooltips));
gtk_object_sink (GTK_OBJECT (tooltips));
g_object_set_data_full (G_OBJECT (widget),
"tooltips", tooltips,
(GDestroyNotify) g_object_unref);
@ -69,7 +71,7 @@ GType
glade_util_get_type_from_name (const gchar *name)
{
static GModule *allsymbols;
guint (*get_type) ();
GType (*get_type) ();
GType type;
if (!allsymbols)
@ -88,7 +90,7 @@ glade_util_get_type_from_name (const gchar *name)
if (type == 0) {
g_warning(_("Could not get the type from \"%s"),
name);
return FALSE;
return 0;
}
/* Disabled for GtkAdjustment, but i'd like to check for this somehow. Chema */
@ -365,7 +367,8 @@ glade_util_file_chooser_new (const gchar *title, GtkWindow *parent,
file_chooser = gtk_file_chooser_dialog_new (title, parent, action,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
action == GTK_FILE_CHOOSER_ACTION_OPEN ? GTK_STOCK_OPEN : GTK_STOCK_SAVE,
action == GTK_FILE_CHOOSER_ACTION_OPEN ?
GTK_STOCK_OPEN : GTK_STOCK_SAVE,
GTK_RESPONSE_OK,
NULL);
@ -469,17 +472,21 @@ glade_util_draw_nodes (GdkWindow *window, GdkGC *gc,
if (width > GLADE_UTIL_SELECTION_NODE_SIZE && height > GLADE_UTIL_SELECTION_NODE_SIZE) {
gdk_draw_rectangle (window, gc, TRUE,
x, y,
GLADE_UTIL_SELECTION_NODE_SIZE, GLADE_UTIL_SELECTION_NODE_SIZE);
GLADE_UTIL_SELECTION_NODE_SIZE,
GLADE_UTIL_SELECTION_NODE_SIZE);
gdk_draw_rectangle (window, gc, TRUE,
x, y + height - GLADE_UTIL_SELECTION_NODE_SIZE,
GLADE_UTIL_SELECTION_NODE_SIZE, GLADE_UTIL_SELECTION_NODE_SIZE);
GLADE_UTIL_SELECTION_NODE_SIZE,
GLADE_UTIL_SELECTION_NODE_SIZE);
gdk_draw_rectangle (window, gc, TRUE,
x + width - GLADE_UTIL_SELECTION_NODE_SIZE, y,
GLADE_UTIL_SELECTION_NODE_SIZE, GLADE_UTIL_SELECTION_NODE_SIZE);
GLADE_UTIL_SELECTION_NODE_SIZE,
GLADE_UTIL_SELECTION_NODE_SIZE);
gdk_draw_rectangle (window, gc, TRUE,
x + width - GLADE_UTIL_SELECTION_NODE_SIZE,
y + height - GLADE_UTIL_SELECTION_NODE_SIZE,
GLADE_UTIL_SELECTION_NODE_SIZE, GLADE_UTIL_SELECTION_NODE_SIZE);
GLADE_UTIL_SELECTION_NODE_SIZE,
GLADE_UTIL_SELECTION_NODE_SIZE);
}
gdk_draw_rectangle (window, gc, FALSE, x, y, width - 1, height - 1);
@ -565,35 +572,35 @@ glade_util_can_draw_nodes (GtkWidget *sel_widget, GdkWindow *sel_win,
gboolean
glade_util_draw_nodes_idle (GdkWindow *expose_win)
{
GladeWidget *expose_gwidget;
GtkWidget *expose_widget;
gint expose_win_x, expose_win_y;
gint expose_win_w, expose_win_h;
GdkWindow *expose_toplevel;
GladeWidget *expose_gwidget;
GdkWindow *expose_toplevel;
GdkGC *gc;
GList *elem;
/* Find the corresponding GtkWidget and GladeWidget. */
gdk_window_get_user_data (expose_win, (gpointer *)&expose_widget);
if ((expose_gwidget = glade_widget_get_from_gtk_widget(expose_widget)) == NULL)
{
expose_gwidget = glade_util_get_parent (expose_widget);
}
g_assert(expose_gwidget);
/* Check that the window is still alive. */
if (!gdk_window_is_viewable (expose_win))
goto out;
/* Find the corresponding GtkWidget and GladeWidget. */
gdk_window_get_user_data (expose_win, (gpointer*) &expose_widget);
gc = expose_widget->style->black_gc;
expose_gwidget = glade_widget_get_from_gtk_widget (expose_widget);
if (!expose_gwidget)
expose_gwidget = glade_util_get_parent (expose_widget);
if (!expose_gwidget)
goto out;
/* Calculate the offset of the expose window within its toplevel. */
glade_util_calculate_window_offset (expose_win,
&expose_win_x,
&expose_win_y,
&expose_toplevel);
gdk_drawable_get_size (expose_win,
&expose_win_w, &expose_win_h);
@ -633,8 +640,8 @@ glade_util_draw_nodes_idle (GdkWindow *expose_win)
out:
/* Remove the reference added in glade_util_queue_draw_nodes(). */
gdk_window_unref (expose_win);
g_object_unref(G_OBJECT(expose_gwidget));
/* Return FALSE so the idle handler isn't called again. */
return FALSE;
}
@ -643,7 +650,7 @@ glade_util_draw_nodes_idle (GdkWindow *expose_win)
/**
* glade_util_queue_draw_nodes:
* @window:
* @window: A #GdkWindow
*
* This function should be called whenever a widget in the interface receives
* an expose event. It sets up an idle function which will redraw any selection
@ -652,17 +659,31 @@ glade_util_draw_nodes_idle (GdkWindow *expose_win)
void
glade_util_queue_draw_nodes (GdkWindow *window)
{
GtkWidget *widget;
GladeWidget *gwidget;
g_return_if_fail (GDK_IS_WINDOW (window));
/* We need to ref the window, to make sure it isn't freed before
our idle function is called. We unref it there. */
gdk_window_ref (window);
gdk_window_get_user_data (window, (gpointer *)&widget);
if ((gwidget = glade_widget_get_from_gtk_widget(widget)) == NULL)
{
gwidget = glade_util_get_parent (widget);
}
g_idle_add_full (GLADE_DRAW_NODES_IDLE_PRIORITY,
(GSourceFunc) glade_util_draw_nodes_idle,
window, NULL);
if (gwidget) {
g_idle_add_full (GLADE_DRAW_NODES_IDLE_PRIORITY,
(GSourceFunc)glade_util_draw_nodes_idle,
window, NULL);
/* We need to ref the glade widget, to make sure it isn't freed before
* our idle function is called. We unref it there. (ofcourse, the glade
* widget holds reference to everything we need there).
*/
g_object_ref (G_OBJECT(gwidget));
}
}
/**
* glade_util_add_nodes:
* @widget: a #GtkWidget
@ -702,7 +723,8 @@ glade_util_remove_nodes (GtkWidget *widget)
gboolean
glade_util_has_nodes (GtkWidget *widget)
{
return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), GLADE_UTIL_HAS_NODES)) != 0;
return GPOINTER_TO_INT (g_object_get_data
(G_OBJECT (widget), GLADE_UTIL_HAS_NODES)) != 0;
}
/**
@ -885,8 +907,9 @@ glade_util_object_set_property (GObject *object, GladeProperty *property)
{
GValue void_string = {0,};
GValue *value = property->value;
if (G_VALUE_HOLDS_STRING (property->value) && g_value_get_string (property->value) == NULL)
if (G_VALUE_HOLDS_STRING (property->value) &&
g_value_get_string (property->value) == NULL)
{
g_value_init (&void_string, G_TYPE_STRING);
g_value_set_static_string (&void_string, "");

View File

@ -46,6 +46,7 @@
/* hash table that will contain all the GtkWidgetClass'es created, indexed by its name */
static GHashTable *widget_classes = NULL;
static gchar *
glade_widget_class_compose_get_type_func (GladeWidgetClass *class)
{
@ -155,6 +156,10 @@ glade_widget_class_list_properties (GladeWidgetClass *class)
property_class->optional = FALSE;
/* Flag the construct only properties */
if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
property_class->construct_only = TRUE;
list = g_list_prepend (list, property_class);
}
}
@ -206,9 +211,14 @@ glade_widget_class_list_child_properties (GladeWidgetClass *class)
property_class->optional = FALSE;
property_class->packing = TRUE;
/* Flag the construct only properties */
if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
property_class->construct_only = TRUE;
list = g_list_prepend (list, property_class);
}
}
}
list = g_list_reverse (list);
@ -288,7 +298,8 @@ glade_widget_class_update_properties_from_node (GladeXmlNode *node,
if (!glade_xml_node_verify (child, GLADE_TAG_PROPERTY))
continue;
id = glade_xml_get_property_string_required (child, GLADE_TAG_ID, widget_class->name);
id = glade_xml_get_property_string_required
(child, GLADE_TAG_ID, widget_class->name);
if (!id)
continue;
@ -311,10 +322,12 @@ glade_widget_class_update_properties_from_node (GladeXmlNode *node,
list = g_list_last (properties);
}
updated = glade_property_class_update_from_node (child, widget_class, &property_class);
updated = glade_property_class_update_from_node
(child, widget_class, &property_class);
if (!updated)
{
g_warning ("failed to update %s property of %s from xml", id, widget_class->name);
g_warning ("failed to update %s property of %s from xml",
id, widget_class->name);
g_free (id);
continue;
}
@ -325,8 +338,6 @@ glade_widget_class_update_properties_from_node (GladeXmlNode *node,
g_free (id);
}
*pproperties = properties;
}
/**
@ -358,7 +369,8 @@ glade_widget_class_extend_with_file (GladeWidgetClass *widget_class, const char
g_return_val_if_fail (filename != NULL, FALSE);
context = glade_xml_context_new_from_path (filename, NULL, GLADE_TAG_GLADE_WIDGET_CLASS);
context = glade_xml_context_new_from_path
(filename, NULL, GLADE_TAG_GLADE_WIDGET_CLASS);
if (!context)
return FALSE;
@ -369,50 +381,69 @@ glade_widget_class_extend_with_file (GladeWidgetClass *widget_class, const char
return FALSE;
}
replace_child_function_name = glade_xml_get_value_string (node, GLADE_TAG_REPLACE_CHILD_FUNCTION);
replace_child_function_name =
glade_xml_get_value_string (node, GLADE_TAG_REPLACE_CHILD_FUNCTION);
if (replace_child_function_name && widget_class->module)
{
if (!g_module_symbol (widget_class->module, replace_child_function_name, (void **) &widget_class->replace_child))
if (!g_module_symbol (widget_class->module,
replace_child_function_name,
(void **) &widget_class->replace_child))
g_warning ("Could not find %s\n", replace_child_function_name);
}
g_free (replace_child_function_name);
pre_create_function_name = glade_xml_get_value_string (node, GLADE_TAG_PRE_CREATE_FUNCTION);
pre_create_function_name =
glade_xml_get_value_string (node, GLADE_TAG_PRE_CREATE_FUNCTION);
if (pre_create_function_name && widget_class->module)
{
if (!g_module_symbol (widget_class->module, pre_create_function_name, (void **) &widget_class->pre_create_function))
if (!g_module_symbol (widget_class->module,
pre_create_function_name,
(void **) &widget_class->pre_create_function))
g_warning ("Could not find %s\n", pre_create_function_name);
}
g_free (pre_create_function_name);
post_create_function_name = glade_xml_get_value_string (node, GLADE_TAG_POST_CREATE_FUNCTION);
post_create_function_name =
glade_xml_get_value_string (node, GLADE_TAG_POST_CREATE_FUNCTION);
if (post_create_function_name && widget_class->module)
{
if (!g_module_symbol (widget_class->module, post_create_function_name, (void **) &widget_class->post_create_function))
if (!g_module_symbol (widget_class->module,
post_create_function_name,
(void **) &widget_class->post_create_function))
g_warning ("Could not find %s\n", post_create_function_name);
}
g_free (post_create_function_name);
fill_empty_function_name = glade_xml_get_value_string (node, GLADE_TAG_FILL_EMPTY_FUNCTION);
fill_empty_function_name =
glade_xml_get_value_string (node, GLADE_TAG_FILL_EMPTY_FUNCTION);
if (fill_empty_function_name && widget_class->module)
{
if (!g_module_symbol (widget_class->module, fill_empty_function_name, (void **) &widget_class->fill_empty))
if (!g_module_symbol (widget_class->module,
fill_empty_function_name,
(void **) &widget_class->fill_empty))
g_warning ("Could not find %s\n", fill_empty_function_name);
}
g_free (fill_empty_function_name);
get_internal_child_function_name = glade_xml_get_value_string (node, GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION);
get_internal_child_function_name =
glade_xml_get_value_string (node, GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION);
if (get_internal_child_function_name && widget_class->module)
{
if (!g_module_symbol (widget_class->module, get_internal_child_function_name, (void **) &widget_class->get_internal_child))
if (!g_module_symbol (widget_class->module,
get_internal_child_function_name,
(void **) &widget_class->get_internal_child))
g_warning ("Could not find %s\n", get_internal_child_function_name);
}
g_free (get_internal_child_function_name);
child_property_applies_function_name = glade_xml_get_value_string (node, GLADE_TAG_CHILD_PROPERTY_APPLIES_FUNCTION);
child_property_applies_function_name =
glade_xml_get_value_string (node, GLADE_TAG_CHILD_PROPERTY_APPLIES_FUNCTION);
if (child_property_applies_function_name && widget_class->module)
{
if (!g_module_symbol (widget_class->module, child_property_applies_function_name, (void **) &widget_class->child_property_applies))
if (!g_module_symbol (widget_class->module,
child_property_applies_function_name,
(void **) &widget_class->child_property_applies))
g_warning ("Could not find %s\n", child_property_applies_function_name);
}
g_free (child_property_applies_function_name);
@ -422,14 +453,16 @@ glade_widget_class_extend_with_file (GladeWidgetClass *widget_class, const char
*/
properties = glade_xml_search_child (node, GLADE_TAG_PROPERTIES);
if (properties)
glade_widget_class_update_properties_from_node (properties, widget_class, &widget_class->properties);
glade_widget_class_update_properties_from_node
(properties, widget_class, &widget_class->properties);
/* if we found a <ChildProperties> tag on the xml file, we add the
* properties that we read from the xml file to the class.
*/
properties = glade_xml_search_child (node, GLADE_TAG_CHILD_PROPERTIES);
if (properties)
glade_widget_class_update_properties_from_node (properties, widget_class, &widget_class->child_properties);
glade_widget_class_update_properties_from_node
(properties, widget_class, &widget_class->child_properties);
for (tmp = widget_class->child_properties; tmp != NULL; tmp = tmp->next)
{
@ -520,9 +553,6 @@ glade_widget_class_merge (GladeWidgetClass *widget_class,
g_return_if_fail (GLADE_IS_WIDGET_CLASS (widget_class));
g_return_if_fail (GLADE_IS_WIDGET_CLASS (parent_class));
if (GLADE_WIDGET_CLASS_FLAGS (widget_class) == 0)
widget_class->flags = parent_class->flags;
if (widget_class->replace_child == NULL)
widget_class->replace_child = parent_class->replace_child;
@ -539,8 +569,10 @@ glade_widget_class_merge (GladeWidgetClass *widget_class,
widget_class->child_property_applies = parent_class->child_property_applies;
/* merge the parent's properties & child-properties */
glade_widget_class_merge_properties (&widget_class->properties, parent_class->properties);
glade_widget_class_merge_properties (&widget_class->child_properties, parent_class->child_properties);
glade_widget_class_merge_properties
(&widget_class->properties, parent_class->properties);
glade_widget_class_merge_properties
(&widget_class->child_properties, parent_class->child_properties);
}
/**
@ -636,7 +668,8 @@ glade_widget_class_new (const char *name,
if (glade_widget_class_get_by_name (name) != NULL)
{
g_warning ("The widget class [%s] has at least two different definitions.\n", name);
g_warning ("The widget class [%s] has at least two different definitions.\n",
name);
goto lblError;
}
@ -679,22 +712,11 @@ glade_widget_class_new (const char *name,
widget_class->type = glade_util_get_type_from_name (init_function_name);
if (widget_class->type == 0)
goto lblError;
widget_class->properties = glade_widget_class_list_properties (widget_class);
widget_class->child_properties = glade_widget_class_list_child_properties (widget_class);
widget_class->signals = glade_widget_class_list_signals (widget_class);
widget_class->child_property_applies = glade_widget_class_direct_children;
/* is the widget a toplevel? TODO: We're going away from this flag, and
* just doing this test each time that we want to know if it's a toplevel */
if (g_type_is_a (widget_class->type, GTK_TYPE_WINDOW))
GLADE_WIDGET_CLASS_SET_FLAGS (widget_class, GLADE_TOPLEVEL);
/* is the widget a container? TODO: We're going away from this flag, and
* just doing this test each time that we want to know if it's a container */
if (g_type_is_a (widget_class->type, GTK_TYPE_CONTAINER))
GLADE_WIDGET_CLASS_SET_FLAGS (widget_class, GLADE_ADD_PLACEHOLDER);
widget_class->icon = glade_widget_class_create_icon (widget_class);
g_free (init_function_name);
@ -703,11 +725,15 @@ glade_widget_class_new (const char *name,
parent_type != 0;
parent_type = g_type_parent (parent_type))
{
const gchar *parent_name;
GladeWidgetClass *parent_class;
parent_class = glade_widget_class_get_by_name (g_type_name (parent_type));
if (parent_class)
parent_name = g_type_name (parent_type);
parent_class = glade_widget_class_get_by_name (parent_name);
if (parent_class) {
glade_widget_class_merge (widget_class, parent_class);
}
}
/* if there is an associated filename, then open and parse it */

View File

@ -10,26 +10,9 @@
G_BEGIN_DECLS
typedef enum {
GLADE_TOPLEVEL = 1 << 2,
GLADE_ADD_PLACEHOLDER = 1 << 3,
} GladeWidgetClassFlags;
#define GLADE_WIDGET_CLASS(gwc) ((GladeWidgetClass *) gwc)
#define GLADE_IS_WIDGET_CLASS(gwc) (gwc != NULL)
#define GLADE_WIDGET_FLAGS(gw) ((GLADE_WIDGET(gw)->widget_class)->flags)
#define GLADE_WIDGET_IS_TOPLEVEL(gw) ((GLADE_WIDGET_FLAGS(gw) & GLADE_TOPLEVEL) != 0)
#define GLADE_WIDGET_ADD_PLACEHOLDER(gw) ((GLADE_WIDGET_FLAGS(gw) & GLADE_ADD_PLACEHOLDER) != 0)
#define GLADE_WIDGET_CLASS_FLAGS(gwc) ((GLADE_WIDGET_CLASS(gwc)->flags))
#define GLADE_WIDGET_CLASS_TOPLEVEL(gwc) ((GLADE_WIDGET_CLASS_FLAGS(gwc) & GLADE_TOPLEVEL) != 0)
#define GLADE_WIDGET_CLASS_ADD_PLACEHOLDER(gwc) ((GLADE_WIDGET_CLASS_FLAGS(gwc) & GLADE_ADD_PLACEHOLDER) != 0)
#define GLADE_WIDGET_CLASS_SET_FLAGS(gwc,flag) G_STMT_START{ (GLADE_WIDGET_CLASS_FLAGS (gwc) |= (flag)); }G_STMT_END
#define GLADE_WIDGET_CLASS_UNSET_FLAGS(gwc,flag) G_STMT_START{ (GLADE_WIDGET_CLASS_FLAGS (gwc) &= ~(flag)); }G_STMT_END
/* GladeWidgetClass contains all the information we need regarding an widget
* type. It is also used to store information that has been loaded to memory
* for that object like the icon/mask.
@ -48,8 +31,6 @@ struct _GladeWidgetClass
*/
gchar *palette_name; /* Name used in the palette */
gint flags; /* See GladeWidgetClassFlags above */
GList *properties; /* List of GladePropertyClass objects.
* [see glade-property.h ] this list contains
* properties about the widget that we are going

View File

@ -41,13 +41,25 @@ static void glade_widget_class_init (GladeWidgetKlass *klass);
static void glade_widget_init (GladeWidget *widget);
static void glade_widget_finalize (GObject *object);
static void glade_widget_dispose (GObject *object);
static void glade_widget_set_real_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void glade_widget_get_real_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void glade_widget_set_class (GladeWidget *widget, GladeWidgetClass *klass);
static void glade_widget_real_add_signal_handler (GladeWidget *widget, GladeSignal *signal_handler);
static void glade_widget_real_remove_signal_handler (GladeWidget *widget, GladeSignal *signal_handler);
static void glade_widget_real_change_signal_handler (GladeWidget *widget, GladeSignal *old_signal_handler, GladeSignal *new_signal_handler);
static void glade_widget_set_packing_properties (GladeWidget *widget, GladeWidget *container);
static void glade_widget_set_real_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void glade_widget_get_real_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void glade_widget_set_class (GladeWidget *widget,
GladeWidgetClass *klass);
static void glade_widget_real_add_signal_handler (GladeWidget *widget,
GladeSignal *signal_handler);
static void glade_widget_real_remove_signal_handler (GladeWidget *widget,
GladeSignal *signal_handler);
static void glade_widget_real_change_signal_handler (GladeWidget *widget,
GladeSignal *old_signal_handler,
GladeSignal *new_signal_handler);
static void glade_widget_set_packing_properties (GladeWidget *widget,
GladeWidget *container);
enum
{
@ -120,22 +132,46 @@ glade_widget_class_init (GladeWidgetKlass *klass)
klass->add_signal_handler = glade_widget_real_add_signal_handler;
klass->remove_signal_handler = glade_widget_real_remove_signal_handler;
klass->change_signal_handler = glade_widget_real_change_signal_handler;
g_object_class_install_property
(object_class, PROP_NAME,
g_param_spec_string ("name", _("Name"),
_("The name of the widget"),
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property
(object_class, PROP_INTERNAL,
g_param_spec_string ("internal", _("Internal name"),
_("The internal name of the widget"),
NULL, G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property
(object_class, PROP_WIDGET,
g_param_spec_object ("widget", _("Widget"),
_("The gtk+ widget associated"),
GTK_TYPE_WIDGET,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property
(object_class, PROP_CLASS,
g_param_spec_pointer ("class", _("Class"),
_("The class of the associated"
" gtk+ widget"),
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_PROJECT,
g_param_spec_object ("project", _("Project"),
_("The glade project that "
"this widget belongs to"),
GLADE_TYPE_PROJECT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_NAME,
g_param_spec_string ("name", _("Name"), _("The name of the widget"),
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_INTERNAL,
g_param_spec_string ("internal", _("Internal name"), _("The internal name of the widget"),
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_WIDGET,
g_param_spec_object ("widget", _("Widget"), _("The gtk+ widget associated"),
GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_CLASS,
g_param_spec_pointer ("class", _("Class"), _("The class of the associated gtk+ widget"),
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_PROJECT,
g_param_spec_object ("project", _("Project"), _("The glade project that this widget belongs to"),
GLADE_TYPE_PROJECT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
glade_widget_signals[ADD_SIGNAL_HANDLER] =
g_signal_new ("add_signal_handler",
G_TYPE_FROM_CLASS (object_class),
@ -178,7 +214,8 @@ free_signals (gpointer value)
if (signals == NULL)
return;
/* g_ptr_array_foreach (signals, (GFunc) glade_signal_free, NULL); only available in modern versions of Gtk+ */
/* g_ptr_array_foreach (signals, (GFunc) glade_signal_free, NULL);
* only available in modern versions of Gtk+ */
nb_signals = signals->len;
for (i = 0; i < nb_signals; i++)
glade_signal_free (g_ptr_array_index (signals, i));
@ -196,7 +233,10 @@ glade_widget_init (GladeWidget *widget)
widget->widget = NULL;
widget->properties = NULL;
widget->packing_properties = NULL;
widget->signals = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) free_signals);
widget->signals = g_hash_table_new_full
(g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) free_signals);
}
static void
@ -241,6 +281,88 @@ glade_widget_debug (GladeWidget *widget)
}
/**
* glade_widget_build_object:
* @klass: a #GladeWidgetClass
* @widget: a #GladeWidget
*
* This function creates a new GObject who's parameters are based
* on the GType of the GladeWidgetClass and its default values, if a
* GladeWidget is specified, it will be used to apply the values currently in use.
*
* Returns: A newly created GObject
*/
static GObject *
glade_widget_build_object (GladeWidgetClass *klass, GladeWidget *widget)
{
GArray *params;
GObjectClass *oclass;
GParamSpec **pspec;
GladeProperty *glade_property;
GObject *object;
gint n_props, i;
/* As a slight optimization, we never unref the class
*/
oclass = g_type_class_ref(klass->type);
pspec = g_object_class_list_properties (oclass, &n_props);
params = g_array_new(FALSE, FALSE, sizeof(GParameter));
for (i = 0; i < n_props; i++)
{
GParameter parameter = { 0, };
if (!glade_widget_class_has_property(klass, pspec[i]->name))
/* Ignore properties that are not accounted for
* by the GladeWidgetClass
*/
continue;
parameter.name = pspec[i]->name; /* No need to dup this */
g_value_init(&parameter.value, pspec[i]->value_type);
/* If a widget is specified and has a value set for that
* property, then that value will be used (otherwise, we
* use the default value)
*/
if (widget &&
(glade_property =
glade_widget_get_property(widget, parameter.name)) != NULL)
{
if (g_value_type_compatible(G_VALUE_TYPE(glade_property->value),
G_VALUE_TYPE(&parameter.value)))
g_value_copy(glade_property->value, &parameter.value);
else
{
g_critical("Type mismatch on %s property of %s",
parameter.name, widget->widget_class->name);
continue;
}
}
else
g_param_value_set_default (pspec[i], &parameter.value);
g_array_append_val(params, parameter);
}
g_free(pspec);
/* Create the new object with the correct parameters.
*/
object = g_object_newv(klass->type, params->len,
(GParameter *)params->data);
/* Cleanup parameters
*/
for (i = 0; i < params->len; i++)
{
GParameter parameter = g_array_index(params, GParameter, i);
g_value_unset(&parameter.value);
}
g_array_free(params, TRUE);
return object;
}
/**
* glade_widget_new:
@ -254,10 +376,12 @@ glade_widget_debug (GladeWidget *widget)
GladeWidget *
glade_widget_new (GladeWidgetClass *klass, GladeProject *project)
{
GObject *widget = g_object_new (klass->type, NULL);
GObject *widget;
GObject *glade_widget;
char *widget_name;
gchar *widget_name;
widget = glade_widget_build_object(klass, NULL);
if (klass->pre_create_function)
klass->pre_create_function (G_OBJECT (widget));
@ -270,14 +394,47 @@ glade_widget_new (GladeWidgetClass *klass, GladeProject *project)
NULL);
g_free (widget_name);
if (klass->post_create_function)
klass->post_create_function (G_OBJECT (widget));
if (klass->fill_empty)
klass->fill_empty (GTK_WIDGET (widget));
return (GladeWidget *) glade_widget;
}
/**
* glade_widget_rebuild:
* @glade_widget: a #GladeWidget
*
* Replaces the current widget instance with
* a new one while preserving all properties children and
* takes care of reparenting.
*
*/
void
glade_widget_rebuild (GladeWidget *glade_widget)
{
GtkWidget *new_widget, *old_widget;
GladeWidgetClass *klass = glade_widget->widget_class;
/* Clear the project selection before destroying this widget */
glade_project_selection_clear(glade_widget->project, TRUE);
/* Hold a reference to the old widget while we transport properties
* and children from it
*/
new_widget = GTK_WIDGET(glade_widget_build_object(klass, glade_widget));
old_widget = g_object_ref(G_OBJECT(glade_widget_get_widget(glade_widget)));
glade_project_remove_widget(glade_widget->project, old_widget);
glade_widget_set_widget(glade_widget, new_widget);
g_object_unref(G_OBJECT(old_widget));
gtk_widget_show_all(new_widget);
/* Set the new widget as the current selection */
glade_project_add_widget(glade_widget->project, new_widget);
glade_project_selection_set(glade_widget->project, new_widget, TRUE);
}
/**
* glade_widget_new_for_internal_child:
* @klass:
@ -290,16 +447,19 @@ glade_widget_new (GladeWidgetClass *klass, GladeProject *project)
* Returns:
*/
GladeWidget *
glade_widget_new_for_internal_child (GladeWidgetClass *klass, GladeWidget *parent, GtkWidget *internal_widget, const char *internal_name)
glade_widget_new_for_internal_child (GladeWidgetClass *klass,
GladeWidget *parent,
GtkWidget *internal_widget,
const gchar *internal_name)
{
GladeProject *project = glade_widget_get_project (parent);
char *widget_name = glade_project_new_widget_name (project, klass->generic_name);
GladeWidget *widget = g_object_new (GLADE_TYPE_WIDGET,
"class", klass,
"project", project,
"name", widget_name,
"internal", internal_name,
"widget", internal_widget, NULL);
gchar *widget_name = glade_project_new_widget_name (project, klass->generic_name);
GladeWidget *widget = g_object_new (GLADE_TYPE_WIDGET,
"class", klass,
"project", project,
"name", widget_name,
"internal", internal_name,
"widget", internal_widget, NULL);
g_free (widget_name);
return widget;
}
@ -311,12 +471,11 @@ glade_widget_finalize (GObject *object)
g_return_if_fail (GLADE_IS_WIDGET (object));
glade_widget_class_free (widget->widget_class);
g_free (widget->name);
g_free (widget->internal);
g_hash_table_destroy (widget->signals);
g_print ("%s\n", __func__);
G_OBJECT_CLASS(parent_class)->finalize(object);
}
static void
@ -348,7 +507,8 @@ glade_widget_dispose (GObject *object)
widget->packing_properties = NULL;
}
g_print ("%s\n", __func__);
if (G_OBJECT_CLASS(parent_class)->dispose)
G_OBJECT_CLASS(parent_class)->dispose(object);
}
/**
@ -390,11 +550,14 @@ glade_widget_remove_signal_handler (GladeWidget *widget, GladeSignal *signal_han
* TODO: write me
*/
void
glade_widget_change_signal_handler (GladeWidget *widget, GladeSignal *old_signal_handler, GladeSignal *new_signal_handler)
glade_widget_change_signal_handler (GladeWidget *widget,
GladeSignal *old_signal_handler,
GladeSignal *new_signal_handler)
{
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_signal_emit (widget, glade_widget_signals[CHANGE_SIGNAL_HANDLER], 0, old_signal_handler, new_signal_handler);
g_signal_emit (widget, glade_widget_signals[CHANGE_SIGNAL_HANDLER], 0,
old_signal_handler, new_signal_handler);
}
static void
@ -416,13 +579,16 @@ glade_widget_set_real_property (GObject *object,
glade_widget_set_internal (widget, g_value_get_string (value));
break;
case PROP_WIDGET:
glade_widget_set_widget (widget, GTK_WIDGET (g_value_get_object (value)));
glade_widget_set_widget (widget, GTK_WIDGET
(g_value_get_object (value)));
break;
case PROP_PROJECT:
glade_widget_set_project (widget, GLADE_PROJECT (g_value_get_object (value)));
glade_widget_set_project (widget, GLADE_PROJECT
(g_value_get_object (value)));
break;
case PROP_CLASS:
glade_widget_set_class (widget, GLADE_WIDGET_CLASS (g_value_get_pointer (value)));
glade_widget_set_class (widget, GLADE_WIDGET_CLASS
(g_value_get_pointer (value)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -471,7 +637,7 @@ glade_widget_get_real_property (GObject *object,
* Sets @widget's name to @name.
*/
void
glade_widget_set_name (GladeWidget *widget, const char *name)
glade_widget_set_name (GladeWidget *widget, const gchar *name)
{
g_return_if_fail (GLADE_IS_WIDGET (widget));
if (widget->name != name) {
@ -487,7 +653,7 @@ glade_widget_set_name (GladeWidget *widget, const char *name)
*
* Returns: a pointer to @widget's name
*/
const char *
const gchar *
glade_widget_get_name (GladeWidget *widget)
{
g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
@ -502,7 +668,7 @@ glade_widget_get_name (GladeWidget *widget)
* TODO: write me
*/
void
glade_widget_set_internal (GladeWidget *widget, const char *internal)
glade_widget_set_internal (GladeWidget *widget, const gchar *internal)
{
g_return_if_fail (GLADE_IS_WIDGET (widget));
if (widget->internal != internal) {
@ -520,7 +686,7 @@ glade_widget_set_internal (GladeWidget *widget, const char *internal)
*
* Returns:
*/
const char *
const gchar *
glade_widget_get_internal (GladeWidget *widget)
{
g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
@ -612,7 +778,7 @@ glade_widget_get_project (GladeWidget *widget)
* Returns: the #GladeProperty in @widget named @id_property
*/
GladeProperty *
glade_widget_get_property (GladeWidget *widget, const char *id_property)
glade_widget_get_property (GladeWidget *widget, const gchar *id_property)
{
GList *list;
GladeProperty *property;
@ -674,7 +840,9 @@ glade_widget_find_inside_container (GtkWidget *widget, GladeFindInContainerData
}
static GladeWidget *
glade_widget_find_deepest_child_at_position (GtkContainer *toplevel, GtkContainer *container, int top_x, int top_y)
glade_widget_find_deepest_child_at_position (GtkContainer *toplevel,
GtkContainer *container,
int top_x, int top_y)
{
GladeFindInContainerData data;
data.x = top_x;
@ -682,10 +850,12 @@ glade_widget_find_deepest_child_at_position (GtkContainer *toplevel, GtkContaine
data.toplevel = GTK_WIDGET (toplevel);
data.found = NULL;
gtk_container_forall (container, (GtkCallback) glade_widget_find_inside_container, &data);
gtk_container_forall (container, (GtkCallback)
glade_widget_find_inside_container, &data);
if (data.found && GTK_IS_CONTAINER (data.found))
return glade_widget_find_deepest_child_at_position (toplevel, GTK_CONTAINER (data.found), top_x, top_y);
return glade_widget_find_deepest_child_at_position
(toplevel, GTK_CONTAINER (data.found), top_x, top_y);
else if (data.found)
return glade_widget_get_from_gtk_widget (data.found);
else
@ -716,7 +886,9 @@ glade_widget_retrieve_from_position (GtkWidget *base, int x, int y)
return NULL;
gtk_widget_translate_coordinates (base, toplevel_widget, x, y, &top_x, &top_y);
return glade_widget_find_deepest_child_at_position (GTK_CONTAINER (toplevel_widget), GTK_CONTAINER (toplevel_widget), top_x, top_y);
return glade_widget_find_deepest_child_at_position
(GTK_CONTAINER (toplevel_widget),
GTK_CONTAINER (toplevel_widget), top_x, top_y);
}
static gboolean
@ -728,14 +900,18 @@ glade_widget_button_press (GtkWidget *widget,
double y = event->y;
GladeWidget *glade_widget;
glade_widget = glade_widget_retrieve_from_position (widget, (int) (x + 0.5), (int) (y + 0.5));
glade_widget = glade_widget_retrieve_from_position
(widget, (int) (x + 0.5), (int) (y + 0.5));
widget = glade_widget_get_widget (glade_widget);
/* make sure to grab focus, since we may stop default handlers */
if (GTK_WIDGET_CAN_FOCUS (widget) && !GTK_WIDGET_HAS_FOCUS (widget))
gtk_widget_grab_focus (widget);
if (event->type != GDK_BUTTON_PRESS)
/* Allow plugins to use shift/cntl possibilities */
if ((event->type != GDK_BUTTON_PRESS) ||
(event->state & GDK_SHIFT_MASK) != 0 ||
(event->state & GDK_CONTROL_MASK) != 0)
return FALSE;
if (event->button == 1)
@ -745,6 +921,7 @@ glade_widget_button_press (GtkWidget *widget,
return FALSE;
glade_project_selection_set (glade_widget->project, widget, TRUE);
return TRUE;
}
else if (event->button == 3)
@ -801,58 +978,6 @@ glade_widget_event (GtkWidget *widget,
return FALSE;
}
static void
glade_widget_apply_properties (GladeWidget *glade_widget)
{
GList *properties;
GtkWidget *widget;
GObject *object;
g_return_if_fail (GLADE_IS_WIDGET (glade_widget));
g_return_if_fail (glade_widget->properties != NULL);
properties = glade_widget->properties;
widget = glade_widget->widget;
object = G_OBJECT (widget);
g_object_freeze_notify (object);
while (properties != NULL)
{
glade_util_object_set_property (object, GLADE_PROPERTY (properties->data));
properties = properties->next;
}
g_object_thaw_notify (G_OBJECT (widget));
}
static void
glade_widget_retrieve_properties (GladeWidget *glade_widget)
{
GList *properties;
GtkWidget *widget;
GObject *object;
g_return_if_fail (GLADE_IS_WIDGET (glade_widget));
g_return_if_fail (glade_widget->properties != NULL);
properties = glade_widget->properties;
widget = glade_widget->widget;
object = G_OBJECT (widget);
while (properties != NULL)
{
GladeProperty *property = GLADE_PROPERTY (properties->data);
GladePropertyClass *property_class = property->class;
g_value_reset (property->value);
g_object_get_property (object, property_class->id, property->value);
properties = properties->next;
}
g_object_thaw_notify (G_OBJECT (widget));
}
/* Connects a signal handler to the 'event' signal for a widget and
all its children recursively. We need this to draw the selection
rectangles and to get button press/release events reliably. */
@ -882,61 +1007,162 @@ glade_widget_connect_signal_handlers (GtkWidget *widget_gtk, gpointer data)
}
}
/**
* glade_widget_transport_children:
* @gwidget: A #GladeWidget
* @from_container: A #GtkContainer
* @to_container: A #GtkContainer
*
* Transports all children from @from_container to @to_container
*
* Returns: whether any children were transported
*/
static gboolean
glade_widget_transport_children (GladeWidget *gwidget,
GtkContainer *from_container,
GtkContainer *to_container)
{
GList *children, *l;
if (from_container != NULL &&
(l = children =
gtk_container_get_children(from_container)) != NULL)
{
while (l && l->data)
{
GtkWidget *child = (GtkWidget *)l->data;
/* If this widget is a container, all children get a temporary
* reference and are moved from the old container, to the new
* container and thier child properties are applied.
*/
g_object_ref(child);
gtk_container_remove(GTK_CONTAINER(from_container), child);
gtk_container_add(GTK_CONTAINER(to_container), child);
glade_widget_set_packing_properties
(glade_widget_get_from_gtk_widget (child), gwidget);
g_object_unref(child);
l = l->next;
}
g_list_free(children);
return TRUE;
}
return FALSE;
}
/**
* glade_widget_update_parent:
* @gwidget: A #GladeWidget
* @old_widget: A #GtkWidget
* @new_widget: A #GtkWidget
*
* Finds @widget's parent #GladeWidget and calls the replace_child func
* and takes care of packing
*
* Returns: whether this widget had a parent.
*/
static gboolean
glade_widget_update_parent(GladeWidget *gwidget, GtkWidget *old_widget, GtkWidget *new_widget)
{
GladeWidget *parent;
/* Take care of reparenting, if needed (i.e.: if not a GtkWindow)
*/
if (old_widget && (parent = glade_util_get_parent (old_widget)) != NULL)
{
if (parent->widget_class->replace_child)
{
if (old_widget)
parent->widget_class->replace_child
(GTK_WIDGET(old_widget),
GTK_WIDGET(new_widget),
glade_widget_get_widget (parent));
glade_widget_set_packing_properties (gwidget, parent);
}
else
g_warning ("Unable to set packing properties on new instance: replace "
"function has not been implemented for \"%s\"\n",
parent->widget_class->name);
return TRUE;
}
return FALSE;
}
/**
* glade_widget_set_widget:
* @glade_widget:
* @widget_gtk:
* @gwidget:
* @new_widget:
*
* TODO: write me
*/
void
glade_widget_set_widget (GladeWidget *glade_widget, GtkWidget *widget_gtk)
glade_widget_set_widget (GladeWidget *gwidget, GtkWidget *new_widget)
{
g_return_if_fail (GLADE_IS_WIDGET (glade_widget));
g_return_if_fail (GTK_IS_WIDGET (widget_gtk));
g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (widget_gtk), glade_widget->widget_class->type));
GladeWidgetClass *klass;
GtkWidget *old_widget;
g_return_if_fail (GLADE_IS_WIDGET (gwidget));
g_return_if_fail (GTK_IS_WIDGET (new_widget));
g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (new_widget),
gwidget->widget_class->type));
if (glade_widget->widget)
{
g_object_set_data (G_OBJECT (glade_widget->widget), "GladeWidgetDataTag", NULL);
g_object_unref (glade_widget->widget);
}
klass = gwidget->widget_class;
old_widget = gwidget->widget;
/* Call custom notification of widget creation in plugin */
if (klass->post_create_function)
klass->post_create_function (G_OBJECT(new_widget));
g_object_ref (widget_gtk);
glade_widget->widget = widget_gtk;
g_object_set_data (G_OBJECT (widget_gtk), "GladeWidgetDataTag", glade_widget);
/* Add internal reference to new widget */
gwidget->widget = g_object_ref (G_OBJECT(new_widget));
g_object_set_data (G_OBJECT (new_widget), "GladeWidgetDataTag", gwidget);
gtk_widget_add_events (widget_gtk, GDK_BUTTON_PRESS_MASK |
/* Take care of events and toolkit signals */
gtk_widget_add_events (new_widget, GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK);
if (GTK_WIDGET_TOPLEVEL (widget_gtk))
g_signal_connect (G_OBJECT (widget_gtk), "delete_event",
if (GTK_WIDGET_TOPLEVEL (new_widget))
g_signal_connect (G_OBJECT (new_widget), "delete_event",
G_CALLBACK (gtk_widget_hide_on_delete), NULL);
g_signal_connect (G_OBJECT (widget_gtk), "popup_menu",
g_signal_connect (G_OBJECT (new_widget), "popup_menu",
G_CALLBACK (glade_widget_popup_menu), NULL);
g_signal_connect (G_OBJECT (widget_gtk), "key_press_event",
g_signal_connect (G_OBJECT (new_widget), "key_press_event",
G_CALLBACK (glade_widget_key_press), NULL);
glade_widget_connect_signal_handlers (widget_gtk, NULL);
glade_widget_connect_signal_handlers (new_widget, NULL);
if (glade_widget->internal == NULL)
/* Take care of children
*/
if (GTK_IS_CONTAINER (new_widget) &&
glade_widget_transport_children (gwidget,
GTK_CONTAINER(old_widget),
GTK_CONTAINER(new_widget)) == FALSE)
{
/* we should set the values of the properties of this widget
* from the default values that we gather from the class of
* this widget */
glade_widget_apply_properties (glade_widget);
}
else
{
GladeWidget *parent = glade_widget_get_parent (glade_widget);
/* set packing properties */
glade_widget_set_packing_properties (glade_widget, parent);
/* There we're no children to transport, call fill empty */
if (klass->fill_empty)
klass->fill_empty (new_widget);
}
g_object_notify (G_OBJECT (glade_widget), "widget");
/* Take care of reparenting and packing.
*/
if (glade_widget_update_parent(gwidget, old_widget, new_widget) == FALSE)
{
/* TODO: We have to take care of GtkWindow positioning
* (in the case of parentless widgets)
*/
}
/* Remove internal reference to old widget */
if (old_widget) {
g_object_set_data (G_OBJECT (old_widget), "GladeWidgetDataTag", NULL);
g_object_unref (G_OBJECT (old_widget));
}
g_object_notify (G_OBJECT (gwidget), "widget");
}
/**
@ -1002,7 +1228,9 @@ glade_widget_real_remove_signal_handler (GladeWidget *widget, GladeSignal *signa
}
static void
glade_widget_real_change_signal_handler (GladeWidget *widget, GladeSignal *old_signal_handler, GladeSignal *new_signal_handler)
glade_widget_real_change_signal_handler (GladeWidget *widget,
GladeSignal *old_signal_handler,
GladeSignal *new_signal_handler)
{
GPtrArray *signals;
GladeSignal *tmp_signal_handler;
@ -1037,7 +1265,8 @@ glade_widget_real_change_signal_handler (GladeWidget *widget, GladeSignal *old_s
}
GPtrArray *
glade_widget_list_signal_handlers (GladeWidget *widget, const char *signal_name) /* array of GladeSignal* */
glade_widget_list_signal_handlers (GladeWidget *widget,
const gchar *signal_name) /* array of GladeSignal* */
{
return g_hash_table_lookup (widget->signals, signal_name);
}
@ -1090,7 +1319,8 @@ glade_widget_create_packing_properties (GladeWidget *container, GladeWidget *wid
property_class = list->data;
#if 0
if (!container_class->child_property_applies (container->widget, widget->widget, property_class->id))
if (!container_class->child_property_applies
(container->widget, widget->widget, property_class->id))
continue;
#endif
@ -1148,7 +1378,8 @@ glade_widget_set_packing_properties (GladeWidget *widget,
GladeProperty *property = list->data;
g_value_reset (property->value);
if (gtk_container_class_find_child_property (G_OBJECT_GET_CLASS (container->widget), property->class->id))
if (gtk_container_class_find_child_property
(G_OBJECT_GET_CLASS (container->widget), property->class->id))
gtk_container_child_get_property (GTK_CONTAINER (container->widget),
widget->widget,
property->class->id,
@ -1161,12 +1392,13 @@ glade_widget_set_packing_properties (GladeWidget *widget,
* @old_widget: a #GtkWidget
* @new_widget: a #GtkWidget
*
* TODO: write me
* Replaces a GtkWidget with another GtkWidget inside a GtkContainer.
*
* Note that both GtkWidgets must be owned by a GladeWidget.
*/
void
glade_widget_replace (GtkWidget *old_widget, GtkWidget *new_widget)
{
GladeWidget *parent = NULL;
GladeWidget *gnew_widget = NULL;
GladeWidget *gold_widget = NULL;
GtkWidget *real_new_widget = new_widget;
@ -1183,19 +1415,7 @@ glade_widget_replace (GtkWidget *old_widget, GtkWidget *new_widget)
if (gold_widget)
real_old_widget = glade_widget_get_widget (gold_widget);
parent = glade_util_get_parent (old_widget);
g_assert (parent);
if (parent->widget_class->replace_child)
{
parent->widget_class->replace_child (real_old_widget, real_new_widget, glade_widget_get_widget (parent));
if (gnew_widget)
glade_widget_set_packing_properties (gnew_widget, parent);
}
else
g_warning ("Could not replace a placeholder because a replace "
" function has not been implemented for \"%s\"\n",
parent->widget_class->name);
glade_widget_update_parent(gnew_widget, old_widget, new_widget);
}
/* XML Serialization */
@ -1249,7 +1469,8 @@ glade_widget_write (GladeWidget *widget, GladeXmlContext *context)
node = glade_xml_node_new (context, GLADE_XML_TAG_WIDGET);
glade_xml_node_set_property_string (node, GLADE_XML_TAG_CLASS, widget->widget_class->name);
glade_xml_node_set_property_string (node, GLADE_XML_TAG_CLASS,
widget->widget_class->name);
glade_xml_node_set_property_string (node, GLADE_XML_TAG_ID, widget->name);
/* Write the properties */
@ -1270,7 +1491,9 @@ glade_widget_write (GladeWidget *widget, GladeXmlContext *context)
/* Signals */
write_signals_context.node = node;
write_signals_context.context = context;
g_hash_table_foreach (widget->signals, glade_widget_write_signals, &write_signals_context);
g_hash_table_foreach (widget->signals,
glade_widget_write_signals,
&write_signals_context);
/* Children */
if (GTK_IS_CONTAINER (widget->widget)) {
@ -1312,7 +1535,8 @@ glade_widget_write_child (GladeXmlContext *context, GtkWidget *gtk_widget)
return NULL;
if (child_widget->internal)
glade_xml_node_set_property_string (child_tag, GLADE_XML_TAG_INTERNAL_CHILD, child_widget->internal);
glade_xml_node_set_property_string
(child_tag, GLADE_XML_TAG_INTERNAL_CHILD, child_widget->internal);
child = glade_widget_write (child_widget, context);
if (!child)
@ -1456,7 +1680,7 @@ glade_widget_new_from_node_real (GladeXmlNode *node,
GladeWidget *widget;
gchar *class_name;
GObject *widget_gtk;
char *widget_name;
gchar *widget_name;
if (!glade_xml_node_verify (node, GLADE_XML_TAG_WIDGET))
return NULL;
@ -1486,7 +1710,8 @@ glade_widget_new_from_node_real (GladeXmlNode *node,
/* create the packing_properties list, without setting them */
if (parent)
widget->packing_properties = glade_widget_create_packing_properties (parent, widget);
widget->packing_properties =
glade_widget_create_packing_properties (parent, widget);
glade_widget_fill_from_node (node, widget);
@ -1502,10 +1727,13 @@ static GtkWidget *
glade_widget_get_internal_child (GladeWidget *parent,
const gchar *internal)
{
while (parent) {
if (parent->widget_class->get_internal_child) {
while (parent)
{
if (parent->widget_class->get_internal_child)
{
GtkWidget *widget_gtk;
parent->widget_class->get_internal_child (parent->widget, internal, &widget_gtk);
parent->widget_class->get_internal_child (parent->widget,
internal, &widget_gtk);
return widget_gtk;
}
parent = glade_widget_get_parent (parent);
@ -1552,7 +1780,8 @@ glade_widget_new_child_from_node (GladeXmlNode *node,
return FALSE;
}
child_class = glade_widget_class_get_by_name (G_OBJECT_TYPE_NAME (child_gtk));
child = glade_widget_new_for_internal_child (child_class, parent, child_gtk, internalchild);
child = glade_widget_new_for_internal_child (child_class, parent,
child_gtk, internalchild);
g_free (internalchild);
glade_widget_fill_from_node (child_node, child);
} else {
@ -1575,7 +1804,8 @@ glade_widget_new_child_from_node (GladeXmlNode *node,
if (!glade_xml_node_verify (property_node, GLADE_XML_TAG_PROPERTY))
continue;
if (!glade_widget_apply_property_from_node (property_node, child, TRUE)) {
if (!glade_widget_apply_property_from_node (property_node, child, TRUE))
{
g_warning ("Failed to apply packing property");
continue;
}

View File

@ -108,6 +108,8 @@ GladeWidget * glade_widget_read (GladeProject *project, GladeXmlNode *node);
#define glade_widget_get_from_gtk_widget(w) g_object_get_data (G_OBJECT (w), "GladeWidgetDataTag")
GladeWidget * glade_widget_get_parent (GladeWidget *widget);
void glade_widget_rebuild (GladeWidget *widget);
G_END_DECLS
#endif /* __GLADE_WIDGET_H__ */

View File

@ -13,6 +13,7 @@ widgets_DATA = \
gtkcheckbutton.xml \
gtkcontainer.xml \
gtkdialog.xml \
gtkfixed.xml \
gtkframe.xml \
gtkhandlebox.xml \
gtklabel.xml \

View File

@ -21,7 +21,7 @@
<GladeWidget name="GtkArrow" generic_name="arrow" palette_name="Arrow"/>
<GladeWidget name="GtkLayout" generic_name="layout" palette_name="Layout"/>
<GladeWidget name="GtkFixed" generic_name="fixed" palette_name="Fixed"/>
<GladeWidget name="GtkFixed" generic_name="fixed" filename="gtkfixed.xml" palette_name="Fixed"/>
<GladeWidget name="GtkDrawingArea" generic_name="drawingarea" palette_name="Drawing Area"/>
<GladeWidget name="GtkViewport" generic_name="viewport" palette_name="Viewport"/>
<GladeWidget name="GtkScrolledWindow" generic_name="scrolledwindow" palette_name="Scrolled Window"/>

5
widgets/gtkfixed.xml Normal file
View File

@ -0,0 +1,5 @@
<GladeWidgetClass>
<PostCreateFunction>glade_gtk_fixed_post_create</PostCreateFunction>
<FillEmptyFunction>glade_gtk_fixed_fill_empty</FillEmptyFunction>
</GladeWidgetClass>