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

/*
* Copyright (c) 2009-2013 Yorba Foundation
*
* 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
*/
/**/
/* DragAndDropHandler attaches signals to a Page to properly handle drag-and-drop requests for the*/
/* Page as a DnD Source.  (DnD Destination handling is handled by the appropriate AppWindow, i.e.*/
/* LibraryWindow and DirectWindow). Assumes the Page's ViewCollection holds MediaSources.*/
/**/

#include "io.elementary.photos.h"
#include <gtk/gtk.h>
#include <gio/gio.h>
#include <glib.h>
#include <gdk/gdk.h>
#include <glib-object.h>
#include <string.h>
#include <stdlib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gee.h>
#include <glib/gi18n-lib.h>
#include <gobject/gvaluecollector.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

#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef enum  {
	DRAG_AND_DROP_HANDLER_TARGET_TYPE_XDS,
	DRAG_AND_DROP_HANDLER_TARGET_TYPE_MEDIA_LIST
} DragAndDropHandlerTargetType;

#define DRAG_AND_DROP_HANDLER_TYPE_TARGET_TYPE (drag_and_drop_handler_target_type_get_type ())
#define _exporter_ui_unref0(var) ((var == NULL) ? NULL : (var = (exporter_ui_unref (var), NULL)))
#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))
#define _data_collection_unref0(var) ((var == NULL) ? NULL : (var = (data_collection_unref (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef struct _ParamSpecDragAndDropHandler ParamSpecDragAndDropHandler;
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _DragAndDropHandlerPrivate {
	Page* page;
	GtkWidget* event_source;
	GFile* drag_destination;
	ExporterUI* exporter;
};

struct _ParamSpecDragAndDropHandler {
	GParamSpec parent_instance;
};

static gint DragAndDropHandler_private_offset;
static gpointer drag_and_drop_handler_parent_class = NULL;
static GdkAtom* drag_and_drop_handler_xds_atom;
static GdkAtom* drag_and_drop_handler_xds_atom = NULL;
static GdkAtom* drag_and_drop_handler_text_atom;
static GdkAtom* drag_and_drop_handler_text_atom = NULL;
static guint8* drag_and_drop_handler_xds_fake_target;
static gint drag_and_drop_handler_xds_fake_target_length1;
static guint8* drag_and_drop_handler_xds_fake_target = NULL;
static gint drag_and_drop_handler_xds_fake_target_length1 = 0;
static gint _drag_and_drop_handler_xds_fake_target_size_ = 0;

static void drag_and_drop_handler_on_drag_begin (DragAndDropHandler* self,
                                          GdkDragContext* context);
static void _drag_and_drop_handler_on_drag_begin_gtk_widget_drag_begin (GtkWidget* _sender,
                                                                 GdkDragContext* context,
                                                                 gpointer self);
static void drag_and_drop_handler_on_drag_data_get (DragAndDropHandler* self,
                                             GdkDragContext* context,
                                             GtkSelectionData* selection_data,
                                             guint target_type,
                                             guint time);
static void _drag_and_drop_handler_on_drag_data_get_gtk_widget_drag_data_get (GtkWidget* _sender,
                                                                       GdkDragContext* context,
                                                                       GtkSelectionData* selection_data,
                                                                       guint info,
                                                                       guint time_,
                                                                       gpointer self);
static void drag_and_drop_handler_on_drag_end (DragAndDropHandler* self);
static void _drag_and_drop_handler_on_drag_end_gtk_widget_drag_end (GtkWidget* _sender,
                                                             GdkDragContext* context,
                                                             gpointer self);
static gboolean drag_and_drop_handler_on_drag_failed (DragAndDropHandler* self,
                                               GdkDragContext* context,
                                               GtkDragResult drag_result);
static gboolean _drag_and_drop_handler_on_drag_failed_gtk_widget_drag_failed (GtkWidget* _sender,
                                                                       GdkDragContext* context,
                                                                       GtkDragResult _result_,
                                                                       gpointer self);
static GType drag_and_drop_handler_target_type_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static GdkAtom* _gdk_atom_dup (GdkAtom* self);
static void drag_and_drop_handler_on_export_completed (DragAndDropHandler* self);
static void _drag_and_drop_handler_on_export_completed_exporter_completion_callback (Exporter* exporter,
                                                                              gboolean is_cancelled,
                                                                              gpointer self);
