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

Packit 1e8aac
/*
Packit 1e8aac
 * glade-gtk-assistant.c - GladeWidgetAdaptor for GtkAssistant
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
Packit 1e8aac
#include <config.h>
Packit 1e8aac
#include <glib/gi18n-lib.h>
Packit 1e8aac
#include <gladeui/glade.h>
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_assistant_append_new_page (GladeWidget * parent,
Packit 1e8aac
                                     GladeProject * project,
Packit 1e8aac
                                     const gchar * label,
Packit 1e8aac
                                     GtkAssistantPageType type)
Packit 1e8aac
{
Packit 1e8aac
  static GladeWidgetAdaptor *adaptor = NULL;
Packit 1e8aac
  GladeWidget *page;
Packit 1e8aac
Packit 1e8aac
  if (adaptor == NULL)
Packit 1e8aac
    adaptor = glade_widget_adaptor_get_by_type (GTK_TYPE_LABEL);
Packit 1e8aac
Packit 1e8aac
  page = glade_widget_adaptor_create_widget (adaptor, FALSE,
Packit 1e8aac
                                             "parent", parent,
Packit 1e8aac
                                             "project", project, NULL);
Packit 1e8aac
Packit 1e8aac
  glade_widget_add_child (parent, page, FALSE);
Packit 1e8aac
Packit 1e8aac
  glade_widget_property_set (page, "label", label);
Packit 1e8aac
  glade_widget_pack_property_set (page, "page-type", type);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
/*
Packit 1e8aac
  GtkAssistant is a very weird widget, why is it derived from GtkWindow
Packit 1e8aac
  instead of GtkNotebook I do not know!
Packit 1e8aac
Packit 1e8aac
  If there is no GTK_ASSISTANT_PAGE_CONFIRM, GtkAssistant abort when trying to 
Packit 1e8aac
  update its navigation buttons!
Packit 1e8aac
*/
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_assistant_update_page_type (GtkAssistant * assistant)
Packit 1e8aac
{
Packit 1e8aac
  gint i, current, pages;
Packit 1e8aac
  GtkWidget *page;
Packit 1e8aac
Packit 1e8aac
  current = gtk_assistant_get_current_page (assistant);
Packit 1e8aac
  pages = gtk_assistant_get_n_pages (assistant) - 1;
Packit 1e8aac
  if (pages < 0)
Packit 1e8aac
    return;
Packit 1e8aac
Packit 1e8aac
  /* Last Page */
Packit 1e8aac
  page = gtk_assistant_get_nth_page (assistant, pages);
Packit 1e8aac
  gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
Packit 1e8aac
Packit 1e8aac
  /* First page */
Packit 1e8aac
  page = gtk_assistant_get_nth_page (assistant, 0);
Packit 1e8aac
  gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_INTRO);
Packit 1e8aac
Packit 1e8aac
  /* In betwen pages */
Packit 1e8aac
  for (i = 1; i < pages; i++)
