~ubuntu-branches/ubuntu/lucid/gcalctool/lucid-updates

« back to all changes in this revision

Viewing changes to src/gtk.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2010-04-07 19:41:56 UTC
  • mfrom: (1.3.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100407194156-hgj8g002ffce2de0
Tags: 5.30.0.is.5.28.2-0ubuntu1
Downgrade to 5.28.2 as the new version does not support number bases
as well.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
2
 
 *  Copyright (c) 2008-2009 Robert Ancell
 
1
 
 
2
/*  $Header$
3
3
 *
 
4
 *  Copyright (c) 1987-2008 Sun Microsystems, Inc. All Rights Reserved.
 
5
 *  Copyright (c) 2008 Robert Ancell
 
6
 *           
4
7
 *  This program is free software; you can redistribute it and/or modify
5
8
 *  it under the terms of the GNU General Public License as published by
6
9
 *  the Free Software Foundation; either version 2, or (at your option)
7
10
 *  any later version.
8
 
 *
9
 
 *  This program is distributed in the hope that it will be useful, but
 
11
 *           
 
12
 *  This program is distributed in the hope that it will be useful, but 
10
13
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
12
15
 *  General Public License for more details.
13
 
 *
 
16
 *           
14
17
 *  You should have received a copy of the GNU General Public License
15
18
 *  along with this program; if not, write to the Free Software
16
19
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24
27
#include <assert.h>
25
28
 
26
29
#include <gtk/gtk.h>
 
30
#include <gdk/gdkx.h>
27
31
#include <gdk/gdkkeysyms.h>
28
32
 
29
33
#include <limits.h>
34
38
#include "ui.h"
35
39
 
36
40
#include "config.h"
 
41
#include "functions.h"
37
42
#include "financial.h"
38
 
#include "currency.h"
39
43
#include "mp-equation.h"
40
44
#include "display.h"
41
45
#include "get.h"
44
48
static const char *mode_names[] = { "BASIC", "ADVANCED", "FINANCIAL",
45
49
                                    "SCIENTIFIC", "PROGRAMMING", NULL };
46
50
 
47
 
typedef struct {
48
 
    const char *widget_name;
49
 
    const char *data;
50
 
} ButtonData;
51
 
 
52
 
static ButtonData button_data[] = {
53
 
    {"pi",                 "π"},
54
 
    {"eulers_number",      "e"},
55
 
    {"random",             "rand"},
56
 
    {"ans",                "ans"},
57
 
    {"numeric_point",      "."},
58
 
    {"add",                "+"},
59
 
    {"multiply",           "×"},
60
 
    {"divide",             "÷"},
61
 
    {"modulus_divide",     " mod "},
62
 
    {"x_pow_y",            "^"},
63
 
    {"percentage",         "%"},
64
 
    {"factorial",          "!"},
65
 
    {"abs",                "|"},
66
 
    {"root",               "√"},
67
 
    {"logarithm",          "log"},
68
 
    {"natural_logarithm",  "ln"},
69
 
    {"sine",               "sin"},
70
 
    {"cosine",             "cos"},
71
 
    {"tangent",            "tan"},
72
 
    {"hyperbolic_sine",    "sinh"},
73
 
    {"hyperbolic_cosine",  "cosh"},
74
 
    {"hyperbolic_tangent", "tanh"},
75
 
    {"inverse",            "⁻¹"},
76
 
    {"and",                " AND "},
77
 
    {"or",                 " OR "},
78
 
    {"xor",                " XOR "},
79
 
    {"not",                " NOT "},
80
 
    {"integer_portion",    "int"},
81
 
    {"fractional_portion", "frac"},
82
 
    {"ones_complement",    "ones"},
83
 
    {"twos_complement",    "twos"},
84
 
    {"trunc",              "trunc"},
85
 
    {"start_group",        "("},
86
 
    {"end_group",          ")"},
87
 
    {NULL, NULL}
 
51
#define MAX_ACCELERATORS 8
 
52
struct button_widget {
 
53
    int function;
 
54
    char *widget_name;
 
55
    guint accelerator_mods[MAX_ACCELERATORS];
 
56
    guint accelerator_keys[MAX_ACCELERATORS];
88
57
};
89
58
 
90
 
static char *registers[] = {"a", "b", "c", "x", "y", "z", NULL};
91
 
#define MAX_REGISTERS 6
92
 
 
93
59
/* Window titles dependant on mode */
94
60
static char *titles[] = {
95
61
    /* Translators: The window title when in basic mode */
96
62
    N_("Calculator"),
97
 
    /* Translators: The window title when in advanced mode */
98
 
    N_("Calculator — Advanced"),
 
63
    /* Translators: The window title when in advanced mode */    
 
64
    N_("Calculator - Advanced"),
99
65
    /* Translators: The window title when in financial mode */
100
 
    N_("Calculator — Financial"),
 
66
    N_("Calculator - Financial"),
101
67
    /* Translators: The window title when in scientific mode */
102
 
    N_("Calculator — Scientific"),
 
68
    N_("Calculator - Scientific"),
103
69
    /* Translators: The window title when in programming mode */
104
 
    N_("Calculator — Programming")
 
70
    N_("Calculator - Programming")
 
71
};
 
72
 
 
73
/* Window titles dependant on mode and hostname */
 
74
static char *hostname_titles[] = {
 
75
    /* Translators: The window title when in basic mode. %s is replaced with the hostname. */
 
76
    N_("Calculator [%s]"),
 
77
    /* Translators: The window title when in advanced mode. %s is replaced with the hostname. */
 
78
    N_("Calculator [%s] - Advanced"),
 
79
    /* Translators: The window title when in financial mode. %s is replaced with the hostname. */
 
80
    N_("Calculator [%s] - Financial"),
 
81
    /* Translators: The window title when in scientific mode. %s is replaced with the hostname. */
 
82
    N_("Calculator [%s] - Scientific"),
 
83
    /* Translators: The window title when in programming mode. %s is replaced with the hostname. */
 
84
    N_("Calculator [%s] - Programming")
105
85
};
106
86
 
107
87
/* The names of each field in the dialogs for the financial functions */
108
 
static char *finc_dialog_fields[][5] = {
 
88
static char *finc_dialog_fields[FINC_NUM_DIALOGS][5] = {
109
89
    {"ctrm_pint", "ctrm_fv",     "ctrm_pv",    NULL,         NULL},
110
90
    {"ddb_cost",  "ddb_life",    "ddb_period", NULL,         NULL},
111
91
    {"fv_pmt",    "fv_pint",     "fv_n",       NULL,         NULL},
116
96
    {"sln_cost",  "sln_salvage", "sln_life",   NULL,         NULL},
117
97
    {"syd_cost",  "syd_salvage", "syd_life",   "syd_period", NULL},
118
98
    {"term_pmt",  "term_fv",     "term_pint",  NULL,         NULL},
119
 
    {NULL,        NULL,          NULL,         NULL,         NULL}
120
 
};
121
 
 
122
 
#define UI_FILE      UI_DIR "/gcalctool.ui"
123
 
#define UI_FINC_FILE UI_DIR "/financial.ui"
 
99
};
 
100
 
 
101
/*  This table shows the keyboard values that are currently being used:
 
102
 *
 
103
 *           |  a b c d e f g h i j k l m n o p q r s t u v w x y z
 
104
 *-----------+-----------------------------------------------------
 
105
 *  Lower:   |  a b c d e f g h i j k l m n o p q r s t u v w x   z
 
106
 *  Upper:   |  A   C D E F G H I J K   M N O P Q R S T     W X Y Z
 
107
 *  Numeric: |  0 1 2 3 4 5 6 7 8 9
 
108
 *  Other:   |  @ . + - * / = % ( ) # < > [   { | & ~ ^ ? ! :
 
109
 *           |  BackSpace Delete Return
 
110
 *-----------+-----------------------------------------------------
 
111
 */
 
112
    
 
113
static struct button_widget button_widgets[] = {
 
114
    {FN_0,                  "0",
 
115
    { 0,     0,        0,             0 },
 
116
    { GDK_0, GDK_KP_0, GDK_KP_Insert, 0 }},
 
117
 
 
118
    {FN_1,                  "1",
 
119
    { 0,     0,        0,          0,       0 },
 
120
    { GDK_1, GDK_KP_1, GDK_KP_End, GDK_R13, 0 }},
 
121
 
 
122
    {FN_2,                  "2",
 
123
    { 0,     0,        0,           0 }, 
 
124
    { GDK_2, GDK_KP_2, GDK_KP_Down, 0 }},
 
125
 
 
126
    {FN_3,                  "3",
 
127
    { 0,     0,        0,                0,       0 },
 
128
    { GDK_3, GDK_KP_3, GDK_KP_Page_Down, GDK_R15, 0 }},
 
129
 
 
130
    {FN_4,                  "4",
 
131
    { 0,     0,        0,           0 },
 
132
    { GDK_4, GDK_KP_4, GDK_KP_Left, 0 }},
 
133
 
 
134
    {FN_5,                  "5",
 
135
    { 0,     0,        0,            0,       0 },
 
136
    { GDK_5, GDK_KP_5, GDK_KP_Begin, GDK_R11, 0 }},
 
137
 
 
138
    {FN_6,                  "6",
 
139
    { 0,     0,        0,            0 },
 
140
    { GDK_6, GDK_KP_6, GDK_KP_Right, 0 }},
 
141
 
 
142
    {FN_7,                  "7",
 
143
    { 0,     0,        0,           0,      0 },
 
144
    { GDK_7, GDK_KP_7, GDK_KP_Home, GDK_R7, 0 }},
 
145
 
 
146
    {FN_8,                  "8",
 
147
    { 0,     0,        0,         0 },
 
148
    { GDK_8, GDK_KP_8, GDK_KP_Up, 0 }},
 
149
 
 
150
    {FN_9,                  "9",
 
151
    { 0,     0,        0,              0,      0 },
 
152
    { GDK_9, GDK_KP_9, GDK_KP_Page_Up, GDK_R9, 0 }},
 
153
 
 
154
    {FN_A,                  "a",
 
155
    { 0,     0 },
 
156
    { GDK_a, 0 }},
 
157
 
 
158
    {FN_B,                  "b",
 
159
    { 0,     0 },
 
160
    { GDK_b, 0 }},
 
161
 
 
162
    {FN_C,                  "c",
 
163
    { 0,     0 },
 
164
    { GDK_c, 0 }},
 
165
 
 
166
    {FN_D,                  "d",
 
167
    { 0,     0 },
 
168
    { GDK_d, 0 }},
 
169
 
 
170
    {FN_E,                  "e",
 
171
    { 0,     0 },
 
172
    { GDK_e, 0 }},
 
173
 
 
174
    {FN_F,                  "f",
 
175
    { 0,     0 },
 
176
    { GDK_f, 0 }},
 
177
 
 
178
    {FN_CLEAR,              "clear_simple",
 
179
    { GDK_SHIFT_MASK, 0 },
 
180
    { GDK_Delete,     0 }},
 
181
    
 
182
    {FN_CLEAR,              "clear_advanced",
 
183
    { GDK_SHIFT_MASK, 0 },
 
184
    { GDK_Delete,     0 }},
 
185
 
 
186
    {FN_SHIFT,              "shift_left",
 
187
    { 0,        0 },
 
188
    { GDK_less, 0 }},
 
189
 
 
190
    {FN_SHIFT,              "shift_right",
 
191
    { 0,           0 },
 
192
    { GDK_greater, 0 }},
 
193
 
 
194
    {FN_SET_ACCURACY,       "accuracy",
 
195
    { 0,     0 },
 
196
    { GDK_A, 0 }},
 
197
 
 
198
    {FN_CONSTANT,           "constants",
 
199
    { 0,              0 },
 
200
    { GDK_numbersign, 0 }},
 
201
 
 
202
    {FN_FUNCTION,           "functions",
 
203
    { 0,     0 },
 
204
    { GDK_F, 0 }},
 
205
 
 
206
    {FN_STORE,              "store",
 
207
    { 0,     0 },
 
208
    { GDK_S, 0 }},
 
209
 
 
210
    {FN_RECALL,             "recall",
 
211
    { 0,     0 },
 
212
    { GDK_R, 0 }},
 
213
 
 
214
    {FN_EXCHANGE,           "exchange",
 
215
    { 0,     0 },
 
216
    { GDK_X, 0 }},
 
217
 
 
218
    {FN_CLEAR_ENTRY,        "clear_entry_simple",
 
219
    { GDK_CONTROL_MASK, 0,          0 },
 
220
    { GDK_BackSpace,    GDK_Escape, 0 }},
 
221
 
 
222
    {FN_CLEAR_ENTRY,        "clear_entry_advanced",
 
223
    { GDK_CONTROL_MASK, 0,          0 },
 
224
    { GDK_BackSpace,    GDK_Escape, 0 }},
 
225
 
 
226
    {FN_BACKSPACE,          "backspace_simple",
 
227
    { 0,             0 },
 
228
    { GDK_BackSpace, 0 }},
 
229
 
 
230
    {FN_BACKSPACE,          "backspace_advanced",
 
231
    { 0,             0 },
 
232
    { GDK_BackSpace, 0 }},
 
233
    
 
234
    {FN_NUMERIC_POINT,      "numeric_point",
 
235
    { 0,          0,              0,             0,                0 },
 
236
    { GDK_period, GDK_KP_Decimal, GDK_KP_Delete, GDK_KP_Separator, 0 }},
 
237
 
 
238
    {FN_CALCULATE,          "result",
 
239
    { 0,         0,            0,          0 },
 
240
    { GDK_equal, GDK_KP_Enter, GDK_Return, 0 }},
 
241
 
 
242
    {FN_START_BLOCK,        "start_group",
 
243
    { 0,             0 },
 
244
    { GDK_parenleft, 0 }},
 
245
 
 
246
    {FN_END_BLOCK,          "end_group",
 
247
    { 0,              0 },
 
248
    { GDK_parenright, 0 }},
 
249
 
 
250
    {FN_ADD,                "add",
 
251
    { 0,        0,          0 },
 
252
    { GDK_plus, GDK_KP_Add, 0 }},
 
253
 
 
254
    {FN_SUBTRACT,           "subtract",
 
255
    { 0,         0,               0,      0 },
 
256
    { GDK_minus, GDK_KP_Subtract, GDK_R4, 0 }},
 
257
 
 
258
    {FN_MULTIPLY,           "multiply",
 
259
    { 0,            0,            0,               0,      0 },
 
260
    { GDK_asterisk, GDK_multiply, GDK_KP_Multiply, GDK_R6, 0 }},
 
261
 
 
262
    {FN_DIVIDE,             "divide",
 
263
    { 0,         0,            0,             0,      0 },
 
264
    { GDK_slash, GDK_division, GDK_KP_Divide, GDK_R5, 0 }},
 
265
 
 
266
    {FN_CHANGE_SIGN,        "change_sign_simple",
 
267
    { 0,     0 },
 
268
    { GDK_C, 0 }},
 
269
 
 
270
    {FN_CHANGE_SIGN,        "change_sign_advanced",
 
271
    { 0,     0 },
 
272
    { GDK_C, 0 }},
 
273
 
 
274
    {FN_INTEGER,            "integer_portion",
 
275
    { 0,     0 },
 
276
    { GDK_i, 0 }},
 
277
 
 
278
    {FN_FRACTION,           "fractional_portion",
 
279
    { 0,         0 },
 
280
    { GDK_colon, 0 }},
 
281
 
 
282
    {FN_PERCENTAGE,         "percentage",
 
283
    { 0,           0 },
 
284
    { GDK_percent, 0 }},
 
285
 
 
286
    {FN_SQUARE,             "square",
 
287
    { 0,      0 },
 
288
    { GDK_at, 0 }},
 
289
 
 
290
    {FN_SQUARE_ROOT,        "sqrt",
 
291
    { 0,     0 },
 
292
    { GDK_s, 0 }},
 
293
 
 
294
    {FN_RECIPROCAL,         "reciprocal",
 
295
    { 0,     0 },
 
296
    { GDK_r, 0 }},
 
297
 
 
298
    {FN_ABSOLUTE_VALUE_FUNC, "abs",
 
299
    { 0,     0 },
 
300
    { GDK_u, 0 }},
 
301
 
 
302
    {FN_TRUNC,              "trunc",
 
303
    { 0,                0 },
 
304
    { GDK_bracketleft, 0 }},
 
305
 
 
306
    {FN_MODULUS_DIVIDE,     "modulus_divide",
 
307
    { 0,     0 },
 
308
    { GDK_M, 0 }},
 
309
 
 
310
    {FN_1S_COMPLEMENT,      "1s",
 
311
    { 0,     0 },
 
312
    { GDK_z, 0 }},
 
313
 
 
314
    {FN_2S_COMPLEMENT,      "2s",
 
315
    { 0,     0 },
 
316
    { GDK_Z, 0 }},
 
317
 
 
318
    {FN_EXPONENTIAL,        "exponential",
 
319
    { 0,     0 },
 
320
    { GDK_E, 0 }},
 
321
 
 
322
    {FN_FACTORIAL,          "factorial",
 
323
    { 0,          0 },
 
324
    { GDK_exclam, 0 }},
 
325
 
 
326
    {FN_RANDOM,             "random",
 
327
    { 0,            0 },
 
328
    { GDK_question, 0 }},
 
329
 
 
330
    {FN_NOT,                "not",
 
331
    { 0,              0 },
 
332
    { GDK_asciitilde, 0 }},
 
333
 
 
334
    {FN_OR,                 "or",
 
335
    { 0,       0 },
 
336
    { GDK_bar, 0 }},
 
337
 
 
338
    {FN_AND,                "and",
 
339
    { 0,             0 },
 
340
    { GDK_ampersand, 0 }},
 
341
 
 
342
    {FN_XOR,                "xor",
 
343
    { 0,     0 },
 
344
    { GDK_x, 0 }},
 
345
 
 
346
    {FN_XNOR,               "xnor",
 
347
    { 0,     0 },
 
348
    { GDK_braceleft, 0 }},
 
349
 
 
350
    {FN_SIN,                "sine",
 
351
    { 0,     0 },
 
352
    { GDK_k, 0 }},
 
353
 
 
354
    {FN_ASIN,                "sine",
 
355
    { 0,     0 },
 
356
    { GDK_K, 0 }},
 
357
 
 
358
    {FN_COS,                 "cosine",
 
359
    { 0,     0 },
 
360
    { GDK_j, 0 }},
 
361
 
 
362
    {FN_ACOS,                "cosine",
 
363
    { 0,     0 },
 
364
    { GDK_J, 0 }},
 
365
 
 
366
    {FN_TAN,                 "tangent",
 
367
    { 0,     0 },
 
368
    { GDK_w, 0 }},
 
369
 
 
370
    {FN_ATAN,                "tangent",
 
371
    { 0,     0 },
 
372
    { GDK_W, 0 }},
 
373
 
 
374
    {FN_NATURAL_LOGARITHM,  "natural_logarithm",
 
375
    { 0,     0 },
 
376
    { GDK_n, 0 }},
 
377
 
 
378
    {FN_E_POW_X,            "natural_logarithm",
 
379
    { 0,             0 },
 
380
    { GDK_N, 0 }},
 
381
 
 
382
    {FN_LOGARITHM,          "logarithm",
 
383
    { 0,     0 },
 
384
    { GDK_g, 0 }},
 
385
 
 
386
    {FN_10_POW_X,           "logarithm",
 
387
    { 0,              0 },
 
388
    { GDK_G, 0 }},
 
389
 
 
390
    {FN_LOGARITHM2,         "logarithm2",
 
391
    { 0,     0 },
 
392
    { GDK_h, 0 }},
 
393
 
 
394
    {FN_2_POW_X,            "logarithm2",
 
395
    { 0,     0 },
 
396
    { GDK_H, 0 }},
 
397
 
 
398
    {FN_X_POW_Y,            "x_pow_y",
 
399
    { 0,     0,         0,               0,                   0 },
 
400
    { GDK_o, GDK_caret, GDK_asciicircum, GDK_dead_circumflex, 0 }},
 
401
 
 
402
    {FN_X_POW_Y_INV,        "x_pow_y",
 
403
    { 0,     0 },
 
404
    { GDK_O, 0 }},
 
405
    
 
406
    {FN_FINC_CTRM,          "finc_compounding_term",
 
407
    { 0,     0 },
 
408
    { GDK_m, 0 }},
 
409
 
 
410
    {FN_FINC_DDB,           "finc_double_declining_depreciation",
 
411
    { 0,     0 },
 
412
    { GDK_D, 0 }},
 
413
 
 
414
    {FN_FINC_FV,            "finc_future_value",
 
415
    { 0,     0 },
 
416
    { GDK_v, 0 }},
 
417
 
 
418
    {FN_FINC_GPM,           "finc_gross_profit_margin",
 
419
    { 0,     0 },
 
420
    { GDK_I, 0 }},
 
421
 
 
422
    {FN_FINC_PMT,           "finc_periodic_payment",
 
423
    { 0,     0 },
 
424
    { GDK_P, 0 }},
 
425
 
 
426
    {FN_FINC_PV,            "finc_present_value",
 
427
    { 0,     0 },
 
428
    { GDK_p, 0 }},
 
429
 
 
430
    {FN_FINC_RATE,          "finc_periodic_interest_rate",
 
431
    { 0,     0 },
 
432
    { GDK_T, 0 }},
 
433
 
 
434
    {FN_FINC_SLN,           "finc_straight_line_depreciation",
 
435
    { 0,     0 },
 
436
    { GDK_l, 0 }},
 
437
 
 
438
    {FN_FINC_SYD,           "finc_sum_of_the_years_digits_depreciation",
 
439
    { 0,     0 },
 
440
    { GDK_Y, 0 }},
 
441
 
 
442
    {FN_FINC_TERM,          "finc_term",
 
443
    { 0,     0 },
 
444
    { GDK_t, 0 }}
 
445
};
 
446
#define NBUTTONS (sizeof(button_widgets) / sizeof(struct button_widget))
 
447
 
 
448
#define UI_FILE      PACKAGE_UI_DIR "/gcalctool.ui"
 
449
#define UI_FINC_FILE PACKAGE_UI_DIR "/financial.ui"
124
450
 
125
451
#define MAXBITS 64      /* Bit panel: number of bit fields. */
126
452
 
131
457
#define GET_FINC_WIDGET(name) \
132
458
          GTK_WIDGET(gtk_builder_get_object(X.financial, (name)))
133
459
 
134
 
/* Calculator modes. */
135
 
typedef enum {
136
 
    BASIC,
137
 
    ADVANCED,
138
 
    FINANCIAL,
139
 
    SCIENTIFIC,
140
 
    PROGRAMMING
141
 
} ModeType;
142
 
 
143
460
/* Gtk+/Xlib graphics object. */
144
461
typedef struct {
145
 
    ModeType mode;  /* Current calculator mode. */
 
462
    ModeType mode;  /* Current calculator mode. */   
146
463
 
147
464
    GtkBuilder *ui;
148
465
    GtkBuilder *financial;
149
 
 
 
466
    
150
467
    GtkWidget *main_window;
 
468
 
 
469
    GtkTreeModel *constants_model;
 
470
    GtkWidget    *constants_dialog;
 
471
    
 
472
    GtkTreeModel *functions_model;
 
473
    GtkWidget    *function_dialog;
151
474
 
152
475
    GtkWidget *menubar; // FIXME: Why is this needed?
153
476
 
154
477
    GtkWidget *bit_panel;
155
478
    GtkWidget *bit_labels[MAXBITS];
156
479
 
 
480
    GtkWidget *status_image;           /* Statusbar image */
 
481
    GtkWidget *statusbar; 
 
482
 
157
483
    GtkWidget *ascii_dialog;
158
484
    GtkWidget *ascii_entry;
159
485
 
160
486
    GtkWidget *display_item;           /* Calculator display. */
161
487
    GtkTextBuffer *display_buffer;     /* Buffer used in display */
162
 
    GtkTextBuffer *info_buffer;        /* Buffer used in info messages */
163
488
    GtkWidget *scrolledwindow;         /* Scrolled window for display_item. */
164
489
 
 
490
    GtkWidget *register_dialog;
 
491
    GtkWidget *register_entries[MAX_REGISTERS];
 
492
 
 
493
    GtkWidget *precision_dialog;
 
494
    GtkWidget *precision_spin;
 
495
 
 
496
    GtkWidget *buttons[NBUTTONS];
 
497
    GtkWidget *digit_buttons[16];
 
498
    GtkWidget *clear_buttons[2];
 
499
 
165
500
    GtkWidget *bas_panel;      /* Panel containing basic mode widgets. */
166
501
    GtkWidget *adv_panel;      /* Panel containing advanced mode widgets. */
167
502
    GtkWidget *fin_panel;      /* Panel containing financial mode widgets. */
168
503
    GtkWidget *sci_panel;      /* Panel containing scientific mode widgets. */
169
504
    GtkWidget *prog_panel;     /* Panel containing programming mode widgets. */
170
 
 
171
 
    GtkWidget *superscript_toggle;
172
 
    GtkWidget *subscript_toggle;
173
 
 
174
 
    gboolean can_super_minus;
175
 
 
 
505
    GtkWidget *sci_mode_panel; /* Panel containing scientific mode widgets. */
 
506
    GtkWidget *prog_mode_panel;/* Panel containing programming mode widgets. */
 
507
    
176
508
    /* Labels for popup menus */
 
509
    GtkWidget *constant_menu_labels[MAX_CONSTANTS];
 
510
    GtkWidget *function_menu_labels[MAX_FUNCTIONS];
177
511
    GtkWidget *memory_store_labels[MAX_REGISTERS];
178
512
    GtkWidget *memory_recall_labels[MAX_REGISTERS];
 
513
    GtkWidget *memory_exchange_labels[MAX_REGISTERS];
 
514
    
 
515
    /* Scientific mode widgets */
 
516
    GtkWidget *hyperbolic_toggle;      /* Hyperbolic mode. */
 
517
    GtkWidget *inverse_toggle;         /* Inverse mode. */
 
518
    GtkWidget *display_mode_radios[MAXDISPMODES]; /* Numeric display mode. */
 
519
    GtkWidget *radian_radio;           /* Radian radio button. */
 
520
    GtkWidget *degree_radio;           /* Degree radio button. */
 
521
    GtkWidget *gradian_radio;          /* Gradian radio button. */
179
522
 
180
 
    GtkWidget *preferences_dialog;
 
523
    /* Programming mode widgets */
 
524
    GtkWidget *binary_radio;
 
525
    GtkWidget *octal_radio;
 
526
    GtkWidget *decimal_radio;
 
527
    GtkWidget *hexadecimal_radio;
 
528
    GtkWidget *word_length_radios[3];             /* Wordlength radio buttons. */
181
529
 
182
530
    GdkAtom clipboard_atom;
183
 
    GdkAtom primary_atom;
 
531
    GdkAtom primary_atom;  
184
532
    char *shelf;                       /* PUT selection shelf contents. */
185
 
 
186
 
    /* Last text entered */
187
 
    char *last_text;
 
533
    
 
534
    int last_function;
188
535
} GtkUI;
189
536
static GtkUI X;
190
537
 
211
558
    POPUP_CENTERED   /* Center popup within baseframe */
212
559
} PopupLocation;
213
560
 