static void drag_and_drop_handler_finalize (DragAndDropHandler * obj);
static GType drag_and_drop_handler_get_type_once (void);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static const GtkTargetEntry DRAG_AND_DROP_HANDLER_SOURCE_TARGET_ENTRIES[2] = {{"XdndDirectSave0", (guint) GTK_TARGET_OTHER_APP, (guint) DRAG_AND_DROP_HANDLER_TARGET_TYPE_XDS}, {"shotwell/media-id-atom", (guint) GTK_TARGET_SAME_APP, (guint) DRAG_AND_DROP_HANDLER_TARGET_TYPE_MEDIA_LIST}};

static inline gpointer
drag_and_drop_handler_get_instance_private (DragAndDropHandler* self)
{
	return G_STRUCT_MEMBER_P (self, DragAndDropHandler_private_offset);
}

static void
_drag_and_drop_handler_on_drag_begin_gtk_widget_drag_begin (GtkWidget* _sender,
                                                            GdkDragContext* context,
                                                            gpointer self)
{
	drag_and_drop_handler_on_drag_begin ((DragAndDropHandler*) self, context);
}

static void
_drag_and_drop_handler_on_drag_data_get_gtk_widget_drag_data_get (GtkWidget* _sender,
                                                                  GdkDragContext* context,
                                                                  GtkSelectionData* selection_data,
                                                                  guint info,
                                                                  guint time_,
                                                                  gpointer self)
{
	drag_and_drop_handler_on_drag_data_get ((DragAndDropHandler*) self, context, selection_data, info, time_);
}

static void
_drag_and_drop_handler_on_drag_end_gtk_widget_drag_end (GtkWidget* _sender,
                                                        GdkDragContext* context,
                                                        gpointer self)
{
	drag_and_drop_handler_on_drag_end ((DragAndDropHandler*) self);
}

static gboolean
_drag_and_drop_handler_on_drag_failed_gtk_widget_drag_failed (GtkWidget* _sender,
                                                              GdkDragContext* context,
                                                              GtkDragResult _result_,
                                                              gpointer self)
{
	gboolean result;
	result = drag_and_drop_handler_on_drag_failed ((DragAndDropHandler*) self, context, _result_);
	return result;
}

static GType
drag_and_drop_handler_target_type_get_type_once (void)
{
	static const GEnumValue values[] = {{DRAG_AND_DROP_HANDLER_TARGET_TYPE_XDS, "DRAG_AND_DROP_HANDLER_TARGET_TYPE_XDS", "xds"}, {DRAG_AND_DROP_HANDLER_TARGET_TYPE_MEDIA_LIST, "DRAG_AND_DROP_HANDLER_TARGET_TYPE_MEDIA_LIST", "media-list"}, {0, NULL, NULL}};
	GType drag_and_drop_handler_target_type_type_id;
	drag_and_drop_handler_target_type_type_id = g_enum_register_static ("DragAndDropHandlerTargetType", values);
	return drag_and_drop_handler_target_type_type_id;
}

static GType
drag_and_drop_handler_target_type_get_type (void)
{
	static volatile gsize drag_and_drop_handler_target_type_type_id__once = 0;
	if (g_once_init_enter (&drag_and_drop_handler_target_type_type_id__once)) {
		GType drag_and_drop_handler_target_type_type_id;
		drag_and_drop_handler_target_type_type_id = drag_and_drop_handler_target_type_get_type_once ();
		g_once_init_leave (&drag_and_drop_handler_target_type_type_id__once, drag_and_drop_handler_target_type_type_id);
	}
	return drag_and_drop_handler_target_type_type_id__once;
}

static GdkAtom*
_gdk_atom_dup (GdkAtom* self)
{
	GdkAtom* dup;
	dup = g_new0 (GdkAtom, 1);
	memcpy (dup, self, sizeof (GdkAtom));
	return dup;
}

static gpointer
__gdk_atom_dup0 (gpointer self)
{
	return self ? _gdk_atom_dup (self) : NULL;
}