Packit 1e8aac
    {
Packit 1e8aac
      page = gtk_assistant_get_nth_page (assistant, i);
Packit 1e8aac
      gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Now we have set page-type in every page, force button update */
Packit 1e8aac
  for (i = 0; i <= pages; i++)
Packit 1e8aac
    {
Packit 1e8aac
      page = gtk_assistant_get_nth_page (assistant, i);
Packit 1e8aac
      gtk_assistant_set_page_complete (assistant, page, TRUE);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (current >= 0)
Packit 1e8aac
    gtk_assistant_set_current_page (assistant, current);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static gint
Packit 1e8aac
glade_gtk_assistant_get_page (GtkAssistant * assistant, GtkWidget * page)
Packit 1e8aac
{
Packit 1e8aac
  gint i, pages = gtk_assistant_get_n_pages (assistant);
Packit 1e8aac
Packit 1e8aac
  for (i = 0; i < pages; i++)
Packit 1e8aac
    if (gtk_assistant_get_nth_page (assistant, i) == page)
Packit 1e8aac
      return i;
Packit 1e8aac
Packit 1e8aac
  return -1;
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_assistant_update_position (GtkAssistant * assistant)
Packit 1e8aac
{
Packit 1e8aac
  gint i, pages = gtk_assistant_get_n_pages (assistant);
Packit 1e8aac
Packit 1e8aac
  for (i = 0; i < pages; i++)
Packit 1e8aac
    {
Packit 1e8aac
      GtkWidget *page = gtk_assistant_get_nth_page (assistant, i);
Packit 1e8aac
      GladeWidget *gpage = glade_widget_get_from_gobject (G_OBJECT (page));
Packit 1e8aac
      if (gpage)
Packit 1e8aac
        glade_widget_pack_property_set (gpage, "position", i);
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
glade_gtk_assistant_parse_finished (GladeProject * project, GObject * object)
Packit 1e8aac
{
Packit 1e8aac
  GtkAssistant *assistant = GTK_ASSISTANT (object);
Packit 1e8aac
  gint pages = gtk_assistant_get_n_pages (assistant);
Packit 1e8aac
Packit 1e8aac
  if (pages)
Packit 1e8aac
    {
Packit 1e8aac
      /* also sets pages "complete" and thus allows navigation under glade */
Packit 1e8aac
      glade_gtk_assistant_update_page_type (assistant);
Packit 1e8aac
Packit 1e8aac
      gtk_assistant_set_current_page (assistant, 0);
Packit 1e8aac
      glade_widget_property_set (glade_widget_get_from_gobject (object),
Packit 1e8aac
                                 "n-pages", pages);
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
GList *
Packit 1e8aac
glade_gtk_assistant_get_children (GladeWidgetAdaptor *adaptor,
Packit 1e8aac
                                  GObject *container)
Packit 1e8aac
{
Packit 1e8aac
  GtkAssistant *assist = GTK_ASSISTANT (container);
Packit 1e8aac
  gint i, n_pages = gtk_assistant_get_n_pages (assist);
Packit 1e8aac
  GList *children = NULL, *parent_children;
Packit 1e8aac
Packit 1e8aac
  /* Chain up */
Packit 1e8aac
  if (GWA_GET_CLASS (GTK_TYPE_WINDOW)->get_children)
Packit 1e8aac
    parent_children = GWA_GET_CLASS (GTK_TYPE_WINDOW)->get_children (adaptor, container);
Packit 1e8aac
  else
Packit 1e8aac
    parent_children = NULL;
Packit 1e8aac
  
Packit 1e8aac
  for (i = 0; i < n_pages; i++)
Packit 1e8aac
    children = g_list_prepend (children, gtk_assistant_get_nth_page (assist, i));
Packit 1e8aac
Packit 1e8aac
  children = g_list_reverse (children);
Packit 1e8aac
Packit 1e8aac
  return glade_util_purify_list (g_list_concat (children, parent_children));
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
on_assistant_project_selection_changed (GladeProject *project,
Packit 1e8aac
                                        GladeWidget *gassist)
Packit 1e8aac
{
Packit 1e8aac
  GList *selection = glade_project_selection_get (project);
Packit 1e8aac
Packit 1e8aac
  if (selection && g_list_next (selection) == NULL)
Packit 1e8aac
    {
Packit 1e8aac
      GladeWidget *selected = glade_widget_get_from_gobject (selection->data);
Packit 1e8aac
      GtkAssistant *assist = GTK_ASSISTANT (glade_widget_get_object (gassist));
Packit 1e8aac
      gint pos;
Packit 1e8aac
Packit 1e8aac
      if (!selected) return;
Packit 1e8aac
Packit 1e8aac
      if (glade_widget_get_parent (selected) == gassist &&
Packit 1e8aac
          glade_widget_property_get (selected, "position", &pos, NULL))
Packit 1e8aac
	gtk_assistant_set_current_page (assist, pos);
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_post_create (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                 GObject * object, GladeCreateReason reason)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *parent = glade_widget_get_from_gobject (object);
Packit 1e8aac
  GladeProject *project = glade_widget_get_project (parent);
Packit 1e8aac
Packit 1e8aac
  if (reason == GLADE_CREATE_LOAD)
Packit 1e8aac
    {
Packit 1e8aac
      g_signal_connect (project, "parse-finished",
Packit 1e8aac
                        G_CALLBACK (glade_gtk_assistant_parse_finished),
Packit 1e8aac
                        object);
Packit 1e8aac
    }
Packit 1e8aac
  else if (reason == GLADE_CREATE_USER)
Packit 1e8aac
    {
Packit 1e8aac
      glade_gtk_assistant_append_new_page (parent, project,
Packit 1e8aac
                                           _("Introduction page"),
Packit 1e8aac
                                           GTK_ASSISTANT_PAGE_INTRO);
Packit 1e8aac
Packit 1e8aac
      glade_gtk_assistant_append_new_page (parent, project,
Packit 1e8aac
                                           _("Content page"),
Packit 1e8aac
                                           GTK_ASSISTANT_PAGE_CONTENT);
Packit 1e8aac
Packit 1e8aac
      glade_gtk_assistant_append_new_page (parent, project,
Packit 1e8aac
                                           _("Confirmation page"),
Packit 1e8aac
                                           GTK_ASSISTANT_PAGE_CONFIRM);
Packit 1e8aac
Packit 1e8aac
      gtk_assistant_set_current_page (GTK_ASSISTANT (object), 0);
Packit 1e8aac
Packit 1e8aac
      glade_widget_property_set (parent, "n-pages", 3);
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  if (project)
Packit 1e8aac
    g_signal_connect (project, "selection-changed",
Packit 1e8aac
		      G_CALLBACK (on_assistant_project_selection_changed),
Packit 1e8aac
		      parent);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_add_child (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                               GObject * container, GObject * child)
Packit 1e8aac
{
Packit 1e8aac
  GtkAssistant *assistant = GTK_ASSISTANT (container);
Packit 1e8aac
  GtkWidget *widget = GTK_WIDGET (child);
Packit 1e8aac
Packit 1e8aac
  gtk_assistant_append_page (assistant, widget);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
static void
Packit 1e8aac
assistant_remove_child (GtkAssistant *assistant, GtkWidget *child)
Packit 1e8aac
{
Packit 1e8aac
  gint i, n = gtk_assistant_get_n_pages (assistant);
Packit 1e8aac
Packit 1e8aac
  for (i = 0; i < n; i++)
Packit 1e8aac
    {
Packit 1e8aac
      if (child == gtk_assistant_get_nth_page (assistant, i))
Packit 1e8aac
	{
Packit 1e8aac
	  gtk_assistant_remove_page (assistant, i);
Packit 1e8aac
	  return;
Packit 1e8aac
	}
Packit 1e8aac
    }
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_remove_child (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                  GObject * container, GObject * child)
Packit 1e8aac
{
Packit 1e8aac
  GladeWidget *gassistant = glade_widget_get_from_gobject (container);
Packit 1e8aac
  GtkAssistant *assistant = GTK_ASSISTANT (container);
Packit 1e8aac
Packit 1e8aac
  assistant_remove_child (assistant, GTK_WIDGET (child));
Packit 1e8aac
Packit 1e8aac
  glade_widget_property_set (gassistant, "n-pages", 
Packit 1e8aac
                             gtk_assistant_get_n_pages (assistant));
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_replace_child (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                   GObject * container,
Packit 1e8aac
                                   GObject * current, GObject * new_object)
Packit 1e8aac
{
Packit 1e8aac
  GtkAssistant *assistant = GTK_ASSISTANT (container);
Packit 1e8aac
  GtkWidget *page = GTK_WIDGET (new_object), *old_page = GTK_WIDGET (current);
Packit 1e8aac
  gint pos = glade_gtk_assistant_get_page (assistant, old_page);
Packit 1e8aac
  gboolean set_current = gtk_assistant_get_current_page (assistant) == pos;
Packit 1e8aac
Packit 1e8aac
  assistant_remove_child (assistant, old_page);
Packit 1e8aac
Packit 1e8aac
  gtk_assistant_insert_page (assistant, page, pos);
Packit 1e8aac
  glade_gtk_assistant_update_page_type (assistant);
Packit 1e8aac
Packit 1e8aac
  if (set_current)
Packit 1e8aac
    gtk_assistant_set_current_page (assistant, pos);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
gboolean
Packit 1e8aac
glade_gtk_assistant_verify_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                     GObject * object,
Packit 1e8aac
                                     const gchar * property_name,
Packit 1e8aac
                                     const GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  if (strcmp (property_name, "n-pages") == 0)
Packit 1e8aac
    return g_value_get_int (value) >=
Packit 1e8aac
        gtk_assistant_get_n_pages (GTK_ASSISTANT (object));
Packit 1e8aac
Packit 1e8aac
  /* Chain Up */
Packit 1e8aac
  if (GWA_GET_CLASS (GTK_TYPE_WINDOW)->verify_property == NULL)
Packit 1e8aac
    return TRUE;
Packit 1e8aac
  return GWA_GET_CLASS (GTK_TYPE_WINDOW)->verify_property (adaptor,
Packit 1e8aac
                                                           object,
Packit 1e8aac
                                                           property_name,
Packit 1e8aac
                                                           value);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_set_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                  GObject * object,
Packit 1e8aac
                                  const gchar * property_name,
Packit 1e8aac
                                  const GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  if (strcmp (property_name, "n-pages") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      GtkAssistant *assistant = GTK_ASSISTANT (object);
Packit 1e8aac
      gint size, i;
Packit 1e8aac
Packit 1e8aac
      for (i = gtk_assistant_get_n_pages (GTK_ASSISTANT (object)),
Packit 1e8aac
           size = g_value_get_int (value); i < size; i++)
Packit 1e8aac
	{
Packit 1e8aac
	  g_message ("aaaa %d %d", i,size);
Packit 1e8aac
        gtk_assistant_append_page (assistant, glade_placeholder_new ());
Packit 1e8aac
	}
Packit 1e8aac
Packit 1e8aac
      glade_gtk_assistant_update_page_type (assistant);
Packit 1e8aac
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Chain Up */
Packit 1e8aac
  GWA_GET_CLASS (GTK_TYPE_WINDOW)->set_property (adaptor,
Packit 1e8aac
                                                 object, property_name, value);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_get_property (GladeWidgetAdaptor * adaptor,
Packit 1e8aac
                                  GObject * object,
Packit 1e8aac
                                  const gchar * property_name, GValue * value)
Packit 1e8aac
{
Packit 1e8aac
  if (strcmp (property_name, "n-pages") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      g_value_set_int (value,
Packit 1e8aac
                       gtk_assistant_get_n_pages (GTK_ASSISTANT (object)));
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Chain Up */
Packit 1e8aac
  GWA_GET_CLASS (GTK_TYPE_WINDOW)->get_property (adaptor,
Packit 1e8aac
                                                 object, property_name, value);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_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
  if (strcmp (property_name, "position") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      GtkAssistant *assistant = GTK_ASSISTANT (container);
Packit 1e8aac
      GtkWidget *widget = GTK_WIDGET (child);
Packit 1e8aac
      gint pos;
Packit 1e8aac
      gboolean set_current;
Packit 1e8aac
Packit 1e8aac
      if ((pos = g_value_get_int (value)) < 0)
Packit 1e8aac
        return;
Packit 1e8aac
      if (pos == glade_gtk_assistant_get_page (assistant, widget))
Packit 1e8aac
        return;
Packit 1e8aac
      set_current = gtk_assistant_get_current_page (assistant) ==
Packit 1e8aac
          glade_gtk_assistant_get_page (assistant, widget);   
Packit 1e8aac
Packit 1e8aac
      g_object_ref (child);
Packit 1e8aac
      assistant_remove_child (assistant, widget);
Packit 1e8aac
      gtk_assistant_insert_page (assistant, widget, pos);
Packit 1e8aac
      g_object_unref (child);
Packit 1e8aac
Packit 1e8aac
      if (set_current)
Packit 1e8aac
        gtk_assistant_set_current_page (assistant, pos);
Packit 1e8aac
Packit 1e8aac
      glade_gtk_assistant_update_page_type (assistant);
Packit 1e8aac
Packit 1e8aac
      glade_gtk_assistant_update_position (assistant);
Packit 1e8aac
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Chain Up */
Packit 1e8aac
  GWA_GET_CLASS (GTK_TYPE_WINDOW)->child_set_property (adaptor,
Packit 1e8aac
                                                       container,
Packit 1e8aac
                                                       child,
Packit 1e8aac
                                                       property_name, value);
Packit 1e8aac
}
Packit 1e8aac
Packit 1e8aac
void
Packit 1e8aac
glade_gtk_assistant_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
  if (strcmp (property_name, "position") == 0)
Packit 1e8aac
    {
Packit 1e8aac
      gint pos;
Packit 1e8aac
      pos = glade_gtk_assistant_get_page (GTK_ASSISTANT (container),
Packit 1e8aac
                                          GTK_WIDGET (child));
Packit 1e8aac
      if (pos >= 0)
Packit 1e8aac
        g_value_set_int (value, pos);
Packit 1e8aac
      return;
Packit 1e8aac
    }
Packit 1e8aac
Packit 1e8aac
  /* Chain Up */
Packit 1e8aac
  GWA_GET_CLASS (GTK_TYPE_WINDOW)->child_get_property (adaptor,
Packit 1e8aac
                                                       container,
Packit 1e8aac
                                                       child,
Packit 1e8aac
                                                       property_name, value);
Packit 1e8aac
}