214
 
typedef enum {
215
 
    CURRENCY_TARGET_UPPER,
216
 
    CURRENCY_TARGET_LOWER
217
 
} CurrencyTargetRow;
218
 
 
219
 
static const char *subscript_digits[] = {"₀", "₁", "₂", "₃", "₄", "₅", "₆", "₇", "₈", "₉", NULL};
220
 
static const char *superscript_digits[] = {"⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹", NULL};
221
 
 
222
561
static void load_ui(GtkBuilder *ui, const gchar *filename)
223
562
{
224
563
    GError *error = NULL;
227
566
    gtk_builder_add_from_file(ui, filename, &error);
228
567
    if (error == NULL)
229
568
        return;
230
 
 
 
569
        
231
570
    dialog = gtk_message_dialog_new(NULL, 0,
232
571
                                    GTK_MESSAGE_ERROR,
233
572
                                    GTK_BUTTONS_NONE,
235
574
                                    N_("Error loading user interface"));
236
575
    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
237
576
                                             /* Translators: Description in UI error dialog when unable to load the UI files. %s is replaced with the error message provided by GTK+ */
238
 
                                             N_("A required file is missing or damaged. Please check your installation.\n\n%s"), error->message);
 
577
                                             N_("A required file is missing or damaged, please check your installation.\n\n%s"), error->message);
239
578
    gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_QUIT, GTK_RESPONSE_ACCEPT, NULL);
240
 
 
 
579
    
241
580
    gtk_dialog_run(GTK_DIALOG(dialog));
242
581
    exit(0);
243
582
}
244
583
 
245
 
static void set_data(GtkBuilder *ui, const gchar *object_name, const gchar *name, const gpointer value)
 
584
static void set_data(GtkBuilder *ui, const gchar *object_name, const gchar *name, gpointer value)
246
585
{
247
586
    g_object_set_data(gtk_builder_get_object(ui, object_name), name, value);
248
587
}
249
588
 
250
 
static void set_string_data(GtkBuilder *ui, const gchar *object_name, const gchar *name, const char *value)
251
 
{
252
 
    g_object_set_data(gtk_builder_get_object(ui, object_name), name, (gpointer)value); // FIXME: Copy?
253
 
}
254
 
 
255
589
static void set_int_data(GtkBuilder *ui, const gchar *object_name, const gchar *name, gint value)
256
590
{
257
591
    set_data(ui, object_name, name, GINT_TO_POINTER(value));
258
592
}
259
593
 
260
594
static void
261
 
position_popup(GtkWidget *base, GtkWidget *popup,
 
595
position_popup(GtkWidget *base, GtkWidget *popup, 
262
596
               PopupLocation location_op)
263
597
{
264
598
    int base_x, base_y, base_width, base_height;
330
664
    gtk_window_move(GTK_WINDOW(popup), popup_x, popup_y);
331
665
}
332
666
 
333
 
 
334
 
void
 
667
void
 
668
ui_set_accuracy(int accuracy)
 
669
{
 
670
    GtkWidget *widget;
 
671
    char text[MAXLINE];
 
672
    
 
673
    /* Translators: Accuracy Popup: Menu item to show the accuracy dialog. %d is replaced with the current accuracy. */
 
674
    SNPRINTF(text, MAXLINE, _("_Other (%d) ..."), accuracy);
 
675
    widget = gtk_bin_get_child(GTK_BIN(GET_OBJECT("acc_item_other")));
 
676
    gtk_label_set_markup_with_mnemonic(GTK_LABEL(widget), text);
 
677
 
 
678
    gtk_widget_set_tooltip_text (GET_WIDGET("calc_accuracy_button"),
 
679
                                 /* Translators: Tooltip for accuracy button */
 
680
                                 ngettext("Set accuracy from 0 to %d numeric place. [A]",
 
681
                                          "Set accuracy from 0 to %d numeric places. [A]",
 
682
                                          MAXACC));
 
683
    
 
684
    if (accuracy >= 0 && accuracy <= 9) {
 
685
        SNPRINTF(text, MAXLINE, "acc_item%d", accuracy);
 
686
        widget = GET_WIDGET(text);
 
687
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), TRUE);
 
688
    }
 
689
 
 
690
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(X.precision_spin), (double)accuracy);
 
691
    
 
692
    /* Hide the manual dialog */
 
693
    gtk_widget_hide(X.precision_dialog);
 
694
   
 
695
    /* Rebuild registers with new format */
 
696
    ui_make_registers();
 
697
}
 
698
 
 
699
 
 
700
static void
 
701
ui_update_modifier_mode()
 
702
{
 
703
    static char *sine_labels[]      = {
 
704
        /* Translators: The sine button */
 
705
        N_("sin"),
 
706
        /* Translators: The inverse sine button */        
 
707
        N_("sin<sup>−1</sup>"),
 
708
        /* Translators: The hyperbolic sine button */
 
709
        N_("sinh"),
 
710
        /* Translators: The inverse hyperbolic sine button */
 
711
        N_("sinh<sup>−1</sup>")};
 
712
    static char *sine_tooltips[]    = {
 
713
        /* Translators: The sine tooltip */
 
714
        N_("Sine [k]"),
 
715
        /* Translators: The inverse sine tooltip */
 
716
        N_("Inverse Sine [K]"),
 
717
        /* Translators: The hyperbolic sine tooltip */
 
718
        N_("Hyperbolic Sine [k]"),
 
719
        /* Translators: The hyperbolic inverse sine tooltip */
 
720
        N_("Hyperbolic Inverse Sine [K]")};
 
721
    static int  sine_functions[]    = {FN_SIN, FN_ASIN, FN_SINH, FN_ASINH};
 
722
    static char *cosine_labels[]    = {
 
723
        /* Translators: The cosine button */
 
724
        N_("cos"),
 
725
        /* Translators: The inverse cosine button */        
 
726
        N_("cos<sup>−1</sup>"),
 
727
        /* Translators: The hyperbolic cosine button */
 
728
        N_("cosh"),
 
729
        /* Translators: The inverse hyperbolic cosine button */
 
730
        N_("cosh<sup>−1</sup>")};
 
731
    static char *cosine_tooltips[]  = {
 
732
        /* Translators: The cosine tooltip */
 
733
        N_("Cosine [j]"),
 
734
        /* Translators: The inverse cosine tooltip */
 
735
        N_("Inverse Cosine [J]"),
 
736
        /* Translators: The hyperbolic cosine tooltip */
 
737
        N_("Hyperbolic Cosine [j]"),
 
738
        /* Translators: The hyperbolic inverse cosine tooltip */
 
739
        N_("Hyperbolic Inverse Cosine [J]")};
 
740
    static int  cosine_functions[]  = {FN_COS, FN_ACOS, FN_COSH, FN_ACOSH};
 
741
    static char *tangent_labels[]   = {
 
742
        /* Translators: The tangent button */
 
743
        N_("tan"),
 
744
        /* Translators: The inverse tangent button */        
 
745
        N_("tan<sup>−1</sup>"),
 
746
        /* Translators: The hyperbolic tangent button */
 
747
        N_("tanh"),
 
748
        /* Translators: The inverse hyperbolic tangent button */
 
749
        N_("tanh<sup>−1</sup>")};
 
750
    static char *tangent_tooltips[] = {
 
751
        /* Translators: The tangent tooltip */
 
752
        N_("Tangent [w]"),
 
753
        /* Translators: The inverse tangent tooltip */
 
754
        N_("Inverse Tangent [W]"),
 
755
        /* Translators: The hyperbolic tangent tooltip */
 
756
        N_("Hyperbolic Tangent [w]"),
 
757
        /* Translators: The hyperbolic inverse tangent tooltip */
 
758
        N_("Hyperbolic Inverse Tangent [W]")};
 
759
    static int  tangent_functions[] = {FN_TAN, FN_ATAN, FN_TANH, FN_ATANH};
 
760
    
 
761
    static char *ln_labels[]        = {
 
762
        /* Translators: The natural logaritm button */
 
763
        N_("ln"),
 
764
        /* Translators: The e to the power of x button */
 
765
        N_("e<sup><i>x</i></sup>")};
 
766
    static char *ln_tooltips[]      = {
 
767
        /* Translators: Tooltip for the natural log button */
 
768
        N_("Natural logarithm [n]"),
 
769
        /* Translators: Tooltip for the e to the power of x button */
 
770
        N_("e to the power of the displayed value [N]")};
 
771
    static int ln_functions[]       = {FN_NATURAL_LOGARITHM, FN_E_POW_X};
 
772
    
 
773
    static char *log_labels[]       = {
 
774
        /* Translators: The 10-based logaritm button */
 
775
        N_("log"),
 
776
        /* Translators: The 10 to the power of x button */
 
777
        N_("10<sup><i>x</i></sup>")};
 
778
    static char *log_tooltips[]     = {
 
779
        /* Translators: Tooltip for the log base 10 button */
 
780
        N_("Base 10 logarithm [g]"),
 
781
        /* Translators: Tooltip for the 10 to the power of x button */
 
782
        N_("10 to the power of displayed value [G]")};
 
783
    static int log_functions[]      = {FN_LOGARITHM, FN_10_POW_X};
 
784
    
 
785
    static char *log2_labels[]      = {
 
786
        /* Translators: The 2-based logaritm button */
 
787
        N_("log<sub>2</sub>"),
 
788
        /* Translators: The 2 to the power of x button */
 
789
        N_("2<sup><i>x</i></sup>")};
 
790
    static char *log2_tooltips[]    = {
 
791
        /* Translators: Tooltip for the log base 2 button */
 
792
        N_("Base 2 logarithm [h]"),
 
793
        /* Translators: Tooltip for the 2 to the power of x button */
 
794
        N_("2 to the power of the displayed value [H]")};
 
795
    static int log2_functions[]     = {FN_LOGARITHM2, FN_2_POW_X};
 
796
 
 
797
    static char *x_pow_y_labels[]   = {
 
798
        /* Translators: The x to the power of y button */
 
799
        N_("x<sup><i>y</i></sup>"),
 
800
        /* Translators: The x to the power of reciprocal y button */
 
801
        N_("x<sup>1/<i>y</i></sup>")};
 
802
    static char *x_pow_y_tooltips[] = {
 
803
        /* Translators: Tooltip for the x to the power of y button */
 
804
        N_("Raise displayed value to the power of y [o]"),
 
805
        /* Translators: Tooltip for the x to the power of reciprocal y button */
 
806
        N_("Raise displayed value to the power of reciprocal y [O]")};
 
807
    static int x_pow_y_functions[]  = {FN_X_POW_Y, FN_X_POW_Y_INV};
 
808
    
 
809
    int index = 0;
 
810
 
 
811
    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(X.inverse_toggle)))
 
812
        index |= 0x1;
 
813
    
 
814
    gtk_label_set_markup(GTK_LABEL(GET_OBJECT("natural_logarithm_label")),
 
815
                         _(ln_labels[index]));
 
816
    gtk_widget_set_tooltip_text(GET_WIDGET("calc_natural_logarithm_button"),
 
817
                                _(ln_tooltips[index]));
 
818
    set_int_data(X.ui, "calc_natural_logarithm_button", "calc_function", ln_functions[index]);
 
819
    
 
820
    gtk_label_set_markup(GTK_LABEL(GET_OBJECT("logarithm_label")),
 
821
                         _(log_labels[index]));
 
822
    gtk_widget_set_tooltip_text(GET_WIDGET("calc_logarithm_button"),
 
823
                                _(log_tooltips[index]));
 
824
    set_int_data(X.ui, "calc_logarithm_button", "calc_function", log_functions[index]);
 
825
 
 
826
    gtk_label_set_markup(GTK_LABEL(GET_OBJECT("logarithm2_label")),
 
827
                         _(log2_labels[index]));
 
828
    gtk_widget_set_tooltip_text(GET_WIDGET("calc_logarithm2_button"),
 
829
                                _(log2_tooltips[index]));
 
830
    set_int_data(X.ui, "calc_logarithm2_button", "calc_function", log2_functions[index]);
 
831
 
 
832
    gtk_label_set_markup(GTK_LABEL(GET_OBJECT("x_pow_y_label")),
 
833
                         _(x_pow_y_labels[index]));
 
834
    gtk_widget_set_tooltip_text(GET_WIDGET("calc_x_pow_y_button"),
 
835
                                _(x_pow_y_tooltips[index]));
 
836
    set_int_data(X.ui, "calc_x_pow_y_button", "calc_function", x_pow_y_functions[index]);
 
837
    
 
838
    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(X.hyperbolic_toggle)))
 
839
        index |= 0x2;
 
840
 
 
841
    gtk_label_set_markup(GTK_LABEL(GET_OBJECT("sine_label")),
 
842
                         _(sine_labels[index]));
 
843
    gtk_widget_set_tooltip_text(GET_WIDGET("calc_sine_button"),
 
844
                                _(sine_tooltips[index]));
 
845
    set_int_data(X.ui, "calc_sine_button", "calc_function", sine_functions[index]);
 
846
 
 
847
    gtk_label_set_markup(GTK_LABEL(GET_OBJECT("cosine_label")),
 
848
                         _(cosine_labels[index]));
 
849
    gtk_widget_set_tooltip_text(GET_WIDGET("calc_cosine_button"),
 
850
                                _(cosine_tooltips[index]));
 
851
    set_int_data(X.ui, "calc_cosine_button", "calc_function", cosine_functions[index]);
 
852
 
 
853
    gtk_label_set_markup(GTK_LABEL(GET_OBJECT("tangent_label")),
 
854
                         _(tangent_labels[index]));
 
855
    gtk_widget_set_tooltip_text(GET_WIDGET("calc_tangent_button"),
 
856
                                _(tangent_tooltips[index]));
 
857
    set_int_data(X.ui, "calc_tangent_button", "calc_function", tangent_functions[index]);
 
858
}
 
859
 
 
860
 
 
861
void
 
862
ui_set_trigonometric_mode(MPAngleUnit units)
 
863
{
 
864
    GtkWidget *radio;
 
865
    switch(units) {
 
866
    default:
 
867
    case MP_RADIANS:
 
868
        radio = X.radian_radio;
 
869
        break;
 
870
    case MP_DEGREES:
 
871
        radio = X.degree_radio;
 
872
        break;
 
873
    case MP_GRADIANS:
 
874
        radio = X.gradian_radio;
 
875
        break;
 
876
    }
 
877
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), 1);
 
878
}
 
879
 
 
880
 
 
881
void
 
882
ui_set_numeric_mode(DisplayFormat mode)
 
883
{
 
884
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.display_mode_radios[mode]), 1);
 
885
}
 
886
 
 
887
 
 
888
void
 
889
ui_set_show_thousands_separator(gboolean visible)
 
890
{
 
891
    GtkWidget *menu;
 
892
   
 
893
    display_set_show_thousands_separator(&v->display, visible);
 
894
 
 
895
    menu = GET_WIDGET("show_thousands_separator_menu");
 
896
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), visible);
 