DragAndDropHandler*
drag_and_drop_handler_construct (GType object_type,
                                 Page* page)
{
	DragAndDropHandler* self = NULL;
	GtkWidget* _tmp0_;
	GtkWidget* _tmp1_;
	GtkWidget* _tmp2_;
	GdkAtom* _tmp3_;
	GdkAtom* _tmp6_;
	guint8* _tmp9_;
	gint _tmp9__length1;
	GtkWidget* _tmp12_;
	GtkWidget* _tmp13_;
	GtkWidget* _tmp14_;
	GtkWidget* _tmp15_;
	GtkWidget* _tmp16_;
	g_return_val_if_fail (page != NULL, NULL);
	self = (DragAndDropHandler*) g_type_create_instance (object_type);
	self->priv->page = page;
	_tmp0_ = page_get_event_source (page);
	_g_object_unref0 (self->priv->event_source);
	self->priv->event_source = _tmp0_;
	_tmp1_ = self->priv->event_source;
	_vala_assert (_tmp1_ != NULL, "event_source != null");
	_tmp2_ = self->priv->event_source;
	_vala_assert (gtk_widget_get_has_window (_tmp2_), "event_source.get_has_window ()");
	_tmp3_ = drag_and_drop_handler_xds_atom;
	if (_tmp3_ == NULL) {
		GdkAtom _tmp4_;
		GdkAtom* _tmp5_;
		_tmp4_ = gdk_atom_intern_static_string ("XdndDirectSave0");
		_tmp5_ = __gdk_atom_dup0 (&_tmp4_);
		_g_free0 (drag_and_drop_handler_xds_atom);
		drag_and_drop_handler_xds_atom = _tmp5_;
	}
	_tmp6_ = drag_and_drop_handler_text_atom;
	if (_tmp6_ == NULL) {
		GdkAtom _tmp7_;
		GdkAtom* _tmp8_;
		_tmp7_ = gdk_atom_intern_static_string ("text/plain");
		_tmp8_ = __gdk_atom_dup0 (&_tmp7_);
		_g_free0 (drag_and_drop_handler_text_atom);
		drag_and_drop_handler_text_atom = _tmp8_;
	}
	_tmp9_ = drag_and_drop_handler_xds_fake_target;
	_tmp9__length1 = drag_and_drop_handler_xds_fake_target_length1;
	if (_tmp9_ == NULL) {
		gint _tmp10_ = 0;
		guchar* _tmp11_;
		_tmp11_ = string_to_uchar_array ("shotwell.txt", &_tmp10_);
		drag_and_drop_handler_xds_fake_target = (g_free (drag_and_drop_handler_xds_fake_target), NULL);
		drag_and_drop_handler_xds_fake_target = _tmp11_;
		drag_and_drop_handler_xds_fake_target_length1 = _tmp10_;
		_drag_and_drop_handler_xds_fake_target_size_ = drag_and_drop_handler_xds_fake_target_length1;
	}
	_tmp12_ = self->priv->event_source;
	gtk_drag_source_set (_tmp12_, GDK_BUTTON1_MASK, DRAG_AND_DROP_HANDLER_SOURCE_TARGET_ENTRIES, (gint) G_N_ELEMENTS (DRAG_AND_DROP_HANDLER_SOURCE_TARGET_ENTRIES), GDK_ACTION_COPY);
	_tmp13_ = self->priv->event_source;
	g_signal_connect (_tmp13_, "drag-begin", (GCallback) _drag_and_drop_handler_on_drag_begin_gtk_widget_drag_begin, self);
	_tmp14_ = self->priv->event_source;
	g_signal_connect (_tmp14_, "drag-data-get", (GCallback) _drag_and_drop_handler_on_drag_data_get_gtk_widget_drag_data_get, self);
	_tmp15_ = self->priv->event_source;
	g_signal_connect (_tmp15_, "drag-end", (GCallback) _drag_and_drop_handler_on_drag_end_gtk_widget_drag_end, self);
	_tmp16_ = self->priv->event_source;
	g_signal_connect (_tmp16_, "drag-failed", (GCallback) _drag_and_drop_handler_on_drag_failed_gtk_widget_drag_failed, self);
	return self;
}

DragAndDropHandler*
drag_and_drop_handler_new (Page* page)
{
	return drag_and_drop_handler_construct (TYPE_DRAG_AND_DROP_HANDLER, page);
}

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

