|
Packit |
1e8aac |
/*
|
|
Packit |
1e8aac |
* glade-gtk-table.c - GladeWidgetAdaptor for GtkTable widget
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Copyright (C) 2008 Tristan Van Berkom
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* Author(s):
|
|
Packit |
1e8aac |
* Tristan Van Berkom <tvb@gnome.org>
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is free software; you can redistribute it and/or modify it
|
|
Packit |
1e8aac |
* under the terms of the GNU Lesser General Public License as
|
|
Packit |
1e8aac |
* published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
1e8aac |
* the License, or (at your option) any later version.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* This library is distributed in the hope that it will be useful, but
|
|
Packit |
1e8aac |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1e8aac |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
1e8aac |
* Lesser General Public License for more details.
|
|
Packit |
1e8aac |
*
|
|
Packit |
1e8aac |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
1e8aac |
* License along with this program; if not, write to the Free Software
|
|
Packit |
1e8aac |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <config.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include <gtk/gtk.h>
|
|
Packit |
1e8aac |
#include <glib/gi18n-lib.h>
|
|
Packit |
1e8aac |
#include <string.h>
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#include "glade-fixed.h"
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
typedef struct
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* comparable part: */
|
|
Packit |
1e8aac |
GladeWidget *widget;
|
|
Packit |
1e8aac |
gint left_attach;
|
|
Packit |
1e8aac |
gint right_attach;
|
|
Packit |
1e8aac |
gint top_attach;
|
|
Packit |
1e8aac |
gint bottom_attach;
|
|
Packit |
1e8aac |
} GladeGtkTableChild;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
typedef enum
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
DIR_UP,
|
|
Packit |
1e8aac |
DIR_DOWN,
|
|
Packit |
1e8aac |
DIR_LEFT,
|
|
Packit |
1e8aac |
DIR_RIGHT
|
|
Packit |
1e8aac |
} GladeTableDir;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
typedef enum
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GROUP_ACTION_INSERT_ROW,
|
|
Packit |
1e8aac |
GROUP_ACTION_INSERT_COLUMN,
|
|
Packit |
1e8aac |
GROUP_ACTION_REMOVE_COLUMN,
|
|
Packit |
1e8aac |
GROUP_ACTION_REMOVE_ROW
|
|
Packit |
1e8aac |
} GroupAction;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Redefine GTK_TABLE() macro, as GtkTable is deprecated */
|
|
Packit |
1e8aac |
#undef GTK_TABLE
|
|
Packit |
1e8aac |
#define GTK_TABLE(obj) ((GtkTable *)obj)
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_gtk_table_get_child_attachments (GtkWidget * table,
|
|
Packit |
1e8aac |
GtkWidget * child,
|
|
Packit |
1e8aac |
GtkTableChild * tchild)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
guint left, right, top, bottom;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_container_child_get (GTK_CONTAINER (table), child,
|
|
Packit |
1e8aac |
"left-attach", (guint *) & left,
|
|
Packit |
1e8aac |
"right-attach", (guint *) & right,
|
|
Packit |
1e8aac |
"bottom-attach", (guint *) & bottom,
|
|
Packit |
1e8aac |
"top-attach", (guint *) & top, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
tchild->widget = child;
|
|
Packit |
1e8aac |
tchild->left_attach = left;
|
|
Packit |
1e8aac |
tchild->right_attach = right;
|
|
Packit |
1e8aac |
tchild->top_attach = top;
|
|
Packit |
1e8aac |
tchild->bottom_attach = bottom;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_gtk_table_widget_exceeds_bounds (GtkTable * table, gint n_rows,
|
|
Packit |
1e8aac |
gint n_cols)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *list, *children;
|
|
Packit |
1e8aac |
gboolean ret = FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
children = gtk_container_get_children (GTK_CONTAINER (table));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (list = children; list && list->data; list = list->next)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTableChild child;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_gtk_table_get_child_attachments (GTK_WIDGET (table),
|
|
Packit |
1e8aac |
GTK_WIDGET (list->data), &child);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (GLADE_IS_PLACEHOLDER (child.widget) == FALSE &&
|
|
Packit |
1e8aac |
(child.right_attach > n_cols || child.bottom_attach > n_rows))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
ret = TRUE;
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_list_free (children);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return ret;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
#define TABLE_OCCUPIED(occmap, n_columns, col, row) \
|
|
Packit |
1e8aac |
(occmap)[row * n_columns + col]
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_gtk_table_build_occupation_maps(GtkTable *table, guint n_columns, guint n_rows,
|
|
Packit |
1e8aac |
gchar **child_map, gpointer **placeholder_map)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
guint i, j;
|
|
Packit |
1e8aac |
GList *list, *children = gtk_container_get_children (GTK_CONTAINER (table));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
*child_map = g_malloc0(n_columns * n_rows * sizeof(gchar)); /* gchar is smaller than gboolean */
|
|
Packit |
1e8aac |
*placeholder_map = g_malloc0(n_columns * n_rows * sizeof(gpointer));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (list = children; list && list->data; list = list->next)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTableChild child;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_gtk_table_get_child_attachments (GTK_WIDGET (table),
|
|
Packit |
1e8aac |
GTK_WIDGET (list->data), &child);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (GLADE_IS_PLACEHOLDER(list->data))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* assumption: placeholders are always attached to exactly 1 cell */
|
|
Packit |
1e8aac |
TABLE_OCCUPIED(*placeholder_map, n_columns, child.left_attach, child.top_attach) = list->data;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
for (i = child.left_attach; i < child.right_attach && i < n_columns; i++)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
for (j = child.top_attach; j < child.bottom_attach && j < n_rows; j++)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
TABLE_OCCUPIED(*child_map, n_columns, i, j) = 1;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
g_list_free (children);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_gtk_table_refresh_placeholders (GtkTable * table)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
guint n_columns, n_rows, i, j;
|
|
Packit |
1e8aac |
gchar *child_map;
|
|
Packit |
1e8aac |
gpointer *placeholder_map;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_get (table, "n-columns", &n_columns, "n-rows", &n_rows, NULL);
|
|
Packit |
1e8aac |
glade_gtk_table_build_occupation_maps (table, n_columns, n_rows,
|
|
Packit |
1e8aac |
&child_map, &placeholder_map);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (i = 0; i < n_columns; i++)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
for (j = 0; j < n_rows; j++)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gpointer placeholder = TABLE_OCCUPIED(placeholder_map, n_columns, i, j);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (TABLE_OCCUPIED(child_map, n_columns, i, j))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (placeholder)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_container_remove (GTK_CONTAINER (table),
|
|
Packit |
1e8aac |
GTK_WIDGET (placeholder));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!placeholder)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
|
Packit |
1e8aac |
gtk_table_attach_defaults (table,
|
|
Packit |
1e8aac |
glade_placeholder_new (),
|
|
Packit |
1e8aac |
i, i + 1, j, j + 1);
|
|
Packit |
1e8aac |
G_GNUC_END_IGNORE_DEPRECATIONS;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
g_free(child_map);
|
|
Packit |
1e8aac |
g_free(placeholder_map);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (gtk_widget_get_realized (GTK_WIDGET (table)))
|
|
Packit |
1e8aac |
gtk_container_check_resize (GTK_CONTAINER (table));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
gtk_table_children_callback (GtkWidget * widget, gpointer client_data)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList **children;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
children = (GList **) client_data;
|
|
Packit |
1e8aac |
*children = g_list_prepend (*children, widget);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
GList *
|
|
Packit |
1e8aac |
glade_gtk_table_get_children (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GtkContainer * container)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *children = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_container_forall (container, gtk_table_children_callback, &children);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* GtkTable has the children list already reversed */
|
|
Packit |
1e8aac |
return children;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_gtk_table_add_child (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GObject * object, GObject * child)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_gtk_table_refresh_placeholders (GTK_TABLE (object));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_gtk_table_remove_child (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GObject * object, GObject * child)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_gtk_table_refresh_placeholders (GTK_TABLE (object));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_gtk_table_replace_child (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GtkWidget * container,
|
|
Packit |
1e8aac |
GtkWidget * current, GtkWidget * new_widget)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* Chain Up */
|
|
Packit |
1e8aac |
GWA_GET_CLASS
|
|
Packit |
1e8aac |
(GTK_TYPE_CONTAINER)->replace_child (adaptor,
|
|
Packit |
1e8aac |
G_OBJECT (container),
|
|
Packit |
1e8aac |
G_OBJECT (current),
|
|
Packit |
1e8aac |
G_OBJECT (new_widget));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* If we are replacing a GladeWidget, we must refresh placeholders
|
|
Packit |
1e8aac |
* because the widget may have spanned multiple rows/columns, we must
|
|
Packit |
1e8aac |
* not do so in the case we are pasting multiple widgets into a table,
|
|
Packit |
1e8aac |
* where destroying placeholders results in default packing properties
|
|
Packit |
1e8aac |
* (since the remaining placeholder templates no longer exist, only the
|
|
Packit |
1e8aac |
* first pasted widget would have proper packing properties).
|
|
Packit |
1e8aac |
*/
|
|
Packit |
1e8aac |
if (!GLADE_IS_PLACEHOLDER (new_widget))
|
|
Packit |
1e8aac |
glade_gtk_table_refresh_placeholders (GTK_TABLE (container));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_gtk_table_set_n_common (GObject * object, const GValue * value,
|
|
Packit |
1e8aac |
gboolean for_rows)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *widget;
|
|
Packit |
1e8aac |
GtkTable *table;
|
|
Packit |
1e8aac |
guint new_size, old_size, n_columns, n_rows;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
table = GTK_TABLE (object);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_get (table, "n-columns", &n_columns, "n-rows", &n_rows, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
new_size = g_value_get_uint (value);
|
|
Packit |
1e8aac |
old_size = for_rows ? n_rows : n_columns;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (new_size < 1)
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (glade_gtk_table_widget_exceeds_bounds
|
|
Packit |
1e8aac |
(table, for_rows ? new_size : n_rows, for_rows ? n_columns : new_size))
|
|
Packit |
1e8aac |
/* Refuse to shrink if it means orphaning widgets */
|
|
Packit |
1e8aac |
return;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
widget = glade_widget_get_from_gobject (GTK_WIDGET (table));
|
|
Packit |
1e8aac |
g_return_if_fail (widget != NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
|
Packit |
1e8aac |
if (for_rows)
|
|
Packit |
1e8aac |
gtk_table_resize (table, new_size, n_columns);
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
gtk_table_resize (table, n_rows, new_size);
|
|
Packit |
1e8aac |
G_GNUC_END_IGNORE_DEPRECATIONS;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Fill table with placeholders */
|
|
Packit |
1e8aac |
glade_gtk_table_refresh_placeholders (table);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (new_size < old_size)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* Remove from the bottom up */
|
|
Packit |
1e8aac |
GList *list, *children;
|
|
Packit |
1e8aac |
GList *list_to_free = NULL;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
children = gtk_container_get_children (GTK_CONTAINER (table));
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
for (list = children; list && list->data; list = list->next)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTableChild child;
|
|
Packit |
1e8aac |
guint start, end;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_gtk_table_get_child_attachments (GTK_WIDGET (table),
|
|
Packit |
1e8aac |
GTK_WIDGET (list->data),
|
|
Packit |
1e8aac |
&child);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
start = for_rows ? child.top_attach : child.left_attach;
|
|
Packit |
1e8aac |
end = for_rows ? child.bottom_attach : child.right_attach;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* We need to completely remove it */
|
|
Packit |
1e8aac |
if (start >= new_size)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
list_to_free = g_list_prepend (list_to_free, child.widget);
|
|
Packit |
1e8aac |
continue;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* If the widget spans beyond the new border,
|
|
Packit |
1e8aac |
* we should resize it to fit on the new table */
|
|
Packit |
1e8aac |
if (end > new_size)
|
|
Packit |
1e8aac |
gtk_container_child_set
|
|
Packit |
1e8aac |
(GTK_CONTAINER (table), GTK_WIDGET (child.widget),
|
|
Packit |
1e8aac |
for_rows ? "bottom_attach" : "right_attach", new_size, NULL);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_list_free (children);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (list_to_free)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
for (list = g_list_first (list_to_free);
|
|
Packit |
1e8aac |
list && list->data; list = list->next)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
g_object_ref (G_OBJECT (list->data));
|
|
Packit |
1e8aac |
gtk_container_remove (GTK_CONTAINER (table),
|
|
Packit |
1e8aac |
GTK_WIDGET (list->data));
|
|
Packit |
1e8aac |
/* This placeholder is no longer valid, force destroy */
|
|
Packit |
1e8aac |
gtk_widget_destroy (GTK_WIDGET (list->data));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
g_list_free (list_to_free);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
|
Packit |
1e8aac |
gtk_table_resize (table,
|
|
Packit |
1e8aac |
for_rows ? new_size : n_rows,
|
|
Packit |
1e8aac |
for_rows ? n_columns : new_size);
|
|
Packit |
1e8aac |
G_GNUC_END_IGNORE_DEPRECATIONS;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_gtk_table_set_property (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GObject * object,
|
|
Packit |
1e8aac |
const gchar * id, const GValue * value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!strcmp (id, "n-rows"))
|
|
Packit |
1e8aac |
glade_gtk_table_set_n_common (object, value, TRUE);
|
|
Packit |
1e8aac |
else if (!strcmp (id, "n-columns"))
|
|
Packit |
1e8aac |
glade_gtk_table_set_n_common (object, value, FALSE);
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object,
|
|
Packit |
1e8aac |
id, value);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_gtk_table_verify_n_common (GObject * object, const GValue * value,
|
|
Packit |
1e8aac |
gboolean for_rows)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GtkTable *table = GTK_TABLE (object);
|
|
Packit |
1e8aac |
guint n_columns, n_rows, new_size = g_value_get_uint (value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_object_get (table, "n-columns", &n_columns, "n-rows", &n_rows, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (glade_gtk_table_widget_exceeds_bounds
|
|
Packit |
1e8aac |
(table, for_rows ? new_size : n_rows, for_rows ? n_columns : new_size))
|
|
Packit |
1e8aac |
/* Refuse to shrink if it means orphaning widgets */
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_gtk_table_verify_property (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GObject * object,
|
|
Packit |
1e8aac |
const gchar * id, const GValue * value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!strcmp (id, "n-rows"))
|
|
Packit |
1e8aac |
return glade_gtk_table_verify_n_common (object, value, TRUE);
|
|
Packit |
1e8aac |
else if (!strcmp (id, "n-columns"))
|
|
Packit |
1e8aac |
return glade_gtk_table_verify_n_common (object, value, FALSE);
|
|
Packit |
1e8aac |
else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property)
|
|
Packit |
1e8aac |
GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property (adaptor, object,
|
|
Packit |
1e8aac |
id, value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_gtk_table_set_child_property (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GObject * container,
|
|
Packit |
1e8aac |
GObject * child,
|
|
Packit |
1e8aac |
const gchar * property_name, GValue * value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GWA_GET_CLASS
|
|
Packit |
1e8aac |
(GTK_TYPE_CONTAINER)->child_set_property (adaptor,
|
|
Packit |
1e8aac |
container, child,
|
|
Packit |
1e8aac |
property_name, value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (strcmp (property_name, "bottom-attach") == 0 ||
|
|
Packit |
1e8aac |
strcmp (property_name, "left-attach") == 0 ||
|
|
Packit |
1e8aac |
strcmp (property_name, "right-attach") == 0 ||
|
|
Packit |
1e8aac |
strcmp (property_name, "top-attach") == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* Refresh placeholders */
|
|
Packit |
1e8aac |
glade_gtk_table_refresh_placeholders (GTK_TABLE (container));
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_gtk_table_verify_attach_common (GObject * object,
|
|
Packit |
1e8aac |
GValue * value,
|
|
Packit |
1e8aac |
guint * val,
|
|
Packit |
1e8aac |
const gchar * prop,
|
|
Packit |
1e8aac |
guint * prop_val,
|
|
Packit |
1e8aac |
const gchar * parent_prop,
|
|
Packit |
1e8aac |
guint * parent_val)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *widget, *parent;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
widget = glade_widget_get_from_gobject (object);
|
|
Packit |
1e8aac |
g_return_val_if_fail (GLADE_IS_WIDGET (widget), TRUE);
|
|
Packit |
1e8aac |
parent = glade_widget_get_parent (widget);
|
|
Packit |
1e8aac |
g_return_val_if_fail (GLADE_IS_WIDGET (parent), TRUE);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
*val = g_value_get_uint (value);
|
|
Packit |
1e8aac |
glade_widget_property_get (widget, prop, prop_val);
|
|
Packit |
1e8aac |
glade_widget_property_get (parent, parent_prop, parent_val);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_gtk_table_verify_left_top_attach (GObject * object,
|
|
Packit |
1e8aac |
GValue * value,
|
|
Packit |
1e8aac |
const gchar * prop,
|
|
Packit |
1e8aac |
const gchar * parent_prop)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
guint val, prop_val, parent_val;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (glade_gtk_table_verify_attach_common (object, value, &val,
|
|
Packit |
1e8aac |
prop, &prop_val,
|
|
Packit |
1e8aac |
parent_prop, &parent_val))
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (val >= parent_val || val >= prop_val)
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static gboolean
|
|
Packit |
1e8aac |
glade_gtk_table_verify_right_bottom_attach (GObject * object,
|
|
Packit |
1e8aac |
GValue * value,
|
|
Packit |
1e8aac |
const gchar * prop,
|
|
Packit |
1e8aac |
const gchar * parent_prop)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
guint val, prop_val, parent_val;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (glade_gtk_table_verify_attach_common (object, value, &val,
|
|
Packit |
1e8aac |
prop, &prop_val,
|
|
Packit |
1e8aac |
parent_prop, &parent_val))
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (val <= prop_val || val > parent_val)
|
|
Packit |
1e8aac |
return FALSE;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gboolean
|
|
Packit |
1e8aac |
glade_gtk_table_child_verify_property (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GObject * container,
|
|
Packit |
1e8aac |
GObject * child,
|
|
Packit |
1e8aac |
const gchar * id, GValue * value)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (!strcmp (id, "left-attach"))
|
|
Packit |
1e8aac |
return glade_gtk_table_verify_left_top_attach (child,
|
|
Packit |
1e8aac |
value,
|
|
Packit |
1e8aac |
"right-attach", "n-columns");
|
|
Packit |
1e8aac |
else if (!strcmp (id, "right-attach"))
|
|
Packit |
1e8aac |
return glade_gtk_table_verify_right_bottom_attach (child,
|
|
Packit |
1e8aac |
value,
|
|
Packit |
1e8aac |
"left-attach",
|
|
Packit |
1e8aac |
"n-columns");
|
|
Packit |
1e8aac |
else if (!strcmp (id, "top-attach"))
|
|
Packit |
1e8aac |
return glade_gtk_table_verify_left_top_attach (child,
|
|
Packit |
1e8aac |
value,
|
|
Packit |
1e8aac |
"bottom-attach", "n-rows");
|
|
Packit |
1e8aac |
else if (!strcmp (id, "bottom-attach"))
|
|
Packit |
1e8aac |
return glade_gtk_table_verify_right_bottom_attach (child,
|
|
Packit |
1e8aac |
value,
|
|
Packit |
1e8aac |
"top-attach", "n-rows");
|
|
Packit |
1e8aac |
else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_verify_property)
|
|
Packit |
1e8aac |
GWA_GET_CLASS
|
|
Packit |
1e8aac |
(GTK_TYPE_CONTAINER)->child_verify_property (adaptor,
|
|
Packit |
1e8aac |
container, child,
|
|
Packit |
1e8aac |
id, value);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
return TRUE;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
static void
|
|
Packit |
1e8aac |
glade_gtk_table_child_insert_remove_action (GladeWidgetAdaptor *adaptor,
|
|
Packit |
1e8aac |
GObject *container,
|
|
Packit |
1e8aac |
GObject *object,
|
|
Packit |
1e8aac |
GroupAction group_action,
|
|
Packit |
1e8aac |
const gchar *n_row_col,
|
|
Packit |
1e8aac |
const gchar *attach1, /* should be smaller (top/left) attachment */
|
|
Packit |
1e8aac |
const gchar *attach2, /* should be larger (bot/right) attachment */
|
|
Packit |
1e8aac |
gboolean remove,
|
|
Packit |
1e8aac |
gboolean after)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *parent;
|
|
Packit |
1e8aac |
GList *children, *l;
|
|
Packit |
1e8aac |
gint child_pos, size, offset;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
gtk_container_child_get (GTK_CONTAINER (container),
|
|
Packit |
1e8aac |
GTK_WIDGET (object),
|
|
Packit |
1e8aac |
after ? attach2 : attach1, &child_pos, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
parent = glade_widget_get_from_gobject (container);
|
|
Packit |
1e8aac |
switch (group_action)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
case GROUP_ACTION_INSERT_ROW:
|
|
Packit |
1e8aac |
glade_command_push_group (_("Insert Row on %s"), glade_widget_get_name (parent));
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GROUP_ACTION_INSERT_COLUMN:
|
|
Packit |
1e8aac |
glade_command_push_group (_("Insert Column on %s"), glade_widget_get_name (parent));
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GROUP_ACTION_REMOVE_COLUMN:
|
|
Packit |
1e8aac |
glade_command_push_group (_("Remove Column on %s"), glade_widget_get_name (parent));
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
case GROUP_ACTION_REMOVE_ROW:
|
|
Packit |
1e8aac |
glade_command_push_group (_("Remove Row on %s"), glade_widget_get_name (parent));
|
|
Packit |
1e8aac |
break;
|
|
Packit |
1e8aac |
default:
|
|
Packit |
1e8aac |
g_assert_not_reached ();
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
children = glade_widget_adaptor_get_children (adaptor, container);
|
|
Packit |
1e8aac |
/* Make sure widgets does not get destroyed */
|
|
Packit |
1e8aac |
g_list_foreach (children, (GFunc) g_object_ref, NULL);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_widget_property_get (parent, n_row_col, &size);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (remove)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GList *del = NULL;
|
|
Packit |
1e8aac |
/* Remove children first */
|
|
Packit |
1e8aac |
for (l = children; l; l = g_list_next (l))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *gchild = glade_widget_get_from_gobject (l->data);
|
|
Packit |
1e8aac |
gint pos1, pos2;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Skip placeholders */
|
|
Packit |
1e8aac |
if (gchild == NULL)
|
|
Packit |
1e8aac |
continue;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_widget_pack_property_get (gchild, attach1, &pos1);
|
|
Packit |
1e8aac |
glade_widget_pack_property_get (gchild, attach2, &pos2);
|
|
Packit |
1e8aac |
if ((pos1 + 1 == pos2) && ((after ? pos2 : pos1) == child_pos))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
del = g_list_prepend (del, gchild);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
if (del)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_command_delete (del);
|
|
Packit |
1e8aac |
g_list_free (del);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
offset = -1;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* Expand the table */
|
|
Packit |
1e8aac |
glade_command_set_property (glade_widget_get_property (parent, n_row_col),
|
|
Packit |
1e8aac |
size + 1);
|
|
Packit |
1e8aac |
offset = 1;
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Reorder children */
|
|
Packit |
1e8aac |
for (l = children; l; l = g_list_next (l))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
GladeWidget *gchild = glade_widget_get_from_gobject (l->data);
|
|
Packit |
1e8aac |
gint pos;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* Skip placeholders */
|
|
Packit |
1e8aac |
if (gchild == NULL)
|
|
Packit |
1e8aac |
continue;
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* if removing, do top/left before bot/right */
|
|
Packit |
1e8aac |
if (remove)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* adjust top-left attachment */
|
|
Packit |
1e8aac |
glade_widget_pack_property_get (gchild, attach1, &pos;;
|
|
Packit |
1e8aac |
if (pos > child_pos || (after && pos == child_pos))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_command_set_property (glade_widget_get_pack_property
|
|
Packit |
1e8aac |
(gchild, attach1), pos + offset);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* adjust bottom-right attachment */
|
|
Packit |
1e8aac |
glade_widget_pack_property_get (gchild, attach2, &pos;;
|
|
Packit |
1e8aac |
if (pos > child_pos || (after && pos == child_pos))
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_command_set_property (glade_widget_get_pack_property
|
|
Packit |
1e8aac |
(gchild, attach2), pos + offset);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
/* if inserting, do bot/right before top/left */
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* adjust bottom-right attachment */
|
|
Packit |
1e8aac |
glade_widget_pack_property_get (gchild, attach2, &pos;;
|
|
Packit |
1e8aac |
if (pos > child_pos)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_command_set_property (glade_widget_get_pack_property
|
|
Packit |
1e8aac |
(gchild, attach2), pos + offset);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
/* adjust top-left attachment */
|
|
Packit |
1e8aac |
glade_widget_pack_property_get (gchild, attach1, &pos;;
|
|
Packit |
1e8aac |
if (pos >= child_pos)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_command_set_property (glade_widget_get_pack_property
|
|
Packit |
1e8aac |
(gchild, attach1), pos + offset);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
if (remove)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
/* Shrink the table */
|
|
Packit |
1e8aac |
glade_command_set_property (glade_widget_get_property (parent, n_row_col),
|
|
Packit |
1e8aac |
size - 1);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
g_list_foreach (children, (GFunc) g_object_unref, NULL);
|
|
Packit |
1e8aac |
g_list_free (children);
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
glade_command_pop_group ();
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
|
|
Packit |
1e8aac |
void
|
|
Packit |
1e8aac |
glade_gtk_table_child_action_activate (GladeWidgetAdaptor * adaptor,
|
|
Packit |
1e8aac |
GObject * container,
|
|
Packit |
1e8aac |
GObject * object,
|
|
Packit |
1e8aac |
const gchar * action_path)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
if (strcmp (action_path, "insert_row/after") == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_gtk_table_child_insert_remove_action (adaptor, container, object,
|
|
Packit |
1e8aac |
GROUP_ACTION_INSERT_ROW,
|
|
Packit |
1e8aac |
"n-rows", "top-attach",
|
|
Packit |
1e8aac |
"bottom-attach", FALSE, TRUE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (strcmp (action_path, "insert_row/before") == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_gtk_table_child_insert_remove_action (adaptor, container, object,
|
|
Packit |
1e8aac |
GROUP_ACTION_INSERT_ROW,
|
|
Packit |
1e8aac |
"n-rows", "top-attach",
|
|
Packit |
1e8aac |
"bottom-attach",
|
|
Packit |
1e8aac |
FALSE, FALSE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (strcmp (action_path, "insert_column/after") == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_gtk_table_child_insert_remove_action (adaptor, container, object,
|
|
Packit |
1e8aac |
GROUP_ACTION_INSERT_COLUMN,
|
|
Packit |
1e8aac |
"n-columns", "left-attach",
|
|
Packit |
1e8aac |
"right-attach", FALSE, TRUE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (strcmp (action_path, "insert_column/before") == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_gtk_table_child_insert_remove_action (adaptor, container, object,
|
|
Packit |
1e8aac |
GROUP_ACTION_INSERT_COLUMN,
|
|
Packit |
1e8aac |
"n-columns", "left-attach",
|
|
Packit |
1e8aac |
"right-attach", FALSE, FALSE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (strcmp (action_path, "remove_column") == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_gtk_table_child_insert_remove_action (adaptor, container, object,
|
|
Packit |
1e8aac |
GROUP_ACTION_REMOVE_COLUMN,
|
|
Packit |
1e8aac |
"n-columns", "left-attach",
|
|
Packit |
1e8aac |
"right-attach", TRUE, FALSE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else if (strcmp (action_path, "remove_row") == 0)
|
|
Packit |
1e8aac |
{
|
|
Packit |
1e8aac |
glade_gtk_table_child_insert_remove_action (adaptor, container, object,
|
|
Packit |
1e8aac |
GROUP_ACTION_REMOVE_ROW,
|
|
Packit |
1e8aac |
"n-rows", "top-attach",
|
|
Packit |
1e8aac |
"bottom-attach", TRUE, FALSE);
|
|
Packit |
1e8aac |
}
|
|
Packit |
1e8aac |
else
|
|
Packit |
1e8aac |
GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_action_activate (adaptor,
|
|
Packit |
1e8aac |
container,
|
|
Packit |
1e8aac |
object,
|
|
Packit |
1e8aac |
action_path);
|
|
Packit |
1e8aac |
}
|