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

/*
* Copyright (c) 2011-2013 Yorba Foundation
*               2018 elementary LLC. (https://elementary.io)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* This dialog displays a boolean search configuration.*/

#include "io.elementary.photos.h"
#include <granite.h>
#include <gtk/gtk.h>
#include <gee.h>
#include <glib-object.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gi18n-lib.h>
#include <gdk/gdk.h>
#include <float.h>
#include <math.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	SAVED_SEARCH_DIALOG_0_PROPERTY,
	SAVED_SEARCH_DIALOG_NUM_PROPERTIES
};
static GParamSpec* saved_search_dialog_properties[SAVED_SEARCH_DIALOG_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _saved_search_table_unref0(var) ((var == NULL) ? NULL : (var = (saved_search_table_unref (var), NULL)))
#define _search_condition_unref0(var) ((var == NULL) ? NULL : (var = (search_condition_unref (var), NULL)))

struct _SavedSearchDialogPrivate {
	GraniteDialog* dialog;
	GtkButton* add_criteria;
	GtkComboBoxText* operator;
	GtkGrid* row_box;
	GtkEntry* search_title;
	GeeArrayList* row_list;
	gboolean edit_mode;
	SavedSearch* previous_search;
	gboolean valid;
};

static gint SavedSearchDialog_private_offset;
static gpointer saved_search_dialog_parent_class = NULL;

static void saved_search_dialog_on_title_changed (SavedSearchDialog* self);
static void _saved_search_dialog_on_title_changed_gtk_editable_changed (GtkEditable* _sender,
                                                                 gpointer self);
static void saved_search_dialog_add_text_search (SavedSearchDialog* self);
static void saved_search_dialog_set_valid (SavedSearchDialog* self,
                                    gboolean v);
static void saved_search_dialog_add_row (SavedSearchDialog* self,
                                  SearchRowContainer* row);
static gboolean saved_search_dialog_on_add_criteria (SavedSearchDialog* self,
                                              GdkEventButton* event);
static void saved_search_dialog_on_remove_row (SavedSearchDialog* self,
                                        SearchRowContainer* row);
static void _saved_search_dialog_on_remove_row_search_row_container_remove (SearchRowContainer* _sender,
                                                                     SearchRowContainer* this_row,
                                                                     gpointer self);
static void saved_search_dialog_on_row_changed (SavedSearchDialog* self,
                                         SearchRowContainer* row);
static void _saved_search_dialog_on_row_changed_search_row_container_changed (SearchRowContainer* _sender,
                                                                       SearchRowContainer* this_row,
                                                                       gpointer self);
static void saved_search_dialog_on_response (SavedSearchDialog* self,
                                      gint response_id);
static gboolean saved_search_dialog_is_title_valid (SavedSearchDialog* self);
static GObject * saved_search_dialog_constructor (GType type,
                                           guint n_construct_properties,
                                           GObjectConstructParam * construct_properties);
static gboolean _saved_search_dialog_on_add_criteria_gtk_widget_button_press_event (GtkWidget* _sender,
                                                                             GdkEventButton* event,
                                                                             gpointer self);
static void _saved_search_dialog_on_response_gtk_dialog_response (GtkDialog* _sender,
                                                           gint response_id,
                                                           gpointer self);
static void saved_search_dialog_finalize (GObject * obj);
static GType saved_search_dialog_get_type_once (void);

static inline gpointer
saved_search_dialog_get_instance_private (SavedSearchDialog* self)
{
	return G_STRUCT_MEMBER_P (self, SavedSearchDialog_private_offset);
}

static void
_saved_search_dialog_on_title_changed_gtk_editable_changed (GtkEditable* _sender,
                                                            gpointer self)
{
	saved_search_dialog_on_title_changed ((SavedSearchDialog*) self);
}

SavedSearchDialog*
saved_search_dialog_construct (GType object_type)
{
	SavedSearchDialog * self = NULL;
	GtkEntry* _tmp0_;
	SavedSearchTable* _tmp1_;
	SavedSearchTable* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	GtkEntry* _tmp5_;
	GeeArrayList* _tmp6_;
	gpointer _tmp7_;
	SearchRowContainer* _tmp8_;
	GtkButton* ok_button = NULL;
	GtkButton* _tmp9_;
	GraniteDialog* _tmp10_;
	GraniteDialog* _tmp11_;
	self = (SavedSearchDialog*) g_object_new (object_type, NULL);
	_tmp0_ = self->priv->search_title;
	_tmp1_ = saved_search_table_get_instance ();
	_tmp2_ = _tmp1_;
	_tmp3_ = saved_search_table_generate_unique_name (_tmp2_);
	_tmp4_ = _tmp3_;
	gtk_entry_set_text (_tmp0_, _tmp4_);
	_g_free0 (_tmp4_);
	_saved_search_table_unref0 (_tmp2_);
	_tmp5_ = self->priv->search_title;
	gtk_editable_select_region ((GtkEditable*) _tmp5_, 0, -1);
	saved_search_dialog_add_text_search (self);
	_tmp6_ = self->priv->row_list;
	_tmp7_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, 0);
	_tmp8_ = (SearchRowContainer*) _tmp7_;
	search_row_container_allow_removal (_tmp8_, FALSE);
	_g_object_unref0 (_tmp8_);
	_tmp9_ = (GtkButton*) gtk_button_new_with_label (_ ("Add"));
	g_object_ref_sink (_tmp9_);
	ok_button = _tmp9_;
	gtk_widget_set_can_default ((GtkWidget*) ok_button, TRUE);
	_tmp10_ = self->priv->dialog;
	gtk_dialog_add_action_widget ((GtkDialog*) _tmp10_, (GtkWidget*) ok_button, (gint) GTK_RESPONSE_OK);
	_tmp11_ = self->priv->dialog;
	gtk_widget_show_all ((GtkWidget*) _tmp11_);
	saved_search_dialog_set_valid (self, FALSE);
	_g_object_unref0 (ok_button);
	return self;
}