static void
drag_and_drop_handler_on_drag_begin (DragAndDropHandler* self,
                                     GdkDragContext* context)
{
	Page* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	Page* _tmp5_;
	ThumbnailSource* thumb = NULL;
	Page* _tmp10_;
	ViewCollection* _tmp11_;
	ViewCollection* _tmp12_;
	DataView* _tmp13_;
	DataView* _tmp14_;
	DataSource* _tmp15_;
	DataSource* _tmp16_;
	ThumbnailSource* _tmp17_;
	ThumbnailSource* _tmp18_;
	GdkWindow* _tmp28_;
	GdkAtom* _tmp29_;
	GdkAtom* _tmp30_;
	guint8* _tmp31_;
	gint _tmp31__length1;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (context != NULL);
	_tmp0_ = self->priv->page;
	_tmp1_ = page_get_page_name (_tmp0_);
	_tmp2_ = _tmp1_;
	g_debug ("DragAndDropHandler.vala:87: on_drag_begin (%s)", _tmp2_);
	_tmp5_ = self->priv->page;
	if (_tmp5_ == NULL) {
		_tmp4_ = TRUE;
	} else {
		Page* _tmp6_;
		ViewCollection* _tmp7_;
		ViewCollection* _tmp8_;
		_tmp6_ = self->priv->page;
		_tmp7_ = page_get_view (_tmp6_);
		_tmp8_ = _tmp7_;
		_tmp4_ = view_collection_get_selected_count (_tmp8_) == 0;
		_data_collection_unref0 (_tmp8_);
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		ExporterUI* _tmp9_;
		_tmp9_ = self->priv->exporter;
		_tmp3_ = _tmp9_ != NULL;
	}
	if (_tmp3_) {
		return;
	}
	_g_object_unref0 (self->priv->drag_destination);
	self->priv->drag_destination = NULL;
	_tmp10_ = self->priv->page;
	_tmp11_ = page_get_view (_tmp10_);
	_tmp12_ = _tmp11_;
	_tmp13_ = view_collection_get_selected_at (_tmp12_, 0);
	_tmp14_ = _tmp13_;
	_tmp15_ = data_view_get_source (_tmp14_);
	_tmp16_ = _tmp15_;
	_tmp17_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp16_, TYPE_THUMBNAIL_SOURCE, ThumbnailSource));
	_tmp18_ = _tmp17_;
	_g_object_unref0 (_tmp14_);
	_data_collection_unref0 (_tmp12_);
	thumb = _tmp18_;
	{
		GdkPixbuf* icon = NULL;
		ThumbnailSource* _tmp19_;
		GdkPixbuf* _tmp20_;
		GtkWidget* _tmp21_;
		GdkPixbuf* _tmp22_;
		_tmp19_ = thumb;
		_tmp20_ = thumbnail_source_get_thumbnail (_tmp19_, 128, &_inner_error0_);
		icon = _tmp20_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp21_ = self->priv->event_source;
		_tmp22_ = icon;
		gtk_drag_source_set_icon_pixbuf (_tmp21_, _tmp22_);
		_g_object_unref0 (icon);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* err = NULL;
		ThumbnailSource* _tmp23_;
		gchar* _tmp24_;
		gchar* _tmp25_;
		GError* _tmp26_;
		const gchar* _tmp27_;
		err = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp23_ = thumb;
		_tmp24_ = data_object_to_string ((DataObject*) _tmp23_);
		_tmp25_ = _tmp24_;
		_tmp26_ = err;
		_tmp27_ = _tmp26_->message;
		g_warning ("DragAndDropHandler.vala:101: Unable to fetch icon for drag-and-drop fr" \
"om %s: %s", _tmp25_, _tmp27_);
		_g_free0 (_tmp25_);
		_g_error_free0 (err);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (thumb);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_tmp28_ = gdk_drag_context_get_source_window (context);
	_tmp29_ = drag_and_drop_handler_xds_atom;
	_tmp30_ = drag_and_drop_handler_text_atom;
	_tmp31_ = drag_and_drop_handler_xds_fake_target;
	_tmp31__length1 = drag_and_drop_handler_xds_fake_target_length1;
	gdk_property_change (_tmp28_, *_tmp29_, *_tmp30_, 8, GDK_PROP_MODE_REPLACE, (const guchar*) _tmp31_, 1);
	_g_object_unref0 (thumb);
}

