Blame plugins/gtk+/glade-gtk-notebook.c

Packit 1e8aac
/*
Packit 1e8aac
 * glade-gtk-notebook.c - GladeWidgetAdaptor for GtkNotebook
Packit 1e8aac
 *
Packit 1e8aac
 * Copyright (C) 2013 Tristan Van Berkom
Packit 1e8aac
 *
Packit 1e8aac
 * Authors:
Packit 1e8aac
 *      Tristan Van Berkom <tristan.van.berkom@gmail.com>
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
#include <config.h>
Packit 1e8aac
#include <glib/gi18n-lib.h>
Packit 1e8aac
#include <gladeui/glade.h>
Packit 1e8aac
Packit 1e8aac
#include "glade-gtk-notebook.h"
Packit 1e8aac
#include "glade-notebook-editor.h"
Packit 1e8aac
Packit 1e8aac
typedef struct
Packit 1e8aac
{
Packit 1e8aac
  gint pages;
Packit 1e8aac
  gint page;
Packit 1e8aac
Packit 1e8aac
  GList *children;
Packit 1e8aac
  GList *tabs;
Packit 1e8aac
Packit 1e8aac
  GList *extra_children;
Packit 1e8aac
  GList *extra_tabs;
Packit 1e8aac
} NotebookChildren;
Packit 1e8aac
Packit 1e8aac
static gboolean glade_gtk_notebook_setting_position = FALSE;
Packit 1e8aac
Packit 1e8aac
Packit 1e8aac
GladeEditable *
Packit 1e8aac
glade_gtk_notebook_create_editable (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
				    GladeEditorPageType type)
Packit 1e8aac
{
Packit 1e8aac
  if (type == GLADE_PAGE_GENERAL)
Packit 1e8aac
    return (GladeEditable *) glade_notebook_editor_new ();
Packit 1e8aac
Packit 1e8aac
  return GWA_GET_CLASS (GTK_TYPE_CONTAINER)->create_editable (adaptor, type);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gint
Packit 1e8aac
notebook_child_compare_func (GtkWidget * widget_a, GtkWidget * widget_b)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *gwidget_a, *gwidget_b;
Packit 1e8aac
  gint pos_a = 0, pos_b = 0;
Packit 1e8aac
Packit 1e8aac
  gwidget_a = glade_widget_get_from_gobject (widget_a);
Packit 1e8aac
  gwidget_b = glade_widget_get_from_gobject (widget_b);
Packit 1e8aac
Packit 1e8aac
  g_assert (gwidget_a && gwidget_b);
Packit 1e8aac
Packit 1e8aac
  glade_widget_pack_property_get (gwidget_a, "position", &pos_a);
Packit 1e8aac
  glade_widget_pack_property_get (gwidget_b, "position", &pos_b);
Packit 1e8aac
Packit 1e8aac
  return pos_a - pos_b;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gint
Packit 1e8aac
notebook_find_child (GtkWidget * check, gpointer cmp_pos_p)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *gcheck;
Packit 1e8aac
  gint position = 0, cmp_pos = GPOINTER_TO_INT (cmp_pos_p);
Packit 1e8aac
Packit 1e8aac
  gcheck = glade_widget_get_from_gobject (check);
Packit 1e8aac
  g_assert (gcheck);
Packit 1e8aac
Packit 1e8aac
  glade_widget_pack_property_get (gcheck, "position", &position);
Packit 1e8aac
Packit 1e8aac
  return position - cmp_pos;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gint
Packit 1e8aac
notebook_search_tab (GtkNotebook * notebook, GtkWidget * tab)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *page;
Packit 1e8aac
  gint i;
Packit 1e8aac
Packit 1e8aac
  for (i = 0; i < gtk_notebook_get_n_pages (notebook); i++)
Packit 1e8aac
    {
Packit 1e8aac
      page = gtk_notebook_get_nth_page (notebook, i);
Packit 1e8aac
Packit 1e8aac
      if (tab == gtk_notebook_get_tab_label (notebook, page))
Packit 1e8aac
        return i;
Packit 1e8aac
    }
Packit 1e8aac
  g_critical ("Unable to find tab position in a notebook");
Packit 1e8aac
  return -1;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkWidget *
Packit 1e8aac
notebook_get_filler (NotebookChildren * nchildren, gboolean page)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *widget = NULL;
Packit 1e8aac
Packit 1e8aac
  if (page && nchildren->extra_children)
Packit 1e8aac
    {
Packit 1e8aac
      widget = nchildren->extra_children->data;
Packit 1e8aac
      nchildren->extra_children =
Packit 1e8aac
          g_list_remove (nchildren->extra_children, widget);
Packit 1e8aac
      g_assert (widget);
Packit 1e8aac
    }
Packit 1e8aac
  else if (!page && nchildren->extra_tabs)
Packit 1e8aac
    {
Packit 1e8aac
      widget = nchildren->extra_tabs->data;
Packit 1e8aac
      nchildren->extra_tabs = g_list_remove (nchildren->extra_tabs, widget);
Packit 1e8aac
      g_assert (widget);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (widget == NULL)
Packit 1e8aac
    {
Packit 1e8aac
      /* Need explicit reference here */
Packit 1e8aac
      widget = glade_placeholder_new ();
Packit 1e8aac
Packit 1e8aac
      g_object_ref (G_OBJECT (widget));
Packit 1e8aac
Packit 1e8aac
      if (!page)
Packit 1e8aac
        g_object_set_data (G_OBJECT (widget), "special-child-type", "tab");
Packit 1e8aac
Packit 1e8aac
    }
Packit 1e8aac
  return widget;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkWidget *
Packit 1e8aac
notebook_get_page (NotebookChildren * nchildren, gint position)
Packit 1e8aac
{
Packit 1e8aac
  GList *node;
Packit 1e8aac
  GtkWidget *widget = NULL;
Packit 1e8aac
Packit 1e8aac
  if ((node = g_list_find_custom
Packit 1e8aac
       (nchildren->children,
Packit 1e8aac
        GINT_TO_POINTER (position),
Packit 1e8aac
        (GCompareFunc) notebook_find_child)) != NULL)
Packit 1e8aac
    {
Packit 1e8aac
      widget = node->data;
Packit 1e8aac
      nchildren->children = g_list_remove (nchildren->children, widget);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    widget = notebook_get_filler (nchildren, TRUE);
Packit 1e8aac
Packit 1e8aac
  return widget;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GtkWidget *
Packit 1e8aac
notebook_get_tab (NotebookChildren * nchildren, gint position)
Packit 1e8aac
{
Packit 1e8aac
  GList *node;
Packit 1e8aac
  GtkWidget *widget = NULL;
Packit 1e8aac
Packit 1e8aac
  if ((node = g_list_find_custom
Packit 1e8aac
       (nchildren->tabs,
Packit 1e8aac
        GINT_TO_POINTER (position),
Packit 1e8aac
        (GCompareFunc) notebook_find_child)) != NULL)
Packit 1e8aac
    {
Packit 1e8aac
      widget = node->data;
Packit 1e8aac
      nchildren->tabs = g_list_remove (nchildren->tabs, widget);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    widget = notebook_get_filler (nchildren, FALSE);
Packit 1e8aac
Packit 1e8aac
  return widget;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static NotebookChildren *
Packit 1e8aac
glade_gtk_notebook_extract_children (GtkWidget * notebook)
Packit 1e8aac
{
Packit 1e8aac
  NotebookChildren *nchildren;
Packit 1e8aac
  gchar *special_child_type;
Packit 1e8aac
  GList *list, *children =
Packit 1e8aac
      glade_util_container_get_all_children (GTK_CONTAINER (notebook));
Packit 1e8aac
  GladeWidget *gchild;
Packit 1e8aac
  gint position = 0;
Packit 1e8aac
  GtkNotebook *nb;
Packit 1e8aac
Packit 1e8aac
  nb = GTK_NOTEBOOK (notebook);
Packit 1e8aac
  nchildren = g_new0 (NotebookChildren, 1);
Packit 1e8aac
  nchildren->pages = gtk_notebook_get_n_pages (nb);
Packit 1e8aac
  nchildren->page = gtk_notebook_get_current_page (nb);
Packit 1e8aac
Packit 1e8aac
  /* Ref all the project widgets and build returned list first */
Packit 1e8aac
  for (list = children; list; list = list->next)
Packit 1e8aac
    {
Packit 1e8aac
      if ((gchild = glade_widget_get_from_gobject (list->data)) != NULL)
Packit 1e8aac
        {
Packit 1e8aac
          special_child_type =
Packit 1e8aac
              g_object_get_data (G_OBJECT (list->data), "special-child-type");
Packit 1e8aac
Packit 1e8aac
          glade_widget_pack_property_get (gchild, "position", &position);
Packit 1e8aac
Packit 1e8aac
          g_object_ref (G_OBJECT (list->data));
Packit 1e8aac
Packit 1e8aac
          /* Sort it into the proper struct member
Packit 1e8aac
           */
Packit 1e8aac
          if (special_child_type == NULL)
Packit 1e8aac
            {
Packit 1e8aac
              if (g_list_find_custom (nchildren->children,
Packit 1e8aac
                                      GINT_TO_POINTER (position),
Packit 1e8aac
                                      (GCompareFunc) notebook_find_child))
Packit 1e8aac
                nchildren->extra_children =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->extra_children, list->data,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
              else
Packit 1e8aac
                nchildren->children =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->children, list->data,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
            }
Packit 1e8aac
          else if (!strcmp (special_child_type, "tab"))
Packit 1e8aac
            {
Packit 1e8aac
              if (g_list_find_custom (nchildren->tabs,
Packit 1e8aac
                                      GINT_TO_POINTER (position),
Packit 1e8aac
                                      (GCompareFunc) notebook_find_child))
Packit 1e8aac
                nchildren->extra_tabs =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->extra_tabs, list->data,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
              else
Packit 1e8aac
                nchildren->tabs =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->tabs, list->data,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
            }
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Remove all pages, resulting in the unparenting of all widgets including tab-labels.
Packit 1e8aac
   */
Packit 1e8aac
  while (gtk_notebook_get_n_pages (nb) > 0)
Packit 1e8aac
    {
Packit 1e8aac
      GtkWidget *page = gtk_notebook_get_nth_page (nb, 0);
Packit 1e8aac
      GtkWidget *tab = gtk_notebook_get_tab_label (nb, page);
Packit 1e8aac
Packit 1e8aac
      if (tab)
Packit 1e8aac
	g_object_ref (tab);
Packit 1e8aac
Packit 1e8aac
      /* Explicitly remove the tab label first */
Packit 1e8aac
      gtk_notebook_set_tab_label (nb, page, NULL);
Packit 1e8aac
Packit 1e8aac
      /* FIXE: we need to unparent here to avoid anoying warning when reparenting */
Packit 1e8aac
      if (tab)
Packit 1e8aac
	{
Packit 1e8aac
	  gtk_widget_unparent (tab);
Packit 1e8aac
	  g_object_unref (tab);
Packit 1e8aac
	}
Packit 1e8aac
Packit 1e8aac
      gtk_notebook_remove_page (nb, 0);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (children)
Packit 1e8aac
    g_list_free (children);
Packit 1e8aac
Packit 1e8aac
  return nchildren;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_notebook_insert_children (GtkWidget * notebook,
Packit 1e8aac
                                    NotebookChildren * nchildren)
Packit 1e8aac
{
Packit 1e8aac
  gint i;
Packit 1e8aac
Packit 1e8aac
  /*********************************************************
Packit 1e8aac
   *                     INSERT PAGES                      *
Packit 1e8aac
   *********************************************************/
Packit 1e8aac
  for (i = 0; i < nchildren->pages; i++)
Packit 1e8aac
    {
Packit 1e8aac
      GtkWidget *page = notebook_get_page (nchildren, i);
Packit 1e8aac
      GtkWidget *tab = notebook_get_tab (nchildren, i);
Packit 1e8aac
Packit 1e8aac
      gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), page, tab, i);
Packit 1e8aac
Packit 1e8aac
      g_object_unref (G_OBJECT (page));
Packit 1e8aac
      g_object_unref (G_OBJECT (tab));
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Stay on the same page */
Packit 1e8aac
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), nchildren->page);
Packit 1e8aac
Packit 1e8aac
  /* Free the original lists now */
Packit 1e8aac
  if (nchildren->children)
Packit 1e8aac
    g_list_free (nchildren->children);
Packit 1e8aac
Packit 1e8aac
  if (nchildren->tabs)
Packit 1e8aac
    g_list_free (nchildren->tabs);
Packit 1e8aac
Packit 1e8aac
  if (nchildren->children ||
Packit 1e8aac
      nchildren->tabs || nchildren->extra_children || nchildren->extra_tabs)
Packit 1e8aac
    g_critical ("Unbalanced children when inserting notebook children"
Packit 1e8aac
                " (pages: %d tabs: %d extra pages: %d extra tabs %d)",
Packit 1e8aac
                g_list_length (nchildren->children),
Packit 1e8aac
                g_list_length (nchildren->tabs),
Packit 1e8aac
                g_list_length (nchildren->extra_children),
Packit 1e8aac
                g_list_length (nchildren->extra_tabs));
Packit 1e8aac
Packit 1e8aac
  g_free (nchildren);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_notebook_switch_page (GtkNotebook * notebook,
Packit 1e8aac
                                GtkWidget * page,
Packit 1e8aac
                                guint page_num, gpointer user_data)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *gnotebook = glade_widget_get_from_gobject (notebook);
Packit 1e8aac
Packit 1e8aac
  glade_widget_property_set (gnotebook, "page", page_num);
Packit 1e8aac
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/* Track project selection to set the notebook pages to display
Packit 1e8aac
 * the selected widget.
Packit 1e8aac
 */
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_notebook_selection_changed (GladeProject * project,
Packit 1e8aac
                                      GladeWidget * gwidget)
Packit 1e8aac
{
Packit 1e8aac
  GList *list;
Packit 1e8aac
  gint i;
Packit 1e8aac
  GtkWidget *page, *sel_widget;
Packit 1e8aac
  GtkNotebook *notebook = GTK_NOTEBOOK (glade_widget_get_object (gwidget));
Packit 1e8aac
Packit 1e8aac
  if ((list = glade_project_selection_get (project)) != NULL &&
Packit 1e8aac
      g_list_length (list) == 1)
Packit 1e8aac
    {
Packit 1e8aac
      sel_widget = list->data;
Packit 1e8aac
Packit 1e8aac
      /* Check if selected widget is inside the notebook */
Packit 1e8aac
      if (GTK_IS_WIDGET (sel_widget) &&
Packit 1e8aac
          gtk_widget_is_ancestor (sel_widget, GTK_WIDGET (notebook)))
Packit 1e8aac
        {
Packit 1e8aac
          /* Find and activate the page */
Packit 1e8aac
          for (i = 0;
Packit 1e8aac
               i < gtk_notebook_get_n_pages (notebook);
Packit 1e8aac
               i++)
Packit 1e8aac
            {
Packit 1e8aac
              page = gtk_notebook_get_nth_page (notebook, i);
Packit 1e8aac
Packit 1e8aac
              if (sel_widget == page ||
Packit 1e8aac
                  gtk_widget_is_ancestor (sel_widget, GTK_WIDGET (page)))
Packit 1e8aac
                {
Packit 1e8aac
                  glade_widget_property_set (gwidget, "page", i);
Packit 1e8aac
                  return;
Packit 1e8aac
                }
Packit 1e8aac
            }
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_notebook_project_changed (GladeWidget * gwidget,
Packit 1e8aac
                                    GParamSpec * pspec, gpointer userdata)
Packit 1e8aac
{
Packit 1e8aac
  GladeProject
Packit 1e8aac
      * project = glade_widget_get_project (gwidget),
Packit 1e8aac
      *old_project =
Packit 1e8aac
      g_object_get_data (G_OBJECT (gwidget), "notebook-project-ptr");
Packit 1e8aac
Packit 1e8aac
  if (old_project)
Packit 1e8aac
    g_signal_handlers_disconnect_by_func (G_OBJECT (old_project),
Packit 1e8aac
                                          G_CALLBACK
Packit 1e8aac
                                          (glade_gtk_notebook_selection_changed),
Packit 1e8aac
                                          gwidget);
Packit 1e8aac
Packit 1e8aac
  if (project)
Packit 1e8aac
    g_signal_connect (G_OBJECT (project), "selection-changed",
Packit 1e8aac
                      G_CALLBACK (glade_gtk_notebook_selection_changed),
Packit 1e8aac
                      gwidget);
Packit 1e8aac
Packit 1e8aac
  g_object_set_data (G_OBJECT (gwidget), "notebook-project-ptr", project);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_notebook_parse_finished (GladeProject * project, GObject * object)
Packit 1e8aac
{
Packit 1e8aac
  GtkWidget *action;
Packit 1e8aac
Packit 1e8aac
  action = gtk_notebook_get_action_widget (GTK_NOTEBOOK (object), GTK_PACK_START);
Packit 1e8aac
  glade_widget_property_set (glade_widget_get_from_gobject (object),
Packit 1e8aac
                             "has-action-start", action != NULL);
Packit 1e8aac
  action = gtk_notebook_get_action_widget (GTK_NOTEBOOK (object), GTK_PACK_END);
Packit 1e8aac
  glade_widget_property_set (glade_widget_get_from_gobject (object),
Packit 1e8aac
                             "has-action-end", action != NULL);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_notebook_post_create (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                GObject * notebook, GladeCreateReason reason)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *gwidget = glade_widget_get_from_gobject (notebook);
Packit 1e8aac
  GladeProject *project = glade_widget_get_project (gwidget);
Packit 1e8aac
Packit 1e8aac
  gtk_notebook_popup_disable (GTK_NOTEBOOK (notebook));
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (G_OBJECT (gwidget), "notify::project",
Packit 1e8aac
                    G_CALLBACK (glade_gtk_notebook_project_changed), NULL);
Packit 1e8aac
Packit 1e8aac
  glade_gtk_notebook_project_changed (gwidget, NULL, NULL);
Packit 1e8aac
Packit 1e8aac
  g_signal_connect (G_OBJECT (notebook), "switch-page",
Packit 1e8aac
                    G_CALLBACK (glade_gtk_notebook_switch_page), NULL);
Packit 1e8aac
Packit 1e8aac
  if (reason == GLADE_CREATE_LOAD)
Packit 1e8aac
    g_signal_connect (project, "parse-finished",
Packit 1e8aac
                      G_CALLBACK (glade_gtk_notebook_parse_finished),
Packit 1e8aac
                      notebook);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gint
Packit 1e8aac
glade_gtk_notebook_get_first_blank_page (GtkNotebook * notebook)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *gwidget;
Packit 1e8aac
  GtkWidget *widget;
Packit 1e8aac
  gint position;
Packit 1e8aac
Packit 1e8aac
  for (position = 0; position < gtk_notebook_get_n_pages (notebook); position++)
Packit 1e8aac
    {
Packit 1e8aac
      widget = gtk_notebook_get_nth_page (notebook, position);
Packit 1e8aac
      if ((gwidget = glade_widget_get_from_gobject (widget)) != NULL)
Packit 1e8aac
        {
Packit 1e8aac
          GladeProperty *property =
Packit 1e8aac
              glade_widget_get_property (gwidget, "position");
Packit 1e8aac
          gint gwidget_position = g_value_get_int (glade_property_inline_value (property));
Packit 1e8aac
Packit 1e8aac
          if ((gwidget_position - position) > 0)
Packit 1e8aac
            return position;
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
  return position;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static GladeWidget *
Packit 1e8aac
glade_gtk_notebook_generate_tab (GladeWidget * notebook, gint page_id)
Packit 1e8aac
{
Packit 1e8aac
  static GladeWidgetAdaptor *wadaptor = NULL;
Packit 1e8aac
  gchar *str;
Packit 1e8aac
  GladeWidget *glabel;
Packit 1e8aac
Packit 1e8aac
  if (wadaptor == NULL)
Packit 1e8aac
    wadaptor = glade_widget_adaptor_get_by_type (GTK_TYPE_LABEL);
Packit 1e8aac
Packit 1e8aac
  glabel = glade_widget_adaptor_create_widget (wadaptor, FALSE,
Packit 1e8aac
                                               "parent", notebook,
Packit 1e8aac
                                               "project",
Packit 1e8aac
                                               glade_widget_get_project
Packit 1e8aac
                                               (notebook), NULL);
Packit 1e8aac
Packit 1e8aac
  str = g_strdup_printf ("page %d", page_id);
Packit 1e8aac
  glade_widget_property_set (glabel, "label", str);
Packit 1e8aac
  g_free (str);
Packit 1e8aac
Packit 1e8aac
  g_object_set_data (glade_widget_get_object (glabel), "special-child-type", "tab");
Packit 1e8aac
  gtk_widget_show (GTK_WIDGET (glade_widget_get_object (glabel)));
Packit 1e8aac
Packit 1e8aac
  return glabel;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_notebook_set_n_pages (GObject * object, const GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *widget;
Packit 1e8aac
  GtkNotebook *notebook;
Packit 1e8aac
  GtkWidget *child_widget;
Packit 1e8aac
  gint new_size, i;
Packit 1e8aac
  gint old_size;
Packit 1e8aac
Packit 1e8aac
  notebook = GTK_NOTEBOOK (object);
Packit 1e8aac
  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
Packit 1e8aac
Packit 1e8aac
  widget = glade_widget_get_from_gobject (GTK_WIDGET (notebook));
Packit 1e8aac
  g_return_if_fail (widget != NULL);
Packit 1e8aac
Packit 1e8aac
  new_size = g_value_get_int (value);
Packit 1e8aac
  old_size = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
Packit 1e8aac
Packit 1e8aac
  /* Ensure base size of notebook */
Packit 1e8aac
  if (glade_widget_superuser () == FALSE)
Packit 1e8aac
    {
Packit 1e8aac
      for (i = gtk_notebook_get_n_pages (notebook); i < new_size; i++)
Packit 1e8aac
        {
Packit 1e8aac
          gint position = glade_gtk_notebook_get_first_blank_page (notebook);
Packit 1e8aac
          GtkWidget *placeholder = glade_placeholder_new ();
Packit 1e8aac
          GladeWidget *gtab;
Packit 1e8aac
Packit 1e8aac
          gtk_notebook_insert_page (notebook, placeholder, NULL, position);
Packit 1e8aac
Packit 1e8aac
          /* XXX Ugly hack amongst many, this one only creates project widgets
Packit 1e8aac
           * when the 'n-pages' of a notebook is initially set, otherwise it puts
Packit 1e8aac
           * placeholders. (this makes the job easier when doing "insert before/after")
Packit 1e8aac
           */
Packit 1e8aac
          if (old_size == 0 && new_size > 1)
Packit 1e8aac
            {
Packit 1e8aac
              gtab = glade_gtk_notebook_generate_tab (widget, position + 1);
Packit 1e8aac
Packit 1e8aac
              /* Must pass through GladeWidget api so that packing props
Packit 1e8aac
               * are correctly assigned.
Packit 1e8aac
               */
Packit 1e8aac
              glade_widget_add_child (widget, gtab, FALSE);
Packit 1e8aac
            }
Packit 1e8aac
          else
Packit 1e8aac
            {
Packit 1e8aac
              GtkWidget *tab_placeholder = glade_placeholder_new ();
Packit 1e8aac
Packit 1e8aac
              g_object_set_data (G_OBJECT (tab_placeholder),
Packit 1e8aac
                                 "special-child-type", "tab");
Packit 1e8aac
Packit 1e8aac
              gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), placeholder,
Packit 1e8aac
                                          tab_placeholder);
Packit 1e8aac
            }
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /*
Packit 1e8aac
   * Thing to remember is that GtkNotebook starts the
Packit 1e8aac
   * page numbers from 0, not 1 (C-style). So we need to do
Packit 1e8aac
   * old_size-1, where we're referring to "nth" widget.
Packit 1e8aac
   */
Packit 1e8aac
  while (old_size > new_size)
Packit 1e8aac
    {
Packit 1e8aac
      /* Get the last page and remove it (project objects have been cleared by
Packit 1e8aac
       * the action code already). */
Packit 1e8aac
      child_widget = gtk_notebook_get_nth_page (notebook, old_size - 1);
Packit 1e8aac
Packit 1e8aac
      /* Ok there shouldnt be widget in the content area, that's
Packit 1e8aac
       * the placeholder, we should clean up the project widget that
Packit 1e8aac
       * we put in the tab here though (this happens in the case where
Packit 1e8aac
       * we undo increasing the "pages" property).
Packit 1e8aac
       */
Packit 1e8aac
      if (glade_widget_get_from_gobject (child_widget))
Packit 1e8aac
        g_critical ("Bug in notebook_set_n_pages()");
Packit 1e8aac
Packit 1e8aac
      gtk_notebook_remove_page (notebook, old_size - 1);
Packit 1e8aac
Packit 1e8aac
      old_size--;
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_notebook_set_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                 GObject * object,
Packit 1e8aac
                                 const gchar * id, const GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  if (!strcmp (id, "pages"))
Packit 1e8aac
    glade_gtk_notebook_set_n_pages (object, value);
Packit 1e8aac
  else if (!strcmp (id, "has-action-start"))
Packit 1e8aac
    {
Packit 1e8aac
      if (g_value_get_boolean (value))
Packit 1e8aac
        {
Packit 1e8aac
          GtkWidget *action = gtk_notebook_get_action_widget (GTK_NOTEBOOK (object), GTK_PACK_START);
Packit 1e8aac
          if (!action)
Packit 1e8aac
            action = glade_placeholder_new ();
Packit 1e8aac
          g_object_set_data (G_OBJECT (action), "special-child-type", "action-start");
Packit 1e8aac
          gtk_notebook_set_action_widget (GTK_NOTEBOOK (object), action, GTK_PACK_START); 
Packit 1e8aac
        }
Packit 1e8aac
      else
Packit 1e8aac
        gtk_notebook_set_action_widget (GTK_NOTEBOOK (object), NULL, GTK_PACK_START); 
Packit 1e8aac
    }
Packit 1e8aac
  else if (!strcmp (id, "has-action-end"))
Packit 1e8aac
    {
Packit 1e8aac
      if (g_value_get_boolean (value))
Packit 1e8aac
        {
Packit 1e8aac
          GtkWidget *action = gtk_notebook_get_action_widget (GTK_NOTEBOOK (object), GTK_PACK_END);
Packit 1e8aac
          if (!action)
Packit 1e8aac
            action = glade_placeholder_new ();
Packit 1e8aac
          g_object_set_data (G_OBJECT (action), "special-child-type", "action-end");
Packit 1e8aac
          gtk_notebook_set_action_widget (GTK_NOTEBOOK (object), action, GTK_PACK_END); 
Packit 1e8aac
        }
Packit 1e8aac
      else
Packit 1e8aac
        gtk_notebook_set_action_widget (GTK_NOTEBOOK (object), NULL, GTK_PACK_END); 
Packit 1e8aac
    }
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
void
Packit 1e8aac
glade_gtk_notebook_get_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                            GObject * object, const gchar * id, GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  if (!strcmp (id, "has-action-start"))
Packit 1e8aac
    {
Packit 1e8aac
      g_value_reset (value);
Packit 1e8aac
      g_value_set_boolean (value, gtk_notebook_get_action_widget (GTK_NOTEBOOK (object), GTK_PACK_START) != NULL);
Packit 1e8aac
    }
Packit 1e8aac
  else if (!strcmp (id, "has-action-end"))
Packit 1e8aac
    {
Packit 1e8aac
      g_value_reset (value);
Packit 1e8aac
      g_value_set_boolean (value, gtk_notebook_get_action_widget (GTK_NOTEBOOK (object), GTK_PACK_END) != NULL);
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    GWA_GET_CLASS (GTK_TYPE_CONTAINER)->get_property (adaptor, object, id,
Packit 1e8aac
                                                      value);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gboolean
Packit 1e8aac
glade_gtk_notebook_verify_n_pages (GObject * object, const GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  GtkNotebook *notebook = GTK_NOTEBOOK (object);
Packit 1e8aac
  GtkWidget *child_widget, *tab_widget;
Packit 1e8aac
  gint old_size, new_size = g_value_get_int (value);
Packit 1e8aac
Packit 1e8aac
  for (old_size = gtk_notebook_get_n_pages (notebook);
Packit 1e8aac
       old_size > new_size; old_size--)
Packit 1e8aac
    {
Packit 1e8aac
      /* Get the last widget. */
Packit 1e8aac
      child_widget = gtk_notebook_get_nth_page (notebook, old_size - 1);
Packit 1e8aac
      tab_widget = gtk_notebook_get_tab_label (notebook, child_widget);
Packit 1e8aac
Packit 1e8aac
      /* 
Packit 1e8aac
       * If we got it, and its not a placeholder, remove it
Packit 1e8aac
       * from project.
Packit 1e8aac
       */
Packit 1e8aac
      if (glade_widget_get_from_gobject (child_widget) ||
Packit 1e8aac
          glade_widget_get_from_gobject (tab_widget))
Packit 1e8aac
        return FALSE;
Packit 1e8aac
    }
Packit 1e8aac
  return TRUE;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
gboolean
Packit 1e8aac
glade_gtk_notebook_verify_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                    GObject * object,
Packit 1e8aac
                                    const gchar * id, const GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  if (!strcmp (id, "pages"))
Packit 1e8aac
    return glade_gtk_notebook_verify_n_pages (object, value);
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_notebook_add_child (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                              GObject * object, GObject * child)
Packit 1e8aac
{
Packit 1e8aac
  GtkNotebook *notebook;
Packit 1e8aac
  gint num_page, position = 0;
Packit 1e8aac
  GtkWidget *last_page;
Packit 1e8aac
  GladeWidget *gwidget;
Packit 1e8aac
  gchar *special_child_type;
Packit 1e8aac
Packit 1e8aac
  notebook = GTK_NOTEBOOK (object);
Packit 1e8aac
Packit 1e8aac
  num_page = gtk_notebook_get_n_pages (notebook);
Packit 1e8aac
  gwidget = glade_widget_get_from_gobject (object);
Packit 1e8aac
Packit 1e8aac
  special_child_type = g_object_get_data (child, "special-child-type");
Packit 1e8aac
  if (special_child_type && !strcmp (special_child_type, "action-start"))
Packit 1e8aac
    {
Packit 1e8aac
      gtk_notebook_set_action_widget (notebook, GTK_WIDGET (child), GTK_PACK_START);
Packit 1e8aac
    }
Packit 1e8aac
  else if (special_child_type && !strcmp (special_child_type, "action-end"))
Packit 1e8aac
    {
Packit 1e8aac
      gtk_notebook_set_action_widget (notebook, GTK_WIDGET (child), GTK_PACK_END);
Packit 1e8aac
    }
Packit 1e8aac
  else if (glade_widget_superuser ())
Packit 1e8aac
    {
Packit 1e8aac
      /* Just append pages blindly when loading/dupping */
Packit 1e8aac
      special_child_type = g_object_get_data (child, "special-child-type");
Packit 1e8aac
      if (special_child_type && !strcmp (special_child_type, "tab"))
Packit 1e8aac
        {
Packit 1e8aac
          last_page = gtk_notebook_get_nth_page (notebook, num_page - 1);
Packit 1e8aac
          gtk_notebook_set_tab_label (notebook, last_page, GTK_WIDGET (child));
Packit 1e8aac
        }
Packit 1e8aac
      else
Packit 1e8aac
        {
Packit 1e8aac
          gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
Packit 1e8aac
Packit 1e8aac
          glade_widget_property_set (gwidget, "pages", num_page + 1);
Packit 1e8aac
Packit 1e8aac
          gwidget = glade_widget_get_from_gobject (child);
Packit 1e8aac
          if (gwidget && glade_widget_get_packing_properties (gwidget))
Packit 1e8aac
            glade_widget_pack_property_set (gwidget, "position", num_page);
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      NotebookChildren *nchildren;
Packit 1e8aac
Packit 1e8aac
      /* Just destroy placeholders */
Packit 1e8aac
      if (GLADE_IS_PLACEHOLDER (child))
Packit 1e8aac
        gtk_widget_destroy (GTK_WIDGET (child));
Packit 1e8aac
      else
Packit 1e8aac
        {
Packit 1e8aac
          gwidget = glade_widget_get_from_gobject (child);
Packit 1e8aac
          g_assert (gwidget);
Packit 1e8aac
Packit 1e8aac
          glade_widget_pack_property_get (gwidget, "position", &position);
Packit 1e8aac
Packit 1e8aac
          nchildren =
Packit 1e8aac
              glade_gtk_notebook_extract_children (GTK_WIDGET (notebook));
Packit 1e8aac
Packit 1e8aac
          if (g_object_get_data (child, "special-child-type") != NULL)
Packit 1e8aac
            {
Packit 1e8aac
              if (g_list_find_custom (nchildren->tabs,
Packit 1e8aac
                                      GINT_TO_POINTER (position),
Packit 1e8aac
                                      (GCompareFunc) notebook_find_child))
Packit 1e8aac
                nchildren->extra_tabs =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->extra_tabs, child,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
              else
Packit 1e8aac
                nchildren->tabs =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->tabs, child,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
            }
Packit 1e8aac
          else
Packit 1e8aac
            {
Packit 1e8aac
              if (g_list_find_custom (nchildren->children,
Packit 1e8aac
                                      GINT_TO_POINTER (position),
Packit 1e8aac
                                      (GCompareFunc) notebook_find_child))
Packit 1e8aac
                nchildren->extra_children =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->extra_children, child,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
              else
Packit 1e8aac
                nchildren->children =
Packit 1e8aac
                    g_list_insert_sorted
Packit 1e8aac
                    (nchildren->children, child,
Packit 1e8aac
                     (GCompareFunc) notebook_child_compare_func);
Packit 1e8aac
            }
Packit 1e8aac
Packit 1e8aac
          /* Takes an explicit reference when sitting on the list */
Packit 1e8aac
          g_object_ref (child);
Packit 1e8aac
Packit 1e8aac
          glade_gtk_notebook_insert_children (GTK_WIDGET (notebook), nchildren);
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_notebook_remove_child (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                 GObject * object, GObject * child)
Packit 1e8aac
{
Packit 1e8aac
  NotebookChildren *nchildren;
Packit 1e8aac
  gchar *special_child_type;
Packit 1e8aac
Packit 1e8aac
  special_child_type = g_object_get_data (child, "special-child-type");
Packit 1e8aac
  if (special_child_type && !strcmp (special_child_type, "action-start"))
Packit 1e8aac
    {
Packit 1e8aac
      GtkWidget *placeholder = glade_placeholder_new ();
Packit 1e8aac
      g_object_set_data (G_OBJECT (placeholder), "special-child-type", "action-start");
Packit 1e8aac
      gtk_notebook_set_action_widget (GTK_NOTEBOOK (object), placeholder, GTK_PACK_START);
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
  else if (special_child_type && !strcmp (special_child_type, "action-end"))
Packit 1e8aac
    {
Packit 1e8aac
      GtkWidget *placeholder = glade_placeholder_new ();
Packit 1e8aac
      g_object_set_data (G_OBJECT (placeholder), "special-child-type", "action-end");
Packit 1e8aac
      gtk_notebook_set_action_widget (GTK_NOTEBOOK (object), placeholder, GTK_PACK_END);
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  nchildren = glade_gtk_notebook_extract_children (GTK_WIDGET (object));
Packit 1e8aac
Packit 1e8aac
  if (g_list_find (nchildren->children, child))
Packit 1e8aac
    {
Packit 1e8aac
      nchildren->children = g_list_remove (nchildren->children, child);
Packit 1e8aac
      g_object_unref (child);
Packit 1e8aac
    }
Packit 1e8aac
  else if (g_list_find (nchildren->extra_children, child))
Packit 1e8aac
    {
Packit 1e8aac
      nchildren->extra_children =
Packit 1e8aac
          g_list_remove (nchildren->extra_children, child);
Packit 1e8aac
      g_object_unref (child);
Packit 1e8aac
    }
Packit 1e8aac
  else if (g_list_find (nchildren->tabs, child))
Packit 1e8aac
    {
Packit 1e8aac
      nchildren->tabs = g_list_remove (nchildren->tabs, child);
Packit 1e8aac
      g_object_unref (child);
Packit 1e8aac
    }
Packit 1e8aac
  else if (g_list_find (nchildren->extra_tabs, child))
Packit 1e8aac
    {
Packit 1e8aac
      nchildren->extra_tabs = g_list_remove (nchildren->extra_tabs, child);
Packit 1e8aac
      g_object_unref (child);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  glade_gtk_notebook_insert_children (GTK_WIDGET (object), nchildren);
Packit 1e8aac
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_notebook_replace_child (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                  GtkWidget * container,
Packit 1e8aac
                                  GtkWidget * current, GtkWidget * new_widget)
Packit 1e8aac
{
Packit 1e8aac
  GtkNotebook *notebook;
Packit 1e8aac
  GladeWidget *gcurrent, *gnew;
Packit 1e8aac
  gint position = 0;
Packit 1e8aac
  gchar *special_child_type;
Packit 1e8aac
Packit 1e8aac
  notebook = GTK_NOTEBOOK (container);
Packit 1e8aac
Packit 1e8aac
  special_child_type = g_object_get_data (G_OBJECT (current), "special-child-type");
Packit 1e8aac
  g_object_set_data (G_OBJECT (new_widget), "special-child-type", special_child_type);
Packit 1e8aac
  if (!g_strcmp0 (special_child_type, "action-start"))
Packit 1e8aac
    {
Packit 1e8aac
      gtk_notebook_set_action_widget (notebook, GTK_WIDGET (new_widget), GTK_PACK_START);
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
  else if (!g_strcmp0 (special_child_type, "action-end"))
Packit 1e8aac
    {
Packit 1e8aac
      gtk_notebook_set_action_widget (notebook, GTK_WIDGET (new_widget), GTK_PACK_END);
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if ((gcurrent = glade_widget_get_from_gobject (current)) != NULL)
Packit 1e8aac
    glade_widget_pack_property_get (gcurrent, "position", &position);
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      if ((position = gtk_notebook_page_num (notebook, current)) < 0)
Packit 1e8aac
        {
Packit 1e8aac
          position = notebook_search_tab (notebook, current);
Packit 1e8aac
          g_assert (position >= 0);
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  glade_gtk_notebook_remove_child (adaptor,
Packit 1e8aac
                                   G_OBJECT (container), G_OBJECT (current));
Packit 1e8aac
Packit 1e8aac
  if (GLADE_IS_PLACEHOLDER (new_widget) == FALSE)
Packit 1e8aac
    {
Packit 1e8aac
      gnew = glade_widget_get_from_gobject (new_widget);
Packit 1e8aac
Packit 1e8aac
      glade_gtk_notebook_add_child (adaptor,
Packit 1e8aac
                                    G_OBJECT (container),
Packit 1e8aac
                                    G_OBJECT (new_widget));
Packit 1e8aac
Packit 1e8aac
      if (glade_widget_pack_property_set (gnew, "position", position) == FALSE)
Packit 1e8aac
        g_critical ("No position property found on new widget");
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    gtk_widget_destroy (GTK_WIDGET (new_widget));
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
gboolean
Packit 1e8aac
glade_gtk_notebook_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, "position"))
Packit 1e8aac
    return g_value_get_int (value) >= 0 &&
Packit 1e8aac
        g_value_get_int (value) <
Packit 1e8aac
        gtk_notebook_get_n_pages (GTK_NOTEBOOK (container));
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
void
Packit 1e8aac
glade_gtk_notebook_set_child_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                       GObject * container,
Packit 1e8aac
                                       GObject * child,
Packit 1e8aac
                                       const gchar * property_name,
Packit 1e8aac
                                       const GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  NotebookChildren *nchildren;
Packit 1e8aac
Packit 1e8aac
  if (strcmp (property_name, "position") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      /* If we are setting this internally, avoid feedback. */
Packit 1e8aac
      if (glade_gtk_notebook_setting_position || glade_widget_superuser ())
Packit 1e8aac
        return;
Packit 1e8aac
Packit 1e8aac
      /* Just rebuild the notebook, property values are already set at this point */
Packit 1e8aac
      nchildren = glade_gtk_notebook_extract_children (GTK_WIDGET (container));
Packit 1e8aac
      glade_gtk_notebook_insert_children (GTK_WIDGET (container), nchildren);
Packit 1e8aac
    }
Packit 1e8aac
  /* packing properties are unsupported on tabs ... except "position" */
Packit 1e8aac
  else if (g_object_get_data (child, "special-child-type") == NULL)
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
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_notebook_get_child_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                       GObject * container,
Packit 1e8aac
                                       GObject * child,
Packit 1e8aac
                                       const gchar * property_name,
Packit 1e8aac
                                       GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  gint position;
Packit 1e8aac
Packit 1e8aac
  if (strcmp (property_name, "position") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      if (g_strcmp0 (g_object_get_data (child, "special-child-type"), "tab") == 0)
Packit 1e8aac
        {
Packit 1e8aac
          if ((position = notebook_search_tab (GTK_NOTEBOOK (container),
Packit 1e8aac
                                               GTK_WIDGET (child))) >= 0)
Packit 1e8aac
            g_value_set_int (value, position);
Packit 1e8aac
          else
Packit 1e8aac
            g_value_set_int (value, 0);
Packit 1e8aac
        }
Packit 1e8aac
      else if (g_object_get_data (child, "special-child-type") != NULL)
Packit 1e8aac
        {
Packit 1e8aac
          g_value_set_int (value, 0);
Packit 1e8aac
        }
Packit 1e8aac
      else
Packit 1e8aac
        gtk_container_child_get_property (GTK_CONTAINER (container),
Packit 1e8aac
                                          GTK_WIDGET (child),
Packit 1e8aac
                                          property_name, value);
Packit 1e8aac
    }
Packit 1e8aac
  /* packing properties are unsupported on tabs ... except "position" */
Packit 1e8aac
  else if (g_object_get_data (child, "special-child-type") == NULL)
Packit 1e8aac
    gtk_container_child_get_property (GTK_CONTAINER (container),
Packit 1e8aac
                                      GTK_WIDGET (child), property_name, value);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_notebook_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_page_after") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
Packit 1e8aac
                                                         object, FALSE, TRUE);
Packit 1e8aac
    }
Packit 1e8aac
  else if (strcmp (action_path, "insert_page_before") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
Packit 1e8aac
                                                         object, FALSE, FALSE);
Packit 1e8aac
    }
Packit 1e8aac
  else if (strcmp (action_path, "remove_page") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
Packit 1e8aac
                                                         object, TRUE, TRUE);
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
}
Packit 1e8aac
Packit 1e8aac
/* Shared with glade-gtk-box.c */
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_box_notebook_child_insert_remove_action (GladeWidgetAdaptor *adaptor,
Packit 1e8aac
                                                   GObject            *container,
Packit 1e8aac
                                                   GObject            *object,
Packit 1e8aac
                                                   gboolean            remove,
Packit 1e8aac
                                                   gboolean            after)
Packit 1e8aac
{
Packit 1e8aac
  gboolean is_notebook = GTK_IS_NOTEBOOK (container);
Packit 1e8aac
  const gchar *size_prop = (is_notebook) ? "pages" : "size";
Packit 1e8aac
  GladeWidget *parent;
Packit 1e8aac
  GList *children, *l;
Packit 1e8aac
  gint child_pos, size, offset;
Packit 1e8aac
Packit 1e8aac
  if (is_notebook && g_object_get_data (object, "special-child-type"))
Packit 1e8aac
    /* Its a Tab! */
Packit 1e8aac
    child_pos = notebook_search_tab (GTK_NOTEBOOK (container),
Packit 1e8aac
                                     GTK_WIDGET (object));
Packit 1e8aac
  else
Packit 1e8aac
    gtk_container_child_get (GTK_CONTAINER (container),
Packit 1e8aac
                             GTK_WIDGET (object), "position", &child_pos, NULL);
Packit 1e8aac
Packit 1e8aac
  parent = glade_widget_get_from_gobject (container);
Packit 1e8aac
  if (is_notebook)
Packit 1e8aac
    {
Packit 1e8aac
      if (remove)
Packit 1e8aac
        glade_command_push_group (_("Remove page from %s"), glade_widget_get_name (parent));
Packit 1e8aac
      else
Packit 1e8aac
        glade_command_push_group (_("Insert page on %s"), glade_widget_get_name (parent));
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      if (remove)
Packit 1e8aac
        glade_command_push_group (_("Remove placeholder from %s"), glade_widget_get_name (parent));
Packit 1e8aac
      else
Packit 1e8aac
        glade_command_push_group (_("Insert placeholder to %s"), glade_widget_get_name (parent));
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Make sure widgets does not get destroyed */
Packit 1e8aac
  children = glade_widget_adaptor_get_children (adaptor, container);
Packit 1e8aac
  g_list_foreach (children, (GFunc) g_object_ref, NULL);
Packit 1e8aac
Packit 1e8aac
  glade_widget_property_get (parent, size_prop, &size);
Packit 1e8aac
Packit 1e8aac
  if (remove)
Packit 1e8aac
    {
Packit 1e8aac
      GList *del = NULL;
Packit 1e8aac
      offset = -1;
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 pos;
Packit 1e8aac
Packit 1e8aac
          /* Skip placeholders */
Packit 1e8aac
          if (gchild == NULL)
Packit 1e8aac
            continue;
Packit 1e8aac
Packit 1e8aac
          glade_widget_pack_property_get (gchild, "position", &pos;;
Packit 1e8aac
          if (pos == child_pos)
Packit 1e8aac
            del = g_list_prepend (del, gchild);
Packit 1e8aac
        }
Packit 1e8aac
      if (del)
Packit 1e8aac
        {
Packit 1e8aac
          glade_command_delete (del);
Packit 1e8aac
          g_list_free (del);
Packit 1e8aac
        }
Packit 1e8aac
    }
Packit 1e8aac
  else
Packit 1e8aac
    {
Packit 1e8aac
      /* Expand container */
Packit 1e8aac
      glade_command_set_property (glade_widget_get_property (parent, size_prop),
Packit 1e8aac
                                  size + 1);
Packit 1e8aac
      offset = 1;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Reoder children (fix the position property tracking widget positions) */
Packit 1e8aac
  for (l = g_list_last (children); l; l = g_list_previous (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
      glade_widget_pack_property_get (gchild, "position", &pos;;
Packit 1e8aac
      if ((after) ? pos > child_pos : pos >= child_pos)
Packit 1e8aac
        glade_command_set_property (glade_widget_get_pack_property
Packit 1e8aac
                                    (gchild, "position"), pos + offset);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (remove)
Packit 1e8aac
    {
Packit 1e8aac
      /* Shrink container */
Packit 1e8aac
      glade_command_set_property (glade_widget_get_property (parent, size_prop),
Packit 1e8aac
                                  size - 1);
Packit 1e8aac
    }
Packit 1e8aac
  /* If it's a notebook we need to create an undoable tab now */
Packit 1e8aac
  else if (GTK_IS_NOTEBOOK (container))
Packit 1e8aac
    {
Packit 1e8aac
      gint new_pos = after ? child_pos + 1 : child_pos;
Packit 1e8aac
      GtkWidget *new_page;
Packit 1e8aac
      GtkWidget *tab_placeholder;
Packit 1e8aac
      GladeWidget *gtab;
Packit 1e8aac
      GList list = { 0, };
Packit 1e8aac
Packit 1e8aac
      new_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (container), new_pos);
Packit 1e8aac
Packit 1e8aac
      /* Deleting the project widget gives us a real placeholder now */
Packit 1e8aac
      new_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (container), new_pos);
Packit 1e8aac
      tab_placeholder =
Packit 1e8aac
          gtk_notebook_get_tab_label (GTK_NOTEBOOK (container), new_page);
Packit 1e8aac
      gtab = glade_gtk_notebook_generate_tab (parent, new_pos + 1);
Packit 1e8aac
      list.data = gtab;
Packit 1e8aac
Packit 1e8aac
      glade_command_paste (&list, parent, GLADE_PLACEHOLDER (tab_placeholder),
Packit 1e8aac
			   glade_widget_get_project (parent));
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  g_list_foreach (children, (GFunc) g_object_unref, NULL);
Packit 1e8aac
  g_list_free (children);
Packit 1e8aac
  glade_command_pop_group ();
Packit 1e8aac
}