SavedSearchDialog*
saved_search_dialog_new (void)
{
	return saved_search_dialog_construct (TYPE_SAVED_SEARCH_DIALOG);
}

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

SavedSearchDialog*
saved_search_dialog_construct_edit_existing (GType object_type,
                                             SavedSearch* saved_search)
{
	SavedSearchDialog * self = NULL;
	SavedSearch* _tmp0_;
	GtkButton* close_button = NULL;
	GtkButton* _tmp1_;
	GtkButton* _tmp2_;
	GraniteDialog* _tmp3_;
	GtkButton* _tmp4_;
	GraniteDialog* _tmp5_;
	GtkComboBoxText* _tmp6_;
	GtkEntry* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	GeeArrayList* _tmp21_;
	gint _tmp22_;
	gint _tmp23_;
	g_return_val_if_fail (saved_search != NULL, NULL);
	self = (SavedSearchDialog*) g_object_new (object_type, NULL);
	_tmp0_ = _g_object_ref0 (saved_search);
	_g_object_unref0 (self->priv->previous_search);
	self->priv->previous_search = _tmp0_;
	self->priv->edit_mode = TRUE;
	_tmp1_ = (GtkButton*) gtk_button_new_with_label (_ ("Save"));
	g_object_ref_sink (_tmp1_);
	close_button = _tmp1_;
	_tmp2_ = close_button;
	gtk_widget_set_can_default ((GtkWidget*) _tmp2_, TRUE);
	_tmp3_ = self->priv->dialog;
	_tmp4_ = close_button;
	gtk_dialog_add_action_widget ((GtkDialog*) _tmp3_, (GtkWidget*) _tmp4_, (gint) GTK_RESPONSE_OK);
	_tmp5_ = self->priv->dialog;
	gtk_widget_show_all ((GtkWidget*) _tmp5_);
	_tmp6_ = self->priv->operator;
	gtk_combo_box_set_active ((GtkComboBox*) _tmp6_, (gint) ((SearchOperator) saved_search_get_operator (saved_search)));
	_tmp7_ = self->priv->search_title;
	_tmp8_ = data_object_get_name ((DataObject*) saved_search);
	_tmp9_ = _tmp8_;
	gtk_entry_set_text (_tmp7_, _tmp9_);
	_g_free0 (_tmp9_);
	{
		GeeList* _sc_list = NULL;
		GeeList* _tmp10_;
		gint _sc_size = 0;
		GeeList* _tmp11_;
		gint _tmp12_;
		gint _tmp13_;
		gint _sc_index = 0;
		_tmp10_ = saved_search_get_conditions (saved_search);
		_sc_list = _tmp10_;
		_tmp11_ = _sc_list;
		_tmp12_ = gee_collection_get_size ((GeeCollection*) _tmp11_);
		_tmp13_ = _tmp12_;
		_sc_size = _tmp13_;
		_sc_index = -1;
		while (TRUE) {
			gint _tmp14_;
			gint _tmp15_;
			SearchCondition* sc = NULL;
			GeeList* _tmp16_;
			gpointer _tmp17_;
			SearchCondition* _tmp18_;
			SearchRowContainer* _tmp19_;
			SearchRowContainer* _tmp20_;
			_sc_index = _sc_index + 1;
			_tmp14_ = _sc_index;
			_tmp15_ = _sc_size;
			if (!(_tmp14_ < _tmp15_)) {
				break;
			}
			_tmp16_ = _sc_list;
			_tmp17_ = gee_list_get (_tmp16_, _sc_index);
			sc = (SearchCondition*) _tmp17_;
			_tmp18_ = sc;
			_tmp19_ = search_row_container_new_edit_existing (_tmp18_);
			_tmp20_ = _tmp19_;
			saved_search_dialog_add_row (self, _tmp20_);
			_g_object_unref0 (_tmp20_);
			_search_condition_unref0 (sc);
		}
		_g_object_unref0 (_sc_list);
	}
	_tmp21_ = self->priv->row_list;
	_tmp22_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp21_);
	_tmp23_ = _tmp22_;
	if (_tmp23_ == 1) {
		GeeArrayList* _tmp24_;
		gpointer _tmp25_;
		SearchRowContainer* _tmp26_;
		_tmp24_ = self->priv->row_list;
		_tmp25_ = gee_abstract_list_get ((GeeAbstractList*) _tmp24_, 0);
		_tmp26_ = (SearchRowContainer*) _tmp25_;
		search_row_container_allow_removal (_tmp26_, FALSE);
		_g_object_unref0 (_tmp26_);
	}
	saved_search_dialog_set_valid (self, TRUE);
	_g_object_unref0 (close_button);
	return self;
}