static void
drag_and_drop_handler_on_drag_data_get (DragAndDropHandler* self,
                                        GdkDragContext* context,
                                        GtkSelectionData* selection_data,
                                        guint target_type,
                                        guint time)
{
	Page* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gboolean _tmp3_ = FALSE;
	Page* _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (context != NULL);
	g_return_if_fail (selection_data != NULL);
	_tmp0_ = self->priv->page;
	_tmp1_ = page_get_page_name (_tmp0_);
	_tmp2_ = _tmp1_;
	g_debug ("DragAndDropHandler.vala:117: on_drag_data_get (%s)", _tmp2_);
	_tmp4_ = self->priv->page;
	if (_tmp4_ == NULL) {
		_tmp3_ = TRUE;
	} else {
		Page* _tmp5_;
		ViewCollection* _tmp6_;
		ViewCollection* _tmp7_;
		_tmp5_ = self->priv->page;
		_tmp6_ = page_get_view (_tmp5_);
		_tmp7_ = _tmp6_;
		_tmp3_ = view_collection_get_selected_count (_tmp7_) == 0;
		_data_collection_unref0 (_tmp7_);
	}
	if (_tmp3_) {
		return;
	}
	switch (target_type) {
		case DRAG_AND_DROP_HANDLER_TARGET_TYPE_XDS:
		{
			guchar* data = NULL;
			guchar* _tmp8_;
			gint data_length1;
			gint _data_size_;
			GdkAtom actual_type = (GdkAtom) 0U;
			gint actual_format = 0;
			gboolean fetched = FALSE;
			GdkWindow* _tmp9_;
			GdkAtom* _tmp10_;
			GdkAtom* _tmp11_;
			guchar* _tmp12_;
			gint _tmp12__length1;
			GdkAtom _tmp13_ = (GdkAtom) 0U;
			gint _tmp14_ = 0;
			guint8* _tmp15_ = NULL;
			gint _tmp16_ = 0;
			gboolean _tmp17_;
			gboolean _tmp18_ = FALSE;
			gboolean _tmp19_ = FALSE;
			gchar* _tmp28_ = NULL;
			GFile* _tmp29_;
			Page* _tmp33_;
			const gchar* _tmp34_;
			const gchar* _tmp35_;
			const gchar* _tmp36_ = NULL;
			GFile* _tmp37_;
			GdkAtom* _tmp38_;
			gint _tmp39_ = 0;
			guchar* _tmp40_;
			guchar* _tmp41_;
			gint _tmp41__length1;
			_tmp8_ = g_new0 (guchar, 4096);
			data = _tmp8_;
			data_length1 = 4096;
			_data_size_ = data_length1;
			actual_format = 0;
			_tmp9_ = gdk_drag_context_get_source_window (context);
			_tmp10_ = drag_and_drop_handler_xds_atom;
			_tmp11_ = drag_and_drop_handler_text_atom;
			_tmp12_ = data;
			_tmp12__length1 = data_length1;
			_tmp17_ = gdk_property_get (_tmp9_, *_tmp10_, *_tmp11_, (gulong) 0, (gulong) _tmp12__length1, 0, &_tmp13_, &_tmp14_, &_tmp16_, &_tmp15_);
			actual_type = _tmp13_;
			actual_format = _tmp14_;
			data = (g_free (data), NULL);
			data = _tmp15_;
			data_length1 = _tmp16_;
			_data_size_ = data_length1;
			fetched = _tmp17_;
			if (fetched) {
				guchar* _tmp20_;
				gint _tmp20__length1;
				_tmp20_ = data;
				_tmp20__length1 = data_length1;
				_tmp19_ = _tmp20_ != NULL;
			} else {
				_tmp19_ = FALSE;
			}
			if (_tmp19_) {
				guchar* _tmp21_;
				gint _tmp21__length1;
				_tmp21_ = data;
				_tmp21__length1 = data_length1;
				_tmp18_ = _tmp21__length1 > 0;
			} else {
				_tmp18_ = FALSE;
			}
			if (_tmp18_) {
				guchar* _tmp22_;
				gint _tmp22__length1;
				gchar* _tmp23_;
				gchar* _tmp24_;
				GFile* _tmp25_;
				GFile* _tmp26_;
				GFile* _tmp27_;
				_tmp22_ = data;
				_tmp22__length1 = data_length1;
				_tmp23_ = uchar_array_to_string (_tmp22_, (gint) _tmp22__length1, -1);
				_tmp24_ = _tmp23_;
				_tmp25_ = g_file_new_for_uri (_tmp24_);
				_tmp26_ = _tmp25_;
				_tmp27_ = g_file_get_parent (_tmp26_);
				_g_object_unref0 (self->priv->drag_destination);
				self->priv->drag_destination = _tmp27_;
				_g_object_unref0 (_tmp26_);
				_g_free0 (_tmp24_);
			}
			_tmp29_ = self->priv->drag_destination;
			if (_tmp29_ != NULL) {
				GFile* _tmp30_;
				gchar* _tmp31_;
				_tmp30_ = self->priv->drag_destination;
				_tmp31_ = g_file_get_path (_tmp30_);
				_g_free0 (_tmp28_);
				_tmp28_ = _tmp31_;
			} else {
				gchar* _tmp32_;
				_tmp32_ = g_strdup ("(no path)");
				_g_free0 (_tmp28_);
				_tmp28_ = _tmp32_;
			}
			_tmp33_ = self->priv->page;
			_tmp34_ = page_get_page_name (_tmp33_);
			_tmp35_ = _tmp34_;
			g_debug ("DragAndDropHandler.vala:136: on_drag_data_get (%s): %s", _tmp35_, _tmp28_);
			_tmp37_ = self->priv->drag_destination;
			if (_tmp37_ != NULL) {
				_tmp36_ = "S";
			} else {
				_tmp36_ = "E";
			}
			_tmp38_ = drag_and_drop_handler_xds_atom;
			_tmp40_ = string_to_uchar_array (_tmp36_, &_tmp39_);
			_tmp41_ = _tmp40_;
			_tmp41__length1 = _tmp39_;
			gtk_selection_data_set (selection_data, *_tmp38_, 8, _tmp41_, (gint) _tmp39_);
			_tmp41_ = (g_free (_tmp41_), NULL);
			_g_free0 (_tmp28_);
			data = (g_free (data), NULL);
			break;
		}
		case DRAG_AND_DROP_HANDLER_TARGET_TYPE_MEDIA_LIST:
		{
			GeeCollection* sources = NULL;
			Page* _tmp42_;
			ViewCollection* _tmp43_;
			ViewCollection* _tmp44_;
			GeeList* _tmp45_;
			GeeCollection* _tmp46_;
			GeeCollection* _tmp47_;
			gint _tmp48_ = 0;
			guchar* _tmp49_;
			guchar* _tmp50_;
			gint _tmp50__length1;
			_tmp42_ = self->priv->page;
			_tmp43_ = page_get_view (_tmp42_);
			_tmp44_ = _tmp43_;
			_tmp45_ = view_collection_get_selected_sources (_tmp44_);
			_tmp46_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp45_, GEE_TYPE_COLLECTION, GeeCollection);
			_data_collection_unref0 (_tmp44_);
			sources = _tmp46_;
			_tmp47_ = sources;
			_tmp49_ = serialize_media_sources (_tmp47_, &_tmp48_);
			_tmp50_ = _tmp49_;
			_tmp50__length1 = _tmp48_;
			gtk_selection_data_set (selection_data, gdk_atom_intern_static_string ("SourceIDAtom"), (gint) sizeof (GdkAtom), _tmp50_, (gint) _tmp48_);
			_tmp50_ = (g_free (_tmp50_), NULL);
			_g_object_unref0 (sources);
			break;
		}
		default:
		{
			Page* _tmp51_;
			const gchar* _tmp52_;
			const gchar* _tmp53_;
			_tmp51_ = self->priv->page;
			_tmp52_ = page_get_page_name (_tmp51_);
			_tmp53_ = _tmp52_;
			g_warning ("DragAndDropHandler.vala:155: on_drag_data_get (%s): unknown target typ" \
"e %u", _tmp53_, target_type);
			break;
		}
	}
}