897
 
 
898
    /* Rebuild registers */
 
899
    ui_make_registers();
 
900
}
 
901
 
 
902
 
 
903
void
 
904
ui_set_show_trailing_zeroes(gboolean visible)
 
905
{
 
906
    GtkWidget *menu;
 
907
   
 
908
    display_set_show_trailing_zeroes(&v->display, visible);   
 
909
 
 
910
    /* Rebuild registers */
 
911
    ui_make_registers();
 
912
 
 
913
    menu = GET_WIDGET("show_trailing_zeroes_menu");
 
914
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), visible);
 
915
    menu = GET_WIDGET("acc_trailing_zeroes_item");
 
916
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), visible);
 
917
}
 
918
 
 
919
 
 
920
void 
335
921
ui_set_undo_enabled(gboolean undo, gboolean redo)
336
922
{
337
 
//    gtk_widget_set_sensitive(GET_WIDGET("undo_menu"), undo);
338
 
//    gtk_widget_set_sensitive(GET_WIDGET("redo_menu"), redo);
 
923
    gtk_widget_set_sensitive(GET_WIDGET("undo_menu"), undo); 
 
924
    gtk_widget_set_sensitive(GET_WIDGET("redo_menu"), redo);
 
925
}
 
926
 
 
927
 
 
928
static char *
 
929
make_hostname()
 
930
{
 
931
    Display *dpy = GDK_DISPLAY();
 
932
    char client_hostname[MAXLINE] = "";
 
933
    char hostname[MAXHOSTNAMELEN];
 
934
    char *display = DisplayString(dpy);
 
935
    char *scanner = display;
 
936
 
 
937
    gethostname(hostname, MAXHOSTNAMELEN);
 
938
 
 
939
    while (*scanner)
 
940
        scanner++;
 
941
 
 
942
    while (*scanner != ':')
 
943
        scanner--;
 
944
 
 
945
    *scanner = '\0';
 
946
                                            
 
947
    if (strcmp(display, hostname) &&        
 
948
        strcmp(display, "localhost") &&     
 
949
        strcmp(display, "unix") &&          
 
950
        strcmp(display, ""))
 
951
        SNPRINTF(client_hostname, MAXLINE, " [%s] ", hostname);
 
952
 
 
953
    *scanner = ':';
 
954
    
 
955
    if (client_hostname[0] == '\0')
 
956
        return NULL;
 
957
    else
 
958
        return strdup(client_hostname);
339
959
}
340
960
 
341
961
 
353
973
{
354
974
    int i;
355
975
    const gchar *label;
356
 
 
 
976
    
357
977
    gtk_widget_set_sensitive(X.bit_panel, enabled);
358
978
 
359
979
    for (i = 0; i < MAXBITS; i++) {
365
985
    }
366
986
}
367
987
 
368
 
 
369
 
static void
370
 
do_button(int function, gpointer arg)
 
988
static void do_button(int function, int arg)
371
989
{
372
990
    GtkTextIter start, end;
373
991
    gint cursor_start, cursor_end;
374
 
  
375
 
    /* Can't enter superscript minus after entering digits */
376
 
    if (function == FN_TEXT && strstr("⁰¹²³⁴⁵⁶⁷⁸⁹", (char *)arg) != NULL)
377
 
        X.can_super_minus = FALSE;
378
 
 
379
 
    /* Disable super/subscript mode when finished entering */
380
 
    if (function == FN_CALCULATE ||
381
 
        function == FN_CLEAR ||
382
 
        (function == FN_TEXT && strstr("⁻⁰¹²³⁴⁵⁶⁷⁸⁹₀₁₂₃₄₅₆₇₈₉", (char *)arg) == NULL)) {
383
 
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.subscript_toggle), FALSE);
384
 
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.superscript_toggle), FALSE);
385
 
    }
386
992
 
387
993
    if(gtk_text_buffer_get_selection_bounds(X.display_buffer, &start, &end)) {
388
994
        cursor_start = gtk_text_iter_get_offset(&start);
394
1000
            cursor_start = -1;
395
1001
        cursor_end = cursor_start;
396
1002
    }
397
 
 
 
1003
    
398
1004
    /* Some keyboards don't have a '^' button so convert two multiplies to one '^' */
399
1005
    if (cursor_start == cursor_end &&
400
 
        function == FN_TEXT && X.last_text != NULL &&
401
 
        strcmp((char *)arg, "×") == 0 && strcmp(X.last_text, "×") == 0) {
402
 
        do_button(FN_BACKSPACE, NULL);
403
 
        do_button(FN_TEXT, "^");
 
1006
        function == FN_MULTIPLY && X.last_function == FN_MULTIPLY) {
 
1007
        do_button(FN_BACKSPACE, 0);
 
1008
        do_button(FN_X_POW_Y, 0);
404
1009
    }
405
1010
    else {
406
 
        display_do_function(&v->display, function, arg, cursor_start, cursor_end);
407
 
        if (function == FN_TEXT)
408
 
            X.last_text = (char *)arg;
409
 
        else
410
 
            X.last_text = NULL;
 
1011
        do_expression(function, arg, cursor_start, cursor_end);
 
1012
        X.last_function = function;
411
1013
    }
412
1014
}
413
1015
 
414
 
 
415
 
static void
416
 
do_text(const char *text)
417
 
{
418
 
    do_button(FN_TEXT, (gpointer) text);
419
 
}
420
 
 
421
 
 
422
1016
static void
423
1017
do_finc(char* dialog)
424
1018
{
428
1022
    gtk_widget_hide(GTK_WIDGET(GET_FINC_WIDGET(dialog)));
429
1023
}
430
1024
 
431
 
static void
 
1025
void
432
1026
ui_set_mode(ModeType mode)
433
1027
{
 
1028
    GtkRequisition *r;
 
1029
    gint w, h;
 
1030
    char *hostname, title[MAXLINE];
434
1031
    GtkWidget *menu;
435
1032
 
436
 
    X.mode = mode;
437
 
 
 
1033
    if (X.mode != mode) {
 
1034
        X.mode = mode;
 
1035
 
 
1036
        // FIXME: These should affect display but not the actual UI settings
 
1037
        if (mode != PROGRAMMING)
 
1038
            ui_set_base(10);
 
1039
        if (mode != SCIENTIFIC) {
 
1040
            ui_set_numeric_mode(FIX);
 
1041
            do_button(FN_SET_ACCURACY, DEFAULT_ACCURACY);
 
1042
        }
 
1043
        if (mode == BASIC)
 
1044
            ui_set_show_trailing_zeroes(FALSE);
 
1045
 
 
1046
        ui_make_registers();
 
1047
    }
 
1048
    
438
1049
    /* Save mode */
439
1050
    set_enumerated_resource(R_MODE, mode_names, (int)mode);
440
 
 
 
1051
    
441
1052
    /* Show/enable the widgets used in this mode */
 
1053
    g_object_set(G_OBJECT(X.bas_panel), "visible", mode == BASIC, NULL);
442
1054
    g_object_set(G_OBJECT(X.adv_panel), "visible", mode != BASIC, NULL);
443
1055
    g_object_set(G_OBJECT(X.fin_panel), "visible", mode == FINANCIAL, NULL);
 
1056
    g_object_set(G_OBJECT(X.sci_mode_panel), "visible", mode == SCIENTIFIC, NULL);
 
1057
    g_object_set(G_OBJECT(X.prog_mode_panel), "visible", mode == PROGRAMMING, NULL);
444
1058
    g_object_set(G_OBJECT(X.sci_panel), "visible", mode == SCIENTIFIC, NULL);
445
1059
    g_object_set(G_OBJECT(X.prog_panel), "visible", mode == PROGRAMMING, NULL);
446
1060
    g_object_set(G_OBJECT(X.bit_panel), "visible", mode == PROGRAMMING, NULL);
447
 
 
448
 
    gtk_window_set_title(GTK_WINDOW(X.main_window), gettext(titles[mode]));
 
1061
    gtk_widget_set_sensitive(GET_WIDGET("show_trailing_zeroes_menu"), mode != BASIC);
 
1062
    gtk_widget_set_sensitive(GET_WIDGET("show_registers_menu"), mode != BASIC);
 
1063
    
 
1064
    /* HACK: Some horrible hack down below to keep the buttons the same size.
 
1065
     * There must be a safer way of doing this... */
 
1066
    r = g_new0(GtkRequisition, 1);
 
1067
    gtk_widget_size_request(X.menubar, r);
 
1068
    w = r->width;
 
1069
    h = r->height;
 
1070
    gtk_widget_size_request(X.display_item, r);
 
1071
    w = MAX(w, r->width);
 
1072
    h += r->height;
 
1073
 
 
1074
#if GTK_CHECK_VERSION (2,17,7)
 
1075
    if (gtk_widget_get_visible (GTK_WIDGET (X.fin_panel))) {
 
1076
#else
 
1077
    if (GTK_WIDGET_VISIBLE(X.fin_panel)) {
 
1078
#endif
 
1079
        gtk_widget_size_request(X.fin_panel, r);
 
1080
        w = MAX(w, r->width);
 
1081
        h += r->height;
 
1082
    }
 
1083
 
 
1084
#if GTK_CHECK_VERSION (2,17,7)
 
1085
    if (gtk_widget_get_visible (GTK_WIDGET (X.sci_mode_panel))) {
 
1086
#else
 
1087
    if (GTK_WIDGET_VISIBLE(X.sci_mode_panel)) {
 
1088
#endif
 
1089
        gtk_widget_size_request(X.sci_mode_panel, r);
 
1090
        w = MAX(w, r->width);
 
1091
        h += r->height;
 
1092
    }
 
1093
 
 
1094
#if GTK_CHECK_VERSION (2,17,7)
 
1095
    if (gtk_widget_get_visible (GTK_WIDGET (X.prog_mode_panel))) {
 
1096
#else
 
1097
    if (GTK_WIDGET_VISIBLE(X.prog_mode_panel)) {
 
1098
#endif
 
1099
        gtk_widget_size_request(X.prog_mode_panel, r);
 
1100
        w = MAX(w, r->width);
 
1101
        h += r->height;
 
1102
    }
 
1103
 
 
1104
#if GTK_CHECK_VERSION (2,17,7)
 
1105
    if (gtk_widget_get_visible (GTK_WIDGET (X.sci_panel))) {
 
1106
#else
 
1107
    if (GTK_WIDGET_VISIBLE(X.sci_panel)) {
 
1108
#endif
 
1109
        gtk_widget_size_request(X.sci_panel, r);
 
1110
        w = MAX(w, r->width);
 
1111
        h += r->height;
 
1112
    }
 
1113
 
 
1114
#if GTK_CHECK_VERSION (2,17,7)
 
1115
    if (gtk_widget_get_visible (GTK_WIDGET (X.prog_panel))) {
 
1116
#else
 
1117
    if (GTK_WIDGET_VISIBLE(X.prog_panel)) {
 
1118
#endif
 
1119
        gtk_widget_size_request(X.prog_panel, r);
 
1120
        w = MAX(w, r->width);
 
1121
        h += r->height;
 
1122
    }
 
1123
    g_free(r);
 
1124
  
 
1125
    /* For initial display. */
 
1126
    gtk_window_set_default_size(GTK_WINDOW(X.main_window), w, h);
 
1127
    gtk_window_resize(GTK_WINDOW(X.main_window), w, h);
 
1128
 
 
1129
    /* Set the title */
 
1130
    if((hostname = make_hostname())) {
 
1131
        SNPRINTF(title, MAXLINE, gettext(hostname_titles[mode]), hostname);
 
1132
        g_free(hostname);
 
1133
    } else {
 
1134
        SNPRINTF(title, MAXLINE, "%s", gettext(titles[mode]));
 
1135
    }
 
1136
    gtk_window_set_title(GTK_WINDOW(X.main_window), title);
449
1137
 
450
1138
    /* Update the menu */
451
1139
    switch (mode) {
464
1152
        case SCIENTIFIC:
465
1153
            menu = GET_WIDGET("view_scientific_menu");
466
1154
            break;
467
 
 
 
1155
        
468
1156
        case PROGRAMMING:
469
1157
            menu = GET_WIDGET("view_programming_menu");
470
1158
            break;
477
1165
}
478
1166
 
479
1167
 
480
 
void
481
 
ui_set_statusbar(const gchar *text)
 
1168
void 
 
1169
ui_set_statusbar(const gchar *text, const gchar *imagename)
482
1170
{
483
 
    gtk_text_buffer_set_text(X.info_buffer, text, -1);
 
1171
    GtkImage *image = GTK_IMAGE(X.status_image);
 
1172
 
 
1173
    assert(text);
 
1174
    assert(imagename);
 
1175
    assert(image);
 
1176
 
 
1177
    gtk_image_set_from_stock(image, imagename, GTK_ICON_SIZE_BUTTON);
 
1178
    gtk_statusbar_pop(GTK_STATUSBAR(X.statusbar), 0);
 
1179
    gtk_statusbar_push(GTK_STATUSBAR(X.statusbar), 0, text); 
484
1180
}
485
1181
 
486
1182
 
494
1190
    gtk_text_buffer_get_start_iter(X.display_buffer, &start);
495
1191
    gtk_text_buffer_get_end_iter(X.display_buffer, &end);
496
1192
    text = gtk_text_buffer_get_text(X.display_buffer, &start, &end, FALSE);
497
 
 
 
1193
    
498
1194
    g_object_get(G_OBJECT(X.display_buffer), "cursor-position", &cursor_position, NULL);
499
1195
 
500
 
    gtk_text_buffer_set_text(X.display_buffer, text, -1);
 
1196
    gtk_text_buffer_set_text(X.display_buffer, text, -1);    
501
1197
    gtk_text_buffer_get_iter_at_offset(X.display_buffer, &cursor, cursor_position);
502
1198
    gtk_text_buffer_place_cursor(X.display_buffer, &cursor);
503
1199
 
504
1200
    g_free(text);
505
 
 
 
1201
    
506
1202
    return FALSE;
507
1203
}
508
1204
 
513
1209
    GtkTextIter iter;
514
1210
    GtkAdjustment *adj;
515
1211
 
 
1212
    // ???
 
1213
    if (str[0] == '\0')
 
1214
        str = " ";
 
1215
 
516
1216
    gtk_text_buffer_set_text(X.display_buffer, str, -1);
517
 
 
 
1217
    
518
1218
    if (cursor < 0)
519
1219
        gtk_text_buffer_get_end_iter(X.display_buffer, &iter);
520
1220
    else
521
1221
        gtk_text_buffer_get_iter_at_offset(X.display_buffer, &iter, cursor);
522
1222
    gtk_text_buffer_place_cursor(X.display_buffer, &iter);
523
1223
    gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(X.display_item), &iter, 0.0, TRUE, 1.0, 0.0);
524
 
 
 
1224
    
525
1225
    /* This is a workaround for bug #524602.
526
1226
     * Basically the above code can cause the display to disappear when going from
527
1227
     * a display that is wider than the widget to one that is thinner. The following
528
1228
     * causes the display to be set twice which seems to work the second time.
529
1229
     */
530
1230
    g_idle_add(redo_display, NULL);
531
 
 
 
1231
    
532
1232
    /* Align to the right */
533
1233
    if (cursor < 0) {
534
1234
        adj = gtk_scrolled_window_get_hadjustment(
538
1238
}
539
1239
 
540
1240
 
 
1241
/* When an error condition occurs:
 
1242
 *
 
1243
 * - make insensitive all buttons except Clr.
 
1244
 * - make all Scientific mode toggles and checkboxes insensitive.
 
1245
 * - make all menubar items insensitive except:
 
1246
 *     Calculator->Quit
 
1247
 *     Help->Contents
 
1248
 *
 
1249
 * When the error condition is cleared, resensitise everything, setting
 
1250
 * the numeric base buttons correctly.
 
1251
 */
 
1252
void
 
1253
ui_set_error_state(gboolean error)
 
1254
{
 
1255
    int i;
 
1256
 
 
1257
    v->error = error;
 
1258
 
 
1259
    for (i = 0; i < NBUTTONS; i++)
 
1260
        gtk_widget_set_sensitive(X.buttons[i], !v->error);
 
1261
    /* Clr button always sensitive. */
 
1262
    gtk_widget_set_sensitive(X.clear_buttons[0], TRUE);
 
1263
    gtk_widget_set_sensitive(X.clear_buttons[1], TRUE);
 
1264
 
 
1265
    if (!v->error)
 
1266
        ui_set_base(v->base);
 
1267
 
 
1268
    gtk_widget_set_sensitive(X.sci_mode_panel, !v->error);
 
1269
    gtk_widget_set_sensitive(X.prog_mode_panel, !v->error);
 
1270
 
 
1271
    gtk_widget_set_sensitive(GET_WIDGET("copy_menu"),            !v->error);
 
1272
    gtk_widget_set_sensitive(GET_WIDGET("paste_menu"),           !v->error); 
 
1273
    gtk_widget_set_sensitive(GET_WIDGET("undo_menu"),            !v->error);
 
1274
    gtk_widget_set_sensitive(GET_WIDGET("redo_menu"),            !v->error);
 
1275
    gtk_widget_set_sensitive(GET_WIDGET("insert_ascii_menu"),    !v->error); 
 
1276
 
 
1277
    gtk_widget_set_sensitive(GET_WIDGET("view_basic_menu"),      !v->error); 
 
1278
    gtk_widget_set_sensitive(GET_WIDGET("view_advanced_menu"),   !v->error); 
 
1279
    gtk_widget_set_sensitive(GET_WIDGET("view_financial_menu"),  !v->error); 
 
1280
    gtk_widget_set_sensitive(GET_WIDGET("view_scientific_menu"), !v->error); 
 
1281
    gtk_widget_set_sensitive(GET_WIDGET("show_trailing_zeroes_menu"),
 
1282
                             !v->error && (X.mode != BASIC));
 
1283
    gtk_widget_set_sensitive(GET_WIDGET("show_thousands_separator_menu"),
 
1284
                             !v->error); 
 
1285
    gtk_widget_set_sensitive(GET_WIDGET("show_registers_menu"), !v->error); 
 
1286
 
 
1287
    gtk_widget_set_sensitive(GET_WIDGET("about_menu"), !v->error);
 
1288
}
 
1289
 
 
1290
 
 
1291
void
 
1292
ui_beep()
 
1293
{
 
1294
    gdk_beep();
 
1295
}
 
1296
 
 
1297
 
 
1298
void
 
1299
ui_set_base(int base)
 
1300
{
 
1301
    GtkWidget *widget;
 
1302
    int i;
 
1303
    
 
1304
    v->base = base;
 
1305
 
 
1306
    for (i = 0; i < 16; i++)
 
1307
        gtk_widget_set_sensitive(X.digit_buttons[i], i < base);
 
1308
    switch (base)
 
1309
    {
 
1310
    case 2:
 
1311
        widget = X.binary_radio;
 
1312
        break;
 
1313
    case 8:
 
1314
        widget = X.octal_radio;
 
1315
        break;
 
1316
    case 10:
 
1317
        widget = X.decimal_radio;
 
1318
        break;
 
1319
    case 16:
 
1320
        widget = X.hexadecimal_radio;
 
1321
        break;
 
1322
    default:
 
1323
        return;
 
1324
    }
 
1325
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
 
1326
}
 
1327
 
 
1328
 
 
1329
void
 
1330
ui_set_wordlen(int len)
 
1331
{
 
1332
    GtkWidget *widget;
 
1333
    v->wordlen = len;
 
1334
    switch (len) {
 
1335
        case 64:
 
1336
            widget = X.word_length_radios[0];
 
1337
            break;
 
1338
        case 32:
 
1339
            widget = X.word_length_radios[1];
 
1340
            break;
 
1341
        case 16:
 
1342
            widget = X.word_length_radios[2];
 
1343
            break;
 
1344
        default:
 
1345
            return;
 
1346
    }
 
1347
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), 1);
 
1348
}
 
1349
 
 
1350
 
 
1351
void
 
1352
ui_set_registers_visible(gboolean visible)
 
1353
{
 
1354
    GtkWidget *menu;
 
1355
 
 
1356
    ui_make_registers();
 
1357
 
 
1358
    menu = GET_WIDGET("show_registers_menu");
 
1359
    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), visible);   
 
1360
 
 
1361
    gtk_widget_realize(X.register_dialog);
 
1362
 
 
1363
    if (visible) {
 
1364
        if (gdk_window_is_visible(gtk_widget_get_window(X.register_dialog))) {
 
1365
            gdk_window_raise(gtk_widget_get_window(X.register_dialog));
 
1366
            return;
 
1367
        }
 
1368
        position_popup(X.main_window, X.register_dialog, POPUP_ABOVE);
 
1369
        gtk_widget_show(X.register_dialog);
 
1370
    } else {
 
1371
        gtk_widget_hide(X.register_dialog);
 
1372
    }
 
1373
    
 
1374
    set_boolean_resource(R_REGS, visible);
 
1375
}
 
1376
 
 
1377
 
541
1378
G_MODULE_EXPORT
542
1379
void
543
1380
about_cb(GtkWidget *widget)
544
1381
{
545
1382
    const gchar *authors[] = {
546
1383
        "Rich Burridge <rich.burridge@sun.com>",
 
1384
        "Sami Pietila <sampie@ariana-dsl.utu.fi>",
547
1385
        "Robert Ancell <robert.ancell@gmail.com>",
548
1386
        "Klaus Niederkrüger <kniederk@umpa.ens-lyon.fr>",
549
1387
        NULL
552
1390
        "Sun Microsystems",
553
1391
        NULL
554
1392
    };
555
 
 
 
1393
    
556
1394
    /* Translators: The translator credits. Please translate this with your name(s). */
557
1395
    const gchar *translator_credits = _("translator-credits");
558
1396
 
559
1397
    /* Translators: The license this software is under (GPL2+) */
560
 
    char *license = _("Gcalctool is free software; you can redistribute it and/or modify\n"
 
1398
    char *license =
 
1399
        _("Gcalctool is free software; you can redistribute it and/or modify\n"
561
1400
          "it under the terms of the GNU General Public License as published by\n"
562
1401
          "the Free Software Foundation; either version 2 of the License, or\n"
563
1402
          "(at your option) any later version.\n"
576
1415
                          "name", _("Gcalctool"),
577
1416
                          "version", VERSION,
578
1417
                          /* Translators: Copyright notice in the about dialog */
579
 
                          "copyright", _("\xc2\xa9 1986–2008 The Gcalctool authors"),
 
1418
                          "copyright", _("\xc2\xa9 1986-2008 The Gcalctool authors"),
580
1419
                          "license", license,
581
1420
                          /* Translators: Short description in the about dialog */
582
1421
                          "comments", _("Calculator with financial and scientific modes."),
587
1426
                          NULL);
588
1427
}
589
1428
 
 
1429
static void
 
1430
cell_edited_cb(GtkCellRendererText *cell, const gchar *path_string,
 
1431
               const gchar *new_text, gpointer data)
 
1432
{
 
1433
    GtkTreeModel *model = (GtkTreeModel *) data;
 
1434
    GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
 
1435
    GtkTreeIter iter;
 
1436
    gint *column;
 
1437
 
 
1438
    column = g_object_get_data(G_OBJECT(cell), "column");
 
1439
 
 
1440
    gtk_tree_model_get_iter(model, &iter, path);
 
1441
 
 
1442
    switch (GPOINTER_TO_INT(column)) {
 
1443
        case COLUMN_VALUE:
 
1444
            gtk_list_store_set(GTK_LIST_STORE(model), &iter, column,
 
1445
                               g_strdup(new_text), -1);
 
1446
            break;
 
1447
 
 
1448
        case COLUMN_DESCRIPTION:
 
1449
            gtk_list_store_set(GTK_LIST_STORE(model), &iter, column,
 
1450
                               g_strdup(new_text), -1);
 
1451
            break;
 
1452
    }
 
1453
 
 
1454
    gtk_tree_path_free(path);
 
1455
}
 
1456
 
 
1457
 
 
1458
static void
 
1459
add_cf_column(GtkTreeView *treeview, gchar *name, gint colno, gboolean editable)
 
1460
{
 
1461
    GtkCellRenderer *renderer;
 
1462
    GtkTreeModel *model = gtk_tree_view_get_model(treeview);
 
1463
 
 
1464
    renderer = gtk_cell_renderer_text_new();
 
1465
    if (editable)
 
1466
        g_signal_connect(G_OBJECT(renderer), "edited",
 
1467
                         G_CALLBACK(cell_edited_cb), model);
 
1468
    g_object_set_data(G_OBJECT(renderer), "column", GINT_TO_POINTER(colno));
 
1469
 
 
1470
    if (editable)
 
1471
        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
 
1472
                                                -1, name, renderer,
 
1473
                                                "text", colno,
 
1474
                                                "editable", COLUMN_EDITABLE,
 
1475
                                                NULL);
 
1476
    else
 
1477
        gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
 
1478
                                                -1, name, renderer,
 
1479
                                                "text", colno,
 
1480
                                                NULL);
 
1481
}
 