SavedSearchDialog*
saved_search_dialog_new_edit_existing (SavedSearch* saved_search)
{
	return saved_search_dialog_construct_edit_existing (TYPE_SAVED_SEARCH_DIALOG, saved_search);
}

void
saved_search_dialog_show (SavedSearchDialog* self)
{
	GraniteDialog* _tmp0_;
	GraniteDialog* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->dialog;
	gtk_dialog_run ((GtkDialog*) _tmp0_);
	_tmp1_ = self->priv->dialog;
	gtk_widget_destroy ((GtkWidget*) _tmp1_);
}

static gboolean
saved_search_dialog_on_add_criteria (SavedSearchDialog* self,
                                     GdkEventButton* event)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (event != NULL, FALSE);
	saved_search_dialog_add_text_search (self);
	result = FALSE;
	return result;
}

static void
saved_search_dialog_add_text_search (SavedSearchDialog* self)
{
	SearchRowContainer* text = NULL;
	SearchRowContainer* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = search_row_container_new ();
	text = _tmp0_;
	saved_search_dialog_add_row (self, text);
	_g_object_unref0 (text);
}

static void
_saved_search_dialog_on_remove_row_search_row_container_remove (SearchRowContainer* _sender,
                                                                SearchRowContainer* this_row,
                                                                gpointer self)
{
	saved_search_dialog_on_remove_row ((SavedSearchDialog*) self, this_row);
}

static void
_saved_search_dialog_on_row_changed_search_row_container_changed (SearchRowContainer* _sender,
                                                                  SearchRowContainer* this_row,
                                                                  gpointer self)
{
	saved_search_dialog_on_row_changed ((SavedSearchDialog*) self, this_row);
}

static void
saved_search_dialog_add_row (SavedSearchDialog* self,
                             SearchRowContainer* row)
{
	GeeArrayList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	GtkGrid* _tmp6_;
	GtkWidget* _tmp7_;
	GtkWidget* _tmp8_;
	GeeArrayList* _tmp9_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (row != NULL);
	_tmp0_ = self->priv->row_list;
	_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_ == 1) {
		GeeArrayList* _tmp3_;
		gpointer _tmp4_;
		SearchRowContainer* _tmp5_;
		_tmp3_ = self->priv->row_list;
		_tmp4_ = gee_abstract_list_get ((GeeAbstractList*) _tmp3_, 0);
		_tmp5_ = (SearchRowContainer*) _tmp4_;
		search_row_container_allow_removal (_tmp5_, TRUE);
		_g_object_unref0 (_tmp5_);
	}
	_tmp6_ = self->priv->row_box;
	_tmp7_ = search_row_container_get_widget (row);
	_tmp8_ = _tmp7_;
	gtk_container_add ((GtkContainer*) _tmp6_, _tmp8_);
	_g_object_unref0 (_tmp8_);
	_tmp9_ = self->priv->row_list;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp9_, row);
	g_signal_connect_object (row, "remove", (GCallback) _saved_search_dialog_on_remove_row_search_row_container_remove, self, 0);
	g_signal_connect_object (row, "changed", (GCallback) _saved_search_dialog_on_row_changed_search_row_container_changed, self, 0);
	saved_search_dialog_set_valid (self, search_row_container_is_complete (row));
}

static void
saved_search_dialog_on_remove_row (SavedSearchDialog* self,
                                   SearchRowContainer* row)
{
	guint _tmp0_;
	guint _tmp1_;
	GtkGrid* _tmp2_;
	GtkWidget* _tmp3_;
	GtkWidget* _tmp4_;
	GeeArrayList* _tmp5_;
	GeeArrayList* _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (row != NULL);
	g_signal_parse_name ("remove", TYPE_SEARCH_ROW_CONTAINER, &_tmp0_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (row, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp0_, 0, NULL, (GCallback) _saved_search_dialog_on_remove_row_search_row_container_remove, self);
	g_signal_parse_name ("changed", TYPE_SEARCH_ROW_CONTAINER, &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (row, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _saved_search_dialog_on_row_changed_search_row_container_changed, self);
	_tmp2_ = self->priv->row_box;
	_tmp3_ = search_row_container_get_widget (row);
	_tmp4_ = _tmp3_;
	gtk_container_remove ((GtkContainer*) _tmp2_, _tmp4_);
	_g_object_unref0 (_tmp4_);
	_tmp5_ = self->priv->row_list;
	gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp5_, row);
	_tmp6_ = self->priv->row_list;
	_tmp7_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp6_);
	_tmp8_ = _tmp7_;
	if (_tmp8_ == 1) {
		GeeArrayList* _tmp9_;
		gpointer _tmp10_;
		SearchRowContainer* _tmp11_;
		_tmp9_ = self->priv->row_list;
		_tmp10_ = gee_abstract_list_get ((GeeAbstractList*) _tmp9_, 0);
		_tmp11_ = (SearchRowContainer*) _tmp10_;
		search_row_container_allow_removal (_tmp11_, FALSE);
		_g_object_unref0 (_tmp11_);
	}
	saved_search_dialog_set_valid (self, TRUE);
}