static void
_drag_and_drop_handler_on_export_completed_exporter_completion_callback (Exporter* exporter,
                                                                         gboolean is_cancelled,
                                                                         gpointer self)
{
	drag_and_drop_handler_on_export_completed ((DragAndDropHandler*) self);
}

static void
drag_and_drop_handler_on_drag_end (DragAndDropHandler* self)
{
	Page* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	Page* _tmp6_;
	GFile* _tmp12_;
	gchar* _tmp13_;
	gchar* _tmp14_;
	GFile* _tmp15_;
	gchar* _tmp16_;
	gchar* _tmp17_;
	gboolean _tmp18_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->page;
	_tmp1_ = page_get_page_name (_tmp0_);
	_tmp2_ = _tmp1_;
	g_debug ("DragAndDropHandler.vala:162: on_drag_end (%s)", _tmp2_);
	_tmp6_ = self->priv->page;
	if (_tmp6_ == NULL) {
		_tmp5_ = TRUE;
	} else {
		Page* _tmp7_;
		ViewCollection* _tmp8_;
		ViewCollection* _tmp9_;
		_tmp7_ = self->priv->page;
		_tmp8_ = page_get_view (_tmp7_);
		_tmp9_ = _tmp8_;
		_tmp5_ = view_collection_get_selected_count (_tmp9_) == 0;
		_data_collection_unref0 (_tmp9_);
	}
	if (_tmp5_) {
		_tmp4_ = TRUE;
	} else {
		GFile* _tmp10_;
		_tmp10_ = self->priv->drag_destination;
		_tmp4_ = _tmp10_ == NULL;
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		ExporterUI* _tmp11_;
		_tmp11_ = self->priv->exporter;
		_tmp3_ = _tmp11_ != NULL;
	}
	if (_tmp3_) {
		return;
	}
	_tmp12_ = self->priv->drag_destination;
	_tmp13_ = g_file_get_path (_tmp12_);
	_tmp14_ = _tmp13_;
	g_debug ("DragAndDropHandler.vala:169: Exporting to %s", _tmp14_);
	_g_free0 (_tmp14_);
	_tmp15_ = self->priv->drag_destination;
	_tmp16_ = g_file_get_path (_tmp15_);
	_tmp17_ = _tmp16_;
	_tmp18_ = _tmp17_ != NULL;
	_g_free0 (_tmp17_);
	if (_tmp18_) {
		Page* _tmp19_;
		ViewCollection* _tmp20_;
		ViewCollection* _tmp21_;
		GeeList* _tmp22_;
		GeeCollection* _tmp23_;
		GFile* _tmp24_;
		Scaling _tmp25_ = {0};
		ExportFormatParameters _tmp26_ = {0};
		Exporter* _tmp27_;
		Exporter* _tmp28_;
		ExporterUI* _tmp29_;
		ExporterUI* _tmp30_;
		_tmp19_ = self->priv->page;
		_tmp20_ = page_get_view (_tmp19_);
		_tmp21_ = _tmp20_;
		_tmp22_ = view_collection_get_selected_sources (_tmp21_);
		_tmp23_ = G_TYPE_CHECK_INSTANCE_CAST (_tmp22_, GEE_TYPE_COLLECTION, GeeCollection);
		_tmp24_ = self->priv->drag_destination;
		scaling_for_original (&_tmp25_);
		export_format_parameters_current (&_tmp26_);
		_tmp27_ = exporter_new (_tmp23_, _tmp24_, &_tmp25_, &_tmp26_, FALSE);
		_tmp28_ = _tmp27_;
		_tmp29_ = exporter_ui_new (_tmp28_);
		_exporter_ui_unref0 (self->priv->exporter);
		self->priv->exporter = _tmp29_;
		_g_object_unref0 (_tmp28_);
		_g_object_unref0 (_tmp23_);
		_data_collection_unref0 (_tmp21_);
		_tmp30_ = self->priv->exporter;
		exporter_ui_export (_tmp30_, _drag_and_drop_handler_on_export_completed_exporter_completion_callback, self);
	} else {
		app_window_error_message (_ ("Photos cannot be exported to this directory."), NULL, NULL);
	}
	_g_object_unref0 (self->priv->drag_destination);
	self->priv->drag_destination = NULL;
}