1482
 
590
1483
 
591
1484
G_MODULE_EXPORT
592
1485
void
593
1486
ascii_dialog_response_cb(GtkWidget *dialog, gint response_id)
594
1487
{
595
1488
    const gchar *text;
596
 
 
 
1489
    
597
1490
    text = gtk_entry_get_text(GTK_ENTRY(X.ascii_entry));
598
 
 
 
1491
    
599
1492
    if (response_id == GTK_RESPONSE_OK)
600
 
        do_button(FN_INSERT_CHARACTER, (gpointer) text);
601
 
 
 
1493
        do_button(FN_INSERT_CHARACTER, GPOINTER_TO_INT(text));
 
1494
    
602
1495
    gtk_widget_hide(dialog);
603
1496
}
604
1497
 
620
1513
}
621
1514
 
622
1515
 
 
1516
G_MODULE_EXPORT
 
1517
void
 
1518
register_dialog_response_cb(GtkWidget *dialog, int response_id)
 
1519
{
 
1520
    ui_set_registers_visible(FALSE);
 
1521
}
 
1522
 
 
1523
 
 
1524
G_MODULE_EXPORT
 
1525
gboolean
 
1526
register_dialog_delete_cb(GtkWidget *dialog)
 
1527
{
 
1528
    register_dialog_response_cb(dialog, GTK_RESPONSE_OK);
 
1529
    return TRUE;
 
1530
}
 
1531
 
 
1532
 
 
1533
G_MODULE_EXPORT
 
1534
void
 
1535
disp_cb(GtkWidget *widget)
 
1536
{
 
1537
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
 
1538
        do_button(FN_SET_NUMBERTYPE, (int)g_object_get_data(G_OBJECT(widget), "numeric_mode"));
 
1539
}
 
1540
 
 
1541
 
 
1542
G_MODULE_EXPORT
 
1543
void
 
1544
base_cb(GtkWidget *widget)
 
1545
{
 
1546
    int base;
 
1547
 
 
1548
    base = (int) g_object_get_data(G_OBJECT(widget), "base_mode");
 
1549
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
 
1550
        do_button(FN_SET_BASE, base);
 
1551
}
 
1552
 
 
1553
G_MODULE_EXPORT
 
1554
void
 
1555
word_cb(GtkWidget *widget)
 
1556
{
 
1557
    int wordlen;
 
1558
 
 
1559
    wordlen = (int) g_object_get_data(G_OBJECT(widget), "wordlen_mode");
 
1560
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
 
1561
        do_button(FN_SET_WORDLEN, wordlen);
 
1562
}
 
1563
 
623
1564
static void
624
1565
help_display(void)
625
1566
{
628
1569
 
629
1570
    screen = gtk_widget_get_screen (GTK_WIDGET (X.main_window));
630
1571
    gtk_show_uri (screen, "ghelp:gcalctool", gtk_get_current_event_time (), &error);
631
 
 
 
1572
 
632
1573
    if (error != NULL)
633
1574
    {
634
1575
        GtkWidget *d;
635
 
        /* Translators: Error message displayed when unable to launch help browser */
636
 
        const char *message = _("Unable to open help file");
637
 
 
638
1576
        d = gtk_message_dialog_new (GTK_WINDOW (X.main_window),
639
1577
                                    GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
640
1578
                                    GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
641
 
                                    "%s", message);
 
1579
                                    "%s", _("Unable to open help file"));
642
1580
        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (d),
643
1581
                                                  "%s", error->message);
644
1582
        g_signal_connect (d, "response", G_CALLBACK (gtk_widget_destroy), NULL);
645
1583
        gtk_window_present (GTK_WINDOW (d));
646
 
 
 
1584
        
647
1585
        g_error_free (error);
648
1586
    }
649
1587
}
651
1589
 
652
1590
G_MODULE_EXPORT
653
1591
void
 
1592
constant_menu_cb(GtkMenuItem *menu)
 
1593
{
 
1594
    int arg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "constant_id"));
 
1595
    do_button(FN_CONSTANT, arg);
 
1596
}
 
1597
 
 
1598
 
 
1599
G_MODULE_EXPORT
 
1600
void
 
1601
function_menu_cb(GtkMenuItem *menu)
 
1602
{
 
1603
    int arg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "function_id"));
 
1604
    do_button(FN_FUNCTION, arg);
 
1605
}
 
1606
 
 
1607
 
 
1608
G_MODULE_EXPORT
 
1609
void
654
1610
store_menu_cb(GtkMenuItem *menu)
655
1611
{
656
 
    do_button(FN_STORE, g_object_get_data(G_OBJECT(menu), "register_id"));
 
1612
    int arg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "register_id"));
 
1613
    do_button(FN_STORE, arg);
657
1614
}
658
1615
 
659
1616
 
661
1618
void
662
1619
recall_menu_cb(GtkMenuItem *menu)
663
1620
{
664
 
    do_button(FN_RECALL, g_object_get_data(G_OBJECT(menu), "register_id"));
665
 
}
666
 
 
667
 
 
668
 
G_MODULE_EXPORT
669
 
void
670
 
finc_activate_cb(GtkWidget *widget) {
 
1621
    int arg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "register_id"));
 
1622
    do_button(FN_RECALL, arg);
 
1623
}
 
1624
 
 
1625
 
 
1626
G_MODULE_EXPORT
 
1627
void
 
1628
exchange_menu_cb(GtkMenuItem *menu)
 
1629
{
 
1630
    int arg = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu), "register_id"));
 
1631
    do_button(FN_EXCHANGE, arg);
 
1632
}
 
1633
 
 
1634
 
 
1635
G_MODULE_EXPORT
 
1636
void
 
1637
finc_activate_cb(GtkWidget *widget)
 
1638
{
671
1639
    gint dialog, field;
672
1640
 
673
1641
    dialog = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "finc_dialog"));
674
1642
    field = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "finc_field"));
675
 
 
 
1643
    
676
1644
    if (finc_dialog_fields[dialog][field+1] == NULL) {
677
1645
        GtkWidget *dialog_widget;
678
1646
        dialog_widget = gtk_widget_get_toplevel(widget);
 
1647
#if GTK_CHECK_VERSION (2,17,10)
679
1648
        if (gtk_widget_is_toplevel (dialog_widget)) {
 
1649
#else
 
1650
        if (GTK_WIDGET_TOPLEVEL (dialog_widget)) {
 
1651
#endif
680
1652
            gtk_dialog_response(GTK_DIALOG(dialog_widget),
681
1653
                                GTK_RESPONSE_OK);
682
1654
            return;
701
1673
 
702
1674
    if (response_id != GTK_RESPONSE_OK)
703
1675
        return;
704
 
 
 
1676
    
705
1677
    dialog = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(widget), "finc_dialog"));
706
1678
 
707
1679
    for (i = 0; i < 4; i++) {
710
1682
        }
711
1683
        entry = GET_FINC_WIDGET(finc_dialog_fields[dialog][i]);
712
1684
        // FIXME: Have to delocalize the input
713
 
        mp_set_from_string(gtk_entry_get_text(GTK_ENTRY(entry)), &arg[i]);
 
1685
        mp_set_from_string(gtk_entry_get_text(GTK_ENTRY(entry)), 10, &arg[i]);
714
1686
        gtk_entry_set_text(GTK_ENTRY(entry), "0");
715
1687
    }
716
1688
    gtk_widget_grab_focus(GET_FINC_WIDGET(finc_dialog_fields[dialog][0]));
723
1695
setup_finc_dialogs(void)
724
1696
{
725
1697
    int i, j;
726
 
    GtkListStore *currency_store;
727
 
    GtkCellRenderer *render;
728
 
    GtkSpinButton *currency_amount_upper;
729
 
    GtkSpinButton *currency_amount_lower;
730
 
    GtkComboBox   *currency_type_upper;
731
 
    GtkComboBox   *currency_type_lower;
732
 
 
 
1698
    
733
1699
    X.financial = gtk_builder_new();
734
1700
    load_ui(X.financial, UI_FINC_FILE);
735
 
 
 
1701
    
736
1702
    set_int_data(X.financial, "ctrm_dialog", "finc_dialog", FINC_CTRM_DIALOG);
737
1703
    set_int_data(X.financial, "ddb_dialog", "finc_dialog", FINC_DDB_DIALOG);
738
1704
    set_int_data(X.financial, "fv_dialog", "finc_dialog", FINC_FV_DIALOG);
743
1709
    set_int_data(X.financial, "sln_dialog", "finc_dialog", FINC_SLN_DIALOG);
744
1710
    set_int_data(X.financial, "syd_dialog", "finc_dialog", FINC_SYD_DIALOG);
745
1711
    set_int_data(X.financial, "term_dialog", "finc_dialog", FINC_TERM_DIALOG);
746
 
 
747
 
    for (i = 0; finc_dialog_fields[i][0] != NULL; i++) {
 
1712
    
 
1713
    for (i = 0; i < FINC_NUM_DIALOGS; i++) {
748
1714
        for (j = 0; finc_dialog_fields[i][j]; j++) {
749
1715
            GObject *o;
750
1716
            o = gtk_builder_get_object(X.financial, finc_dialog_fields[i][j]);
752
1718
            g_object_set_data(o, "finc_dialog", GINT_TO_POINTER(i));
753
1719
        }
754
1720
    }
755
 
 
756
 
    currency_amount_upper = GTK_SPIN_BUTTON(gtk_builder_get_object(
757
 
        X.financial,
758
 
        "currency_amount_upper"));
759
 
    currency_amount_lower = GTK_SPIN_BUTTON(gtk_builder_get_object(
760
 
        X.financial,
761
 
        "currency_amount_lower"));
762
 
    currency_type_upper = GTK_COMBO_BOX(gtk_builder_get_object(
763
 
        X.financial,
764
 
        "currency_type_upper"));
765
 
    currency_type_lower = GTK_COMBO_BOX(gtk_builder_get_object(
766
 
        X.financial,
767
 
        "currency_type_lower"));
768
 
 
769
 
    currency_store = gtk_list_store_new(2,
770
 
                                        G_TYPE_INT,
771
 
                                        G_TYPE_STRING);
772
 
 
773
 
    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(currency_store),
774
 
                                         1,
775
 
                                         GTK_SORT_ASCENDING);
776
 
 
777
 
    gtk_combo_box_set_model(currency_type_upper,
778
 
                            GTK_TREE_MODEL(currency_store));
779
 
    gtk_combo_box_set_model(currency_type_lower,
780
 
                            GTK_TREE_MODEL(currency_store));
781
 
 
782
 
    render = gtk_cell_renderer_text_new();
783
 
 
784
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(currency_type_upper),
785
 
                               render,
786
 
                               TRUE);
787
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(currency_type_lower),
788
 
                               render,
789
 
                               TRUE);
790
 
 
791
 
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(currency_type_upper),
792
 
                                  render,
793
 
                                  "text",
794
 
                                  1);
795
 
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(currency_type_lower),
796
 
                                  render,
797
 
                                  "text",
798
 
                                  1);
799
 
 
800
 
    set_int_data(X.financial, "currency_amount_upper", "target", CURRENCY_TARGET_LOWER);
801
 
    set_int_data(X.financial, "currency_amount_lower", "target", CURRENCY_TARGET_UPPER);
802
 
 
 
1721
    
803
1722
    gtk_builder_connect_signals(X.financial, NULL);
804
1723
}
805
1724
 
 
1725
static void
 
1726
update_constants_menu(void)
 
1727
{
 
1728
    char mline[MAXLINE], value[MAXLINE];
 
1729
    int i;
 
1730
 
 
1731
    for (i = 0; i < MAX_CONSTANTS; i++) {
 
1732
        display_make_number(&v->display, value, MAXLINE, constant_get_value(i), 10, TRUE);
 
1733
        SNPRINTF(mline, MAXLINE, 
 
1734
                 "<span weight=\"bold\">%s_%1d:</span> %s [%s]", _("C"), i, 
 
1735
                 value, 
 
1736
                 constant_get_name(i));
 
1737
        gtk_label_set_markup_with_mnemonic(GTK_LABEL(X.constant_menu_labels[i]), mline);
 
1738
    }
 
1739
}
 
1740
 
 
1741
 
 
1742
static void
 
1743
update_functions_menu(void)
 
1744
{
 
1745
    char mline[MAXLINE];
 
1746
    int i;
 
1747
 
 
1748
    for (i = 0; i < MAX_FUNCTIONS; i++) {
 
1749
        const char *name, *value;
 
1750
        
 
1751
        name = function_get_name(i);
 
1752
        value = function_get_value(i);
 
1753
        
 
1754
        if (strlen(value) != 0) {
 
1755
            SNPRINTF(mline, MAXLINE,
 
1756
                     "<span weight=\"bold\">%s_%1d:</span> %s [%s]", 
 
1757
                     _("F"), i, value, name);
 
1758
            gtk_widget_show(gtk_widget_get_parent(X.function_menu_labels[i]));
 
1759
            gtk_label_set_markup_with_mnemonic(GTK_LABEL(X.function_menu_labels[i]), mline);
 
1760
        }
 
1761
        else
 
1762
            gtk_widget_hide(gtk_widget_get_parent(X.function_menu_labels[i]));
 
1763
    }
 
1764
}
 
1765
 
 
1766
 
 
1767
G_MODULE_EXPORT
 
1768
void
 
1769
edit_constants_response_cb(GtkDialog *dialog, gint id)
 
1770
{
 
1771
    GtkTreeIter iter;
 
1772
    gint number;
 
1773
    gchar *value;
 
1774
    gchar *description;
 
1775
 
 
1776
    if (id == GTK_RESPONSE_HELP)
 
1777
        help_display();
 
1778
 
 
1779
    if (id == GTK_RESPONSE_ACCEPT) {
 
1780
        if (gtk_tree_model_get_iter_first(X.constants_model, &iter)) {
 
1781
            do {
 
1782
                MPNumber temp;
 
1783
                gtk_tree_model_get(X.constants_model, &iter,
 
1784
                                   COLUMN_NUMBER, &number,
 
1785
                                   COLUMN_VALUE, &value,
 
1786
                                   COLUMN_DESCRIPTION, &description, -1);
 
1787
                // FIXME: Have to delocalize
 
1788
                mp_set_from_string(value, 10, &temp);
 
1789
                constant_set(number, description, &temp);
 
1790
            } while (gtk_tree_model_iter_next(X.constants_model, &iter));
 
1791
        }
 
1792
    }
 
1793
 
 
1794
    gtk_widget_hide(GTK_WIDGET(dialog));
 
1795
}
 
1796
 
 
1797
 
 
1798
G_MODULE_EXPORT
 
1799
gboolean
 
1800
edit_constants_delete_cb(GtkDialog *dialog)
 
1801
{
 
1802
    edit_constants_response_cb(dialog, GTK_RESPONSE_CANCEL);
 
1803
    return TRUE;
 
1804
}
 
1805
 
 
1806
 
 
1807
G_MODULE_EXPORT
 
1808
void
 
1809
edit_functions_response_cb(GtkDialog *dialog, gint id)
 
1810
{
 
1811
    GtkTreeIter iter;
 
1812
    gint number;
 
1813
    gchar *value;
 
1814
    gchar *description;
 
1815
 
 
1816
    if (id == GTK_RESPONSE_HELP)
 
1817
        help_display();
 
1818
 
 
1819
    if (id == GTK_RESPONSE_ACCEPT) {
 
1820
        if (gtk_tree_model_get_iter_first(X.functions_model, &iter)) {
 
1821
            do {
 
1822
                gtk_tree_model_get(X.functions_model, &iter,
 
1823
                                   COLUMN_NUMBER, &number,
 
1824
                                   COLUMN_VALUE, &value,
 
1825
                                   COLUMN_DESCRIPTION, &description, -1);
 
1826
                function_set(number, description, value);
 
1827
            } while (gtk_tree_model_iter_next(X.functions_model, &iter));
 
1828
        }
 
1829
    }
 
1830
 
 
1831
    gtk_widget_hide(GTK_WIDGET(dialog));
 
1832
}
 
1833
 
 
1834
 
 
1835
G_MODULE_EXPORT
 
1836
gboolean
 
1837
edit_functions_delete_cb(GtkDialog *dialog)
 
1838
{
 
1839
    edit_functions_response_cb(dialog, GTK_RESPONSE_CANCEL);
 
1840
    return TRUE;
 
1841
}
 
1842
 
 
1843
 
 
1844
static GtkTreeModel *
 
1845
create_constants_model()
 
1846
{
 
1847
    gint i = 0;
 
1848
    GtkListStore *model;
 
1849
    GtkTreeIter iter;
 
1850
    char constant[MAXLINE];
 
1851
 
 
1852
    model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
 
1853
                               G_TYPE_STRING, G_TYPE_BOOLEAN);   
 