static void
saved_search_dialog_on_response (SavedSearchDialog* self,
                                 gint response_id)
{
	g_return_if_fail (self != NULL);
	if (response_id == ((gint) GTK_RESPONSE_OK)) {
		gboolean _tmp0_ = FALSE;
		SavedSearchTable* _tmp1_;
		SavedSearchTable* _tmp2_;
		GtkEntry* _tmp3_;
		const gchar* _tmp4_;
		gboolean _tmp5_;
		GeeArrayList* conditions = NULL;
		GeeArrayList* _tmp19_;
		SearchOperator search_operator = 0;
		GtkComboBoxText* _tmp32_;
		SavedSearchTable* _tmp33_;
		SavedSearchTable* _tmp34_;
		GtkEntry* _tmp35_;
		const gchar* _tmp36_;
		GeeArrayList* _tmp37_;
		SavedSearch* _tmp38_;
		SavedSearch* _tmp39_;
		_tmp1_ = saved_search_table_get_instance ();
		_tmp2_ = _tmp1_;
		_tmp3_ = self->priv->search_title;
		_tmp4_ = gtk_entry_get_text (_tmp3_);
		_tmp5_ = saved_search_table_exists (_tmp2_, _tmp4_);
		_saved_search_table_unref0 (_tmp2_);
		if (_tmp5_) {
			gboolean _tmp6_ = FALSE;
			if (self->priv->edit_mode) {
				SavedSearch* _tmp7_;
				gchar* _tmp8_;
				gchar* _tmp9_;
				GtkEntry* _tmp10_;
				const gchar* _tmp11_;
				_tmp7_ = self->priv->previous_search;
				_tmp8_ = data_object_get_name ((DataObject*) _tmp7_);
				_tmp9_ = _tmp8_;
				_tmp10_ = self->priv->search_title;
				_tmp11_ = gtk_entry_get_text (_tmp10_);
				_tmp6_ = g_strcmp0 (_tmp9_, _tmp11_) == 0;
				_g_free0 (_tmp9_);
			} else {
				_tmp6_ = FALSE;
			}
			_tmp0_ = !_tmp6_;
		} else {
			_tmp0_ = FALSE;
		}
		if (_tmp0_) {
			GtkEntry* _tmp12_;
			const gchar* _tmp13_;
			gchar* _tmp14_;
			gchar* _tmp15_;
			_tmp12_ = self->priv->search_title;
			_tmp13_ = gtk_entry_get_text (_tmp12_);
			_tmp14_ = resources_rename_search_exists_message (_tmp13_);
			_tmp15_ = _tmp14_;
			app_window_error_message (_tmp15_, NULL, NULL);
			_g_free0 (_tmp15_);
			return;
		}
		if (self->priv->edit_mode) {
			SavedSearchTable* _tmp16_;
			SavedSearchTable* _tmp17_;
			SavedSearch* _tmp18_;
			_tmp16_ = saved_search_table_get_instance ();
			_tmp17_ = _tmp16_;
			_tmp18_ = self->priv->previous_search;
			saved_search_table_remove (_tmp17_, _tmp18_);
			_saved_search_table_unref0 (_tmp17_);
		}
		_tmp19_ = gee_array_list_new (TYPE_SEARCH_CONDITION, (GBoxedCopyFunc) search_condition_ref, (GDestroyNotify) search_condition_unref, NULL, NULL, NULL);
		conditions = _tmp19_;
		{
			GeeArrayList* _c_list = NULL;
			GeeArrayList* _tmp20_;
			gint _c_size = 0;
			GeeArrayList* _tmp21_;
			gint _tmp22_;
			gint _tmp23_;
			gint _c_index = 0;
			_tmp20_ = self->priv->row_list;
			_c_list = _tmp20_;
			_tmp21_ = _c_list;
			_tmp22_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp21_);
			_tmp23_ = _tmp22_;
			_c_size = _tmp23_;
			_c_index = -1;
			while (TRUE) {
				gint _tmp24_;
				gint _tmp25_;
				SearchRowContainer* c = NULL;
				GeeArrayList* _tmp26_;
				gpointer _tmp27_;
				GeeArrayList* _tmp28_;
				SearchRowContainer* _tmp29_;
				SearchCondition* _tmp30_;
				SearchCondition* _tmp31_;
				_c_index = _c_index + 1;
				_tmp24_ = _c_index;
				_tmp25_ = _c_size;
				if (!(_tmp24_ < _tmp25_)) {
					break;
				}
				_tmp26_ = _c_list;
				_tmp27_ = gee_abstract_list_get ((GeeAbstractList*) _tmp26_, _c_index);
				c = (SearchRowContainer*) _tmp27_;
				_tmp28_ = conditions;
				_tmp29_ = c;
				_tmp30_ = search_row_container_get_search_condition (_tmp29_);
				_tmp31_ = _tmp30_;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp28_, _tmp31_);
				_search_condition_unref0 (_tmp31_);
				_g_object_unref0 (c);
			}
		}
		_tmp32_ = self->priv->operator;
		search_operator = (SearchOperator) gtk_combo_box_get_active ((GtkComboBox*) _tmp32_);
		_tmp33_ = saved_search_table_get_instance ();
		_tmp34_ = _tmp33_;
		_tmp35_ = self->priv->search_title;
		_tmp36_ = gtk_entry_get_text (_tmp35_);
		_tmp37_ = conditions;
		_tmp38_ = saved_search_table_create (_tmp34_, _tmp36_, search_operator, _tmp37_);
		_tmp39_ = _tmp38_;
		_g_object_unref0 (_tmp39_);
		_saved_search_table_unref0 (_tmp34_);
		_g_object_unref0 (conditions);
	}
}

