abstract.c 10.5 KB
/*
 * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270  e X3270
 * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
 * aplicativos mainframe. Registro no INPI sob o nome G3270.
 *
 * Copyright (C) <2008> <Banco do Brasil S.A.>
 *
 * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
 * os termos da GPL v.2 - Licença Pública Geral  GNU,  conforme  publicado  pela
 * Free Software Foundation.
 *
 * Este programa é distribuído na expectativa de  ser  útil,  mas  SEM  QUALQUER
 * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou  de  ADEQUAÇÃO
 * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
 * obter mais detalhes.
 *
 * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
 * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
 * St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Este programa está nomeado como - e possui - linhas de código.
 *
 * Contatos:
 *
 * perry.werneck@gmail.com	(Alexandre Perry de Souza Werneck)
 * erico.mendonca@gmail.com	(Erico Mascarenhas Mendonça)
 *
 */

 #include "private.h"
 #include <v3270.h>

 static void pw3270_action_iface_init(GActionInterface *iface);
 static void pw3270Action_class_init(pw3270ActionClass *klass);
 static void pw3270Action_init(pw3270Action *action);
 static void pw3270_action_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 static void pw3270_action_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
 static void pw3270_action_set_state(GAction *action, GVariant *value);
 static gboolean pw3270_action_get_enabled(GAction *action);
 static void pw3270_action_activate(GAction *action, GVariant *parameter);

 static gboolean get_enabled(GAction *action, GtkWidget *terminal);
 static void activate(GAction *action, GVariant *parameter, GtkWidget *terminal);
 static void change_widget(GAction *action, GtkWidget *from, GtkWidget *to);

 static void finalize(GObject *object);

 static	const GVariantType	* pw3270_action_get_state_type(GAction *action);
 static	GVariant			* pw3270_action_get_state_property(GAction *action);
 static	const GVariantType	* pw3270_action_get_parameter_type(GAction *action);
 static GVariant			* pw3270_action_get_state_hint(GAction *action);
 static void				  pw3270_action_change_state(GAction *action, GVariant *value);

 enum {
	PROP_NONE,
	PROP_NAME,
	PROP_PARAMETER_TYPE,
	PROP_ENABLED,
	PROP_STATE_TYPE,
	PROP_STATE
 };

 enum {
  SIGNAL_CHANGE_STATE,
  NR_SIGNALS
 };

 static guint action_signals[NR_SIGNALS];

 G_DEFINE_TYPE_WITH_CODE(pw3270Action, pw3270Action, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_ACTION, pw3270_action_iface_init))

 void pw3270_action_iface_init(GActionInterface *iface) {
	iface->get_name = pw3270_action_get_name;
	iface->get_parameter_type = pw3270_action_get_parameter_type;
	iface->get_state_type = pw3270_action_get_state_type;
	iface->get_state_hint = pw3270_action_get_state_hint;
	iface->get_enabled = pw3270_action_get_enabled;
	iface->get_state = pw3270_action_get_state_property;
	iface->change_state = pw3270_action_change_state;
	iface->activate = pw3270_action_activate;
 }

 void pw3270Action_class_init(pw3270ActionClass *klass) {

	GObjectClass *object_class = G_OBJECT_CLASS(klass);

	klass->change_widget		= change_widget;
	klass->get_enabled			= get_enabled;
	klass->activate				= activate;

 	object_class->finalize		= finalize;
	object_class->set_property	= pw3270_action_set_property;
	object_class->get_property	= pw3270_action_get_property;

	// Install properties
	g_object_class_install_property(object_class, PROP_NAME,
		g_param_spec_string ("name",
			N_("Action Name"),
			N_("The name used to invoke the action"),
			NULL,
			G_PARAM_READWRITE |
			G_PARAM_CONSTRUCT_ONLY |
			G_PARAM_STATIC_STRINGS));

	g_object_class_install_property (object_class, PROP_PARAMETER_TYPE,
		g_param_spec_boxed ("parameter-type",
			N_("Parameter Type"),
			N_("The type of GVariant passed to activate()"),
			G_TYPE_VARIANT_TYPE,
			G_PARAM_READWRITE |
			G_PARAM_CONSTRUCT_ONLY |
			G_PARAM_STATIC_STRINGS));

	g_object_class_install_property (object_class, PROP_ENABLED,
		g_param_spec_boolean ("enabled",
			N_("Enabled"),
			N_("If the action can be activated"),
			TRUE,
			G_PARAM_READWRITE |
			G_PARAM_STATIC_STRINGS));

	g_object_class_install_property (object_class, PROP_STATE_TYPE,
		g_param_spec_boxed ("state-type",
			N_("State Type"),
			N_("The type of the state kept by the action"),
			G_TYPE_VARIANT_TYPE,
			G_PARAM_READABLE |
			G_PARAM_STATIC_STRINGS));

	g_object_class_install_property (object_class, PROP_STATE,
		g_param_spec_variant ("state",
			N_("State"),
			N_("The state the action is in"),
			G_VARIANT_TYPE_ANY,
			NULL,
			G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
			G_PARAM_STATIC_STRINGS));

	// Install signals
	action_signals[SIGNAL_CHANGE_STATE] =
		g_signal_new(
			I_("change-state"),
			G_TYPE_SIMPLE_ACTION,
			G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
			0, NULL, NULL,
			NULL,
			G_TYPE_NONE, 1,
			G_TYPE_VARIANT
		);
 }

 void pw3270Action_init(pw3270Action *action) {

	action->name		= NULL;
	action->terminal	= NULL;
	action->state		= NULL;

 }

 void finalize(GObject *object) {

	pw3270Action * action = PW3270_ACTION(object);

	debug("Finalizing action %p (%s)",object,action->name);

	if(action->state) {
		g_variant_unref(action->state);
		action->state = NULL;
	}

	if(action->terminal) {
		pw3270_action_set_terminal_widget(G_ACTION(object),NULL);
		action->terminal = NULL;
	}

	if(action->name) {
		g_free(action->name);
		action->name = NULL;
	}

	if(action->parameter_type) {
		g_variant_type_free(action->parameter_type);
		action->parameter_type = NULL;
	}

	G_OBJECT_CLASS(pw3270Action_parent_class)->finalize(object);

 }


 void pw3270_action_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {

	GAction *action = G_ACTION(object);

	debug("%s(%d)",__FUNCTION__,prop_id);

	switch (prop_id) {
    case PROP_NAME:
		g_value_set_string(value, pw3270_action_get_name(action));
		break;

	case PROP_PARAMETER_TYPE:
		g_value_set_boxed(value, pw3270_action_get_parameter_type(action));
		break;

	case PROP_ENABLED:
		g_value_set_boolean(value, pw3270_action_get_enabled(action));
		break;

	case PROP_STATE_TYPE:
		g_value_set_boxed(value, pw3270_action_get_state_type(action));
		break;

	case PROP_STATE:
		g_value_take_variant(value, pw3270_action_get_state_property(action));
		break;

	default:
		g_assert_not_reached ();
	}

 }

 void pw3270_action_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {

//	debug("%s(%d)",__FUNCTION__,prop_id);

	GAction *action = G_ACTION(object);

	switch (prop_id)
	{
	case PROP_NAME:
		pw3270_action_set_name(action, g_value_get_string(value));
		break;

	case PROP_PARAMETER_TYPE:
//		action->parameter_type = g_value_dup_boxed (value);
		break;

	case PROP_ENABLED:
//		action->enabled = g_value_get_boolean (value);
		break;

	case PROP_STATE:
		pw3270_action_set_state(action, g_value_get_variant(value));
		break;

	default:
		g_assert_not_reached ();
	}

 }

 const gchar * pw3270_action_get_name(GAction *action) {
 	return PW3270_ACTION(action)->name;
 }

 void pw3270_action_set_name(GAction *object, const gchar *name) {

 	pw3270Action * action = PW3270_ACTION(object);

// 	debug("%s %s -> %s", __FUNCTION__, action->name, name);

 	if(action->name)
		g_free(action->name);

	if(name)
		action->name = g_strdup(name);
	else
		action->name = NULL;

 }

 GVariant * pw3270_action_get_state_property(GAction *object) {
 	pw3270Action *action = PW3270_ACTION(object);
	return action->state ? g_variant_ref(action->state) : NULL;
 }

 const GVariantType * pw3270_action_get_parameter_type(GAction *action) {
//	debug("%s",__FUNCTION__);
 	return NULL;
 }

 const GVariantType * pw3270_action_get_state_type(GAction *object) {

 	pw3270Action * action = PW3270_ACTION(object);

	if(action->state)
		return g_variant_get_type(action->state);

	return NULL;

 }

 GVariant * pw3270_action_get_state_hint(GAction *action) {
	debug("%s",__FUNCTION__);
	return NULL;
 }

 void pw3270_action_change_state(GAction *object, GVariant *value) {
	pw3270_action_set_state(object, value);
 }

 void pw3270_action_change_state_boolean(GAction *action, gboolean state) {

 	g_return_if_fail(PW3270_IS_ACTION(action));
	pw3270_action_set_state(action,g_variant_new_boolean(state));

 }

 void pw3270_action_set_state(GAction *object, GVariant *value) {

	if(value) {

		pw3270Action * action = PW3270_ACTION(object);

		g_variant_ref_sink(value);

		if (!action->state || !g_variant_equal(action->state, value)) {

			if(action->state)
				g_variant_unref(action->state);

			action->state = g_variant_ref(value);

			if (g_signal_has_handler_pending(object, action_signals[SIGNAL_CHANGE_STATE], 0, TRUE)) {
				g_signal_emit(object, action_signals[SIGNAL_CHANGE_STATE], 0, value);
			}

			g_object_notify(G_OBJECT(object), "state");

		}

		g_variant_unref(value);

	}

 }

 void pw3270_action_set_enabled(GAction *object, gboolean state) {

//	pw3270Action * action = PW3270_ACTION(object);

	g_object_notify(G_OBJECT(object), "enabled");
 }


 static void change_widget(GAction *action, GtkWidget G_GNUC_UNUSED(*from), GtkWidget *to) {
	PW3270_ACTION(action)->terminal = to;
 }

 void pw3270_action_set_terminal_widget(GAction *object, GtkWidget *widget) {

	g_return_if_fail(PW3270_IS_ACTION(object) && GTK_IS_V3270(widget));

 	pw3270Action * action = PW3270_ACTION(object);

 	if(action->terminal != widget) {
		PW3270_ACTION_GET_CLASS(object)->change_widget(object,action->terminal,widget);
		action->terminal = widget;
 	}

 }

 gboolean pw3270_action_get_enabled(GAction *object) {

 	pw3270Action * action = PW3270_ACTION(object);

// 	debug("%s: terminal=%p",__FUNCTION__,action->terminal);

 	if(action && action->terminal) {

		return PW3270_ACTION_GET_CLASS(object)->get_enabled(object,action->terminal);

 	}

	return FALSE;

 }

 void pw3270_action_activate(GAction *object, GVariant *parameter) {

 	pw3270Action * action = PW3270_ACTION(object);

 	debug("%s: terminal=%p",__FUNCTION__,action->terminal);

 	if(action && action->terminal) {
		PW3270_ACTION_GET_CLASS(object)->activate(object,parameter,action->terminal);
 	}

 }

 gboolean get_enabled(GAction *object, GtkWidget *terminal) {
	debug("%s(%s)",__FUNCTION__,pw3270_action_get_name(object));
 	return TRUE;
 }

 void activate(GAction *action, GVariant G_GNUC_UNUSED(*parameter), GtkWidget G_GNUC_UNUSED(*terminal)) {
	g_message("Action %s can't be activated",pw3270_action_get_name(action));
 }