<commit_before>/*
 * Copyright (c) 2003 by the gtk2-perl team (see the file AUTHORS)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 * Boston, MA  02111-1307  USA.
 *
 * $Header$
 */
#include "gtk2perl.h"

/*
 * whee!  since the Callback1 form does not have data at the end and all that
 * fun stuff, so we can't use the spiffy generic GPerlCallback marshaller i
 * just wrote, or even the GPerlClosure stuff that would be rather useful.
 */
static void
gtk2perl_item_factory_item_activate (GtkWidget * widget,
                                     GPerlCallback * callback)
{
	guint callback_action;
	dSP; 

	if (callback->func == NULL || callback->func == &PL_sv_undef)
		return;

	callback_action = (guint)
		g_object_get_data (G_OBJECT (widget), "_callback_action");

	ENTER;
	SAVETMPS;

	PUSHMARK (SP);
	EXTEND (SP, 3);
	PUSHs (sv_2mortal (newSVsv (callback->data
	                            ? callback->data
	                            : &PL_sv_undef)));
	PUSHs (sv_2mortal (newSViv (callback_action)));
	PUSHs (sv_2mortal (newSVGtkWidget (widget)));
	PUTBACK;

	call_sv (callback->func, G_DISCARD);

	FREETMPS;
	LEAVE;
}


MODULE = Gtk2::ItemFactory	PACKAGE = Gtk2::ItemFactory	PREFIX = gtk_item_factory_


##  GtkItemFactory* gtk_item_factory_new (GType container_type, const gchar *path, GtkAccelGroup *accel_group) 
GtkItemFactory*
gtk_item_factory_new (class, container_type_package, path, accel_group)
	SV * class
	char * container_type_package
	const gchar *path
	GtkAccelGroup_ornull *accel_group
    PREINIT:
	GType container_type;
    CODE:
	container_type = gperl_type_from_package (container_type_package);
	RETVAL = gtk_item_factory_new (container_type, path, accel_group);
    OUTPUT:
	RETVAL

### deprecated
##  void gtk_item_factory_add_foreign (GtkWidget *accel_widget, const gchar *full_path, GtkAccelGroup *accel_group, guint keyval, GdkModifierType modifiers) 

GtkItemFactory_ornull*
gtk_item_factory_from_widget (class, widget)
	SV * class
	GtkWidget *widget
    C_ARGS:
	widget

const gchar*
gtk_item_factory_path_from_widget (class, widget)
	SV * class
	GtkWidget *widget
    C_ARGS:
	widget

GtkWidget_ornull*
gtk_item_factory_get_item (ifactory, path)
	GtkItemFactory *ifactory
	const gchar *path

GtkWidget_ornull*
gtk_item_factory_get_widget (ifactory, path)
	GtkItemFactory *ifactory
	const gchar *path

GtkWidget_ornull*
gtk_item_factory_get_widget_by_action (ifactory, action)
	GtkItemFactory *ifactory
	guint action

GtkWidget_ornull*
gtk_item_factory_get_item_by_action (ifactory, action)
	GtkItemFactory *ifactory
	guint action


### this is called by Gtk2::IconFactory::create_item, which is implemented
### in perl and mangles the arguments for us.
void
_create_item (ifactory, path, accel, action, type, extra, clean_path, callback_sv, callback_data)
	GtkItemFactory * ifactory
	gchar * path
	gchar * accel
	gint action
	gchar * type
	SV * extra
	char * clean_path
	SV * callback_sv
	SV * callback_data
    PREINIT:
	GtkItemFactoryEntry entry = {0, };
    CODE:
	entry.path = path;
	entry.accelerator = accel;
	entry.callback = NULL;
	entry.callback_action = action;
	entry.item_type = type;
	entry.extra_data = SvPOK (extra) ? SvGChar (extra) : NULL; 

	gtk_item_factory_create_item (ifactory, &entry, NULL, 1);
	if (callback_sv && callback_sv != &PL_sv_undef) {
		/* set up the callback.  we need to pass two bits of data.  
		 * rather than add yet another ugly hack to GPerlClosure, 
		 * we'll use a GPerlCallback. */
		GPerlCallback * callback;
		GtkWidget * widget;

		widget = gtk_item_factory_get_item (ifactory, clean_path);

		/* we'll be marshalling this ourselves, so don't worry about
		 * the argtypes array. */
		callback = gperl_callback_new (callback_sv, callback_data,
		                               0, NULL, 0);

		g_object_set_data (G_OBJECT (widget), "_callback_action", 
		                   (gpointer)action);

		g_signal_connect_data (G_OBJECT (widget), "activate",
		             G_CALLBACK (gtk2perl_item_factory_item_activate),
			     callback,
			     (GClosureNotify)gperl_callback_destroy,
		             0);
	}


