X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-dialog-action.c;h=f0caabae726872c980ce7e6a8ac6c0652f252713;hb=13ca98079f4cb3cd80deb10b173813548b1f3ddc;hp=70b89ea2867c2d2b8378bfde2a7f8a83ad394c84;hpb=ed208cf009043f0bf319a4e919c279d5b1401f36;p=pspp diff --git a/src/ui/gui/psppire-dialog-action.c b/src/ui/gui/psppire-dialog-action.c index 70b89ea286..f0caabae72 100644 --- a/src/ui/gui/psppire-dialog-action.c +++ b/src/ui/gui/psppire-dialog-action.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2012 Free Software Foundation + Copyright (C) 2012, 2016 Free Software Foundation This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,18 +22,85 @@ #include "executor.h" #include "helper.h" #include "psppire-data-window.h" +#include "builder-wrapper.h" -static void psppire_dialog_action_init (PsppireDialogAction *act); -static void psppire_dialog_action_class_init (PsppireDialogActionClass *class); +static GObjectClass * parent_class = NULL; -G_DEFINE_ABSTRACT_TYPE (PsppireDialogAction, psppire_dialog_action, GTK_TYPE_ACTION); +static const gchar * +__get_name (GAction *act) +{ + return G_OBJECT_TYPE_NAME (act); +} + +static const GVariantType * +__get_state_type (GAction *act) +{ + return NULL; +} + + +static GVariant * +__get_state (GAction *act) +{ + return NULL; +} + + +static const GVariantType * +__get_parameter_type (GAction *act) +{ + return PSPPIRE_DIALOG_ACTION (act)->parameter_type; +} + +static gboolean +__get_enabled (GAction *act) +{ + return TRUE; +} + +static void psppire_dialog_action_activate (PsppireDialogAction *act, GVariant *parameter); + +void +psppire_dialog_action_activate_null (PsppireDialogAction *act) +{ + psppire_dialog_action_activate (act, NULL); +} + + +static void +__activate (GAction *action, GVariant *parameter) +{ + psppire_dialog_action_activate (PSPPIRE_DIALOG_ACTION (action), parameter); +} + + +static void +action_model_init (GActionInterface *iface) +{ + iface->get_name = __get_name; + iface->get_state_type = __get_state_type; + iface->get_state = __get_state; + iface->get_parameter_type = __get_parameter_type; + iface->get_enabled = __get_enabled; + iface->activate = __activate; +} + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (PsppireDialogAction, \ + psppire_dialog_action, \ + G_TYPE_OBJECT, \ + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, \ + action_model_init)) /* Properties */ enum { PROP_0, - PROP_MANAGER, PROP_TOPLEVEL, + PROP_NAME, + PROP_ENABLED, + PROP_STATE, + PROP_STATE_TYPE, + PROP_PARAMETER_TYPE }; static void @@ -46,11 +113,10 @@ psppire_dialog_action_set_property (GObject *object, switch (prop_id) { - case PROP_MANAGER: + case PROP_TOPLEVEL: { - GObject *p = g_value_get_object (value); - act->uim = GTK_UI_MANAGER (p); + act->toplevel = GTK_WIDGET (p); } break; default: @@ -70,10 +136,7 @@ psppire_dialog_action_get_property (GObject *object, switch (prop_id) { - case PROP_MANAGER: - g_value_take_object (value, dialog_action->uim); - break; - case PROP_TOPLEVEL: + case PROP_TOPLEVEL: g_value_take_object (value, dialog_action->toplevel); break; default: @@ -83,42 +146,28 @@ psppire_dialog_action_get_property (GObject *object, } -static void -set_toplevel (PsppireDialogAction *act) -{ - if (act->toplevel) - return; - - GSList *sl = gtk_ui_manager_get_toplevels (act->uim, GTK_UI_MANAGER_MENUBAR | GTK_UI_MANAGER_TOOLBAR); - g_return_if_fail (sl); - - act->toplevel = gtk_widget_get_toplevel (GTK_WIDGET (sl->data)); - g_slist_free (sl); -} static void on_destroy_dataset (GObject *w) { GHashTable *t = g_object_get_data (w, "thing-table"); GSList *dl = g_object_get_data (w, "widget-list"); - + g_slist_free_full (dl, (GDestroyNotify) gtk_widget_destroy); g_hash_table_unref (t); } /* Each toplevel widget - that is the data window, which generally has a 1-1 association with a dataset - has an associated GHashTable. - + This GHashTable is keyed by the address of a PsppireDialogAction, and its values are user determined pointers (typically a GtkBuilder*). This is useful for storing the state of dialogs so they can persist between invocations. */ -GHashTable * +static GHashTable * psppire_dialog_action_get_hash_table (PsppireDialogAction *act) { - set_toplevel (act); - GHashTable *t = g_object_get_data (G_OBJECT (act->toplevel), "thing-table"); if (t == NULL) { @@ -131,38 +180,64 @@ psppire_dialog_action_get_hash_table (PsppireDialogAction *act) return t; } +GtkBuilder * +psppire_dialog_action_get_xml (PsppireDialogAction *da) +{ + GHashTable *thing = psppire_dialog_action_get_hash_table (da); + GtkBuilder *xml = g_hash_table_lookup (thing, da); + return xml; +} + + static void -psppire_dialog_action_activate (PsppireDialogAction *act) +psppire_dialog_action_activate (PsppireDialogAction *act, GVariant *parameter) { gint response; PsppireDialogActionClass *class = PSPPIRE_DIALOG_ACTION_GET_CLASS (act); - gboolean first_time = ! act->toplevel; - - set_toplevel (act); - act->dict = PSPPIRE_DATA_WINDOW(act->toplevel)->dict; - - g_object_set (act->source, "model", act->dict, NULL); GSList *wl = g_object_get_data (G_OBJECT (act->toplevel), "widget-list"); wl = g_slist_prepend (wl, act->dialog); g_object_set_data (G_OBJECT (act->toplevel), "widget-list", wl); - gtk_window_set_transient_for (GTK_WINDOW (act->dialog), GTK_WINDOW (act->toplevel)); + if (class->initial_activate) + { + GHashTable *thing = psppire_dialog_action_get_hash_table (act); + GtkBuilder *xml = g_hash_table_lookup (thing, act); + if (xml == NULL) + { + xml = class->initial_activate (act, parameter); + g_hash_table_insert (thing, act, xml); + } + } - if (GTK_ACTION_CLASS (psppire_dialog_action_parent_class)->activate) - GTK_ACTION_CLASS (psppire_dialog_action_parent_class)->activate ( GTK_ACTION (act)); + if (class->activate) + { + GHashTable *thing = psppire_dialog_action_get_hash_table (act); + GtkBuilder *xml = g_hash_table_lookup (thing, act); + if (xml != NULL) + class->activate (act, parameter); + } - gtk_widget_grab_focus (act->source); + gtk_window_set_transient_for (GTK_WINDOW (act->dialog), + GTK_WINDOW (act->toplevel)); + + if (act->source) + { + g_object_set (act->source, "model", act->dict, NULL); + gtk_widget_grab_focus (act->source); + } - if (first_time) + if (!act->activated) psppire_dialog_reload (PSPPIRE_DIALOG (act->dialog)); + act->activated = TRUE; + response = psppire_dialog_run (PSPPIRE_DIALOG (act->dialog)); - if ( class->generate_syntax ) + if (class->generate_syntax) { switch (response) { @@ -184,34 +259,29 @@ psppire_dialog_action_class_init (PsppireDialogActionClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - GParamSpec *manager_spec = - g_param_spec_object ("manager", - "Manager", - "The GtkUIManager which created this object", - GTK_TYPE_UI_MANAGER, - G_PARAM_READWRITE); + parent_class = g_type_class_peek_parent (class); GParamSpec *toplevel_spec = g_param_spec_object ("top-level", "Top Level", "The top level widget to which this dialog action belongs", GTK_TYPE_WINDOW, - G_PARAM_READABLE); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); object_class->set_property = psppire_dialog_action_set_property; object_class->get_property = psppire_dialog_action_get_property; class->generate_syntax = NULL; - class->activate = psppire_dialog_action_activate; - - g_object_class_install_property (object_class, - PROP_MANAGER, - manager_spec); - g_object_class_install_property (object_class, PROP_TOPLEVEL, toplevel_spec); + + g_object_class_override_property (object_class, PROP_NAME, "name"); + g_object_class_override_property (object_class, PROP_ENABLED, "enabled"); + g_object_class_override_property (object_class, PROP_STATE, "state"); + g_object_class_override_property (object_class, PROP_STATE_TYPE, "state-type"); + g_object_class_override_property (object_class, PROP_PARAMETER_TYPE, "parameter-type"); } @@ -220,11 +290,12 @@ psppire_dialog_action_init (PsppireDialogAction *act) { act->toplevel = NULL; act->dict = NULL; + act->activated = FALSE; + act->parameter_type = NULL; } - void -psppire_dialog_action_set_valid_predicate (PsppireDialogAction *act, +psppire_dialog_action_set_valid_predicate (PsppireDialogAction *act, ContentsAreValid dialog_state_valid) { psppire_dialog_set_valid_predicate (PSPPIRE_DIALOG (act->dialog), @@ -232,16 +303,8 @@ psppire_dialog_action_set_valid_predicate (PsppireDialogAction *act, } void -psppire_dialog_action_set_refresh (PsppireDialogAction *pda, +psppire_dialog_action_set_refresh (PsppireDialogAction *pda, PsppireDialogActionRefresh refresh) { g_signal_connect_swapped (pda->dialog, "refresh", G_CALLBACK (refresh), pda); } - - -void -psppire_dialog_action_set_activation (gpointer class, activation activate) -{ - GTK_ACTION_CLASS (class)->activate = activate; -} -