diff options
Diffstat (limited to 'src/math-preferences.c')
-rw-r--r-- | src/math-preferences.c | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/src/math-preferences.c b/src/math-preferences.c new file mode 100644 index 0000000..c846523 --- /dev/null +++ b/src/math-preferences.c @@ -0,0 +1,401 @@ +/* Copyright (c) 2008-2009 Robert Ancell + * + * 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 + * the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include "math-preferences.h" + +G_DEFINE_TYPE (MathPreferencesDialog, math_preferences, GTK_TYPE_DIALOG); + +enum { + PROP_0, + PROP_EQUATION +}; + +struct MathPreferencesDialogPrivate +{ + MathEquation *equation; + GtkBuilder *ui; +}; + +#define UI_DIALOGS_FILE UI_DIR "/preferences.ui" +#define GET_WIDGET(ui, name) \ + GTK_WIDGET(gtk_builder_get_object(ui, name)) + + +MathPreferencesDialog * +math_preferences_dialog_new(MathEquation *equation) +{ + return g_object_new (math_preferences_get_type(), "equation", equation, NULL); +} + + +static void +preferences_response_cb(GtkWidget *widget, gint id) +{ + gtk_widget_hide(widget); +} + + +static gboolean +preferences_dialog_delete_cb(GtkWidget *widget, GdkEvent *event) +{ + preferences_response_cb(widget, 0); + return TRUE; +} + + +void number_format_combobox_changed_cb(GtkWidget *combo, MathPreferencesDialog *dialog); +G_MODULE_EXPORT +void +number_format_combobox_changed_cb(GtkWidget *combo, MathPreferencesDialog *dialog) +{ + DisplayFormat value; + GtkTreeModel *model; + GtkTreeIter iter; + + model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter); + gtk_tree_model_get(model, &iter, 1, &value, -1); + math_equation_set_number_format(dialog->priv->equation, value); +} + + +void angle_unit_combobox_changed_cb(GtkWidget *combo, MathPreferencesDialog *dialog); +G_MODULE_EXPORT +void +angle_unit_combobox_changed_cb(GtkWidget *combo, MathPreferencesDialog *dialog) +{ + MPAngleUnit value; + GtkTreeModel *model; + GtkTreeIter iter; + + model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter); + gtk_tree_model_get(model, &iter, 1, &value, -1); + math_equation_set_angle_units(dialog->priv->equation, value); +} + + +void word_size_combobox_changed_cb(GtkWidget *combo, MathPreferencesDialog *dialog); +G_MODULE_EXPORT +void +word_size_combobox_changed_cb(GtkWidget *combo, MathPreferencesDialog *dialog) +{ + gint value; + GtkTreeModel *model; + GtkTreeIter iter; + + model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter); + gtk_tree_model_get(model, &iter, 1, &value, -1); + math_equation_set_word_size(dialog->priv->equation, value); +} + + +void decimal_places_spin_change_value_cb(GtkWidget *spin, MathPreferencesDialog *dialog); +G_MODULE_EXPORT +void +decimal_places_spin_change_value_cb(GtkWidget *spin, MathPreferencesDialog *dialog) +{ + gint value = 0; + + value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin)); + math_equation_set_accuracy(dialog->priv->equation, value); +} + + +void thousands_separator_check_toggled_cb(GtkWidget *check, MathPreferencesDialog *dialog); +G_MODULE_EXPORT +void +thousands_separator_check_toggled_cb(GtkWidget *check, MathPreferencesDialog *dialog) +{ + gboolean value; + + value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check)); + math_equation_set_show_thousands_separators(dialog->priv->equation, value); +} + + +void trailing_zeroes_check_toggled_cb(GtkWidget *check, MathPreferencesDialog *dialog); +G_MODULE_EXPORT +void +trailing_zeroes_check_toggled_cb(GtkWidget *check, MathPreferencesDialog *dialog) +{ + gboolean value; + + value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check)); + math_equation_set_show_trailing_zeroes(dialog->priv->equation, value); +} + + +static void +set_combo_box_from_int(GtkWidget *combo, int value) +{ + GtkTreeModel *model; + GtkTreeIter iter; + gboolean valid; + + model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); + valid = gtk_tree_model_get_iter_first(model, &iter); + + while (valid) { + gint v; + + gtk_tree_model_get(model, &iter, 1, &v, -1); + if (v == value) + break; + valid = gtk_tree_model_iter_next(model, &iter); + } + if (!valid) + valid = gtk_tree_model_get_iter_first(model, &iter); + + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter); +} + + +static void +accuracy_cb(MathEquation *equation, GParamSpec *spec, MathPreferencesDialog *dialog) +{ + gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(dialog->priv->ui, "decimal_places_spin")), + math_equation_get_accuracy(equation)); +} + + +static void +show_thousands_separators_cb(MathEquation *equation, GParamSpec *spec, MathPreferencesDialog *dialog) +{ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(dialog->priv->ui, "thousands_separator_check")), + math_equation_get_show_thousands_separators(equation)); +} + + +static void +show_trailing_zeroes_cb(MathEquation *equation, GParamSpec *spec, MathPreferencesDialog *dialog) +{ + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(dialog->priv->ui, "trailing_zeroes_check")), + math_equation_get_show_trailing_zeroes(equation)); +} + + +static void +number_format_cb(MathEquation *equation, GParamSpec *spec, MathPreferencesDialog *dialog) +{ + set_combo_box_from_int(GET_WIDGET(dialog->priv->ui, "number_format_combobox"), math_equation_get_number_format(equation)); +} + + +static void +word_size_cb(MathEquation *equation, GParamSpec *spec, MathPreferencesDialog *dialog) +{ + set_combo_box_from_int(GET_WIDGET(dialog->priv->ui, "word_size_combobox"), math_equation_get_word_size(equation)); +} + + +static void +angle_unit_cb(MathEquation *equation, GParamSpec *spec, MathPreferencesDialog *dialog) +{ + set_combo_box_from_int(GET_WIDGET(dialog->priv->ui, "angle_unit_combobox"), math_equation_get_angle_units(equation)); +} + + +static void +create_gui(MathPreferencesDialog *dialog) +{ + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + GtkCellRenderer *renderer; + gchar *string, **tokens; + GError *error = NULL; + static gchar *objects[] = { "preferences_table", "angle_unit_model", "number_format_model", + "word_size_model", "decimal_places_adjustment", "number_base_model", NULL }; + + // FIXME: Handle errors + dialog->priv->ui = gtk_builder_new(); + gtk_builder_add_objects_from_file(dialog->priv->ui, UI_DIALOGS_FILE, objects, &error); + if (error) + g_warning("Error loading preferences UI: %s", error->message); + g_clear_error(&error); + + gtk_window_set_title(GTK_WINDOW(dialog), + /* Title of preferences dialog */ + _("Preferences")); + gtk_window_set_icon_name(GTK_WINDOW(dialog), "accessories-calculator"); + gtk_container_set_border_width(GTK_CONTAINER(dialog), 8); + gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); + gtk_dialog_add_button(GTK_DIALOG(dialog), + /* Label on close button in preferences dialog */ + _("_Close"), 0); + g_signal_connect(dialog, "response", G_CALLBACK(preferences_response_cb), NULL); + g_signal_connect(dialog, "delete-event", G_CALLBACK(preferences_dialog_delete_cb), NULL); + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), GET_WIDGET(dialog->priv->ui, "preferences_table"), TRUE, TRUE, 0); + + widget = GET_WIDGET(dialog->priv->ui, "angle_unit_combobox"); + model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget)); + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, + /* Preferences dialog: Angle unit combo box: Use degrees for trigonometric calculations */ + _("Degrees"), 1, MP_DEGREES, -1); + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, + /* Preferences dialog: Angle unit combo box: Use radians for trigonometric calculations */ + _("Radians"), 1, MP_RADIANS, -1); + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, + /* Preferences dialog: Angle unit combo box: Use gradians for trigonometric calculations */ + _("Gradians"), 1, MP_GRADIANS, -1); + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0); + + widget = GET_WIDGET(dialog->priv->ui, "number_format_combobox"); + model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget)); + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, + /* Number display mode combo: Fixed, e.g. 1234 */ + _("Fixed"), 1, FIX, -1); + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, + /* Number display mode combo: Scientific, e.g. 1.234×10^3 */ + _("Scientific"), 1, SCI, -1); + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, + /* Number display mode combo: Engineering, e.g. 1.234k */ + _("Engineering"), 1, ENG, -1); + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0); + + widget = GET_WIDGET(dialog->priv->ui, "word_size_combobox"); + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0); + + /* Label used in preferences dialog. The %d is replaced by a spinbutton */ + string = _("Show %d decimal _places"); + tokens = g_strsplit(string, "%d", 2); + widget = GET_WIDGET(dialog->priv->ui, "decimal_places_label1"); + if (tokens[0]) + string = g_strstrip(tokens[0]); + else + string = ""; + if (string[0] != '\0') + gtk_label_set_text_with_mnemonic(GTK_LABEL(widget), string); + else + gtk_widget_hide(widget); + + widget = GET_WIDGET(dialog->priv->ui, "decimal_places_label2"); + if (tokens[0] && tokens[1]) + string = g_strstrip(tokens[1]); + else + string = ""; + if (string[0] != '\0') + gtk_label_set_text_with_mnemonic(GTK_LABEL(widget), string); + else + gtk_widget_hide(widget); + + g_strfreev(tokens); + + gtk_builder_connect_signals(dialog->priv->ui, dialog); + + g_signal_connect(dialog->priv->equation, "notify::accuracy", G_CALLBACK(accuracy_cb), dialog); + g_signal_connect(dialog->priv->equation, "notify::show-thousands-separators", G_CALLBACK(show_thousands_separators_cb), dialog); + g_signal_connect(dialog->priv->equation, "notify::show-trailing_zeroes", G_CALLBACK(show_trailing_zeroes_cb), dialog); + g_signal_connect(dialog->priv->equation, "notify::number-format", G_CALLBACK(number_format_cb), dialog); + g_signal_connect(dialog->priv->equation, "notify::word-size", G_CALLBACK(word_size_cb), dialog); + g_signal_connect(dialog->priv->equation, "notify::angle-units", G_CALLBACK(angle_unit_cb), dialog); + + accuracy_cb(dialog->priv->equation, NULL, dialog); + show_thousands_separators_cb(dialog->priv->equation, NULL, dialog); + show_trailing_zeroes_cb(dialog->priv->equation, NULL, dialog); + number_format_cb(dialog->priv->equation, NULL, dialog); + word_size_cb(dialog->priv->equation, NULL, dialog); + angle_unit_cb(dialog->priv->equation, NULL, dialog); +} + + +static void +math_preferences_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MathPreferencesDialog *self; + + self = MATH_PREFERENCES (object); + + switch (prop_id) { + case PROP_EQUATION: + self->priv->equation = g_value_get_object (value); + create_gui(self); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +math_preferences_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MathPreferencesDialog *self; + + self = MATH_PREFERENCES (object); + + switch (prop_id) { + case PROP_EQUATION: + g_value_set_object (value, self->priv->equation); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void +math_preferences_class_init (MathPreferencesDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = math_preferences_get_property; + object_class->set_property = math_preferences_set_property; + + g_type_class_add_private (klass, sizeof (MathPreferencesDialogPrivate)); + + g_object_class_install_property(object_class, + PROP_EQUATION, + g_param_spec_object("equation", + "equation", + "Equation being configured", + math_equation_get_type(), + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + + +static void +math_preferences_init(MathPreferencesDialog *dialog) +{ + dialog->priv = G_TYPE_INSTANCE_GET_PRIVATE (dialog, math_preferences_get_type(), MathPreferencesDialogPrivate); +} |