/* Assistant.c generated by valac, the Vala compiler
 * generated from Assistant.vala, do not modify */

/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
/*
    This file is part of Déjà Dup.
    © 2009 Michael Terry <mike@mterry.name>

    Déjà Dup is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Déjà Dup is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Déjà Dup.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <gdk-pixbuf/gdk-pixdata.h>
#include <glib/gi18n-lib.h>
#include <gobject/gvaluecollector.h>


#define TYPE_ASSISTANT (assistant_get_type ())
#define ASSISTANT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ASSISTANT, Assistant))
#define ASSISTANT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ASSISTANT, AssistantClass))
#define IS_ASSISTANT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ASSISTANT))
#define IS_ASSISTANT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ASSISTANT))
#define ASSISTANT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ASSISTANT, AssistantClass))

typedef struct _Assistant Assistant;
typedef struct _AssistantClass AssistantClass;
typedef struct _AssistantPrivate AssistantPrivate;

#define ASSISTANT_TYPE_PAGE_INFO (assistant_page_info_get_type ())
#define ASSISTANT_PAGE_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ASSISTANT_TYPE_PAGE_INFO, AssistantPageInfo))
#define ASSISTANT_PAGE_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ASSISTANT_TYPE_PAGE_INFO, AssistantPageInfoClass))
#define ASSISTANT_IS_PAGE_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ASSISTANT_TYPE_PAGE_INFO))
#define ASSISTANT_IS_PAGE_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ASSISTANT_TYPE_PAGE_INFO))
#define ASSISTANT_PAGE_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ASSISTANT_TYPE_PAGE_INFO, AssistantPageInfoClass))

typedef struct _AssistantPageInfo AssistantPageInfo;
typedef struct _AssistantPageInfoClass AssistantPageInfoClass;

#define ASSISTANT_TYPE_TYPE (assistant_type_get_type ())
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define __g_list_free_assistant_page_info_unref0(var) ((var == NULL) ? NULL : (var = (_g_list_free_assistant_page_info_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _AssistantPageInfoPrivate AssistantPageInfoPrivate;
#define _assistant_page_info_unref0(var) ((var == NULL) ? NULL : (var = (assistant_page_info_unref (var), NULL)))
typedef struct _AssistantParamSpecPageInfo AssistantParamSpecPageInfo;

struct _Assistant {
	GtkDialog parent_instance;
	AssistantPrivate * priv;
	GtkImage* header_icon;
	GtkEventBox* page_box;
};

struct _AssistantClass {
	GtkDialogClass parent_class;
};

struct _AssistantPrivate {
	char* _apply_text;
	gboolean _resume_supported;
	GtkLabel* header_title;
	GtkWidget* back_button;
	GtkWidget* forward_button;
	GtkWidget* cancel_button;
	GtkWidget* close_button;
	GtkWidget* resume_button;
	GtkWidget* apply_button;
	gboolean interrupt_can_continue;
	gboolean interrupted_from_hidden;
	GList* interrupted;
	GList* current;
	GList* infos;
	gboolean last_op_was_back;
	GtkRequisition page_box_req;
};

typedef enum  {
	ASSISTANT_TYPE_NORMAL,
	ASSISTANT_TYPE_INTERRUPT,
	ASSISTANT_TYPE_SUMMARY,
	ASSISTANT_TYPE_PROGRESS,
	ASSISTANT_TYPE_FINISH
} AssistantType;

struct _AssistantPageInfo {
	GTypeInstance parent_instance;
	volatile int ref_count;
	AssistantPageInfoPrivate * priv;
	GtkWidget* page;
	char* title;
	AssistantType type;
};

struct _AssistantPageInfoClass {
	GTypeClass parent_class;
	void (*finalize) (AssistantPageInfo *self);
};

struct _AssistantParamSpecPageInfo {
	GParamSpec parent_instance;
};


static gpointer assistant_page_info_parent_class = NULL;
static gpointer assistant_parent_class = NULL;

GType assistant_get_type (void);
static gpointer assistant_page_info_ref (gpointer instance);
static void assistant_page_info_unref (gpointer instance);
static GParamSpec* assistant_param_spec_page_info (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) G_GNUC_UNUSED;
static void assistant_value_set_page_info (GValue* value, gpointer v_object) G_GNUC_UNUSED;
static void assistant_value_take_page_info (GValue* value, gpointer v_object) G_GNUC_UNUSED;
static gpointer assistant_value_get_page_info (const GValue* value) G_GNUC_UNUSED;
static GType assistant_page_info_get_type (void) G_GNUC_UNUSED;
#define ASSISTANT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_ASSISTANT, AssistantPrivate))
enum  {
	ASSISTANT_DUMMY_PROPERTY,
	ASSISTANT_APPLY_TEXT,
	ASSISTANT_RESUME_SUPPORTED
};
GType assistant_type_get_type (void);
static void _g_list_free_assistant_page_info_unref (GList* self);
#define ASSISTANT_APPLY 1
#define ASSISTANT_BACK 2
#define ASSISTANT_FORWARD 3
#define ASSISTANT_CANCEL 4
#define ASSISTANT_CLOSE 5
#define ASSISTANT_RESUME 6
void assistant_allow_forward (Assistant* self, gboolean allow);
void assistant_set_header_icon (Assistant* self, const char* name);
void assistant_go_back (Assistant* self);
void assistant_go_forward (Assistant* self);
static void assistant_handle_response (Assistant* self, gint resp);
void assistant_skip (Assistant* self);
static void assistant_page_changed (Assistant* self);
void assistant_go_to_page (Assistant* self, GtkWidget* page);
void assistant_interrupt (Assistant* self, GtkWidget* page, gboolean can_continue);
static void assistant_use_title (Assistant* self, AssistantPageInfo* info);
static void assistant_set_buttons (Assistant* self);
static void assistant_reset_size (Assistant* self, GtkWidget* page);
gboolean assistant_get_resume_supported (Assistant* self);
const char* assistant_get_apply_text (Assistant* self);
static gboolean assistant_set_first_page (Assistant* self);
static AssistantPageInfo* assistant_page_info_new (void);
static AssistantPageInfo* assistant_page_info_construct (GType object_type);
static gboolean _assistant_set_first_page_gsource_func (gpointer self);
void assistant_append_page (Assistant* self, GtkWidget* page, AssistantType type);
void assistant_set_page_title (Assistant* self, GtkWidget* page, const char* title);
Assistant* assistant_construct (GType object_type);
void assistant_set_apply_text (Assistant* self, const char* value);
void assistant_set_resume_supported (Assistant* self, gboolean value);
static void _assistant_handle_response_gtk_dialog_response (GtkDialog* _sender, gint response_id, gpointer self);
static GObject * assistant_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
enum  {
	ASSISTANT_PAGE_INFO_DUMMY_PROPERTY
};
static void assistant_page_info_finalize (AssistantPageInfo* obj);
static void assistant_finalize (GObject* obj);
static void assistant_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
static void assistant_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);



GType assistant_type_get_type (void) {
	static volatile gsize assistant_type_type_id__volatile = 0;
	if (g_once_init_enter (&assistant_type_type_id__volatile)) {
		static const GEnumValue values[] = {{ASSISTANT_TYPE_NORMAL, "ASSISTANT_TYPE_NORMAL", "normal"}, {ASSISTANT_TYPE_INTERRUPT, "ASSISTANT_TYPE_INTERRUPT", "interrupt"}, {ASSISTANT_TYPE_SUMMARY, "ASSISTANT_TYPE_SUMMARY", "summary"}, {ASSISTANT_TYPE_PROGRESS, "ASSISTANT_TYPE_PROGRESS", "progress"}, {ASSISTANT_TYPE_FINISH, "ASSISTANT_TYPE_FINISH", "finish"}, {0, NULL, NULL}};
		GType assistant_type_type_id;
		assistant_type_type_id = g_enum_register_static ("AssistantType", values);
		g_once_init_leave (&assistant_type_type_id__volatile, assistant_type_type_id);
	}
	return assistant_type_type_id__volatile;
}


static void _g_list_free_assistant_page_info_unref (GList* self) {
	g_list_foreach (self, (GFunc) assistant_page_info_unref, NULL);
	g_list_free (self);
}


void assistant_allow_forward (Assistant* self, gboolean allow) {
	g_return_if_fail (self != NULL);
	gtk_widget_set_sensitive (self->priv->forward_button, allow);
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


void assistant_set_header_icon (Assistant* self, const char* name) {
	GError * _inner_error_;
	g_return_if_fail (self != NULL);
	_inner_error_ = NULL;
	if (name == NULL) {
		name = gtk_window_get_icon_name ((GtkWindow*) self);
	}
	{
		GtkIconTheme* theme;
		GdkPixbuf* pixbuf;
		theme = _g_object_ref0 (gtk_icon_theme_get_for_screen (gtk_window_get_screen ((GtkWindow*) self)));
		pixbuf = _g_object_ref0 (gtk_icon_theme_load_icon (theme, name, 48, GTK_ICON_LOOKUP_FORCE_SIZE, &_inner_error_));
		if (_inner_error_ != NULL) {
			_g_object_unref0 (theme);
			goto __catch0_g_error;
		}
		g_object_set (self->header_icon, "pixbuf", pixbuf, NULL);
		_g_object_unref0 (theme);
		_g_object_unref0 (pixbuf);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		{
			_g_error_free0 (e);
		}
	}
	__finally0:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return;
	}
}


static void assistant_handle_response (Assistant* self, gint resp) {
	g_return_if_fail (self != NULL);
	switch (resp) {
		case ASSISTANT_BACK:
		{
			assistant_go_back (self);
			break;
		}
		case ASSISTANT_APPLY:
		case ASSISTANT_FORWARD:
		{
			assistant_go_forward (self);
			break;
		}
		default:
		{
			g_signal_emit_by_name (self, "canceled");
			break;
		}
		case ASSISTANT_CLOSE:
		{
			g_signal_emit_by_name (self, "closed");
			break;
		}
		case ASSISTANT_RESUME:
		{
			g_signal_emit_by_name (self, "resumed");
			break;
		}
	}
}


void assistant_skip (Assistant* self) {
	g_return_if_fail (self != NULL);
	if (self->priv->last_op_was_back) {
		assistant_go_back (self);
	} else {
		assistant_go_forward (self);
	}
}


void assistant_go_back (Assistant* self) {
	GList* next;
	g_return_if_fail (self != NULL);
	next = NULL;
	if (self->priv->interrupted != NULL) {
		next = self->priv->interrupted->prev;
	} else {
		next = self->priv->current->prev;
		while (TRUE) {
			gboolean _tmp0_ = FALSE;
			if (next != NULL) {
				_tmp0_ = ((AssistantPageInfo*) next->data)->type == ASSISTANT_TYPE_INTERRUPT;
			} else {
				_tmp0_ = FALSE;
			}
			if (!_tmp0_) {
				break;
			}
			next = next->prev;
		}
	}
	if (next != NULL) {
		self->priv->last_op_was_back = TRUE;
		self->priv->current = next;
		assistant_page_changed (self);
		g_signal_emit_by_name (self, "backward");
	}
}


void assistant_go_forward (Assistant* self) {
	GList* next;
	g_return_if_fail (self != NULL);
	next = NULL;
	if (self->priv->interrupted != NULL) {
		next = self->priv->interrupted;
		if (self->priv->interrupted_from_hidden) {
			gtk_widget_hide ((GtkWidget*) self);
		}
	} else {
		GList* _tmp0_;
		_tmp0_ = NULL;
		if (self->priv->current == NULL) {
			_tmp0_ = self->priv->infos;
		} else {
			_tmp0_ = self->priv->current->next;
		}
		next = _tmp0_;
		while (TRUE) {
			gboolean _tmp1_ = FALSE;
			if (next != NULL) {
				_tmp1_ = ((AssistantPageInfo*) next->data)->type == ASSISTANT_TYPE_INTERRUPT;
			} else {
				_tmp1_ = FALSE;
			}
			if (!_tmp1_) {
				break;
			}
			next = next->next;
		}
	}
	if (next != NULL) {
		self->priv->last_op_was_back = FALSE;
		self->priv->current = next;
		assistant_page_changed (self);
		g_signal_emit_by_name (self, "forward");
	}
}


void assistant_go_to_page (Assistant* self, GtkWidget* page) {
	GList* i;
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	i = self->priv->infos;
	while (TRUE) {
		if (!(i != NULL)) {
			break;
		}
		if (((AssistantPageInfo*) i->data)->page == page) {
			self->priv->current = i;
			assistant_page_changed (self);
			break;
		}
		i = i->next;
	}
}


void assistant_interrupt (Assistant* self, GtkWidget* page, gboolean can_continue) {
	GList* was;
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	was = self->priv->current;
	self->priv->interrupt_can_continue = can_continue;
	assistant_go_to_page (self, page);
	if (!gtk_widget_get_visible ((GtkWidget*) self)) {
		self->priv->interrupted_from_hidden = TRUE;
	}
	self->priv->interrupted = was;
}


static void assistant_use_title (Assistant* self, AssistantPageInfo* info) {
	char* title;
	g_return_if_fail (self != NULL);
	g_return_if_fail (info != NULL);
	title = g_markup_printf_escaped ("<span size=\"xx-large\" weight=\"ultrabold\">%s</span>", info->title);
	gtk_label_set_markup (self->priv->header_title, title);
	_g_free0 (title);
}


static void assistant_page_changed (Assistant* self) {
	AssistantPageInfo* info;
	g_return_if_fail (self != NULL);
	g_return_if_fail (self->priv->current != NULL);
	self->priv->interrupted = NULL;
	self->priv->interrupted_from_hidden = FALSE;
	info = (AssistantPageInfo*) self->priv->current->data;
	assistant_set_header_icon (self, NULL);
	g_signal_emit_by_name (self, "prepare", info->page);
	if (((AssistantPageInfo*) self->priv->current->data)->page == info->page) {
		GtkWidget* w;
		gboolean _tmp0_ = FALSE;
		assistant_use_title (self, info);
		assistant_set_buttons (self);
		if (((GtkBin*) self->page_box)->child != NULL) {
			gtk_widget_hide (((GtkBin*) self->page_box)->child);
			gtk_container_remove ((GtkContainer*) self->page_box, ((GtkBin*) self->page_box)->child);
		}
		gtk_container_add ((GtkContainer*) self->page_box, info->page);
		gtk_widget_show (info->page);
		assistant_reset_size (self, info->page);
		w = _g_object_ref0 (gtk_window_get_focus ((GtkWindow*) self));
		if (w != NULL) {
			_tmp0_ = G_TYPE_FROM_INSTANCE ((GObject*) w) == GTK_TYPE_LABEL;
		} else {
			_tmp0_ = FALSE;
		}
		if (_tmp0_) {
			gtk_label_select_region (GTK_LABEL (w), -1, -1);
		}
		_g_object_unref0 (w);
	}
}


static void assistant_set_buttons (Assistant* self) {
	AssistantPageInfo* info;
	gboolean show_cancel;
	gboolean show_back;
	gboolean show_forward;
	gboolean show_apply;
	gboolean show_close;
	gboolean show_resume;
	char* forward_text;
	g_return_if_fail (self != NULL);
	g_return_if_fail (self->priv->current != NULL);
	info = (AssistantPageInfo*) self->priv->current->data;
	show_cancel = FALSE;
	show_back = FALSE;
	show_forward = FALSE;
	show_apply = FALSE;
	show_close = FALSE;
	show_resume = FALSE;
	forward_text = g_strdup (GTK_STOCK_GO_FORWARD);
	switch (info->type) {
		default:
		{
			show_cancel = TRUE;
			show_back = self->priv->current->prev != NULL;
			show_forward = TRUE;
			break;
		}
		case ASSISTANT_TYPE_SUMMARY:
		{
			show_cancel = TRUE;
			show_back = self->priv->current->prev != NULL;
			show_apply = TRUE;
			break;
		}
		case ASSISTANT_TYPE_INTERRUPT:
		{
			show_cancel = TRUE;
			if (self->priv->interrupt_can_continue) {
				char* _tmp0_;
				show_forward = TRUE;
				forward_text = (_tmp0_ = g_strdup (_ ("Co_ntinue")), _g_free0 (forward_text), _tmp0_);
			}
			break;
		}
		case ASSISTANT_TYPE_PROGRESS:
		{
			show_cancel = TRUE;
			show_resume = self->priv->_resume_supported;
			break;
		}
		case ASSISTANT_TYPE_FINISH:
		{
			show_close = TRUE;
			break;
		}
	}
	if (self->priv->cancel_button != NULL) {
		GtkWidget* _tmp1_;
		gtk_container_remove ((GtkContainer*) ((GtkDialog*) self)->action_area, self->priv->cancel_button);
		self->priv->cancel_button = (_tmp1_ = NULL, _g_object_unref0 (self->priv->cancel_button), _tmp1_);
	}
	if (self->priv->close_button != NULL) {
		GtkWidget* _tmp2_;
		gtk_container_remove ((GtkContainer*) ((GtkDialog*) self)->action_area, self->priv->close_button);
		self->priv->close_button = (_tmp2_ = NULL, _g_object_unref0 (self->priv->close_button), _tmp2_);
	}
	if (self->priv->back_button != NULL) {
		GtkWidget* _tmp3_;
		gtk_container_remove ((GtkContainer*) ((GtkDialog*) self)->action_area, self->priv->back_button);
		self->priv->back_button = (_tmp3_ = NULL, _g_object_unref0 (self->priv->back_button), _tmp3_);
	}
	if (self->priv->resume_button != NULL) {
		GtkWidget* _tmp4_;
		gtk_container_remove ((GtkContainer*) ((GtkDialog*) self)->action_area, self->priv->resume_button);
		self->priv->resume_button = (_tmp4_ = NULL, _g_object_unref0 (self->priv->resume_button), _tmp4_);
	}
	if (self->priv->forward_button != NULL) {
		GtkWidget* _tmp5_;
		gtk_container_remove ((GtkContainer*) ((GtkDialog*) self)->action_area, self->priv->forward_button);
		self->priv->forward_button = (_tmp5_ = NULL, _g_object_unref0 (self->priv->forward_button), _tmp5_);
	}
	if (self->priv->apply_button != NULL) {
		GtkWidget* _tmp6_;
		gtk_container_remove ((GtkContainer*) ((GtkDialog*) self)->action_area, self->priv->apply_button);
		self->priv->apply_button = (_tmp6_ = NULL, _g_object_unref0 (self->priv->apply_button), _tmp6_);
	}
	if (show_cancel) {
		GtkWidget* _tmp7_;
		self->priv->cancel_button = (_tmp7_ = _g_object_ref0 (gtk_dialog_add_button ((GtkDialog*) self, GTK_STOCK_CANCEL, ASSISTANT_CANCEL)), _g_object_unref0 (self->priv->cancel_button), _tmp7_);
	}
	if (show_close) {
		GtkWidget* _tmp8_;
		self->priv->close_button = (_tmp8_ = _g_object_ref0 (gtk_dialog_add_button ((GtkDialog*) self, GTK_STOCK_CLOSE, ASSISTANT_CLOSE)), _g_object_unref0 (self->priv->close_button), _tmp8_);
		gtk_widget_grab_default (self->priv->close_button);
	}
	if (show_back) {
		GtkWidget* _tmp9_;
		self->priv->back_button = (_tmp9_ = _g_object_ref0 (gtk_dialog_add_button ((GtkDialog*) self, GTK_STOCK_GO_BACK, ASSISTANT_BACK)), _g_object_unref0 (self->priv->back_button), _tmp9_);
	}
	if (show_resume) {
		GtkWidget* _tmp10_;
		self->priv->resume_button = (_tmp10_ = _g_object_ref0 (gtk_dialog_add_button ((GtkDialog*) self, _ ("_Resume Later"), ASSISTANT_RESUME)), _g_object_unref0 (self->priv->resume_button), _tmp10_);
		gtk_widget_grab_default (self->priv->resume_button);
	}
	if (show_forward) {
		GtkWidget* _tmp11_;
		self->priv->forward_button = (_tmp11_ = _g_object_ref0 (gtk_dialog_add_button ((GtkDialog*) self, forward_text, ASSISTANT_FORWARD)), _g_object_unref0 (self->priv->forward_button), _tmp11_);
		gtk_widget_grab_default (self->priv->forward_button);
	}
	if (show_apply) {
		GtkWidget* _tmp12_;
		self->priv->apply_button = (_tmp12_ = _g_object_ref0 (gtk_dialog_add_button ((GtkDialog*) self, self->priv->_apply_text, ASSISTANT_APPLY)), _g_object_unref0 (self->priv->apply_button), _tmp12_);
		gtk_widget_grab_default (self->priv->apply_button);
	}
	_g_free0 (forward_text);
}


static gboolean assistant_set_first_page (Assistant* self) {
	gboolean result = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	self->priv->current = NULL;
	assistant_go_forward (self);
	result = FALSE;
	return result;
}


static gpointer _assistant_page_info_ref0 (gpointer self) {
	return self ? assistant_page_info_ref (self) : NULL;
}


static gboolean _assistant_set_first_page_gsource_func (gpointer self) {
	return assistant_set_first_page (self);
}


void assistant_append_page (Assistant* self, GtkWidget* page, AssistantType type) {
	gboolean was_empty;
	AssistantPageInfo* info;
	GtkWidget* _tmp0_;
	char* _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	was_empty = self->priv->infos == NULL;
	info = assistant_page_info_new ();
	info->page = (_tmp0_ = _g_object_ref0 (page), _g_object_unref0 (info->page), _tmp0_);
	info->type = type;
	info->title = (_tmp1_ = g_strdup (""), _g_free0 (info->title), _tmp1_);
	self->priv->infos = g_list_append (self->priv->infos, _assistant_page_info_ref0 (info));
	gtk_widget_show_all (page);
	if (was_empty) {
		gtk_widget_size_request ((GtkWidget*) self->page_box, &self->priv->page_box_req);
	}
	assistant_reset_size (self, page);
	if (was_empty) {
		g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, _assistant_set_first_page_gsource_func, g_object_ref (self), g_object_unref);
	}
	_assistant_page_info_unref0 (info);
}


static void assistant_reset_size (Assistant* self, GtkWidget* page) {
	GtkRequisition pagereq = {0};
	gint boxw = 0;
	gint boxh = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	gtk_widget_get_size_request ((GtkWidget*) self->page_box, &boxw, &boxh);
	gtk_widget_size_request (page, &pagereq);
	gtk_widget_set_size_request ((GtkWidget*) self->page_box, MAX (boxw, pagereq.width + self->priv->page_box_req.width), MAX (boxh, pagereq.height + self->priv->page_box_req.height));
}


void assistant_set_page_title (Assistant* self, GtkWidget* page, const char* title) {
	g_return_if_fail (self != NULL);
	g_return_if_fail (page != NULL);
	g_return_if_fail (title != NULL);
	{
		GList* info_collection;
		GList* info_it;
		info_collection = self->priv->infos;
		for (info_it = info_collection; info_it != NULL; info_it = info_it->next) {
			AssistantPageInfo* info;
			info = _assistant_page_info_ref0 ((AssistantPageInfo*) info_it->data);
			{
				if (info->page == page) {
					char* _tmp0_;
					gboolean _tmp1_ = FALSE;
					info->title = (_tmp0_ = g_strdup (title), _g_free0 (info->title), _tmp0_);
					if (self->priv->current != NULL) {
						_tmp1_ = ((AssistantPageInfo*) self->priv->current->data)->page == page;
					} else {
						_tmp1_ = FALSE;
					}
					if (_tmp1_) {
						assistant_use_title (self, info);
					}
					_assistant_page_info_unref0 (info);
					break;
				}
				_assistant_page_info_unref0 (info);
			}
		}
	}
}


Assistant* assistant_construct (GType object_type) {
	Assistant * self;
	self = g_object_newv (object_type, 0, NULL);
	return self;
}


const char* assistant_get_apply_text (Assistant* self) {
	const char* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self->priv->_apply_text;
	return result;
}


void assistant_set_apply_text (Assistant* self, const char* value) {
	char* _tmp0_;
	g_return_if_fail (self != NULL);
	self->priv->_apply_text = (_tmp0_ = g_strdup (value), _g_free0 (self->priv->_apply_text), _tmp0_);
	g_object_notify ((GObject *) self, "apply-text");
}


gboolean assistant_get_resume_supported (Assistant* self) {
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_resume_supported;
	return result;
}


void assistant_set_resume_supported (Assistant* self, gboolean value) {
	g_return_if_fail (self != NULL);
	self->priv->_resume_supported = value;
	g_object_notify ((GObject *) self, "resume-supported");
}


static void _assistant_handle_response_gtk_dialog_response (GtkDialog* _sender, gint response_id, gpointer self) {
	assistant_handle_response (self, response_id);
}


static GObject * assistant_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
	GObject * obj;
	GObjectClass * parent_class;
	Assistant * self;
	parent_class = G_OBJECT_CLASS (assistant_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = ASSISTANT (obj);
	{
		GList* _tmp0_;
		GtkEventBox* ebox;
		GtkVBox* evbox;
		GtkHBox* ehbox;
		GtkLabel* _tmp1_;
		GtkImage* _tmp2_;
		GtkEventBox* _tmp3_;
		GdkColor _tmp4_;
		GdkColor _tmp5_;
		gtk_dialog_set_has_separator ((GtkDialog*) self, FALSE);
		self->priv->infos = (_tmp0_ = NULL, __g_list_free_assistant_page_info_unref0 (self->priv->infos), _tmp0_);
		ebox = g_object_ref_sink ((GtkEventBox*) gtk_event_box_new ());
		evbox = g_object_ref_sink ((GtkVBox*) gtk_vbox_new (FALSE, 0));
		gtk_container_add ((GtkContainer*) ebox, (GtkWidget*) evbox);
		ehbox = g_object_ref_sink ((GtkHBox*) gtk_hbox_new (FALSE, 0));
		self->priv->header_title = (_tmp1_ = g_object_ref_sink ((GtkLabel*) gtk_label_new ("")), _g_object_unref0 (self->priv->header_title), _tmp1_);
		g_object_set ((GtkMisc*) self->priv->header_title, "xalign", 0.f, NULL);
		self->header_icon = (_tmp2_ = g_object_ref_sink ((GtkImage*) gtk_image_new ()), _g_object_unref0 (self->header_icon), _tmp2_);
		gtk_container_set_border_width ((GtkContainer*) ehbox, (guint) 6);
		gtk_box_pack_start ((GtkBox*) ehbox, (GtkWidget*) self->priv->header_title, TRUE, TRUE, (guint) 0);
		gtk_box_pack_start ((GtkBox*) ehbox, (GtkWidget*) self->header_icon, FALSE, FALSE, (guint) 0);
		gtk_box_pack_start ((GtkBox*) evbox, (GtkWidget*) ehbox, FALSE, FALSE, (guint) 0);
		self->page_box = (_tmp3_ = g_object_ref_sink ((GtkEventBox*) gtk_event_box_new ()), _g_object_unref0 (self->page_box), _tmp3_);
		gtk_container_set_border_width ((GtkContainer*) self->page_box, (guint) 1);
		gtk_box_pack_start ((GtkBox*) evbox, (GtkWidget*) self->page_box, TRUE, TRUE, (guint) 0);
		gtk_container_add ((GtkContainer*) ((GtkDialog*) self)->vbox, (GtkWidget*) ebox);
		gtk_widget_show_all ((GtkWidget*) ((GtkDialog*) self)->vbox);
		gtk_widget_ensure_style ((GtkWidget*) ebox);
		gtk_widget_modify_bg ((GtkWidget*) ebox, GTK_STATE_NORMAL, (_tmp4_ = gtk_widget_get_style ((GtkWidget*) ebox)->bg[GTK_STATE_SELECTED], &_tmp4_));
		gtk_widget_modify_fg ((GtkWidget*) ebox, GTK_STATE_NORMAL, (_tmp5_ = gtk_widget_get_style ((GtkWidget*) ebox)->fg[GTK_STATE_SELECTED], &_tmp5_));
		g_signal_connect_object ((GtkDialog*) self, "response", (GCallback) _assistant_handle_response_gtk_dialog_response, self, 0);
		_g_object_unref0 (ebox);
		_g_object_unref0 (evbox);
		_g_object_unref0 (ehbox);
	}
	return obj;
}


static AssistantPageInfo* assistant_page_info_construct (GType object_type) {
	AssistantPageInfo* self;
	self = (AssistantPageInfo*) g_type_create_instance (object_type);
	return self;
}


static AssistantPageInfo* assistant_page_info_new (void) {
	return assistant_page_info_construct (ASSISTANT_TYPE_PAGE_INFO);
}


static void assistant_value_page_info_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void assistant_value_page_info_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		assistant_page_info_unref (value->data[0].v_pointer);
	}
}


static void assistant_value_page_info_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = assistant_page_info_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer assistant_value_page_info_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* assistant_value_page_info_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		AssistantPageInfo* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = assistant_page_info_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* assistant_value_page_info_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	AssistantPageInfo** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags && G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = assistant_page_info_ref (value->data[0].v_pointer);
	}
	return NULL;
}


static GParamSpec* assistant_param_spec_page_info (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	AssistantParamSpecPageInfo* spec;
	g_return_val_if_fail (g_type_is_a (object_type, ASSISTANT_TYPE_PAGE_INFO), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


static gpointer assistant_value_get_page_info (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, ASSISTANT_TYPE_PAGE_INFO), NULL);
	return value->data[0].v_pointer;
}


static void assistant_value_set_page_info (GValue* value, gpointer v_object) {
	AssistantPageInfo* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, ASSISTANT_TYPE_PAGE_INFO));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, ASSISTANT_TYPE_PAGE_INFO));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		assistant_page_info_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		assistant_page_info_unref (old);
	}
}


static void assistant_value_take_page_info (GValue* value, gpointer v_object) {
	AssistantPageInfo* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, ASSISTANT_TYPE_PAGE_INFO));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, ASSISTANT_TYPE_PAGE_INFO));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		assistant_page_info_unref (old);
	}
}


static void assistant_page_info_class_init (AssistantPageInfoClass * klass) {
	assistant_page_info_parent_class = g_type_class_peek_parent (klass);
	ASSISTANT_PAGE_INFO_CLASS (klass)->finalize = assistant_page_info_finalize;
}


static void assistant_page_info_instance_init (AssistantPageInfo * self) {
	self->ref_count = 1;
}


static void assistant_page_info_finalize (AssistantPageInfo* obj) {
	AssistantPageInfo * self;
	self = ASSISTANT_PAGE_INFO (obj);
	_g_object_unref0 (self->page);
	_g_free0 (self->title);
}


static GType assistant_page_info_get_type (void) {
	static volatile gsize assistant_page_info_type_id__volatile = 0;
	if (g_once_init_enter (&assistant_page_info_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { assistant_value_page_info_init, assistant_value_page_info_free_value, assistant_value_page_info_copy_value, assistant_value_page_info_peek_pointer, "p", assistant_value_page_info_collect_value, "p", assistant_value_page_info_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (AssistantPageInfoClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) assistant_page_info_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (AssistantPageInfo), 0, (GInstanceInitFunc) assistant_page_info_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType assistant_page_info_type_id;
		assistant_page_info_type_id = g_type_register_fundamental (g_type_fundamental_next (), "AssistantPageInfo", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&assistant_page_info_type_id__volatile, assistant_page_info_type_id);
	}
	return assistant_page_info_type_id__volatile;
}


static gpointer assistant_page_info_ref (gpointer instance) {
	AssistantPageInfo* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


static void assistant_page_info_unref (gpointer instance) {
	AssistantPageInfo* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		ASSISTANT_PAGE_INFO_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}


static void assistant_class_init (AssistantClass * klass) {
	assistant_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (AssistantPrivate));
	G_OBJECT_CLASS (klass)->get_property = assistant_get_property;
	G_OBJECT_CLASS (klass)->set_property = assistant_set_property;
	G_OBJECT_CLASS (klass)->constructor = assistant_constructor;
	G_OBJECT_CLASS (klass)->finalize = assistant_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), ASSISTANT_APPLY_TEXT, g_param_spec_string ("apply-text", "apply-text", "apply-text", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), ASSISTANT_RESUME_SUPPORTED, g_param_spec_boolean ("resume-supported", "resume-supported", "resume-supported", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_signal_new ("canceled", TYPE_ASSISTANT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("closed", TYPE_ASSISTANT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("resumed", TYPE_ASSISTANT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("prepare", TYPE_ASSISTANT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
	g_signal_new ("forward", TYPE_ASSISTANT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	g_signal_new ("backward", TYPE_ASSISTANT, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}


static void assistant_instance_init (Assistant * self) {
	self->priv = ASSISTANT_GET_PRIVATE (self);
	self->priv->_apply_text = g_strdup (GTK_STOCK_APPLY);
	self->priv->_resume_supported = FALSE;
	self->priv->interrupt_can_continue = TRUE;
	self->priv->interrupted_from_hidden = FALSE;
	self->priv->last_op_was_back = FALSE;
}


static void assistant_finalize (GObject* obj) {
	Assistant * self;
	self = ASSISTANT (obj);
	_g_free0 (self->priv->_apply_text);
	_g_object_unref0 (self->priv->header_title);
	_g_object_unref0 (self->header_icon);
	_g_object_unref0 (self->priv->back_button);
	_g_object_unref0 (self->priv->forward_button);
	_g_object_unref0 (self->priv->cancel_button);
	_g_object_unref0 (self->priv->close_button);
	_g_object_unref0 (self->priv->resume_button);
	_g_object_unref0 (self->priv->apply_button);
	_g_object_unref0 (self->page_box);
	__g_list_free_assistant_page_info_unref0 (self->priv->infos);
	G_OBJECT_CLASS (assistant_parent_class)->finalize (obj);
}


GType assistant_get_type (void) {
	static volatile gsize assistant_type_id__volatile = 0;
	if (g_once_init_enter (&assistant_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (AssistantClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) assistant_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Assistant), 0, (GInstanceInitFunc) assistant_instance_init, NULL };
		GType assistant_type_id;
		assistant_type_id = g_type_register_static (GTK_TYPE_DIALOG, "Assistant", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
		g_once_init_leave (&assistant_type_id__volatile, assistant_type_id);
	}
	return assistant_type_id__volatile;
}


static void assistant_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
	Assistant * self;
	self = ASSISTANT (object);
	switch (property_id) {
		case ASSISTANT_APPLY_TEXT:
		g_value_set_string (value, assistant_get_apply_text (self));
		break;
		case ASSISTANT_RESUME_SUPPORTED:
		g_value_set_boolean (value, assistant_get_resume_supported (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}


static void assistant_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
	Assistant * self;
	self = ASSISTANT (object);
	switch (property_id) {
		case ASSISTANT_APPLY_TEXT:
		assistant_set_apply_text (self, g_value_get_string (value));
		break;
		case ASSISTANT_RESUME_SUPPORTED:
		assistant_set_resume_supported (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}




