#include "data/datasheet.h"
#include "data/value-labels.h"
#include "libpspp/range-set.h"
+#include "libpspp/str.h"
#include "ui/gui/helper.h"
#include "ui/gui/pspp-sheet-selection.h"
#include "ui/gui/psppire-data-sheet.h"
#include "ui/gui/psppire-data-store.h"
#include "ui/gui/psppire-value-entry.h"
#include "ui/gui/psppire-var-sheet.h"
-#include "ui/gui/psppire.h"
+#include "ui/gui/psppire-conf.h"
#include <gettext.h>
#define _(msgid) gettext (msgid)
static void disconnect_data_sheets (PsppireDataEditor *);
static void refresh_entry (PsppireDataEditor *);
-static void psppire_data_editor_update_ui_manager (PsppireDataEditor *);
GType
psppire_data_editor_get_type (void)
de->data_store = NULL;
}
- if (de->var_store)
+ if (de->dict)
{
- g_object_unref (de->var_store);
- de->var_store = NULL;
+ g_object_unref (de->dict);
+ de->dict = NULL;
}
if (de->font != NULL)
de->font = NULL;
}
- if (de->ui_manager)
- {
- g_object_unref (de->ui_manager);
- de->ui_manager = NULL;
- }
-
/* Chain up to the parent class */
G_OBJECT_CLASS (parent_class)->dispose (obj);
}
{
PROP_0,
PROP_DATA_STORE,
- PROP_VAR_STORE,
+ PROP_DICTIONARY,
PROP_VALUE_LABELS,
- PROP_SPLIT_WINDOW,
- PROP_UI_MANAGER
+ PROP_SPLIT_WINDOW
};
static void
FOR_EACH_DATA_SHEET (data_sheet, i, de)
psppire_data_sheet_set_data_store (data_sheet, de->data_store);
- psppire_var_sheet_set_dictionary (var_sheet, de->var_store->dictionary);
+ psppire_var_sheet_set_dictionary (var_sheet, de->dict);
}
static void
G_CALLBACK (refresh_entry), de);
break;
- case PROP_VAR_STORE:
- if ( de->var_store) g_object_unref (de->var_store);
- de->var_store = g_value_get_pointer (value);
- g_object_ref (de->var_store);
+ case PROP_DICTIONARY:
+ if (de->dict)
+ g_object_unref (de->dict);
+ de->dict = g_value_get_pointer (value);
+ g_object_ref (de->dict);
psppire_var_sheet_set_dictionary (PSPPIRE_VAR_SHEET (de->var_sheet),
- de->var_store->dictionary);
+ de->dict);
break;
case PROP_VALUE_LABELS:
FOR_EACH_DATA_SHEET (data_sheet, i, de)
psppire_data_sheet_set_value_labels (data_sheet,
g_value_get_boolean (value));
break;
- case PROP_UI_MANAGER:
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_DATA_STORE:
g_value_set_pointer (value, de->data_store);
break;
- case PROP_VAR_STORE:
- g_value_set_pointer (value, de->var_store);
+ case PROP_DICTIONARY:
+ g_value_set_pointer (value, de->dict);
break;
case PROP_VALUE_LABELS:
g_value_set_boolean (value,
psppire_data_sheet_get_value_labels (
PSPPIRE_DATA_SHEET (de->data_sheets[0])));
break;
- case PROP_UI_MANAGER:
- g_value_set_object (value, psppire_data_editor_get_ui_manager (de));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
static void
psppire_data_editor_switch_page (GtkNotebook *notebook,
- GtkNotebookPage *page,
+ GtkWidget *w,
guint page_num)
{
- GTK_NOTEBOOK_CLASS (parent_class)->switch_page (notebook, page, page_num);
- psppire_data_editor_update_ui_manager (PSPPIRE_DATA_EDITOR (notebook));
+ GTK_NOTEBOOK_CLASS (parent_class)->switch_page (notebook, w, page_num);
+
}
static void
GtkWidget *widget)
{
GTK_CONTAINER_CLASS (parent_class)->set_focus_child (container, widget);
- psppire_data_editor_update_ui_manager (PSPPIRE_DATA_EDITOR (container));
+
}
static void
psppire_data_editor_class_init (PsppireDataEditorClass *klass)
{
GParamSpec *data_store_spec ;
- GParamSpec *var_store_spec ;
+ GParamSpec *dict_spec ;
GParamSpec *value_labels_spec;
GParamSpec *split_window_spec;
- GParamSpec *ui_manager_spec;
+
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
PROP_DATA_STORE,
data_store_spec);
- var_store_spec =
- g_param_spec_pointer ("var-store",
- "Variable Store",
- "A pointer to the variable store associated with this editor",
+ dict_spec =
+ g_param_spec_pointer ("dictionary",
+ "Dictionary",
+ "A pointer to the dictionary associated with this editor",
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_READABLE );
g_object_class_install_property (object_class,
- PROP_VAR_STORE,
- var_store_spec);
+ PROP_DICTIONARY,
+ dict_spec);
value_labels_spec =
g_param_spec_boolean ("value-labels",
PROP_SPLIT_WINDOW,
split_window_spec);
- ui_manager_spec =
- g_param_spec_object ("ui-manager",
- "UI Manager",
- "UI manager for the active notebook tab. The client should merge this UI manager with the active UI manager to obtain menu items and tool bar items specific to the active notebook tab.",
- GTK_TYPE_UI_MANAGER,
- G_PARAM_READABLE);
- g_object_class_install_property (object_class,
- PROP_UI_MANAGER,
- ui_manager_spec);
}
static gboolean
PSPPIRE_DATA_EDITOR_DATA_VIEW);
data_sheet = psppire_data_editor_get_active_data_sheet (de);
- psppire_data_sheet_show_variable (data_sheet, dict_index);
+ psppire_data_sheet_goto_variable (data_sheet, dict_index);
return TRUE;
}
}
else
{
- GString *string;
-
- string = g_string_sized_new (25);
- g_string_append_printf (string,
- ngettext ("%'d case", "%'d cases", n_cases),
- n_cases);
- g_string_append_c (string, ' ');
- g_string_append_unichar (string, 0xd7); /* U+00D7 MULTIPLICATION SIGN */
- g_string_append_c (string, ' ');
- g_string_append_printf (string,
- ngettext ("%'d variable", "%'d variables",
- n_vars),
- n_vars);
- ref_cell_text = string->str;
- g_string_free (string, FALSE);
+ struct string s;
+
+ /* The glib string library does not understand the ' printf modifier
+ on all platforms, but the "struct string" library does (because
+ Gnulib fixes that problem), so use the latter. */
+ ds_init_empty (&s);
+ ds_put_format (&s, ngettext ("%'d case", "%'d cases", n_cases),
+ n_cases);
+ ds_put_byte (&s, ' ');
+ ds_put_unichar (&s, 0xd7); /* U+00D7 MULTIPLICATION SIGN */
+ ds_put_byte (&s, ' ');
+ ds_put_format (&s, ngettext ("%'d variable", "%'d variables",
+ n_vars),
+ n_vars);
+ ref_cell_text = ds_steal_cstr (&s);
}
psppire_value_entry_set_variable (PSPPIRE_VALUE_ENTRY (de->datum_entry),
}
static GtkWidget *
-make_data_sheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines)
+make_data_sheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines,
+ gboolean show_value_labels)
{
PsppSheetSelection *selection;
GtkWidget *ds;
ds = psppire_data_sheet_new ();
pspp_sheet_view_set_grid_lines (PSPP_SHEET_VIEW (ds), grid_lines);
+ psppire_data_sheet_set_value_labels (PSPPIRE_DATA_SHEET (ds),
+ show_value_labels);
g_signal_connect_swapped (ds, "notify::value-labels",
G_CALLBACK (refresh_entry), de);
}
static GtkWidget *
-make_single_datasheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines)
+make_single_datasheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines,
+ gboolean show_value_labels)
{
GtkWidget *data_sheet_scroller;
- de->data_sheets[0] = make_data_sheet (de, grid_lines);
+ de->data_sheets[0] = make_data_sheet (de, grid_lines, show_value_labels);
de->data_sheets[1] = de->data_sheets[2] = de->data_sheets[3] = NULL;
/* Put data sheet in scroller. */
}
static GtkWidget *
-make_split_datasheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines)
+make_split_datasheet (PsppireDataEditor *de, GtkTreeViewGridLines grid_lines,
+ gboolean show_value_labels)
{
/* Panes, in the order in which we want to create them. */
enum
GtkPolicyType hpolicy, vpolicy;
GtkWidget *scroller;
- de->data_sheets[i] = make_data_sheet (de, grid_lines);
+ de->data_sheets[i] = make_data_sheet (de, grid_lines, show_value_labels);
ds[i] = PSPP_SHEET_VIEW (de->data_sheets[i]);
if (i == BL)
return GTK_WIDGET (xpaned);
}
+static void set_font_recursively (GtkWidget *w, gpointer data);
+
static void
psppire_data_editor_init (PsppireDataEditor *de)
{
GtkWidget *var_sheet_scroller;
GtkWidget *hbox;
+ gchar *fontname = NULL;
de->font = NULL;
- de->ui_manager = NULL;
+ de->old_vbox_widget = NULL;
g_object_set (de, "tab-pos", GTK_POS_BOTTOM, NULL);
de->cell_ref_label = gtk_label_new ("");
gtk_label_set_width_chars (GTK_LABEL (de->cell_ref_label), 25);
- gtk_misc_set_alignment (GTK_MISC (de->cell_ref_label), 0.0, 0.5);
+ gtk_widget_set_valign (de->cell_ref_label, GTK_ALIGN_CENTER);
de->datum_entry = psppire_value_entry_new ();
g_signal_connect (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (de->datum_entry))),
"activate", G_CALLBACK (on_datum_entry_activate), de);
- hbox = gtk_hbox_new (FALSE, 0);
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (hbox), de->cell_ref_label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), de->datum_entry, TRUE, TRUE, 0);
de->split = FALSE;
de->datasheet_vbox_widget
- = make_single_datasheet (de, GTK_TREE_VIEW_GRID_LINES_BOTH);
+ = make_single_datasheet (de, GTK_TREE_VIEW_GRID_LINES_BOTH, FALSE);
- de->vbox = gtk_vbox_new (FALSE, 0);
+ de->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (de->vbox), hbox, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (de->vbox), de->datasheet_vbox_widget,
TRUE, TRUE, 0);
g_object_set (de, "can-focus", FALSE, NULL);
- psppire_data_editor_update_ui_manager (de);
+ if (psppire_conf_get_string (psppire_conf_new (),
+ "Data Editor", "font",
+ &fontname) )
+ {
+ de->font = pango_font_description_from_string (fontname);
+ g_free (fontname);
+ set_font_recursively (GTK_WIDGET (de), de->font);
+ }
+
}
GtkWidget*
-psppire_data_editor_new (PsppireVarStore *var_store,
+psppire_data_editor_new (PsppireDict *dict,
PsppireDataStore *data_store)
{
return g_object_new (PSPPIRE_DATA_EDITOR_TYPE,
- "var-store", var_store,
+ "dictionary", dict,
"data-store", data_store,
NULL);
}
set_font_recursively (GtkWidget *w, gpointer data)
{
PangoFontDescription *font_desc = data;
- GtkRcStyle *style = gtk_widget_get_modifier_style (w);
-
- pango_font_description_free (style->font_desc);
- style->font_desc = pango_font_description_copy (font_desc);
- gtk_widget_modify_style (w, style);
+ gtk_widget_override_font (w, font_desc);
if ( GTK_IS_CONTAINER (w))
gtk_container_foreach (GTK_CONTAINER (w), set_font_recursively, font_desc);
void
psppire_data_editor_set_font (PsppireDataEditor *de, PangoFontDescription *font_desc)
{
+ gchar *font_name;
set_font_recursively (GTK_WIDGET (de), font_desc);
if (de->font)
pango_font_description_free (de->font);
de->font = pango_font_description_copy (font_desc);
+ font_name = pango_font_description_to_string (de->font);
+
+ psppire_conf_set_string (psppire_conf_new (),
+ "Data Editor", "font",
+ font_name);
+
}
/* If SPLIT is TRUE, splits DE's data sheet into four panes.
psppire_data_editor_split_window (PsppireDataEditor *de, gboolean split)
{
GtkTreeViewGridLines grid_lines;
+ gboolean labels;
if (split == de->split)
return;
grid_lines = pspp_sheet_view_get_grid_lines (
PSPP_SHEET_VIEW (de->data_sheets[0]));
+ labels = psppire_data_sheet_get_value_labels (PSPPIRE_DATA_SHEET (
+ de->data_sheets[0]));
disconnect_data_sheets (de);
- gtk_widget_destroy (de->datasheet_vbox_widget);
+ if (de->old_vbox_widget)
+ g_object_unref (de->old_vbox_widget);
+ de->old_vbox_widget = de->datasheet_vbox_widget;
+ g_object_ref (de->old_vbox_widget);
+ /* FIXME: old_vbox_widget needs to be unreffed in dispose.
+ (currently it seems to provoke an error if I do that.
+ I don't know why. */
+ gtk_container_remove (GTK_CONTAINER (de->vbox), de->datasheet_vbox_widget);
if (split)
- de->datasheet_vbox_widget = make_split_datasheet (de, grid_lines);
+ de->datasheet_vbox_widget = make_split_datasheet (de, grid_lines, labels);
else
- de->datasheet_vbox_widget = make_single_datasheet (de, grid_lines);
+ de->datasheet_vbox_widget = make_single_datasheet (de, grid_lines, labels);
+
psppire_data_editor_refresh_model (de);
gtk_box_pack_start (GTK_BOX (de->vbox), de->datasheet_vbox_widget,
de->split = split;
g_object_notify (G_OBJECT (de), "split");
- psppire_data_editor_update_ui_manager (de);
}
/* Makes the variable with dictionary index DICT_INDEX in DE's dictionary
{
case PSPPIRE_DATA_EDITOR_DATA_VIEW:
data_sheet = psppire_data_editor_get_active_data_sheet (de);
- psppire_data_sheet_show_variable (data_sheet, dict_index);
+ psppire_data_sheet_goto_variable (data_sheet, dict_index);
break;
case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
return PSPPIRE_DATA_SHEET (de->data_sheets[0]);
}
-
-/* Returns the UI manager that should be merged into DE's toplevel widget's UI
- manager to display menu items and toolbar items specific to DE's current
- page and data sheet.
-
- DE's toplevel widget can watch for changes by connecting to DE's
- notify::ui-manager signal. */
-GtkUIManager *
-psppire_data_editor_get_ui_manager (PsppireDataEditor *de)
-{
- psppire_data_editor_update_ui_manager (de);
- return de->ui_manager;
-}
-
-static void
-psppire_data_editor_update_ui_manager (PsppireDataEditor *de)
-{
- PsppireDataSheet *data_sheet;
- GtkUIManager *ui_manager;
-
- ui_manager = NULL;
-
- switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (de)))
- {
- case PSPPIRE_DATA_EDITOR_DATA_VIEW:
- data_sheet = psppire_data_editor_get_active_data_sheet (de);
- if (data_sheet != NULL)
- ui_manager = psppire_data_sheet_get_ui_manager (data_sheet);
- else
- {
- /* This happens transiently in psppire_data_editor_split_window(). */
- }
- break;
-
- case PSPPIRE_DATA_EDITOR_VARIABLE_VIEW:
- ui_manager = psppire_var_sheet_get_ui_manager (
- PSPPIRE_VAR_SHEET (de->var_sheet));
- break;
-
- default:
- /* This happens transiently in psppire_data_editor_init(). */
- break;
- }
-
- if (ui_manager != de->ui_manager)
- {
- if (de->ui_manager)
- g_object_unref (de->ui_manager);
- if (ui_manager)
- g_object_ref (ui_manager);
- de->ui_manager = ui_manager;
-
- g_object_notify (G_OBJECT (de), "ui-manager");
- }
-}