1854
    for (i = 0; i < MAX_CONSTANTS; i++) {
 
1855
        gtk_list_store_append(model, &iter);
 
1856
        
 
1857
        display_make_number(&v->display, constant, MAXLINE, constant_get_value(i), 10, TRUE);
 
1858
        gtk_list_store_set(model, &iter,
 
1859
                           COLUMN_NUMBER, i,
 
1860
                           COLUMN_EDITABLE, TRUE,
 
1861
                           COLUMN_VALUE, constant,
 
1862
                           COLUMN_DESCRIPTION, constant_get_name(i),
 
1863
                           -1);
 
1864
    }
 
1865
 
 
1866
    return GTK_TREE_MODEL(model);
 
1867
}
 
1868
 
 
1869
 
 
1870
static GtkTreeModel *
 
1871
create_functions_model()
 
1872
{
 
1873
    gint i = 0;
 
1874
    GtkListStore *model;
 
1875
    GtkTreeIter iter;
 
1876
 
 
1877
    model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
 
1878
                               G_TYPE_STRING, G_TYPE_BOOLEAN);   
 
1879
    for (i = 0; i < MAX_FUNCTIONS; i++) {
 
1880
        gtk_list_store_append(model, &iter);
 
1881
        
 
1882
        gtk_list_store_set(model, &iter,
 
1883
                           COLUMN_NUMBER, i,
 
1884
                           COLUMN_EDITABLE, TRUE,
 
1885
                           COLUMN_VALUE, function_get_value(i),
 
1886
                           COLUMN_DESCRIPTION, function_get_name(i),
 
1887
                           -1);
 
1888
    }
 
1889
 
 
1890
    return GTK_TREE_MODEL(model);
 
1891
}
 
1892
 
 
1893
 
 
1894
void
 
1895
ui_make_registers()            /* Calculate memory register frame values. */
 
1896
{
 
1897
    char mval[MAXLINE], key[MAXLINE], value[MAXLINE];
 
1898
    int n;
 
1899
 
 
1900
    for (n = 0; n < MAX_REGISTERS; n++) {
 
1901
        MPNumber temp;
 
1902
        
 
1903
        register_get(n, &temp);
 
1904
        display_make_number(&v->display, mval, MAXLINE, &temp, v->base, TRUE);
 
1905
        gtk_entry_set_width_chars(GTK_ENTRY(X.register_entries[n]), strlen(mval));
 
1906
        gtk_entry_set_text(GTK_ENTRY(X.register_entries[n]), mval);
 
1907
 
 
1908
        SNPRINTF(key, MAXLINE, "register%d", n);
 
1909
        display_make_number(&v->display, value, MAXLINE, &temp, 10, TRUE);
 
1910
        set_resource(key, value);
 
1911
    }
 
1912
}
 
1913
 
 
1914
 
 
1915
static void
 
1916
save_win_position()
 
1917
{
 
1918
    int x, y;
 
1919
 
 
1920
    (void) gdk_window_get_origin(gtk_widget_get_window(X.main_window), &x, &y);
 
1921
    set_int_resource(R_XPOS, x);
 
1922
    set_int_resource(R_YPOS, y);
 
1923
}
 
1924
 
806
1925
 
807
1926
G_MODULE_EXPORT
808
1927
gboolean
809
1928
bit_toggle_cb(GtkWidget *event_box, GdkEventButton *event)
810
1929
{
811
 
    do_button(FN_TOGGLE_BIT,
812
 
              g_object_get_data(G_OBJECT(event_box), "bit_index"));
 
1930
    int index;
 
1931
    index = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(event_box), "bit_index"));
 
1932
    do_button(FN_TOGGLE_BIT, index);
813
1933
    return TRUE;
814
1934
}
815
1935
 
816
1936
 
817
1937
G_MODULE_EXPORT
818
1938
void
819
 
set_superscript_cb(GtkWidget *widget)
 
1939
menu_item_select_cb(GtkWidget *widget)
820
1940
{
821
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
822
 
       X.can_super_minus = TRUE;
823
 
       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.subscript_toggle), FALSE);
824
 
    }
825
 
    else
826
 
       X.can_super_minus = FALSE;
 
1941
    GtkStatusbar *statusbar = GTK_STATUSBAR(X.statusbar);
 
1942
    gchar *tooltip;
 
1943
    guint context_id;
 
1944
 
 
1945
    context_id = gtk_statusbar_get_context_id(statusbar, "menuhelp");
 
1946
 
 
1947
    tooltip = (gchar *)g_object_get_data(G_OBJECT(widget), "tooltip");
 
1948
    if (tooltip)
 
1949
        gtk_statusbar_push(statusbar, context_id, tooltip);
827
1950
}
828
1951
 
829
1952
 
830
1953
G_MODULE_EXPORT
831
1954
void
832
 
set_subscript_cb(GtkWidget *widget)
833
 
{
834
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
835
 
       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.superscript_toggle), FALSE);
 
1955
menu_item_deselect_cb(GtkWidget *widget)
 
1956
{
 
1957
    GtkStatusbar *statusbar = GTK_STATUSBAR(X.statusbar);
 
1958
    guint context_id;
 
1959
 
 
1960
    context_id = gtk_statusbar_get_context_id(statusbar, "menuhelp");
 
1961
    gtk_statusbar_pop(statusbar, context_id);
 
1962
}
 
1963
 
 
1964
 
 
1965
static void
 
1966
set_menubar_tooltip(gchar *menu_name)
 
1967
{
 
1968
    GtkWidget *menu;
 
1969
    gchar *tooltip;
 
1970
    
 
1971
    menu = GET_WIDGET(menu_name);
 
1972
    tooltip = gtk_widget_get_tooltip_text(menu);
 
1973
    g_object_set_data(G_OBJECT(menu), "tooltip", tooltip);
 
1974
    gtk_widget_set_tooltip_text(menu, NULL);
836
1975
}
837
1976
 
838
1977
 
839
1978
static void
840
1979
update_memory_menus()
841
1980
{
 
1981
    char mstr[MAXLINE], value[MAXLINE];
842
1982
    int i;
843
1983
 
844
 
    for (i = 0; registers[i] != NULL; i++) {
845
 
        char value[MAXLINE] = "", mstr[MAXLINE];
846
 
        MPNumber *t;
847
 
 
848
 
        t = register_get_value(registers[i]);
849
 
        if (t)
850
 
            display_make_number(&v->display, value, MAXLINE, t);
851
 
        SNPRINTF(mstr, MAXLINE, "<span weight=\"bold\">%s</span> = %s", registers[i], value);
 
1984
    for (i = 0; i < MAX_REGISTERS; i++) {
 
1985
        MPNumber temp;
 
1986
        register_get(i, &temp);
 
1987
        display_make_number(&v->display, value, MAXLINE, &temp, v->base, TRUE);
 
1988
        SNPRINTF(mstr, MAXLINE, "<span weight=\"bold\">%s_%d:</span>    %s",
 
1989
        /* Translators: R is the short form of register used inter alia in popup menus */
 
1990
                _("R"), i, value);
852
1991
        gtk_label_set_markup_with_mnemonic(GTK_LABEL(X.memory_store_labels[i]), mstr);
853
1992
        gtk_label_set_markup_with_mnemonic(GTK_LABEL(X.memory_recall_labels[i]), mstr);
 
1993
        gtk_label_set_markup_with_mnemonic(GTK_LABEL(X.memory_exchange_labels[i]), mstr);
854
1994
    }
855
1995
}
856
1996
 
857
 
/* The Copy function key has been pressed. */
858
1997
static void
859
 
get_display()
 
1998
get_display()              /* The Copy function key has been pressed. */
860
1999
{
861
2000
    gchar *string = NULL;
862
2001
    GtkTextIter start, end;
878
2017
static gboolean
879
2018
check_for_localized_numeric_point(int keyval)
880
2019
{
881
 
    gchar outbuf[10]; /* Minumum size 6. */
 
2020
    gchar outbuf[10];        /* Minumum size 6. */
882
2021
    gunichar ch;
883
2022
 
884
2023
    ch = gdk_keyval_to_unicode(keyval);
891
2030
 
892
2031
 
893
2032
G_MODULE_EXPORT
894
 
void
 
2033
void 
895
2034
help_cb(GtkWidget *widget)
896
2035
{
897
2036
    help_display();
898
2037
}
899
2038
 
900
2039
 
 
2040
G_MODULE_EXPORT
 
2041
void
 
2042
hyp_cb(GtkWidget *widget)
 
2043
{
 
2044
    ui_update_modifier_mode();
 
2045
}
 
2046
 
 
2047
 
 
2048
G_MODULE_EXPORT
 
2049
void
 
2050
trig_cb(GtkWidget *widget)
 
2051
{
 
2052
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
 
2053
        do_button(FN_SET_TRIG_TYPE, (int)g_object_get_data(G_OBJECT(widget), "trig_mode"));
 
2054
}
 
2055
 
 
2056
 
 
2057
G_MODULE_EXPORT
 
2058
void
 
2059
inv_cb(GtkWidget *widget)
 
2060
{
 
2061
    ui_update_modifier_mode();
 
2062
}
 
2063
 
 
2064
 
901
2065
static void
902
2066
menu_pos_func(GtkMenu *menu, gint *x, gint *y,
903
2067
              gboolean *push_in, gpointer user_data)
911
2075
 
912
2076
G_MODULE_EXPORT
913
2077
void
914
 
solve_cb(GtkWidget *widget, GdkEventButton *event)
915
 
{
916
 
    do_button(FN_CALCULATE, NULL);
917
 
}
918
 
 
919
 
 
920
 
G_MODULE_EXPORT
921
 
void
922
 
clear_cb(GtkWidget *widget, GdkEventButton *event)
923
 
{
924
 
    do_button(FN_CLEAR, NULL);
925
 
}
926
 
 
927
 
 
928
 
G_MODULE_EXPORT
929
 
void
930
 
finc_cb(GtkWidget *widget, GdkEventButton *event)
931
 
{
932
 
    do_finc(g_object_get_data(G_OBJECT(widget), "finc_dialog"));
933
 
}
934
 
 
935
 
static void
936
 
recalculate_currency(CurrencyTargetRow target)
937
 
{
938
 
    int upper_index, lower_index;
939
 
 
940
 
    GtkComboBox *combo_upper = GTK_COMBO_BOX(gtk_builder_get_object(
941
 
        X.financial,
942
 
        "currency_type_upper"));
943
 
    GtkComboBox *combo_lower = GTK_COMBO_BOX(gtk_builder_get_object(
944
 
        X.financial,
945
 
        "currency_type_lower"));
946
 
    GtkSpinButton *spin_upper = GTK_SPIN_BUTTON(gtk_builder_get_object(
947
 
        X.financial,
948
 
        "currency_amount_upper"));
949
 
    GtkSpinButton *spin_lower = GTK_SPIN_BUTTON(gtk_builder_get_object(
950
 
        X.financial,
951
 
        "currency_amount_lower"));
952
 
 
953
 
    GtkTreeModel *model = gtk_combo_box_get_model(combo_upper);
954
 
    GtkTreeIter iter;
955
 
 
956
 
    if (!gtk_combo_box_get_active_iter(combo_upper, &iter))
957
 
        return;
958
 
    gtk_tree_model_get(model, &iter, 0, &upper_index, -1);
959
 
 
960
 
    if (!gtk_combo_box_get_active_iter(combo_lower, &iter))
961
 
        return;
962
 
    gtk_tree_model_get(model, &iter, 0, &lower_index, -1);
963
 
 
964
 
    if (target == CURRENCY_TARGET_LOWER) {
965
 
        MPNumber input, output;
966
 
        mp_set_from_double (gtk_spin_button_get_value(spin_upper), &input);
967
 
        currency_convert(&input, upper_index, lower_index, &output);
968
 
        if (!mp_is_zero(&output))
969
 
            gtk_spin_button_set_value(spin_lower, mp_cast_to_double(&output));
970
 
    } else {
971
 
        MPNumber input, output;
972
 
        mp_set_from_double (gtk_spin_button_get_value(spin_lower), &input);
973
 
        currency_convert(&input, lower_index, upper_index, &output);
974
 
        if (!mp_is_zero(&output))
975
 
            gtk_spin_button_set_value(spin_upper, mp_cast_to_double(&output));
976
 
    }
977
 
}
978
 
 
979
 
G_MODULE_EXPORT
980
 
void
981
 
currency_type_cb(GtkComboBox *combo, gpointer user_data)
982
 
{
983
 
    recalculate_currency(CURRENCY_TARGET_LOWER);
984
 
}
985
 
 
986
 
G_MODULE_EXPORT
987
 
void
988
 
currency_amount_cb (GtkSpinButton *spinbutton, gpointer user_data)
989
 
{
990
 
    recalculate_currency(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spinbutton),
991
 
                                                           "target")));
992
 
}
993
 
 
994
 
static void
995
 
setup_currency_rates ()
996
 
{
997
 
    static int has_run = 0;
998
 
    int i;
999
 
    GtkListStore *currency_store;
1000
 
    GObject *currency_type;
1001
 
 
1002
 
    if (has_run)
1003
 
        return;
1004
 
 
1005
 
    if (currency_rates_needs_update()) {
1006
 
        GtkWidget *dialog = gtk_message_dialog_new(NULL, 0,
1007
 
                                        GTK_MESSAGE_INFO,
1008
 
                                        GTK_BUTTONS_YES_NO,
1009
 
                                        /* Translators: Title of the error dialog when prompting to download currency rates */
1010
 
                                        N_("You don't have any recent currency rates. Should some be downloaded now?"));
1011
 
        int response = gtk_dialog_run(GTK_DIALOG(dialog));
1012
 
        gtk_widget_destroy(dialog);
1013
 
 
1014
 
        if (response == GTK_RESPONSE_YES) {
1015
 
            if (!currency_download_rates()) {
1016
 
                dialog = gtk_message_dialog_new(NULL, 0,
1017
 
                                                GTK_MESSAGE_ERROR,
1018
 
                                                GTK_BUTTONS_OK,
1019
 
                                                /* Translators: Title of the error dialog when unable to download currency rates */
1020
 
                                                N_("Currency rates could not be downloaded. You may receive inaccurate results, or you may not receive any results at all."));
1021
 
            }
1022
 
        }
1023
 
    }
1024
 
    currency_load_rates();
1025
 
 
1026
 
    currency_type = gtk_builder_get_object(X.financial, "currency_type_upper");
1027
 
    currency_store = GTK_LIST_STORE(gtk_combo_box_get_model(
1028
 
        GTK_COMBO_BOX(currency_type)));
1029
 
 
1030
 
    for (i = 0; currency_names[i].short_name; i++) {
1031
 
        GtkTreeIter iter;
1032
 
        int index;
1033
 
 
1034
 
        if ((index = currency_get_index(currency_names[i].short_name)) < 0) {
1035
 
            continue;
1036
 
        }
1037
 
        gtk_list_store_append(currency_store, &iter);
1038
 
        gtk_list_store_set(currency_store, &iter,
1039
 
                           0, index,
1040
 
                           1, gettext(currency_names[i].long_name),
1041
 
                           -1);
1042
 
    }
1043
 
 
1044
 
    has_run = 1;
1045
 
}
1046
 
 
1047
 
G_MODULE_EXPORT
1048
 
void
1049
 
currency_cb(GtkWidget *widget, GdkEventButton *event)
1050
 
{
1051
 
    GtkDialog *win;
1052
 
    GtkSpinButton *c_amount_upper, *c_amount_lower;
1053
 
    MPNumber display_val;
1054
 
 
1055
 
    if (X.financial == NULL)
1056
 
        setup_finc_dialogs();
1057
 
 
1058
 
    setup_currency_rates();
1059
 
 
1060
 
    win = GTK_DIALOG(gtk_builder_get_object(X.financial, "currency_dialog"));
1061
 
    c_amount_upper = GTK_SPIN_BUTTON(gtk_builder_get_object(
1062
 
        X.financial,
1063
 
        "currency_amount_upper"));
1064
 
    c_amount_lower = GTK_SPIN_BUTTON(gtk_builder_get_object(
1065
 
        X.financial,
1066
 
        "currency_amount_lower"));
1067
 
    if (display_is_usable_number(&v->display, &display_val)) {
1068
 
        double start_val = mp_cast_to_double(&display_val);
1069
 
        gtk_spin_button_set_value(c_amount_upper, start_val);
1070
 
    }
1071
 
    gtk_widget_grab_focus(GTK_WIDGET(c_amount_upper));
1072
 
 
1073
 
    if (gtk_dialog_run(win) == GTK_RESPONSE_OK) {
1074
 
        gchar *result;
1075
 
        
1076
 
        result = g_strdup_printf("%.2f",
1077
 
                                 gtk_spin_button_get_value(c_amount_lower));
1078
 
        mp_set_from_string(result, &display_val);
1079
 
        g_free(result);
1080
 
 
1081
 
        display_set_number(&v->display, &display_val);
1082
 
    }
1083
 
 
1084
 
    gtk_widget_hide(GTK_WIDGET(win));
1085
 
}
1086
 
 
1087
 
G_MODULE_EXPORT
1088
 
void
1089
 
popup_cb(GtkWidget *widget, GdkEventButton *event)
1090
 
{
 
2078
button_cb(GtkWidget *widget, GdkEventButton *event)
 
2079
{
 
2080
    int function;
1091
2081
    GtkWidget *menu;
1092
2082
    GdkPoint loc;
1093
 
 
1094
 
    /* If gcalctool is being driven by gok, the on-screen keyboard
1095
 
     * assistive technology, it's possible that the event returned by
1096
 
     * gtk_get_current_event() is NULL. If this is the case, we need
1097
 
     * to fudge the popping up on the menu associated with this menu
1098
 
     * button.
1099
 
     */
1100
 
 
1101
 
    update_memory_menus();
1102
 
 
 
2083
    char* dialog;
 
2084
#if GTK_CHECK_VERSION (2,17,7)
 
2085
    GtkAllocation allocation;
 
2086
#endif
 
2087
    
 
2088
    function = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "calc_function"));
1103
2089
    menu = (GtkWidget *)g_object_get_data(G_OBJECT(widget), "calc_menu");
1104
 
    if (event == NULL) {
1105
 
        GtkAllocation allocation;
1106
 
 
1107
 
        if (X.mode == PROGRAMMING) {
 
2090
    dialog = g_object_get_data(G_OBJECT(widget), "finc_dialog");
 
2091
 
 
2092
    if (menu == NULL && dialog == NULL) {
 
2093
        do_button(function, 0);
 
2094
    } else if (dialog != NULL) {
 
2095
        do_finc(dialog);
 
2096
    } else {
 
2097
        /* If gcalctool is being driven by gok, the on-screen keyboard 
 
2098
         * assistive technology, it's possible that the event returned by 
 
2099
         * gtk_get_current_event() is NULL. If this is the case, we need 
 
2100
         * to fudge the popping up on the menu associated with this menu 
 
2101
         * button.
 
2102
         */
 
2103
 
 
2104
        update_constants_menu();
 
2105
        update_functions_menu();
 
2106
        update_memory_menus();
 
2107
 
 
2108
        if (event == NULL) {
1108
2109
            gdk_window_get_origin(gtk_widget_get_window(widget), &loc.x, &loc.y);
1109
 
            gtk_widget_get_allocation(widget, &allocation);
 
2110
#if GTK_CHECK_VERSION (2,17,7)
 
2111
            gtk_widget_get_allocation (widget, &allocation);
1110
2112
            loc.x += allocation.x;
1111
2113
            loc.y += allocation.y;
1112
 
        } else {
1113
 
            gdk_window_get_origin(gtk_widget_get_window(X.display_item), &loc.x, &loc.y);
1114
 
            gtk_widget_get_allocation(X.display_item, &allocation);
1115
 
            loc.x += allocation.x + allocation.width;
1116
 
            loc.y += allocation.y + allocation.height;
1117
 
        }
1118
 
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, menu_pos_func,
1119
 
                       (gpointer) &loc, 0, gtk_get_current_event_time());
1120
 
    } else if (event->button == 1) {
1121
 
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
1122
 
                       event->button, event->time);
1123
 
    }
1124
 
}
1125
 
 
1126
 
 
1127
 
G_MODULE_EXPORT
1128
 
void
1129
 
factorize_cb(GtkWidget *widget, GdkEventButton *event)
1130
 
{
1131
 
    do_button(FN_FACTORIZE, NULL);
1132
 
}
1133
 
 
1134
 
 
1135
 
G_MODULE_EXPORT
1136
 
void
1137
 
digit_cb(GtkWidget *widget, GdkEventButton *event)
1138
 
{
1139
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(X.superscript_toggle)))
1140
 
        do_text(g_object_get_data(G_OBJECT(widget), "calc_superscript_text"));
1141
 
    else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(X.subscript_toggle)))
1142
 
        do_text(g_object_get_data(G_OBJECT(widget), "calc_subscript_text"));
1143
 
    else
1144
 
        do_text(g_object_get_data(G_OBJECT(widget), "calc_text"));
1145
 
}
1146
 
 
1147
 
 
1148
 
static void
1149
 
do_base(gint base)
1150
 