###### implemented in perl, see Gtk2.pm
#####  void gtk_item_factory_create_items (GtkItemFactory *ifactory, guint n_entries, GtkItemFactoryEntry *entries, gpointer callback_data) 

void
gtk_item_factory_delete_item (ifactory, path)
	GtkItemFactory *ifactory
	const gchar *path

#### FIXME how to handle GtkItemFactoryEntry?:
###  void gtk_item_factory_delete_entry (GtkItemFactory *ifactory, GtkItemFactoryEntry *entry) 
#void
#gtk_item_factory_delete_entry (ifactory, entry)
#	GtkItemFactory *ifactory
#	GtkItemFactoryEntry *entry

#### FIXME how to handle GtkItemFactoryEntry?:<commit_msg>complete redo of the callback handling and general cleanup.<commit_after>/*
 * Copyright (c) 2003 by the gtk2-perl team (see the file AUTHORS)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 * Boston, MA  02111-1307  USA.
 *
 * $Header$
 */
#include "gtk2perl.h"

/*
 * a custom marshaler for the item factory callbacks
 */
static void
gtk2perl_item_factory_item_activate (gpointer    nothing,
				     guint       callback_action,
				     GtkWidget * widget)
{
	SV    * callback_sv;
	SV    * callback_data;

	dSP; 

	/* the the callback and it's data out of the widget */
	callback_sv = (SV*)g_object_get_data (
				G_OBJECT (widget), "_callback_sv");
	callback_data = (SV*)g_object_get_data (
				G_OBJECT (widget), "_callback_data");

	ENTER;
	SAVETMPS;

	PUSHMARK (SP);
	/* put the parameters on the stack (we're always type 1) */
	EXTEND (SP, 3);
	PUSHs (sv_2mortal (newSVsv (callback_data
	                            ? callback_data
	       	                    : &PL_sv_undef)));
	PUSHs (sv_2mortal (newSViv (callback_action)));
	PUSHs (sv_2mortal (newSVGtkWidget (widget)));
	PUTBACK;

	/* call the code in sv */
	call_sv (callback_sv, G_DISCARD);

	FREETMPS;
	LEAVE;
}

/* we unfortunately have to fake out the type0 callback stuff */
static void
gtk2perl_item_factory_item_activate_type0 (gpointer    nothing,
				           guint       callback_action,
				           GtkWidget * widget)
{
	SV * callback_sv;
	SV * callback_data;

	dSP; 

	callback_sv = (SV*)g_object_get_data (
				G_OBJECT (widget), "_callback_sv");
	callback_data = (SV*)g_object_get_data (
				G_OBJECT (widget), "_callback_data");

	ENTER;
	SAVETMPS;

	PUSHMARK (SP);
	EXTEND (SP, 3);
	PUSHs (sv_2mortal (newSVsv (callback_data
	                            ? callback_data
	                            : &PL_sv_undef)));
	PUSHs (sv_2mortal (newSViv (callback_action)));
	PUSHs (sv_2mortal (newSVGtkWidget (widget)));
	PUTBACK;

	call_sv (callback_sv, G_DISCARD);

	FREETMPS;
	LEAVE;
}


MODULE = Gtk2::ItemFactory	PACKAGE = Gtk2::ItemFactory	PREFIX = gtk_item_factory_


##  GtkItemFactory* gtk_item_factory_new (GType container_type, const gchar *path, GtkAccelGroup *accel_group) 
GtkItemFactory*
gtk_item_factory_new (class, container_type_package, path, accel_group)
	SV * class
	char * container_type_package
	const gchar *path
	GtkAccelGroup_ornull *accel_group
    PREINIT:
	GType container_type;
    CODE:
	container_type = gperl_type_from_package (container_type_package);
	RETVAL = gtk_item_factory_new (container_type, path, accel_group);
    OUTPUT:
	RETVAL