static void
saved_search_dialog_on_row_changed (SavedSearchDialog* self,
                                    SearchRowContainer* row)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (row != NULL);
	saved_search_dialog_set_valid (self, search_row_container_is_complete (row));
}

static void
saved_search_dialog_on_title_changed (SavedSearchDialog* self)
{
	g_return_if_fail (self != NULL);
	saved_search_dialog_set_valid (self, saved_search_dialog_is_title_valid (self));
}

static gchar*
string_chomp (const gchar* self)
{
	gchar* _result_ = NULL;
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	g_strchomp (_result_);
	result = _result_;
	return result;
}

static gboolean
saved_search_dialog_is_title_valid (SavedSearchDialog* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GtkEntry* _tmp8_;
	const gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	gboolean _tmp12_;
	SavedSearchTable* _tmp13_;
	SavedSearchTable* _tmp14_;
	GtkEntry* _tmp15_;
	const gchar* _tmp16_;
	gboolean _tmp17_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->priv->edit_mode) {
		SavedSearch* _tmp2_;
		_tmp2_ = self->priv->previous_search;
		_tmp1_ = _tmp2_ != NULL;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		SavedSearch* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		GtkEntry* _tmp6_;
		const gchar* _tmp7_;
		_tmp3_ = self->priv->previous_search;
		_tmp4_ = data_object_get_name ((DataObject*) _tmp3_);
		_tmp5_ = _tmp4_;
		_tmp6_ = self->priv->search_title;
		_tmp7_ = gtk_entry_get_text (_tmp6_);
		_tmp0_ = g_strcmp0 (_tmp5_, _tmp7_) == 0;
		_g_free0 (_tmp5_);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		result = TRUE;
		return result;
	}
	_tmp8_ = self->priv->search_title;
	_tmp9_ = gtk_entry_get_text (_tmp8_);
	_tmp10_ = string_chomp (_tmp9_);
	_tmp11_ = _tmp10_;
	_tmp12_ = g_strcmp0 (_tmp11_, "") == 0;
	_g_free0 (_tmp11_);
	if (_tmp12_) {
		result = FALSE;
		return result;
	}
	_tmp13_ = saved_search_table_get_instance ();
	_tmp14_ = _tmp13_;
	_tmp15_ = self->priv->search_title;
	_tmp16_ = gtk_entry_get_text (_tmp15_);
	_tmp17_ = saved_search_table_exists (_tmp14_, _tmp16_);
	_saved_search_table_unref0 (_tmp14_);
	if (_tmp17_) {
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}

static void
saved_search_dialog_set_valid (SavedSearchDialog* self,
                               gboolean v)
{
	GraniteDialog* _tmp13_;
	g_return_if_fail (self != NULL);
	if (!v) {
		self->priv->valid = FALSE;
	} else {
		if (v != self->priv->valid) {
			if (saved_search_dialog_is_title_valid (self)) {
				gint valid_rows = 0;
				GeeArrayList* _tmp10_;
				gint _tmp11_;
				gint _tmp12_;
				valid_rows = 0;
				{
					GeeArrayList* _c_list = NULL;
					GeeArrayList* _tmp0_;
					gint _c_size = 0;
					GeeArrayList* _tmp1_;
					gint _tmp2_;
					gint _tmp3_;
					gint _c_index = 0;
					_tmp0_ = self->priv->row_list;
					_c_list = _tmp0_;
					_tmp1_ = _c_list;
					_tmp2_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp1_);
					_tmp3_ = _tmp2_;
					_c_size = _tmp3_;
					_c_index = -1;
					while (TRUE) {
						gint _tmp4_;
						gint _tmp5_;
						SearchRowContainer* c = NULL;
						GeeArrayList* _tmp6_;
						gpointer _tmp7_;
						SearchRowContainer* _tmp8_;
						_c_index = _c_index + 1;
						_tmp4_ = _c_index;
						_tmp5_ = _c_size;
						if (!(_tmp4_ < _tmp5_)) {
							break;
						}
						_tmp6_ = _c_list;
						_tmp7_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, _c_index);
						c = (SearchRowContainer*) _tmp7_;
						_tmp8_ = c;
						if (search_row_container_is_complete (_tmp8_)) {
							gint _tmp9_;
							_tmp9_ = valid_rows;
							valid_rows = _tmp9_ + 1;
						}
						_g_object_unref0 (c);
					}
				}
				_tmp10_ = self->priv->row_list;
				_tmp11_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp10_);
				_tmp12_ = _tmp11_;
				self->priv->valid = valid_rows == _tmp12_;
			} else {
				self->priv->valid = FALSE;
			}
		}
	}
	_tmp13_ = self->priv->dialog;
	gtk_dialog_set_response_sensitive ((GtkDialog*) _tmp13_, (gint) GTK_RESPONSE_OK, self->priv->valid);
}

