Updated Latvian translation and added Latvian translation for help by Viesturs Ružāns...
[gcalctool.git] / src / math-variable-popup.c
blobd0335711c0d9ef5311c0be5fbb5c53f0a73d80bc
1 /*
2 * Copyright (C) 2008-2011 Robert Ancell
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation, either version 2 of the License, or (at your option) any later
7 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
8 * license.
9 */
11 #include <glib/gi18n.h>
12 #include <gdk/gdkkeysyms.h>
14 #include "math-variable-popup.h"
16 enum {
17 PROP_0,
18 PROP_EQUATION
21 struct MathVariablePopupPrivate
23 MathEquation *equation;
25 GtkWidget *vbox;
26 GtkWidget *variable_name_entry;
27 GtkWidget *add_variable_button;
30 G_DEFINE_TYPE (MathVariablePopup, math_variable_popup, GTK_TYPE_WINDOW);
32 MathVariablePopup *
33 math_variable_popup_new(MathEquation *equation)
35 return g_object_new(math_variable_popup_get_type(), "equation", equation, NULL);
39 static void
40 variable_focus_out_event_cb(GtkWidget *widget, GdkEventFocus *event, MathVariablePopup *popup)
42 gtk_widget_destroy(widget);
46 static void
47 insert_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
49 const gchar *name;
51 name = g_object_get_data(G_OBJECT(widget), "variable_name");
52 math_equation_insert(popup->priv->equation, name);
54 gtk_widget_destroy(gtk_widget_get_toplevel(widget));
58 static gboolean
59 variable_name_key_press_cb(GtkWidget *widget, GdkEventKey *event, MathVariablePopup *popup)
61 /* Can't have whitespace in names, so replace with underscores */
62 if (event->keyval == GDK_KEY_space || event->keyval == GDK_KEY_KP_Space)
63 event->keyval = GDK_KEY_underscore;
65 return FALSE;
69 static void
70 variable_name_changed_cb(GtkWidget *widget, MathVariablePopup *popup)
72 const gchar *text = gtk_entry_get_text(GTK_ENTRY(popup->priv->variable_name_entry));
73 gtk_widget_set_sensitive(popup->priv->add_variable_button, text[0] != '\0');
77 static void
78 add_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
80 const gchar *name;
81 MPNumber z;
83 name = gtk_entry_get_text(GTK_ENTRY(popup->priv->variable_name_entry));
84 if (name[0] == '\0')
85 return;
87 if (math_equation_get_number(popup->priv->equation, &z))
88 math_variables_set(math_equation_get_variables(popup->priv->equation), name, &z);
89 else if (math_equation_is_result(popup->priv->equation))
90 math_variables_set(math_equation_get_variables(popup->priv->equation), name, math_equation_get_answer(popup->priv->equation));
91 else
92 g_warning("Can't add variable %s, the display is not a number", name);
94 gtk_widget_destroy(gtk_widget_get_toplevel(widget));
98 static void
99 save_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
101 const gchar *name;
102 MPNumber z;
104 name = g_object_get_data(G_OBJECT(widget), "variable_name");
105 if (math_equation_get_number(popup->priv->equation, &z))
106 math_variables_set(math_equation_get_variables(popup->priv->equation), name, &z);
107 else if (math_equation_is_result(popup->priv->equation))
108 math_variables_set(math_equation_get_variables(popup->priv->equation), name, math_equation_get_answer(popup->priv->equation));
109 else
110 g_warning("Can't save variable %s, the display is not a number", name);
112 gtk_widget_destroy(gtk_widget_get_toplevel(widget));
116 static void
117 delete_variable_cb(GtkWidget *widget, MathVariablePopup *popup)
119 const gchar *name;
121 name = g_object_get_data(G_OBJECT(widget), "variable_name");
122 math_variables_delete(math_equation_get_variables(popup->priv->equation), name);
124 gtk_widget_destroy(gtk_widget_get_toplevel(widget));
128 static GtkWidget *
129 make_variable_entry(MathVariablePopup *popup, const gchar *name, const MPNumber *value, gboolean writable)
131 GtkWidget *hbox, *button, *label;
132 gchar *text;
134 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
136 if (value)
138 gchar *value_text = mp_serializer_to_string(math_equation_get_serializer(popup->priv->equation), value);
139 text = g_strdup_printf("<b>%s</b> = %s", name, value_text);
140 g_free (value_text);
142 else
143 text = g_strdup_printf("<b>%s</b>", name);
145 button = gtk_button_new();
146 g_object_set_data(G_OBJECT(button), "variable_name", g_strdup(name)); // FIXME: These will all leak memory
147 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(insert_variable_cb), popup);
148 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
149 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
150 gtk_widget_show(button);
152 label = gtk_label_new(text);
153 g_free(text);
154 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
155 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
156 gtk_container_add(GTK_CONTAINER(button), label);
157 gtk_widget_show(label);
159 if (writable)
161 GtkWidget *image;
163 button = gtk_button_new();
164 g_object_set_data(G_OBJECT(button), "variable_name", g_strdup(name));
165 image = gtk_image_new_from_stock(GTK_STOCK_SAVE, GTK_ICON_SIZE_BUTTON);
166 gtk_container_add(GTK_CONTAINER(button), image);
167 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
168 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(save_variable_cb), popup);
169 gtk_widget_show(image);
170 gtk_widget_show(button);
172 button = gtk_button_new();
173 g_object_set_data(G_OBJECT(button), "variable_name", g_strdup(name));
174 image = gtk_image_new_from_stock(GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON);
175 gtk_container_add(GTK_CONTAINER(button), image);
176 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
177 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(delete_variable_cb), popup);
178 gtk_widget_show(image);
179 gtk_widget_show(button);
182 return hbox;
186 static void
187 math_variable_popup_set_property(GObject *object,
188 guint prop_id,
189 const GValue *value,
190 GParamSpec *pspec)
192 MathVariablePopup *self;
193 gchar **names;
194 int i;
195 GtkWidget *entry, *image;
197 self = MATH_VARIABLE_POPUP(object);
199 switch (prop_id) {
200 case PROP_EQUATION:
201 self->priv->equation = g_value_get_object(value);
203 names = math_variables_get_names(math_equation_get_variables(self->priv->equation));
204 for (i = 0; names[i]; i++) {
205 MPNumber *value;
207 value = math_variables_get(math_equation_get_variables(self->priv->equation), names[i]);
208 entry = make_variable_entry(self, names[i], value, TRUE);
209 gtk_widget_show(entry);
210 gtk_box_pack_start(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
212 g_strfreev(names);
214 entry = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
215 gtk_widget_show(entry);
217 // TODO: Show greyed "variable name" text to give user a hint how to use
218 self->priv->variable_name_entry = gtk_entry_new();
219 g_signal_connect(G_OBJECT(self->priv->variable_name_entry), "key-press-event", G_CALLBACK(variable_name_key_press_cb), self);
220 g_signal_connect(G_OBJECT(self->priv->variable_name_entry), "changed", G_CALLBACK(variable_name_changed_cb), self);
221 g_signal_connect(G_OBJECT(self->priv->variable_name_entry), "activate", G_CALLBACK(add_variable_cb), self);
222 gtk_box_pack_start(GTK_BOX(entry), self->priv->variable_name_entry, TRUE, TRUE, 0);
223 gtk_widget_show(self->priv->variable_name_entry);
225 self->priv->add_variable_button = gtk_button_new();
226 gtk_widget_set_sensitive(self->priv->add_variable_button, FALSE);
227 g_signal_connect(G_OBJECT(self->priv->add_variable_button), "clicked", G_CALLBACK(add_variable_cb), self);
228 image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
229 gtk_container_add(GTK_CONTAINER(self->priv->add_variable_button), image);
230 gtk_box_pack_start(GTK_BOX(entry), self->priv->add_variable_button, FALSE, TRUE, 0);
231 gtk_widget_show(image);
232 gtk_widget_show(self->priv->add_variable_button);
233 gtk_box_pack_end(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
235 entry = make_variable_entry(self, "rand", NULL, FALSE);
236 gtk_widget_show(entry);
237 gtk_box_pack_end(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
239 entry = make_variable_entry(self, "ans", math_equation_get_answer(self->priv->equation), FALSE);
240 gtk_widget_show(entry);
241 gtk_box_pack_end(GTK_BOX(self->priv->vbox), entry, FALSE, TRUE, 0);
242 break;
243 default:
244 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
245 break;
250 static void
251 math_variable_popup_get_property(GObject *object,
252 guint prop_id,
253 GValue *value,
254 GParamSpec *pspec)
256 MathVariablePopup *self;
258 self = MATH_VARIABLE_POPUP(object);
260 switch (prop_id) {
261 case PROP_EQUATION:
262 g_value_set_object(value, self->priv->equation);
263 break;
264 default:
265 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
266 break;
271 static void
272 math_variable_popup_class_init(MathVariablePopupClass *klass)
274 GObjectClass *object_class = G_OBJECT_CLASS(klass);
276 object_class->get_property = math_variable_popup_get_property;
277 object_class->set_property = math_variable_popup_set_property;
279 g_type_class_add_private(klass, sizeof(MathVariablePopupPrivate));
281 g_object_class_install_property(object_class,
282 PROP_EQUATION,
283 g_param_spec_object("equation",
284 "equation",
285 "Equation being controlled",
286 math_equation_get_type(),
287 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
291 static void
292 math_variable_popup_init(MathVariablePopup *popup)
294 popup->priv = G_TYPE_INSTANCE_GET_PRIVATE(popup, math_variable_popup_get_type(), MathVariablePopupPrivate);
296 gtk_window_set_decorated(GTK_WINDOW(popup), FALSE);
297 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(popup), TRUE);
299 gtk_container_set_border_width(GTK_CONTAINER(popup), 6);
301 /* Destroy this window when it loses focus */
302 g_signal_connect(G_OBJECT(popup), "focus-out-event", G_CALLBACK(variable_focus_out_event_cb), popup);
304 popup->priv->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
305 gtk_box_set_homogeneous(GTK_BOX(popup->priv->vbox), TRUE);
306 gtk_container_add(GTK_CONTAINER(popup), popup->priv->vbox);
307 gtk_widget_show(popup->priv->vbox);