### deprecated
##  void gtk_item_factory_add_foreign (GtkWidget *accel_widget, const gchar *full_path, GtkAccelGroup *accel_group, guint keyval, GdkModifierType modifiers) 

GtkItemFactory_ornull*
gtk_item_factory_from_widget (class, widget)
	SV * class
	GtkWidget *widget
    C_ARGS:
	widget

const gchar*
gtk_item_factory_path_from_widget (class, widget)
	SV * class
	GtkWidget *widget
    C_ARGS:
	widget

GtkWidget_ornull*
gtk_item_factory_get_item (ifactory, path)
	GtkItemFactory *ifactory
	const gchar *path

GtkWidget_ornull*
gtk_item_factory_get_widget (ifactory, path)
	GtkItemFactory *ifactory
	const gchar *path

GtkWidget_ornull*
gtk_item_factory_get_widget_by_action (ifactory, action)
	GtkItemFactory *ifactory
	guint action

GtkWidget_ornull*
gtk_item_factory_get_item_by_action (ifactory, action)
	GtkItemFactory *ifactory
	guint action


### this is called by Gtk2::IconFactory::create_item, which is implemented
### in perl and mangles the arguments for us.
void
_create_item (ifactory, path, accelerator, callback_action, item_type, extra_data, clean_path, callback_sv, callback_data)
	GtkItemFactory * ifactory
	gchar * path
	gchar * accelerator
	gint    callback_action
	gchar * item_type
	SV    * extra_data
	char  * clean_path
	SV    * callback_sv
	SV    * callback_data
    PREINIT:
	GtkItemFactoryEntry   entry = {0, };
	GtkWidget           * widget = NULL;
    CODE:
	entry.path = path;
	entry.accelerator = accelerator;
	/* start out with no callback, we'll probably add one in a min */
	entry.callback = NULL;
	entry.callback_action = callback_action;
	entry.item_type = item_type;
	entry.extra_data = SvPOK (extra_data) ? SvGChar (extra_data) : NULL; 

	/* if the user supplied a callback then we'll need to call our
	 * marshaler in order to call it */
	if( SvTRUE(callback_sv) )
		entry.callback = gtk2perl_item_factory_item_activate;

	/* create the item in the normal manner now */
	gtk_item_factory_create_item (ifactory, &entry, NULL, 1);
	
	/* get the widget that was created by create_item (this is why
	 * we needed clean_path) */
	widget = gtk_item_factory_get_item (ifactory, clean_path);
	if ( widget )
	{
		/* put the sv we need to call into the widget */
		g_object_set_data_full (G_OBJECT (widget), "_callback_sv", 
					(gpointer)gperl_sv_copy(callback_sv),
				        (GtkDestroyNotify)gperl_sv_free);
		
		/* and put the callback data in there as well */
		g_object_set_data_full (G_OBJECT (widget), "_callback_data", 
					(gpointer)gperl_sv_copy(callback_data),
					(GtkDestroyNotify)gperl_sv_free);
	}
	else
		croak("ItemFactory couldn't retrieve widget it just created");


###### implemented in perl, see Gtk2.pm
#####  void gtk_item_factory_create_items (GtkItemFactory *ifactory, guint n_entries, GtkItemFactoryEntry *entries, gpointer callback_data) 

void
gtk_item_factory_delete_item (ifactory, path)
	GtkItemFactory *ifactory
	const gchar *path

#### FIXME how to handle GtkItemFactoryEntry?:
###  void gtk_item_factory_delete_entry (GtkItemFactory *ifactory, GtkItemFactoryEntry *entry) 
#void
#gtk_item_factory_delete_entry (ifactory, entry)
#	GtkItemFactory *ifactory
#	GtkItemFactoryEntry *entry

#### FIXME how to handle GtkItemFactoryEntry?:
{'fraction_non_alphanumeric': 0.08223014256619145, 'fraction_numerical': 0.006619144602851324, 'mean_word_length': 4.184777826660801, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3584886', 'n_tokens_mistral': 4155, 'n_tokens_neox': 3891, 'n_words': 1140}