{
1151
 
    /* If has a number already in a base, then solve and convert it */
1152
 
    if (!display_is_result(&v->display) && display_is_number_with_base(&v->display))
1153
 
        do_button(FN_CALCULATE, NULL);
1154
 
 
1155
 
    if (display_is_result(&v->display)) {
1156
 
        if (base == 2)
1157
 
            display_convert (&v->display, BIN);
1158
 
        else if (base == 8)
1159
 
            display_convert (&v->display, OCT);
1160
 
        else if (base == 16)
1161
 
            display_convert (&v->display, HEX);
1162
 
        else
1163
 
            display_convert (&v->display, DEC);
1164
 
    }
1165
 
    else {
1166
 
        if (base == 2)
1167
 
            do_text("₂");
1168
 
        else if (base == 8)
1169
 
            do_text("₈");
1170
 
        else if (base == 16)
1171
 
            do_text("₁₆");
1172
 
    }
1173
 
}
1174
 
 
1175
 
 
1176
 
static void
1177
 
do_exponent()
1178
 
{
1179
 
    do_text("×10");
1180
 
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.superscript_toggle), TRUE);
1181
 
}
1182
 
 
1183
 
 
1184
 
static void
1185
 
do_subtract()
1186
 
{
1187
 
    if (X.can_super_minus) {
1188
 
        do_text("⁻");
1189
 
        X.can_super_minus = FALSE;
1190
 
    }
1191
 
    else {
1192
 
        do_text("−");
1193
 
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.superscript_toggle), FALSE);
1194
 
    }
1195
 
}
1196
 
 
1197
 
 
1198
 
G_MODULE_EXPORT
1199
 
void
1200
 
base_cb(GtkWidget *widget, GdkEventButton *event)
1201
 
{
1202
 
    do_base(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "base")));
1203
 
}
1204
 
 
1205
 
 
1206
 
G_MODULE_EXPORT
1207
 
void
1208
 
exponent_cb(GtkWidget *widget, GdkEventButton *event)
1209
 
{
1210
 
    do_exponent();
1211
 
}
1212
 
 
1213
 
 
1214
 
G_MODULE_EXPORT
1215
 
void
1216
 
subtract_cb(GtkWidget *widget, GdkEventButton *event)
1217
 
{
1218
 
    do_subtract();
1219
 
}
1220
 
 
1221
 
 
1222
 
G_MODULE_EXPORT
1223
 
void
1224
 
button_cb(GtkWidget *widget, GdkEventButton *event)
1225
 
{
1226
 
    do_text(g_object_get_data(G_OBJECT(widget), "calc_text"));
1227
 
}
1228
 
 
1229
 
 
1230
 
/*static void
 
2114
#else
 
2115
            loc.x += widget->allocation.x;
 
2116
            loc.y += widget->allocation.y;
 
2117
#endif
 
2118
            gtk_menu_popup(GTK_MENU(menu), NULL, NULL, menu_pos_func,
 
2119
                           (gpointer) &loc, 0, gtk_get_current_event_time());
 
2120
        } else if (event->button == 1) {
 
2121
            gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
 
2122
                           event->button, event->time);
 
2123
        }
 
2124
    }
 
2125
}
 
2126
 
 
2127
 
 
2128
static void
1231
2129
select_display_entry(int offset)
1232
2130
{
1233
2131
    GtkTextIter iter;
1234
 
 
 
2132
    
1235
2133
    gtk_text_buffer_get_iter_at_offset(X.display_buffer, &iter, offset);
1236
2134
    gtk_text_buffer_place_cursor(X.display_buffer, &iter);
1237
2135
    gtk_widget_grab_focus(X.display_item);
1238
 
}*/
 
2136
}
1239
2137
 
1240
2138
 
1241
2139
G_MODULE_EXPORT
1242
2140
gboolean
1243
2141
main_window_key_press_cb(GtkWidget *widget, GdkEventKey *event)
1244
2142
{
1245
 
    int i, state;
1246
 
    const char *conversions[]       = {"*", "/", NULL};
1247
 
    const char *conversion_values[] = {"×", "÷", NULL };
 
2143
    int i, j, state;
 
2144
    GtkWidget *button;
1248
2145
 
1249
2146
    /* Only look at the modifiers we use */
1250
2147
    state = event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK);
1251
 
 
1252
 
    // FIXME: Convert event to character
1253
 
    // FIXME: Or safer to intercept characters as they enter the text input (handles input methods)
1254
 
 
 
2148
    
1255
2149
    if (check_for_localized_numeric_point(event->keyval) == TRUE) {
1256
2150
        event->state = 0;
1257
2151
        event->keyval = GDK_KP_Decimal;
1258
2152
    }
1259
 
 
1260
 
    /* Shortcuts */
1261
 
    if (state == GDK_CONTROL_MASK) {
1262
 
        switch(event->keyval)
1263
 
        {
1264
 
        case GDK_b:
1265
 
            do_base(2);
1266
 
            return TRUE;
1267
 
        case GDK_d:
1268
 
            do_base(10);
1269
 
            return TRUE;
1270
 
        case GDK_e:
1271
 
            do_exponent();
1272
 
            return TRUE;
1273
 
        case GDK_f:
1274
 
            do_button(FN_FACTORIZE, NULL);
1275
 
            return TRUE;
1276
 
        case GDK_h:
1277
 
            do_base(16);          
1278
 
            return TRUE;
1279
 
        case GDK_i:
1280
 
            do_text("⁻¹");
1281
 
            return TRUE;
1282
 
        case GDK_o:
1283
 
            do_base(8);
1284
 
            return TRUE;
1285
 
        case GDK_p:
1286
 
            do_text("π");
1287
 
            return TRUE;
1288
 
        case GDK_r:
1289
 
            do_text("√");
1290
 
            return TRUE;
1291
 
        case GDK_u:
1292
 
            do_text("µ");
1293
 
            return TRUE;
1294
 
        }
1295
 
    }
1296
 
    if (state == GDK_CONTROL_MASK ||
1297
 
        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(X.superscript_toggle))) {
1298
 
        switch(event->keyval)
1299
 
        {
1300
 
        case GDK_0:
1301
 
            do_text("⁰");
1302
 
            return TRUE;
1303
 
        case GDK_1:
1304
 
            do_text("¹");
1305
 
            return TRUE;
1306
 
        case GDK_2:
1307
 
            do_text("²");
1308
 
            return TRUE;
1309
 
        case GDK_3:
1310
 
            do_text("³");
1311
 
            return TRUE;
1312
 
        case GDK_4:
1313
 
            do_text("⁴");
1314
 
            return TRUE;
1315
 
        case GDK_5:
1316
 
            do_text("⁵");
1317
 
            return TRUE;
1318
 
        case GDK_6:
1319
 
            do_text("⁶");
1320
 
            return TRUE;
1321
 
        case GDK_7:
1322
 
            do_text("⁷");
1323
 
            return TRUE;
1324
 
        case GDK_8:
1325
 
            do_text("⁸");
1326
 
            return TRUE;
1327
 
        case GDK_9:
1328
 
            do_text("⁹");
1329
 
            return TRUE;
1330
 
        }
1331
 
    }
1332
 
    else if (state == GDK_MOD1_MASK ||
1333
 
             gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(X.subscript_toggle))) {
1334
 
        switch(event->keyval)
1335
 
        {
1336
 
        case GDK_0:
1337
 
            do_text("₀");
1338
 
            return TRUE;
1339
 
        case GDK_1:
1340
 
            do_text("₁");
1341
 
            return TRUE;
1342
 
        case GDK_2:
1343
 
            do_text("₂");
1344
 
            return TRUE;
1345
 
        case GDK_3:
1346
 
            do_text("₃");
1347
 
            return TRUE;
1348
 
        case GDK_4:
1349
 
            do_text("₄");
1350
 
            return TRUE;
1351
 
        case GDK_5:
1352
 
            do_text("₅");
1353
 
            return TRUE;
1354
 
        case GDK_6:
1355
 
            do_text("₆");
1356
 
            return TRUE;
1357
 
        case GDK_7:
1358
 
            do_text("₇");
1359
 
            return TRUE;
1360
 
        case GDK_8:
1361
 
            do_text("₈");
1362
 
            return TRUE;
1363
 
        case GDK_9:
1364
 
            do_text("₉");
1365
 
            return TRUE;
1366
 
        }
1367
 
    }
1368
 
 
 
2153
    
 
2154
    /* Accuracy shortcuts */
 
2155
    if (state == GDK_CONTROL_MASK && (X.mode == SCIENTIFIC || 
 
2156
                                      X.mode == PROGRAMMING)) {
 
2157
        switch (event->keyval) {
 
2158
            case GDK_0:
 
2159
                do_button(FN_SET_ACCURACY, 0);
 
2160
                return TRUE;
 
2161
            case GDK_1:
 
2162
                do_button(FN_SET_ACCURACY, 1);
 
2163
                return TRUE;
 
2164
            case GDK_2:
 
2165
                do_button(FN_SET_ACCURACY, 2);
 
2166
                return TRUE;
 
2167
            case GDK_3:
 
2168
                do_button(FN_SET_ACCURACY, 3);
 
2169
                return TRUE;
 
2170
            case GDK_4:
 
2171
                do_button(FN_SET_ACCURACY, 4);
 
2172
                return TRUE;
 
2173
            case GDK_5:
 
2174
                do_button(FN_SET_ACCURACY, 5);
 
2175
                return TRUE;
 
2176
            case GDK_6:
 
2177
                do_button(FN_SET_ACCURACY, 6);
 
2178
                return TRUE;
 
2179
            case GDK_7:
 
2180
                do_button(FN_SET_ACCURACY, 7);
 
2181
                return TRUE;
 
2182
            case GDK_8:
 
2183
                do_button(FN_SET_ACCURACY, 8);
 
2184
                return TRUE;
 
2185
            case GDK_9:
 
2186
                do_button(FN_SET_ACCURACY, 9);
 
2187
                return TRUE;
 
2188
        }
 
2189
    }
 
2190
    
 
2191
    /* Connect home and end keys to move into the display entry */
 
2192
    if (!gtk_widget_is_focus(X.display_item)) {
 
2193
        if (event->keyval == GDK_Home) { /* || event->keyval == GDK_Left) { */
 
2194
            select_display_entry(0);
 
2195
            return TRUE;
 
2196
        } else if (event->keyval == GDK_End) { /* || event->keyval == GDK_Right) { */
 
2197
            select_display_entry(-1);
 
2198
            return TRUE;
 
2199
        }
 
2200
    }
 
2201
 
 
2202
    /* Whitespace (but don't override activating buttons from the keyboard) */
 
2203
    if (gtk_widget_is_focus(X.display_item) && event->keyval == GDK_space && state == 0) {
 
2204
        do_button(FN_SPACE, 0);
 
2205
        return TRUE;
 
2206
    }
 
2207
 
 
2208
    /* Absolute value */
 
2209
    /*if (event->keyval == GDK_bar && state == 0) {
 
2210
        do_button(FN_ABSOLUTE_VALUE, 0);
 
2211
        return TRUE;
 
2212
    }*/
 
2213
    
1369
2214
    /* Delete in display */
1370
2215
    if (event->keyval == GDK_Delete && state == 0 && (event->state & GDK_SHIFT_MASK) == 0) {
1371
 
        do_button(FN_DELETE, NULL);
1372
 
        return TRUE;
1373
 
    }
1374
 
    if (event->keyval == GDK_BackSpace && state == 0 && (event->state & GDK_SHIFT_MASK) == 0) {
1375
 
        do_button(FN_BACKSPACE, NULL);
1376
 
        return TRUE;
1377
 
    }
1378
 
 
1379
 
    /* Clear display */
1380
 
    if ((event->keyval == GDK_Escape && state == 0) ||
1381
 
        (event->keyval == GDK_BackSpace && state == GDK_CONTROL_MASK) ||
1382
 
        (event->keyval == GDK_Delete && state == GDK_SHIFT_MASK)) {
1383
 
        do_button(FN_CLEAR, NULL);
1384
 
        return TRUE;
1385
 
    }
1386
 
 
1387
 
    /* Solve */
1388
 
    if ((event->keyval == GDK_Return && state == 0) ||
1389
 
        (event->keyval == GDK_KP_Enter && state == 0)) {
1390
 
        if (gtk_widget_has_focus(X.display_item)) {
1391
 
            do_button(FN_CALCULATE, NULL);
1392
 
            return TRUE;
1393
 
        }
1394
 
        else {
1395
 
            return FALSE;
1396
 
        }
1397
 
    }
1398
 
 
1399
 
    if (state == GDK_CONTROL_MASK && event->keyval == GDK_minus) 
1400
 
    {
1401
 
        do_text("⁻");
1402
 
        X.can_super_minus = FALSE;
1403
 
        return TRUE;
1404
 
    }
1405
 
 
1406
 
    if (state != 0)
1407
 
        return FALSE;
1408
 
 
1409
 
    // FIXME: event->string deprecated
1410
 
 
1411
 
    if (strcmp(event->string, "-") == 0 || strcmp(event->string, "−") == 0) {
1412
 
        do_subtract();
1413
 
        return TRUE;
1414
 
    }
1415
 
 
1416
 
    for (i = 0; conversions[i]; i++) {
1417
 
        if (strcmp(event->string, conversions[i]) == 0) {
1418
 
            do_text(conversion_values[i]);
1419
 
            return TRUE;
1420
 
        }
1421
 
    }
1422
 
    if (strcmp(event->string, ".") == 0) {
1423
 
        do_text(v->radix);
1424
 
        return TRUE;
1425
 
    }
1426
 
 
1427
 
    /* Some keyboards use this keyval for '^' (e.g. German) */
1428
 
    if (event->keyval == GDK_dead_circumflex) {
1429
 
        do_text("^");
1430
 
        return TRUE;
1431
 
    }
1432
 
 
1433
 
    switch(*event->string)
1434
 
    {
1435
 
    case '<':
1436
 
        popup_cb(GET_WIDGET("calc_shift_left_button"), NULL);
1437
 
        return TRUE;
1438
 
    case '>':
1439
 
        popup_cb(GET_WIDGET("calc_shift_right_button"), NULL);
1440
 
        return TRUE;
1441
 
    case '\n':
1442
 
        do_button(FN_CALCULATE, NULL);
1443
 
        return TRUE;
1444
 
    }
1445
 
  
1446
 
    /* Don't override space - it is used in UI */
1447
 
    if (event->string[0] == ' ' && !gtk_widget_has_focus(X.display_item))
1448
 
        return FALSE;
1449
 
 
1450
 
    if (event->string[0] != '\0') {
1451
 
        do_text(event->string);
1452
 
        return TRUE;
1453
 
    }
1454
 
 
1455
 
    return FALSE;
1456
 
}
1457
 
 
1458
 
 
1459
 
G_MODULE_EXPORT void
 
2216
        do_button(FN_DELETE, 0);
 
2217
        return TRUE;
 
2218
    }
 
2219
 
 
2220
    /* Shift inverse mode based on if shift is pressed */
 
2221
    if (event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R) {
 
2222
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.inverse_toggle), 
 
2223
                                     TRUE);
 
2224
        return TRUE;
 
2225
    }
 
2226
    
 
2227
    for (i = 0; i < NBUTTONS; i++) {
 
2228
        button = X.buttons[i];
 
2229
        
 
2230
        /* Check if function is available */
 
2231
#if GTK_CHECK_VERSION (2,17,5)
 
2232
        if (!gtk_widget_is_sensitive (button))
 
2233
#else
 
2234
        if (!GTK_WIDGET_IS_SENSITIVE(button))
 
2235
#endif
 
2236
            continue;
 
2237
        
 
2238
        /* In basic mode only allow buttons that the user can see */
 
2239
        if (X.mode == BASIC &&
 
2240
#if GTK_CHECK_VERSION (2,17,5)
 
2241
            (!gtk_widget_get_visible (gtk_widget_get_parent(button)) ||
 
2242
             !gtk_widget_get_visible (button)))
 
2243
#else
 
2244
            (!GTK_WIDGET_VISIBLE(gtk_widget_get_parent(button)) ||
 
2245
             !GTK_WIDGET_VISIBLE(button)))
 
2246
#endif
 
2247
            continue;
 
2248
 
 
2249
        // FIXME: This is a bit hacky - needs to be rethought
 
2250
        for (j = 0; button_widgets[i].accelerator_keys[j] != 0; j++) {
 
2251
            if (button_widgets[i].accelerator_keys[j] == event->keyval &&
 
2252
                (button_widgets[i].accelerator_mods[j] & ~GDK_SHIFT_MASK) == state) {
 
2253
                
 
2254
                // If we use shift for this shortcut then check it was in the original mask
 
2255
                if ((button_widgets[i].accelerator_mods[j] & GDK_SHIFT_MASK) &&
 
2256
                    !(event->state & GDK_SHIFT_MASK))
 
2257
                    continue;
 
2258
 
 
2259
                // Hack if this is a multi-function button
 
2260
                if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "calc_function")) !=
 
2261
                    button_widgets[i].function)
 
2262
                    do_button(button_widgets[i].function, 0);
 
2263
                else
 
2264
                    button_cb(button, NULL);
 
2265
                return TRUE;
 
2266
            }
 
2267
        }
 
2268
    }
 
2269
 
 
2270
    return FALSE;
 
2271
}
 
2272
 
 
2273
 
 
2274
G_MODULE_EXPORT
 
2275
gboolean
 
2276
main_window_key_release_cb(GtkWidget *widget, GdkEventKey *event)
 
2277
{
 
2278
    if (event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R) {
 
2279
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(X.inverse_toggle), 
 
2280
                                     FALSE);
 
2281
        return TRUE;
 
2282
    }
 
2283
    return FALSE;
 
2284
}
 
2285
 
 
2286
 
 
2287
G_MODULE_EXPORT
 
2288
void 
1460
2289
edit_cb(GtkWidget *widget)
1461
2290
{
1462
2291
    gboolean can_paste, can_copy;
1463
 
 
 
2292
    
1464
2293
    can_copy = gtk_text_buffer_get_has_selection(X.display_buffer);
1465
2294
    can_paste = gtk_clipboard_wait_is_text_available(
1466
2295
                            gtk_clipboard_get(X.clipboard_atom));
1467
 
 
 
2296
    
1468
2297
    gtk_widget_set_sensitive(GET_WIDGET("copy_menu"), can_copy);
1469
2298
    gtk_widget_set_sensitive(GET_WIDGET("paste_menu"), can_paste);
1470
2299
}
1471
2300
 
1472
2301
 
1473
2302
G_MODULE_EXPORT
1474
 
void
 