static gboolean
_saved_search_dialog_on_add_criteria_gtk_widget_button_press_event (GtkWidget* _sender,
                                                                    GdkEventButton* event,
                                                                    gpointer self)
{
	gboolean result;
	result = saved_search_dialog_on_add_criteria ((SavedSearchDialog*) self, event);
	return result;
}

static void
_saved_search_dialog_on_response_gtk_dialog_response (GtkDialog* _sender,
                                                      gint response_id,
                                                      gpointer self)
{
	saved_search_dialog_on_response ((SavedSearchDialog*) self, response_id);
}

static GObject *
saved_search_dialog_constructor (GType type,
                                 guint n_construct_properties,
                                 GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	SavedSearchDialog * self;
	GtkLabel* search_label = NULL;
	GtkLabel* _tmp0_;
	GtkEntry* _tmp1_;
	GtkEntry* _tmp2_;
	GtkEntry* _tmp3_;
	GtkEntry* _tmp4_;
	GtkLabel* match_label = NULL;
	GtkLabel* _tmp5_;
	GtkComboBoxText* _tmp6_;
	GtkComboBoxText* _tmp7_;
	GtkComboBoxText* _tmp8_;
	GtkComboBoxText* _tmp9_;
	GtkComboBoxText* _tmp10_;
	GtkLabel* match2_label = NULL;
	GtkLabel* _tmp11_;
	GtkLabel* _tmp12_;
	GtkLabel* _tmp13_;
	GtkButton* _tmp14_;
	GtkButton* _tmp15_;
	GtkButton* _tmp16_;
	GtkGrid* _tmp17_;
	GtkGrid* _tmp18_;
	GtkGrid* _tmp19_;
	GtkGrid* search_grid = NULL;
	GtkGrid* _tmp20_;
	GtkGrid* _tmp21_;
	GtkGrid* _tmp22_;
	GtkGrid* _tmp23_;
	GtkGrid* _tmp24_;
	GtkLabel* _tmp25_;
	GtkGrid* _tmp26_;
	GtkEntry* _tmp27_;
	GtkGrid* _tmp28_;
	GtkSeparator* _tmp29_;
	GtkSeparator* _tmp30_;
	GtkGrid* _tmp31_;
	GtkLabel* _tmp32_;
	GtkGrid* _tmp33_;
	GtkComboBoxText* _tmp34_;
	GtkGrid* _tmp35_;
	GtkLabel* _tmp36_;
	GtkGrid* _tmp37_;
	GtkButton* _tmp38_;
	GtkGrid* _tmp39_;
	GtkSeparator* _tmp40_;
	GtkSeparator* _tmp41_;
	GtkGrid* _tmp42_;
	GtkGrid* _tmp43_;
	GraniteDialog* _tmp44_;
	GraniteDialog* _tmp45_;
	GraniteDialog* _tmp46_;
	GraniteDialog* _tmp47_;
	AppWindow* _tmp48_;
	AppWindow* _tmp49_;
	GraniteDialog* _tmp50_;
	GraniteDialog* _tmp51_;
	GraniteDialog* _tmp52_;
	GtkBox* _tmp53_;
	GtkGrid* _tmp54_;
	GraniteDialog* _tmp55_;
	GraniteDialog* _tmp56_;
	GtkButton* _tmp57_;
	GtkButton* _tmp58_;
	parent_class = G_OBJECT_CLASS (saved_search_dialog_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SAVED_SEARCH_DIALOG, SavedSearchDialog);
	_tmp0_ = (GtkLabel*) gtk_label_new (_ ("Name:"));
	g_object_ref_sink (_tmp0_);
	search_label = _tmp0_;
	_tmp1_ = (GtkEntry*) gtk_entry_new ();
	g_object_ref_sink (_tmp1_);
	_g_object_unref0 (self->priv->search_title);
	self->priv->search_title = _tmp1_;
	_tmp2_ = self->priv->search_title;
	gtk_entry_set_activates_default (_tmp2_, TRUE);
	_tmp3_ = self->priv->search_title;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp3_, TRUE);
	_tmp4_ = self->priv->search_title;
	g_signal_connect_object ((GtkEditable*) _tmp4_, "changed", (GCallback) _saved_search_dialog_on_title_changed_gtk_editable_changed, self, 0);
	_tmp5_ = (GtkLabel*) gtk_label_new_with_mnemonic (_ ("_Match"));
	g_object_ref_sink (_tmp5_);
	match_label = _tmp5_;
	_tmp6_ = (GtkComboBoxText*) gtk_combo_box_text_new ();
	g_object_ref_sink (_tmp6_);
	_g_object_unref0 (self->priv->operator);
	self->priv->operator = _tmp6_;
	_tmp7_ = self->priv->operator;
	gtk_combo_box_text_append_text (_tmp7_, _ ("any"));
	_tmp8_ = self->priv->operator;
	gtk_combo_box_text_append_text (_tmp8_, _ ("all"));
	_tmp9_ = self->priv->operator;
	gtk_combo_box_text_append_text (_tmp9_, _ ("none"));
	_tmp10_ = self->priv->operator;
	gtk_combo_box_set_active ((GtkComboBox*) _tmp10_, 0);
	_tmp11_ = (GtkLabel*) gtk_label_new_with_mnemonic (_ ("of the following:"));
	g_object_ref_sink (_tmp11_);
	match2_label = _tmp11_;
	_tmp12_ = match2_label;
	gtk_widget_set_hexpand ((GtkWidget*) _tmp12_, TRUE);
	_tmp13_ = match2_label;
	gtk_label_set_xalign (_tmp13_, (gfloat) 0);
	_tmp14_ = (GtkButton*) gtk_button_new_from_icon_name ("list-add-symbolic", (GtkIconSize) GTK_ICON_SIZE_BUTTON);
	g_object_ref_sink (_tmp14_);
	_g_object_unref0 (self->priv->add_criteria);
	self->priv->add_criteria = _tmp14_;
	_tmp15_ = self->priv->add_criteria;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp15_, _ ("Add rule"));
	_tmp16_ = self->priv->add_criteria;
	g_signal_connect_object ((GtkWidget*) _tmp16_, "button-press-event", (GCallback) _saved_search_dialog_on_add_criteria_gtk_widget_button_press_event, self, 0);
	_tmp17_ = (GtkGrid*) gtk_grid_new ();
	g_object_ref_sink (_tmp17_);
	_g_object_unref0 (self->priv->row_box);
	self->priv->row_box = _tmp17_;
	_tmp18_ = self->priv->row_box;
	gtk_orientable_set_orientation ((GtkOrientable*) _tmp18_, GTK_ORIENTATION_VERTICAL);
	_tmp19_ = self->priv->row_box;
	gtk_grid_set_row_spacing (_tmp19_, 12);
	_tmp20_ = (GtkGrid*) gtk_grid_new ();
	g_object_ref_sink (_tmp20_);
	search_grid = _tmp20_;
	_tmp21_ = search_grid;
	g_object_set ((GtkWidget*) _tmp21_, "margin", 12, NULL);
	_tmp22_ = search_grid;
	gtk_grid_set_column_spacing (_tmp22_, 6);
	_tmp23_ = search_grid;
	gtk_grid_set_row_spacing (_tmp23_, 12);
	_tmp24_ = search_grid;
	_tmp25_ = search_label;
	gtk_grid_attach (_tmp24_, (GtkWidget*) _tmp25_, 0, 0, 1, 1);
	_tmp26_ = search_grid;
	_tmp27_ = self->priv->search_title;
	gtk_grid_attach (_tmp26_, (GtkWidget*) _tmp27_, 1, 0, 3, 1);
	_tmp28_ = search_grid;
	_tmp29_ = (GtkSeparator*) gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
	g_object_ref_sink (_tmp29_);
	_tmp30_ = _tmp29_;
	gtk_grid_attach (_tmp28_, (GtkWidget*) _tmp30_, 0, 1, 4, 1);
	_g_object_unref0 (_tmp30_);
	_tmp31_ = search_grid;
	_tmp32_ = match_label;
	gtk_grid_attach (_tmp31_, (GtkWidget*) _tmp32_, 0, 2, 1, 1);
	_tmp33_ = search_grid;
	_tmp34_ = self->priv->operator;
	gtk_grid_attach (_tmp33_, (GtkWidget*) _tmp34_, 1, 2, 1, 1);
	_tmp35_ = search_grid;
	_tmp36_ = match2_label;
	gtk_grid_attach (_tmp35_, (GtkWidget*) _tmp36_, 2, 2, 1, 1);
	_tmp37_ = search_grid;
	_tmp38_ = self->priv->add_criteria;
	gtk_grid_attach (_tmp37_, (GtkWidget*) _tmp38_, 3, 2, 1, 1);
	_tmp39_ = search_grid;
	_tmp40_ = (GtkSeparator*) gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
	g_object_ref_sink (_tmp40_);
	_tmp41_ = _tmp40_;
	gtk_grid_attach (_tmp39_, (GtkWidget*) _tmp41_, 0, 3, 4, 1);
	_g_object_unref0 (_tmp41_);
	_tmp42_ = search_grid;
	_tmp43_ = self->priv->row_box;
	gtk_grid_attach (_tmp42_, (GtkWidget*) _tmp43_, 0, 4, 4, 1);
	_tmp44_ = granite_dialog_new ();
	g_object_ref_sink (_tmp44_);
	_g_object_unref0 (self->priv->dialog);
	self->priv->dialog = _tmp44_;
	_tmp45_ = self->priv->dialog;
	gtk_window_set_title ((GtkWindow*) _tmp45_, _ ("Smart Album"));
	_tmp46_ = self->priv->dialog;
	gtk_window_set_modal ((GtkWindow*) _tmp46_, TRUE);
	_tmp47_ = self->priv->dialog;
	_tmp48_ = app_window_get_instance ();
	_tmp49_ = _tmp48_;
	gtk_window_set_transient_for ((GtkWindow*) _tmp47_, (GtkWindow*) _tmp49_);
	_g_object_unref0 (_tmp49_);
	_tmp50_ = self->priv->dialog;
	g_signal_connect_object ((GtkDialog*) _tmp50_, "response", (GCallback) _saved_search_dialog_on_response_gtk_dialog_response, self, 0);
	_tmp51_ = self->priv->dialog;
	gtk_window_set_deletable ((GtkWindow*) _tmp51_, FALSE);
	_tmp52_ = self->priv->dialog;
	_tmp53_ = gtk_dialog_get_content_area ((GtkDialog*) _tmp52_);
	_tmp54_ = search_grid;
	gtk_container_add ((GtkContainer*) _tmp53_, (GtkWidget*) _tmp54_);
	_tmp55_ = self->priv->dialog;
	gtk_dialog_set_default_response ((GtkDialog*) _tmp55_, (gint) GTK_RESPONSE_OK);
	_tmp56_ = self->priv->dialog;
	_tmp57_ = (GtkButton*) gtk_button_new_with_label (_ ("Cancel"));
	g_object_ref_sink (_tmp57_);
	_tmp58_ = _tmp57_;
	gtk_dialog_add_action_widget ((GtkDialog*) _tmp56_, (GtkWidget*) _tmp58_, (gint) GTK_RESPONSE_CANCEL);
	_g_object_unref0 (_tmp58_);
	_g_object_unref0 (search_grid);
	_g_object_unref0 (match2_label);
	_g_object_unref0 (match_label);
	_g_object_unref0 (search_label);
	return obj;
}