static gboolean
drag_and_drop_handler_on_drag_failed (DragAndDropHandler* self,
                                      GdkDragContext* context,
                                      GtkDragResult drag_result)
{
	Page* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	Page* _tmp3_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (context != NULL, FALSE);
	_tmp0_ = self->priv->page;
	_tmp1_ = page_get_page_name (_tmp0_);
	_tmp2_ = _tmp1_;
	g_debug ("DragAndDropHandler.vala:187: on_drag_failed (%s): %d", _tmp2_, (gint) drag_result);
	_tmp3_ = self->priv->page;
	if (_tmp3_ == NULL) {
		result = FALSE;
		return result;
	}
	_g_object_unref0 (self->priv->drag_destination);
	self->priv->drag_destination = NULL;
	result = FALSE;
	return result;
}

static void
drag_and_drop_handler_on_export_completed (DragAndDropHandler* self)
{
	g_return_if_fail (self != NULL);
	_exporter_ui_unref0 (self->priv->exporter);
	self->priv->exporter = NULL;
}

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

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

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

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

static gchar*
value_drag_and_drop_handler_collect_value (GValue* value,
                                           guint n_collect_values,
                                           GTypeCValue* collect_values,
                                           guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		DragAndDropHandler * 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 = drag_and_drop_handler_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
value_drag_and_drop_handler_lcopy_value (const GValue* value,
                                         guint n_collect_values,
                                         GTypeCValue* collect_values,
                                         guint collect_flags)
{
	DragAndDropHandler ** 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 = drag_and_drop_handler_ref (value->data[0].v_pointer);
	}
	return NULL;
}

GParamSpec*
param_spec_drag_and_drop_handler (const gchar* name,
                                  const gchar* nick,
                                  const gchar* blurb,
                                  GType object_type,
                                  GParamFlags flags)
{
	ParamSpecDragAndDropHandler* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_DRAG_AND_DROP_HANDLER), 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);
}

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

void
value_set_drag_and_drop_handler (GValue* value,
                                 gpointer v_object)
{
	DragAndDropHandler * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_DRAG_AND_DROP_HANDLER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_DRAG_AND_DROP_HANDLER));
		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;
		drag_and_drop_handler_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		drag_and_drop_handler_unref (old);
	}
}

void
value_take_drag_and_drop_handler (GValue* value,
                                  gpointer v_object)
{
	DragAndDropHandler * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_DRAG_AND_DROP_HANDLER));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_DRAG_AND_DROP_HANDLER));
		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) {
		drag_and_drop_handler_unref (old);
	}
}