2303
void 
1475
2304
copy_cb(GtkWidget *widget)
1476
2305
{
1477
2306
    get_display();
1482
2311
on_paste(GtkClipboard *clipboard, const gchar *text, gpointer data)
1483
2312
{
1484
2313
    if (text != NULL)
1485
 
        do_button(FN_PASTE, (gpointer) text);
 
2314
        do_button(FN_PASTE, GPOINTER_TO_INT(text));
1486
2315
}
1487
2316
 
1488
2317
 
1489
2318
G_MODULE_EXPORT
1490
2319
gboolean
1491
 
middle_click_paste_cb(GtkWidget *widget, GdkEventButton *event)
 
2320
mouse_button_cb(GtkWidget *widget, GdkEventButton *event)
1492
2321
{
1493
2322
    if (event->button == 2)
1494
2323
        gtk_clipboard_request_text(gtk_clipboard_get(X.primary_atom),
1499
2328
 
1500
2329
 
1501
2330
G_MODULE_EXPORT
1502
 
void
 
2331
void 
1503
2332
paste_cb(GtkWidget *widget)
1504
2333
{
1505
2334
    gtk_clipboard_request_text(gtk_clipboard_get(X.clipboard_atom),
1508
2337
 
1509
2338
 
1510
2339
G_MODULE_EXPORT
1511
 
void
 
2340
void 
1512
2341
popup_paste_cb(GtkWidget *menu)
1513
2342
{
1514
2343
    paste_cb(menu);
1519
2348
void
1520
2349
undo_cb(GtkWidget *widget)
1521
2350
{
1522
 
    do_button(FN_UNDO, NULL);
 
2351
    do_button(FN_UNDO, 0);
1523
2352
}
1524
2353
 
1525
2354
 
1527
2356
void
1528
2357
redo_cb(GtkWidget *widget)
1529
2358
{
1530
 
    do_button(FN_REDO, NULL);
 
2359
    do_button(FN_REDO, 0);    
1531
2360
}
1532
2361
 
1533
2362
 
1534
2363
static void
1535
2364
for_each_menu(GtkWidget *widget, gpointer data)
1536
2365
{
1537
 
    /* Find the "Paste" entry and activate it (see bug #317786).
1538
 
     * It is disabled because the GtkEntry is not marked as editable.
1539
 
     */
1540
 
    if (strcmp(G_OBJECT_TYPE_NAME(widget), "GtkImageMenuItem") == 0) {
 
2366
    /* Find the "Paste" entry and activate it (see bug #317786). */
 
2367
    if (strcmp(G_OBJECT_TYPE_NAME(widget), "GtkImageMenuItem") == 0) {  
1541
2368
        GtkWidget *label = gtk_bin_get_child(GTK_BIN(widget));
1542
2369
 
1543
 
         if (strcmp(gtk_label_get_text(GTK_LABEL(label)), _("Paste")) == 0) {
 
2370
        // FIXME: WTF?
 
2371
        if (strcmp(gtk_label_get_text(GTK_LABEL(label)), _("Paste")) == 0) {
1544
2372
            if (gtk_clipboard_wait_is_text_available(
1545
2373
                        gtk_clipboard_get(X.clipboard_atom))) {
1546
2374
                gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE);
1564
2392
void
1565
2393
insert_ascii_cb(GtkWidget *widget)
1566
2394
{
1567
 
    if (!gtk_widget_get_visible(X.ascii_dialog))
 
2395
#if GTK_CHECK_VERSION (2,17,5)
 
2396
    if (!gtk_widget_get_visible (X.ascii_dialog))
 
2397
#else
 
2398
    if (!GTK_WIDGET_VISIBLE(X.ascii_dialog))
 
2399
#endif
1568
2400
        position_popup(X.main_window, X.ascii_dialog, POPUP_LEFT);
1569
2401
    gtk_widget_grab_focus(GTK_WIDGET(X.ascii_entry));
1570
2402
    gtk_widget_show(X.ascii_dialog);
1575
2407
void
1576
2408
shift_cb(GtkWidget *widget)
1577
2409
{
1578
 
    do_button(FN_SHIFT, g_object_get_data(G_OBJECT(widget), "shiftcount"));
 
2410
    int count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), 
 
2411
                                                   "shiftcount"));
 
2412
    do_button(FN_SHIFT, count);
 
2413
}
 
2414
 
 
2415
 
 
2416
G_MODULE_EXPORT
 
2417
void
 
2418
show_registers_cb(GtkWidget *widget)
 
2419
{
 
2420
    gboolean visible;    
 
2421
    visible = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));   
 
2422
    ui_set_registers_visible(visible);
1579
2423
}
1580
2424
 
1581
2425
 
1595
2439
 
1596
2440
G_MODULE_EXPORT
1597
2441
void
 
2442
accuracy_radio_cb(GtkWidget *widget)
 
2443
{
 
2444
    int count;
 
2445
    count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "accuracy"));
 
2446
    if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
 
2447
        do_button(FN_SET_ACCURACY, count);
 
2448
}
 
2449
 
 
2450
 
 
2451
G_MODULE_EXPORT
 
2452
void
 
2453
accuracy_other_cb(GtkWidget *widget)
 
2454
{
 
2455
#if GTK_CHECK_VERSION (2,17,5)
 
2456
    if (!gtk_widget_get_visible (X.precision_dialog))
 
2457
#else
 
2458
    if (!GTK_WIDGET_VISIBLE(X.precision_dialog))
 
2459
#endif
 
2460
        position_popup(X.main_window, X.precision_dialog, POPUP_LEFT);
 
2461
    gtk_widget_grab_focus(GTK_WIDGET(X.precision_spin));
 
2462
    gtk_widget_show(X.precision_dialog);
 
2463
}
 
2464
 
 
2465
 
 
2466
G_MODULE_EXPORT
 
2467
void
 
2468
accuracy_default_cb(GtkWidget *widget)
 
2469
{
 
2470
    do_button(FN_SET_ACCURACY, DEFAULT_ACCURACY);
 
2471
}
 
2472
 
 
2473
 
 
2474
G_MODULE_EXPORT
 
2475
void
 
2476
show_trailing_zeroes_cb(GtkWidget *widget)
 
2477
{
 
2478
    gboolean visible;    
 
2479
    visible = gtk_check_menu_item_get_active(
 
2480
                  GTK_CHECK_MENU_ITEM(widget));
 
2481
    ui_set_show_trailing_zeroes(visible);
 
2482
}
 
2483
 
 
2484
 
 
2485
G_MODULE_EXPORT
 
2486
void
1598
2487
quit_cb(GtkWidget *widget)
1599
2488
{
 
2489
    save_win_position();
1600
2490
    gtk_main_quit();
1601
2491
}
1602
2492
 
1603
2493
 
1604
2494
G_MODULE_EXPORT
1605
2495
void
1606
 
show_preferences_cb(GtkMenuItem *menu)
1607
 
{
1608
 
    gtk_window_present(GTK_WINDOW(X.preferences_dialog));
1609
 
}
1610
 
 
1611
 
 
1612
 
G_MODULE_EXPORT
1613
 
void
1614
 
preferences_response_cb(GtkWidget *widget, gint id)
1615
 
{
1616
 
    gtk_widget_hide(X.preferences_dialog);
 
2496
precision_dialog_response_cb(GtkWidget *dialog, gint response_id)
 
2497
{
 
2498
    int val;
 
2499
    if (response_id == GTK_RESPONSE_OK) {
 
2500
        val = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(X.precision_spin));
 
2501
        do_button(FN_SET_ACCURACY, val);
 
2502
    }
 
2503
    
 
2504
    gtk_widget_hide(dialog);
1617
2505
}
1618
2506
 
1619
2507
 
1620
2508
G_MODULE_EXPORT
1621
2509
gboolean
1622
 
preferences_dialog_delete_cb(GtkWidget *widget)
 
2510
precision_dialog_delete_cb(GtkWidget *dialog)
1623
2511
{
1624
 
    preferences_response_cb(widget, 0);
 
2512
    precision_dialog_response_cb(dialog, GTK_RESPONSE_CANCEL);
1625
2513
    return TRUE;
1626
2514
}
1627
2515
 
1628
2516
 
 
2517
G_MODULE_EXPORT
 
2518
void
 
2519
precision_dialog_activate_cb(GtkWidget *spin)
 
2520
{
 
2521
    precision_dialog_response_cb(X.precision_dialog, GTK_RESPONSE_OK);
 
2522
}
 
2523
 
 
2524
 
 
2525
G_MODULE_EXPORT
 
2526
void
 
2527
show_thousands_separator_cb(GtkWidget *widget)
 
2528
{
 
2529
    gboolean visible;
 
2530
    
 
2531
    visible = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
 
2532
    ui_set_show_thousands_separator(visible);
 
2533
}
 
2534
 
 
2535
 
 
2536
G_MODULE_EXPORT
 
2537
void
 
2538
edit_constants_cb(GtkMenuItem *item)
 
2539
{
 
2540
    gtk_widget_show(X.constants_dialog);
 
2541
}
 
2542
 
 
2543
 
 
2544
G_MODULE_EXPORT
 
2545
void
 
2546
edit_functions_cb(GtkMenuItem *item)
 
2547
{
 
2548
    gtk_widget_show(X.function_dialog);
 
2549
}
 
2550
 
 
2551
 
 
2552
static void
 
2553
set_win_position()
 
2554
{
 
2555
    int intval, screen_height, screen_width;
 
2556
    int x = 0, y = 0;
 
2557
 
 
2558
    screen_width = gdk_screen_get_width(gdk_screen_get_default());
 
2559
    screen_height = gdk_screen_get_height(gdk_screen_get_default());
 
2560
 
 
2561
    if (get_int_resource(R_XPOS, &intval)) {
 
2562
        x = intval;
 
2563
        if (x < 0 || x > screen_width)
 
2564
            x = 0;
 
2565
    }
 
2566
 
 
2567
    if (get_int_resource(R_YPOS, &intval)) {
 
2568
        y = intval;
 
2569
        if (y < 0 || y > screen_height)
 
2570
            y = 0;
 
2571
    }
 
2572
 
 
2573
    gtk_window_move(GTK_WINDOW(X.main_window), x, y);
 
2574
}
 
2575
 
 
2576
 
1629
2577
static void
1630
2578
create_main_window()
1631
2579
{
1633
2581
    char name[MAXLINE];
1634
2582
    GtkWidget *widget;
1635
2583
    PangoFontDescription *font_desc;
1636
 
    GtkCellRenderer *renderer;
1637
 
 
 
2584
    GtkSizeGroup *size_group;
 
2585
    GtkAccelGroup *accel_group;
 
2586
    GtkWidget *treeview;
 
2587
   
1638
2588
    X.ui = gtk_builder_new();
1639
2589
    load_ui(X.ui, UI_FILE);
1640
2590
    gtk_builder_connect_signals(X.ui, NULL);
1644
2594
    X.main_window      = GET_WIDGET("calc_window");
1645
2595
    X.ascii_dialog     = GET_WIDGET("ascii_dialog");
1646
2596
    X.ascii_entry      = GET_WIDGET("ascii_entry");
 
2597
    X.precision_dialog = GET_WIDGET("precision_dialog");
 
2598
    X.precision_spin   = GET_WIDGET("precision_dialog_spin");
 
2599
    X.register_dialog  = GET_WIDGET("register_dialog");
 
2600
    X.constants_dialog = GET_WIDGET("edit_constants_dialog");
 
2601
    X.function_dialog  = GET_WIDGET("edit_functions_dialog");
1647
2602
    X.menubar          = GET_WIDGET("menubar");
1648
2603
    X.scrolledwindow   = GET_WIDGET("display_scroll"),
1649
2604
    X.display_item     = GET_WIDGET("displayitem"),
1653
2608
    X.adv_panel        = GET_WIDGET("advanced_panel");
1654
2609
    X.fin_panel        = GET_WIDGET("financial_panel");
1655
2610
    X.bit_panel        = GET_WIDGET("bit_panel");
1656
 
    X.superscript_toggle = GET_WIDGET("superscript_togglebutton");
1657
 
    X.subscript_toggle   = GET_WIDGET("subscript_togglebutton");
1658
 
    X.preferences_dialog = GET_WIDGET("preferences_dialog");
1659
 
    X.info_buffer = GTK_TEXT_BUFFER(GET_OBJECT("info_buffer"));
1660
 
 
1661
 
    /* Connect text to buttons */
1662
 
    for (i = 0; button_data[i].widget_name != NULL; i++) {
1663
 
        SNPRINTF(name, MAXLINE, "calc_%s_button", button_data[i].widget_name);
1664
 
        set_string_data(X.ui, name, "calc_text", button_data[i].data);
1665
 
    }
1666
 
 
1667
 
    /* Localize buttons */
 
2611
    X.clear_buttons[0] = GET_WIDGET("calc_clear_simple_button");
 
2612
    X.clear_buttons[1] = GET_WIDGET("calc_clear_advanced_button");   
 
2613
    X.sci_mode_panel   = GET_WIDGET("scientific_mode_panel");
 
2614
    X.prog_mode_panel  = GET_WIDGET("programming_mode_panel");
 
2615
    X.degree_radio     = GET_WIDGET("degrees_radio");
 
2616
    X.gradian_radio    = GET_WIDGET("gradians_radio");
 
2617
    X.radian_radio     = GET_WIDGET("radians_radio");
 
2618
    X.binary_radio     = GET_WIDGET("binary_radio");
 
2619
    X.octal_radio      = GET_WIDGET("octal_radio");
 
2620
    X.decimal_radio    = GET_WIDGET("decimal_radio");
 
2621
    X.hexadecimal_radio      = GET_WIDGET("hexadecimal_radio");
 
2622
    X.display_mode_radios[0] = GET_WIDGET("engineering_radio");
 
2623
    X.display_mode_radios[1] = GET_WIDGET("fixed_point_radio");
 
2624
    X.display_mode_radios[2] = GET_WIDGET("scientific_radio");
 
2625
    X.word_length_radios[0]  = GET_WIDGET("64bit_radio");
 
2626
    X.word_length_radios[1]  = GET_WIDGET("32bit_radio");
 
2627
    X.word_length_radios[2]  = GET_WIDGET("16bit_radio");
 
2628
    X.inverse_toggle    = GET_WIDGET("inverse_check");
 
2629
    X.hyperbolic_toggle = GET_WIDGET("hyperbolic_check");
 
2630
    X.statusbar         = GET_WIDGET("statusbar");
1668
2631
    for (i = 0; i < 16; i++) {
1669
 
        SNPRINTF(name, MAXLINE, "calc_%d_button", i);
1670
 
        gtk_button_set_label(GTK_BUTTON(GET_OBJECT(name)), v->digits[i]);
1671
 
        set_string_data(X.ui, name, "calc_text", v->digits[i]);
1672
 
    }
1673
 
    gtk_button_set_label(GTK_BUTTON(GET_OBJECT("calc_numeric_point_button")), v->radix);
1674
 
 
1675
 
    /* Connect super and subscript */
1676
 
    for (i = 0; i < 10; i++) {
1677
 
        SNPRINTF(name, MAXLINE, "calc_%d_button", i);
1678
 
        set_string_data(X.ui, name, "calc_subscript_text", subscript_digits[i]);
1679
 
        set_string_data(X.ui, name, "calc_superscript_text", superscript_digits[i]);
1680
 
    }
1681
 
  
1682
 
    /* Set base button data */
1683
 
    set_int_data(X.ui, "calc_base_2_button", "base", 2);
1684
 
    set_int_data(X.ui, "calc_base_8_button", "base", 8);
1685
 
    set_int_data(X.ui, "calc_base_16_button", "base", 16);
1686
 
 
1687
 
    /* Connect menus to popup buttons */
 
2632
        SNPRINTF(name, MAXLINE, "calc_%x_button", i);
 
2633
        X.digit_buttons[i] = GET_WIDGET(name);
 
2634
    }
 
2635
    for (i = 0; i < MAX_REGISTERS; i++) {
 
2636
        SNPRINTF(name, MAXLINE, "register_entry_%d", i);
 
2637
        X.register_entries[i] = GET_WIDGET(name);
 
2638
    }
 
2639
 
 
2640
    /* Load buttons and set them all to be the same size */
 
2641
    size_group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
 
2642
    for (i = 0; i < NBUTTONS; i++) {
 
2643
        SNPRINTF(name, MAXLINE, "calc_%s_button", 
 
2644
                 button_widgets[i].widget_name);
 
2645
        X.buttons[i] = GET_WIDGET(name);            
 
2646
        assert(X.buttons[i] != NULL);
 
2647
        
 
2648
        gtk_size_group_add_widget(size_group, X.buttons[i]);
 
2649
        
 
2650
        g_object_set_data(G_OBJECT(X.buttons[i]), "calc_function", GINT_TO_POINTER(button_widgets[i].function));
 
2651
    }
 
2652
 
 
2653
    /* Make popup buttons */
 
2654
    set_data(X.ui, "calc_accuracy_button", "calc_menu", GET_WIDGET("accuracy_popup"));
1688
2655
    set_data(X.ui, "calc_shift_left_button", "calc_menu", GET_WIDGET("left_shift_popup"));
1689
2656
    set_data(X.ui, "calc_shift_right_button", "calc_menu", GET_WIDGET("right_shift_popup"));
 
2657
    
 
2658
    set_data(X.ui, "calc_constants_button", "calc_menu", GET_WIDGET("constants_popup"));
 
2659
    for (i = 0; i < MAX_CONSTANTS; i++) {
 
2660
        SNPRINTF(name, MAXLINE, "constant_menu_item%d", i);
 
2661
        widget = GET_WIDGET(name);
 
2662
        g_object_set_data(G_OBJECT(widget), "constant_id", GINT_TO_POINTER(i));
 
2663
        X.constant_menu_labels[i] = gtk_bin_get_child(GTK_BIN(widget));
 
2664
    }
 
2665
 
 
2666
    set_data(X.ui, "calc_functions_button", "calc_menu", GET_WIDGET("functions_popup"));
 
2667
    for (i = 0; i < MAX_FUNCTIONS; i++) {
 
2668
        SNPRINTF(name, MAXLINE, "function_menu_item%d", i);
 
2669
        widget = GET_WIDGET(name);
 
2670
        g_object_set_data(G_OBJECT(widget), "function_id", GINT_TO_POINTER(i));
 
2671
        X.function_menu_labels[i] = gtk_bin_get_child(GTK_BIN(widget));
 
2672
    }
 
2673
 
1690
2674
    set_data(X.ui, "calc_store_button", "calc_menu", GET_WIDGET("memory_store_popup"));
1691
2675
    set_data(X.ui, "calc_recall_button", "calc_menu", GET_WIDGET("memory_recall_popup"));
1692
 
 
1693
 
    /* Get labels from popup menus */
1694
 
    for (i = 0; registers[i]; i++) {
 
2676
    set_data(X.ui, "calc_exchange_button", "calc_menu", GET_WIDGET("memory_exchange_popup"));
 
2677
    for (i = 0; i < MAX_REGISTERS; i++) {
1695
2678
        SNPRINTF(name, MAXLINE, "store_menu_item%d", i);
1696
2679
        widget = GET_WIDGET(name);
1697
 
        g_object_set_data(G_OBJECT(widget), "register_id", registers[i]);
 
2680
        g_object_set_data(G_OBJECT(widget), "register_id", GINT_TO_POINTER(i));
1698
2681
        X.memory_store_labels[i] = gtk_bin_get_child(GTK_BIN(widget));
1699
 
 
 
2682
        
1700
2683
        SNPRINTF(name, MAXLINE, "recall_menu_item%d", i);
1701
2684
        widget = GET_WIDGET(name);
1702
 
        g_object_set_data(G_OBJECT(widget), "register_id", registers[i]);
 
2685
        g_object_set_data(G_OBJECT(widget), "register_id", GINT_TO_POINTER(i));
1703
2686
        X.memory_recall_labels[i] = gtk_bin_get_child(GTK_BIN(widget));
 
2687
        
 
2688
        SNPRINTF(name, MAXLINE, "exchange_menu_item%d", i);
 
2689
        widget = GET_WIDGET(name);
 
2690
        g_object_set_data(G_OBJECT(widget), "register_id", GINT_TO_POINTER(i));
 
2691
        X.memory_exchange_labels[i] = gtk_bin_get_child(GTK_BIN(widget));
1704
2692
    }
1705
2693
 
1706
2694
    /* Load bit panel */
1710
2698
        SNPRINTF(name, MAXLINE, "bit_eventbox_%d", i);
1711
2699
        set_int_data(X.ui, name, "bit_index", i);
1712
2700
    }
 
2701
    
 
2702
    /* Make menu tooltips displayed in the status bar */
 
2703
    set_menubar_tooltip("quit_menu");
 
2704
    set_menubar_tooltip("copy_menu");
 
2705
    set_menubar_tooltip("paste_menu");
 
2706
    set_menubar_tooltip("insert_ascii_menu");
 
2707
    set_menubar_tooltip("undo_menu");
 
2708
    set_menubar_tooltip("redo_menu");
 
2709
    set_menubar_tooltip("view_basic_menu");
 
2710
    set_menubar_tooltip("view_advanced_menu");
 
2711
    set_menubar_tooltip("view_financial_menu");
 
2712
    set_menubar_tooltip("view_scientific_menu");
 
2713
    set_menubar_tooltip("show_trailing_zeroes_menu");
 
2714
    set_menubar_tooltip("show_thousands_separator_menu");
 
2715
    set_menubar_tooltip("show_registers_menu");
 
2716
    set_menubar_tooltip("help_menu");
 
2717
    set_menubar_tooltip("about_menu");
1713
2718
 
1714
2719
    /* Make dialogs transient of the main window */
1715
2720
    gtk_window_set_transient_for(GTK_WINDOW(X.ascii_dialog), GTK_WINDOW(X.main_window));
 
2721
    gtk_window_set_transient_for(GTK_WINDOW(X.precision_dialog), GTK_WINDOW(X.main_window));
 
2722
    gtk_window_set_transient_for(GTK_WINDOW(X.register_dialog), GTK_WINDOW(X.main_window));
 
2723
    gtk_window_set_transient_for(GTK_WINDOW(X.constants_dialog),
 
2724
                                 GTK_WINDOW(X.main_window));
 
2725
 
 
2726
    /* Can't set max length for spin buttons in Glade 2 */
 
2727
    gtk_entry_set_max_length(GTK_ENTRY(X.precision_spin), 2);
 
2728
 
 
2729
    gtk_dialog_set_default_response(GTK_DIALOG(X.constants_dialog), 
 
2730
                                    GTK_RESPONSE_ACCEPT);
 
2731
 
 
2732
    /* Make constant tree model */
 
2733
    X.constants_model = create_constants_model();
 
2734
    treeview = GET_WIDGET("edit_constants_treeview");
 
2735
    gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), X.constants_model);
 
2736
    gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
 
2737
                                GTK_SELECTION_SINGLE);
 
2738
    /* Translators: Edit Constants Dialog: Constant number column title */
 
2739
    add_cf_column(GTK_TREE_VIEW(treeview), _("No."), COLUMN_NUMBER, FALSE);
 
2740
    /* Translators: Edit Constants Dialog: Constant value column title */
 
2741
    add_cf_column(GTK_TREE_VIEW(treeview), _("Value"), COLUMN_VALUE, TRUE);
 
2742
    /* Translators: Edit Constants Dialog: Constant description column title */    
 
2743
    add_cf_column(GTK_TREE_VIEW(treeview), _("Description"), COLUMN_DESCRIPTION, TRUE);
 
2744
 
 
2745
    /* Make function tree model */
 
2746
    X.functions_model = create_functions_model();
 
2747
    treeview = GET_WIDGET("edit_functions_treeview");
 
2748
    gtk_dialog_set_default_response(GTK_DIALOG(X.function_dialog), 
 
2749
                                    GTK_RESPONSE_ACCEPT);
 
2750
    gtk_window_set_transient_for(GTK_WINDOW(X.function_dialog), 
 
2751
                                 GTK_WINDOW(X.main_window));
 
2752
    gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), X.functions_model);
 