static void
saved_search_dialog_class_init (SavedSearchDialogClass * klass,
                                gpointer klass_data)
{
	saved_search_dialog_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &SavedSearchDialog_private_offset);
	G_OBJECT_CLASS (klass)->constructor = saved_search_dialog_constructor;
	G_OBJECT_CLASS (klass)->finalize = saved_search_dialog_finalize;
}

static void
saved_search_dialog_instance_init (SavedSearchDialog * self,
                                   gpointer klass)
{
	GeeArrayList* _tmp0_;
	self->priv = saved_search_dialog_get_instance_private (self);
	_tmp0_ = gee_array_list_new (TYPE_SEARCH_ROW_CONTAINER, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	self->priv->row_list = _tmp0_;
	self->priv->edit_mode = FALSE;
	self->priv->previous_search = NULL;
	self->priv->valid = FALSE;
}

static void
saved_search_dialog_finalize (GObject * obj)
{
	SavedSearchDialog * self;
	GtkEntry* _tmp0_;
	guint _tmp1_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SAVED_SEARCH_DIALOG, SavedSearchDialog);
	_tmp0_ = self->priv->search_title;
	g_signal_parse_name ("changed", gtk_editable_get_type (), &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((GtkEditable*) _tmp0_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _saved_search_dialog_on_title_changed_gtk_editable_changed, self);
	_g_object_unref0 (self->priv->dialog);
	_g_object_unref0 (self->priv->add_criteria);
	_g_object_unref0 (self->priv->operator);
	_g_object_unref0 (self->priv->row_box);
	_g_object_unref0 (self->priv->search_title);
	_g_object_unref0 (self->priv->row_list);
	_g_object_unref0 (self->priv->previous_search);
	G_OBJECT_CLASS (saved_search_dialog_parent_class)->finalize (obj);
}

static GType
saved_search_dialog_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (SavedSearchDialogClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) saved_search_dialog_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SavedSearchDialog), 0, (GInstanceInitFunc) saved_search_dialog_instance_init, NULL };
	GType saved_search_dialog_type_id;
	saved_search_dialog_type_id = g_type_register_static (G_TYPE_OBJECT, "SavedSearchDialog", &g_define_type_info, 0);
	SavedSearchDialog_private_offset = g_type_add_instance_private (saved_search_dialog_type_id, sizeof (SavedSearchDialogPrivate));
	return saved_search_dialog_type_id;
}

GType
saved_search_dialog_get_type (void)
{
	static volatile gsize saved_search_dialog_type_id__once = 0;
	if (g_once_init_enter (&saved_search_dialog_type_id__once)) {
		GType saved_search_dialog_type_id;
		saved_search_dialog_type_id = saved_search_dialog_get_type_once ();
		g_once_init_leave (&saved_search_dialog_type_id__once, saved_search_dialog_type_id);
	}
	return saved_search_dialog_type_id__once;
}