static void
drag_and_drop_handler_class_init (DragAndDropHandlerClass * klass,
                                  gpointer klass_data)
{
	drag_and_drop_handler_parent_class = g_type_class_peek_parent (klass);
	((DragAndDropHandlerClass *) klass)->finalize = drag_and_drop_handler_finalize;
	g_type_class_adjust_private_offset (klass, &DragAndDropHandler_private_offset);
}

static void
drag_and_drop_handler_instance_init (DragAndDropHandler * self,
                                     gpointer klass)
{
	self->priv = drag_and_drop_handler_get_instance_private (self);
	self->priv->drag_destination = NULL;
	self->priv->exporter = NULL;
	self->ref_count = 1;
}

static void
drag_and_drop_handler_finalize (DragAndDropHandler * obj)
{
	DragAndDropHandler * self;
	GtkWidget* _tmp0_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_DRAG_AND_DROP_HANDLER, DragAndDropHandler);
	g_signal_handlers_destroy (self);
	_tmp0_ = self->priv->event_source;
	if (_tmp0_ != NULL) {
		GtkWidget* _tmp1_;
		guint _tmp2_;
		GtkWidget* _tmp3_;
		guint _tmp4_;
		GtkWidget* _tmp5_;
		guint _tmp6_;
		GtkWidget* _tmp7_;
		guint _tmp8_;
		_tmp1_ = self->priv->event_source;
		g_signal_parse_name ("drag-begin", gtk_widget_get_type (), &_tmp2_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp1_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp2_, 0, NULL, (GCallback) _drag_and_drop_handler_on_drag_begin_gtk_widget_drag_begin, self);
		_tmp3_ = self->priv->event_source;
		g_signal_parse_name ("drag-data-get", gtk_widget_get_type (), &_tmp4_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp3_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp4_, 0, NULL, (GCallback) _drag_and_drop_handler_on_drag_data_get_gtk_widget_drag_data_get, self);
		_tmp5_ = self->priv->event_source;
		g_signal_parse_name ("drag-end", gtk_widget_get_type (), &_tmp6_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp5_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp6_, 0, NULL, (GCallback) _drag_and_drop_handler_on_drag_end_gtk_widget_drag_end, self);
		_tmp7_ = self->priv->event_source;
		g_signal_parse_name ("drag-failed", gtk_widget_get_type (), &_tmp8_, NULL, FALSE);
		g_signal_handlers_disconnect_matched (_tmp7_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp8_, 0, NULL, (GCallback) _drag_and_drop_handler_on_drag_failed_gtk_widget_drag_failed, self);
	}
	self->priv->page = NULL;
	_g_object_unref0 (self->priv->event_source);
	self->priv->event_source = NULL;
	_g_object_unref0 (self->priv->event_source);
	_g_object_unref0 (self->priv->drag_destination);
	_exporter_ui_unref0 (self->priv->exporter);
}

static GType
drag_and_drop_handler_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { value_drag_and_drop_handler_init, value_drag_and_drop_handler_free_value, value_drag_and_drop_handler_copy_value, value_drag_and_drop_handler_peek_pointer, "p", value_drag_and_drop_handler_collect_value, "p", value_drag_and_drop_handler_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (DragAndDropHandlerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) drag_and_drop_handler_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DragAndDropHandler), 0, (GInstanceInitFunc) drag_and_drop_handler_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 drag_and_drop_handler_type_id;
	drag_and_drop_handler_type_id = g_type_register_fundamental (g_type_fundamental_next (), "DragAndDropHandler", &g_define_type_info, &g_define_type_fundamental_info, 0);
	DragAndDropHandler_private_offset = g_type_add_instance_private (drag_and_drop_handler_type_id, sizeof (DragAndDropHandlerPrivate));
	return drag_and_drop_handler_type_id;
}

GType
drag_and_drop_handler_get_type (void)
{
	static volatile gsize drag_and_drop_handler_type_id__once = 0;
	if (g_once_init_enter (&drag_and_drop_handler_type_id__once)) {
		GType drag_and_drop_handler_type_id;
		drag_and_drop_handler_type_id = drag_and_drop_handler_get_type_once ();
		g_once_init_leave (&drag_and_drop_handler_type_id__once, drag_and_drop_handler_type_id);
	}
	return drag_and_drop_handler_type_id__once;
}

gpointer
drag_and_drop_handler_ref (gpointer instance)
{
	DragAndDropHandler * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

void
drag_and_drop_handler_unref (gpointer instance)
{
	DragAndDropHandler * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		DRAG_AND_DROP_HANDLER_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