2753
    gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
 
2754
                                GTK_SELECTION_SINGLE);
 
2755
    /* Translators: Edit Functions Dialog: Function number column title */
 
2756
    add_cf_column(GTK_TREE_VIEW(treeview), _("No."),
 
2757
                  COLUMN_NUMBER, FALSE);
 
2758
    /* Translators: Edit Functions Dialog: Function value column title */
 
2759
    add_cf_column(GTK_TREE_VIEW(treeview), _("Value"),
 
2760
                  COLUMN_VALUE, TRUE);
 
2761
    /* Translators: Edit Functions Dialog: Function description column title */
 
2762
    add_cf_column(GTK_TREE_VIEW(treeview), _("Description"),
 
2763
                  COLUMN_DESCRIPTION, TRUE);
1716
2764
 
1717
2765
    X.display_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(X.display_item));
1718
2766
    gtk_widget_ensure_style(X.display_item);
1721
2769
    gtk_widget_modify_font(X.display_item, font_desc);
1722
2770
    pango_font_description_free(font_desc);
1723
2771
    gtk_widget_set_name(X.display_item, "displayitem");
1724
 
    atk_object_set_role(gtk_widget_get_accessible(X.display_item),
 
2772
    atk_object_set_role(gtk_widget_get_accessible(X.display_item), 
1725
2773
                                                  ATK_ROLE_EDITBAR);
1726
2774
 
1727
2775
    gtk_widget_realize(X.main_window);
 
2776
    set_win_position();
 
2777
 
 
2778
    g_object_set_data(G_OBJECT(X.radian_radio),          "trig_mode", GINT_TO_POINTER(MP_RADIANS));
 
2779
    g_object_set_data(G_OBJECT(X.degree_radio),          "trig_mode", GINT_TO_POINTER(MP_DEGREES));
 
2780
    g_object_set_data(G_OBJECT(X.gradian_radio),         "trig_mode", GINT_TO_POINTER(MP_GRADIANS));
 
2781
    g_object_set_data(G_OBJECT(X.binary_radio),          "base_mode", GINT_TO_POINTER(2));
 
2782
    g_object_set_data(G_OBJECT(X.octal_radio),           "base_mode", GINT_TO_POINTER(8));
 
2783
    g_object_set_data(G_OBJECT(X.decimal_radio),         "base_mode", GINT_TO_POINTER(10));
 
2784
    g_object_set_data(G_OBJECT(X.hexadecimal_radio),     "base_mode", GINT_TO_POINTER(16));
 
2785
    g_object_set_data(G_OBJECT(X.display_mode_radios[0]), "numeric_mode", GINT_TO_POINTER(ENG));
 
2786
    g_object_set_data(G_OBJECT(X.display_mode_radios[1]), "numeric_mode", GINT_TO_POINTER(FIX));
 
2787
    g_object_set_data(G_OBJECT(X.display_mode_radios[2]), "numeric_mode", GINT_TO_POINTER(SCI));
 
2788
    g_object_set_data(G_OBJECT(X.word_length_radios[0]), "wordlen_mode", GINT_TO_POINTER(64));
 
2789
    g_object_set_data(G_OBJECT(X.word_length_radios[1]), "wordlen_mode", GINT_TO_POINTER(32));
 
2790
    g_object_set_data(G_OBJECT(X.word_length_radios[2]), "wordlen_mode", GINT_TO_POINTER(16));
 
2791
 
 
2792
    X.status_image = GET_WIDGET("status_image");
1728
2793
 
1729
2794
    /* Set modes for menu items */
1730
2795
    for (i = 1; i < 16; i++) {
1739
2804
    set_int_data(X.ui, "view_scientific_menu", "calcmode", SCIENTIFIC);
1740
2805
    set_int_data(X.ui, "view_programming_menu", "calcmode", PROGRAMMING);
1741
2806
 
 
2807
    /* Make shortcuts for accuracy menus */
 
2808
    accel_group = gtk_accel_group_new();
 
2809
    gtk_window_add_accel_group(GTK_WINDOW(X.main_window), accel_group);
 
2810
    for (i = 0; i < 10; i++) {
 
2811
        SNPRINTF(name, MAXLINE, "acc_item%d", i);
 
2812
        set_int_data(X.ui, name, "accuracy", i);
 
2813
    }
 
2814
 
 
2815
    /* Localize label for numeric point */
 
2816
    gtk_button_set_label(GTK_BUTTON(GET_OBJECT("calc_numeric_point_button")), v->radix);
 
2817
 
1742
2818
    /* Setup financial functions */
1743
2819
    set_data(X.ui, "calc_finc_compounding_term_button", "finc_dialog", "ctrm_dialog");
1744
2820
    set_data(X.ui, "calc_finc_double_declining_depreciation_button", "finc_dialog", "ddb_dialog");
1750
2826
    set_data(X.ui, "calc_finc_straight_line_depreciation_button", "finc_dialog", "sln_dialog");
1751
2827
    set_data(X.ui, "calc_finc_sum_of_the_years_digits_depreciation_button", "finc_dialog", "syd_dialog");
1752
2828
    set_data(X.ui, "calc_finc_term_button", "finc_dialog", "term_dialog");
1753
 
 
1754
 
    /* Configuration dialog */
1755
 
 
1756
 
    widget = GET_WIDGET("angle_unit_combobox");
1757
 
    renderer = gtk_cell_renderer_text_new();
1758
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
1759
 
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0);
1760
 
 
1761
 
    widget = GET_WIDGET("display_format_combobox");
1762
 
    renderer = gtk_cell_renderer_text_new();
1763
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
1764
 
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0);
1765
 
 
1766
 
    widget = GET_WIDGET("word_size_combobox");
1767
 
    renderer = gtk_cell_renderer_text_new();
1768
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, TRUE);
1769
 
    gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(widget), renderer, "text", 0);
1770
 
 
1771
 
    // _("Show %d decimal places") decimal_places_label1, decimal_places_label2
1772
2829
}
1773
2830
 
1774
2831
 
1775
2832
void
1776
2833
ui_init(int *argc, char ***argv)
1777
 
{
 
2834
{  
1778
2835
    gchar *path;
1779
2836
    int value;
1780
2837
 
1783
2840
    memset(&X, 0, sizeof(X));
1784
2841
 
1785
2842
    gtk_rc_get_default_files();
1786
 
 
 
2843
   
1787
2844
    if (get_enumerated_resource(R_MODE, mode_names, &value))
1788
2845
        X.mode = (ModeType) value;
1789
2846
    else
1797
2854
}
1798
2855
 
1799
2856
 
1800
 
G_MODULE_EXPORT
1801
 
void
1802
 
angle_unit_combobox_changed_cb(GtkWidget *combo)
1803
 
{
1804
 
    int i;
1805
 
    const gchar *value;
1806
 
    GtkTreeModel *model;
1807
 
    GtkTreeIter iter;
1808
 
    struct
1809
 
    {
1810
 
        const gchar *value;
1811
 
        MPAngleUnit units;
1812
 
    } unit_map[] =
1813
 
    {
1814
 
        {"degrees",     MP_DEGREES},
1815
 
        {"radians" ,    MP_RADIANS},
1816
 
        {"gradians",    MP_GRADIANS},
1817
 
        {NULL,          MP_DEGREES}
1818
 
    };
1819
 
 
1820
 
    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
1821
 
    gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter);
1822
 
    gtk_tree_model_get(model, &iter, 1, &value, -1);
1823
 
    for (i = 0; unit_map[i].value != NULL && strcmp(unit_map[i].value, value) != 0; i++);
1824
 
    display_set_angle_unit(&v->display, unit_map[i].units);
1825
 
 
1826
 
    set_resource(R_TRIG, value);
1827
 
}
1828
 
 
1829
 
 
1830
 
G_MODULE_EXPORT
1831
 
void
1832
 
display_format_combobox_changed_cb(GtkWidget *combo)
1833
 
{
1834
 
    int i;
1835
 
    const gchar *value;
1836
 
    GtkTreeModel *model;
1837
 
    GtkTreeIter iter;
1838
 
    struct
1839
 
    {
1840
 
        const gchar *value;
1841
 
        DisplayFormat format;
1842
 
    } mode_map[] =
1843
 
    {
1844
 
        {"decimal",     DEC},
1845
 
        {"binary" ,     BIN},
1846
 
        {"octal",       OCT},
1847
 
        {"hexadecimal", HEX},
1848
 
        {"scientific",  SCI},
1849
 
        {"engineering", ENG},
1850
 
        {NULL,          DEC}
1851
 
    };
1852
 
 
1853
 
    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
1854
 
    gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter);
1855
 
    gtk_tree_model_get(model, &iter, 1, &value, -1);
1856
 
    for (i = 0; mode_map[i].value != NULL && strcmp(mode_map[i].value, value) != 0; i++);
1857
 
    display_set_format(&v->display, mode_map[i].format);
1858
 
 
1859
 
    set_resource(R_DISPLAY, value);
1860
 
}
1861
 
 
1862
 
 
1863
 
G_MODULE_EXPORT
1864
 
void
1865
 
word_size_combobox_changed_cb(GtkWidget *combo)
1866
 
{
1867
 
    gint value;
1868
 
    GtkTreeModel *model;
1869
 
    GtkTreeIter iter;
1870
 
 
1871
 
    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
1872
 
    gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter);
1873
 
    gtk_tree_model_get(model, &iter, 1, &value, -1);
1874
 
    display_set_word_size(&v->display, value);
1875
 
 
1876
 
    set_int_resource(R_WORDLEN, value);
1877
 
}
1878
 
 
1879
 
 
1880
 
G_MODULE_EXPORT
1881
 
void
1882
 
decimal_places_spin_change_value_cb(GtkWidget *spin)
1883
 
{
1884
 
    gint value = 0;
1885
 
 
1886
 
    value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
1887
 
    display_set_accuracy(&v->display, value);
1888
 
 
1889
 
    set_int_resource(R_ACCURACY, value);
1890
 
}
1891
 
 
1892
 
 
1893
 
G_MODULE_EXPORT
1894
 
void
1895
 
thousands_separator_check_toggled_cb(GtkWidget *check)
1896
 
{
1897
 
    gboolean value;
1898
 
 
1899
 
    value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check));
1900
 
    display_set_show_thousands_separator(&v->display, value);
1901
 
    set_boolean_resource(R_TSEP, value);
1902
 
}
1903
 
 
1904
 
 
1905
 
G_MODULE_EXPORT
1906
 
void
1907
 
trailing_zeroes_check_toggled_cb(GtkWidget *check)
1908
 
{
1909
 
    gboolean value;
1910
 
 
1911
 
    value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check));
1912
 
    display_set_show_trailing_zeroes(&v->display, value);
1913
 
    set_boolean_resource(R_ZEROES, value);
1914
 
}
1915
 
 
1916
 
 
1917
 
static void
1918
 
set_combo_box_from_config(const gchar *name, const gchar *key_name, GType key_type)
1919
 
{
1920
 
    GtkWidget *combo;
1921
 
    GtkTreeModel *model;
1922
 
    gchar *str_key_value = NULL;
1923
 
    int int_key_value;
1924
 
    GtkTreeIter iter;
1925
 
    gboolean valid;
1926
 
 
1927
 
    combo = GET_WIDGET(name);
1928
 
    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
1929
 
    valid = gtk_tree_model_get_iter_first(model, &iter);
1930
 
 
1931
 
    switch (key_type)
1932
 
    {
1933
 
    case G_TYPE_STRING:
1934
 
        str_key_value = get_resource(key_name);
1935
 
        if (!str_key_value)
1936
 
            valid = FALSE;
1937
 
        break;
1938
 
    case G_TYPE_INT:
1939
 
        if (!get_int_resource(key_name, &int_key_value))
1940
 
            valid = FALSE;
1941
 
        break;
1942
 
    default:
1943
 
        break;
1944
 
    }
1945
 
 
1946
 
    while (valid) {
1947
 
        gchar *str_value;
1948
 
        gint int_value;
1949
 
        gboolean matched = FALSE;
1950
 
 
1951
 
        switch (key_type)
1952
 
        {
1953
 
        case G_TYPE_STRING:
1954
 
            gtk_tree_model_get(model, &iter, 1, &str_value, -1);
1955
 
            matched = strcmp(str_value, str_key_value) == 0;
1956
 
            break;
1957
 
        case G_TYPE_INT:
1958
 
            gtk_tree_model_get(model, &iter, 1, &int_value, -1);
1959
 
            matched = int_value == int_key_value;
1960
 
            break;
1961
 
        default:
1962
 
            break;
1963
 
        }
1964
 
 
1965
 
        if (matched)
1966
 
            break;
1967
 
 
1968
 
        valid = gtk_tree_model_iter_next(model, &iter);
1969
 
    }
1970
 
    if (!valid)
1971
 
        valid = gtk_tree_model_get_iter_first(model, &iter);
1972
 
 
1973
 
    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter);
1974
 
 
1975
 
    g_free(str_key_value);
1976
 
}
1977
 
 
1978
 
 
1979
2857
void
1980
2858
ui_load(void)
1981
2859
{
1982
 
    int value;
 
2860
    int boolval;
 
2861
    char text[MAXLINE];
 
2862
    GtkWidget *widget;
1983
2863
 
1984
2864
    /* Create main gcalctool window. */
1985
2865
    create_main_window();
 
2866
    
 
2867
    /* Load configuration */
 
2868
    ui_set_show_thousands_separator(v->display.show_tsep);
 
2869
    ui_set_show_trailing_zeroes(v->display.show_zeroes);
 
2870
    
 
2871
    ui_set_mode(X.mode);
 
2872
    ui_set_numeric_mode(v->display.format);
 
2873
    ui_set_base(v->base);
 
2874
    ui_set_wordlen(v->wordlen);
 
2875
    ui_set_accuracy(v->accuracy);
1986
2876
    ui_set_undo_enabled(FALSE, FALSE);
1987
 
 
1988
 
    set_combo_box_from_config("angle_unit_combobox", R_TRIG, G_TYPE_STRING);
1989
 
    set_combo_box_from_config("display_format_combobox", R_DISPLAY, G_TYPE_STRING);
1990
 
    set_combo_box_from_config("word_size_combobox", R_WORDLEN, G_TYPE_INT);
1991
 
 
1992
 
    if (!get_int_resource(R_ACCURACY, &value))
1993
 
        value = 9;
1994
 
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_OBJECT("decimal_places_spin")), value);
1995
 
 
1996
 
    if (!get_boolean_resource(R_TSEP, &value))
1997
 
        value = FALSE;
1998
 
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(GET_OBJECT("thousands_separator_check")), value);
1999
 
 
2000
 
    if (!get_boolean_resource(R_ZEROES, &value))
2001
 
        value = FALSE;
2002
 
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(GET_OBJECT("trailing_zeroes_check")), value);
2003
 
}
2004
 
 
2005
 
 
2006
 
static void
2007
 
add_buttons_to_size_group()
2008
 
{
2009
 
    int i;
2010
 
    GtkSizeGroup *size_group;
2011
 
 
2012
 
    const char *button_names[] = {
2013
 
        "calc_finc_straight_line_depreciation_button",
2014
 
        "calc_finc_periodic_interest_rate_button",
2015
 
        "calc_finc_present_value_button",
2016
 
        "calc_finc_periodic_payment_button",
2017
 
        "calc_finc_future_value_button",
2018
 
        "calc_finc_gross_profit_margin_button",
2019
 
        "calc_finc_double_declining_depreciation_button",
2020
 
        "calc_finc_compounding_term_button",
2021
 
        "calc_finc_sum_of_the_years_digits_depreciation_button",
2022
 
        "calc_finc_term_button",
2023
 
        "calc_store_button",
2024
 
        "calc_recall_button",
2025
 
        "calc_pi_button",
2026
 
        "calc_modulus_divide_button",
2027
 
        "calc_root_button",
2028
 
        "calc_x_pow_y_button",
2029
 
        "calc_logarithm_button",
2030
 
        "calc_inverse_button",
2031
 
        "calc_natural_logarithm_button",
2032
 
        "calc_eulers_number_button",
2033
 
        "calc_abs_button",
2034
 
        "calc_factorial_button",
2035
 
        "calc_integer_portion_button",
2036
 
        "calc_exponential_button",
2037
 
        "calc_fractional_portion_button",
2038
 
        "calc_imaginary_button",
2039
 
        "subscript_togglebutton",
2040
 
        "superscript_togglebutton",
2041
 
        "calc_ans_button",
2042
 
        "calc_4_button",
2043
 
        "calc_7_button",
2044
 
        "calc_8_button",
2045
 
        "calc_9_button",
2046
 
        "calc_5_button",
2047
 
        "calc_6_button",
2048
 
        "calc_divide_button",
2049
 
        "calc_1_button",
2050
 
        "calc_2_button",
2051
 
        "calc_0_button",
2052
 
        "calc_numeric_point_button",
2053
 
        "calc_result_button",
2054
 
        "calc_3_button",
2055
 
        "calc_multiply_button",
2056
 
        "calc_subtract_button",
2057
 
        "calc_add_button",
2058
 
        "calc_clear_button",
2059
 
        "calc_start_group_button",
2060
 
        "calc_end_group_button",
2061
 
        "calc_percentage_button",
2062
 
        "calc_10_button",
2063
 
        "calc_11_button",
2064
 
        "calc_12_button",
2065
 
        "calc_13_button",
2066
 
        "calc_14_button",
2067
 
        "calc_15_button",
2068
 
        "calc_and_button",
2069
 
        "calc_or_button",
2070
 
        "calc_not_button",
2071
 
        "calc_xor_button",
2072
 
        "calc_ones_complement_button",
2073
 
        "calc_twos_complement_button",
2074
 
        "calc_shift_right_button",
2075
 
        "calc_shift_left_button",
2076
 
        "calc_trunc_button",
2077
 
        "calc_random_button",
2078
 
        "calc_base_2_button",
2079
 
        "calc_base_8_button",
2080
 
        "calc_base_16_button",
2081
 
        "calc_si_kilo_button",
2082
 
        "calc_si_milli_button",
2083
 
        "calc_si_micro_button",
2084
 
        "calc_si_mega_button",
2085
 
        "calc_si_giga_button",
2086
 
        "calc_si_peta_button",
2087
 
        "calc_si_femto_button",
2088
 
        "calc_si_pico_button",
2089
 
        "calc_si_nano_button",
2090
 
        "calc_tangent_button",
2091
 
        "calc_sine_button",
2092
 
        "calc_cosine_button",
2093
 
        "calc_hyperbolic_cosine_button",
2094
 
        "calc_hyperbolic_sine_button",
2095
 
        "calc_hyperbolic_tangent_button",
2096
 
        "calc_character_button",
2097
 
        NULL};
2098
 
 
2099
 
    size_group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
2100
 
    for (i = 0; button_names[i] != NULL; i++)
2101
 
        gtk_size_group_add_widget(size_group, GET_WIDGET(button_names[i]));
2102
 
}
2103
 
 
 
2877
    ui_update_modifier_mode();
 
2878
    
 
2879
    /* Show the memory register window? */
 
2880
    ui_make_registers();
 
2881
    if (get_boolean_resource(R_REGS, &boolval))
 
2882
        ui_set_registers_visible(boolval);
 
2883
 
 
2884
    /* Set default accuracy menu item */
 
2885
    /* Translators: Accuracy Popup: Menu item to reset the accuracy to the default value. %d is replaced with the default value. */
 
2886
    SNPRINTF(text, MAXLINE, _("Reset to _Default (%d)"), DEFAULT_ACCURACY);
 
2887
    widget = gtk_bin_get_child(GTK_BIN(GET_OBJECT("acc_item_default")));
 
2888
    gtk_label_set_markup_with_mnemonic(GTK_LABEL(widget), text);
 
2889
}
2104
2890
 
2105
2891
void
2106
2892
ui_start(void)
2107
2893
{
2108
 
    ui_set_mode(X.mode);
2109
 
 
 
2894
    ui_set_base(v->base);
 
2895
    ui_set_wordlen(v->wordlen);
 
2896
    ui_set_trigonometric_mode(v->ttype);
 
2897
    ui_set_numeric_mode(v->display.format);
 
2898
    
2110
2899
    gtk_widget_show(X.main_window);
2111
2900
 
2112
 
    /* Add buttons to size group so they are all the same size.
2113
 
     *
2114
 
     * This is supported in GtkBuilder but it does not appear to work, setting
2115
 
     * the group after showing the widgets works. It would have been preferrable
2116
 
     * to make the table homogeneous but this does not ignore hidden rows.
2117
 
     */
2118
 
    add_buttons_to_size_group();
2119
 
 
2120
2901
    gtk_main();
2121
2902
}