1 /*
2 Qalculate (GTK+ UI)
3
4 Copyright (C) 2003-2007, 2008, 2016-2021 Hanna Knutsson (hanna.knutsson@protonmail.com)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 */
11
12
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
16
17 #include <unistd.h>
18 #include <string.h>
19 #include <stdio.h>
20
21 #include <gdk/gdkkeysyms.h>
22 #include <gtk/gtk.h>
23
24 #include "support.h"
25 #include "callbacks.h"
26 #include "interface.h"
27 #include "main.h"
28
29 #include <deque>
30
31 #if HAVE_UNORDERED_MAP
32 # include <unordered_map>
33 using std::unordered_map;
34 #elif defined(__GNUC__)
35
36 # ifndef __has_include
37 # define __has_include(x) 0
38 # endif
39
40 # if (defined(__clang__) && __has_include(<tr1/unordered_map>)) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 3)
41 # include <tr1/unordered_map>
42 namespace Sgi = std;
43 # define unordered_map std::tr1::unordered_map
44 # else
45 # if __GNUC__ < 3
46 # include <hash_map.h>
47 namespace Sgi { using ::hash_map; }; // inherit globals
48 # else
49 # include <ext/hash_map>
50 # if __GNUC__ == 3 && __GNUC_MINOR__ == 0
51 namespace Sgi = std; // GCC 3.0
52 # else
53 namespace Sgi = ::__gnu_cxx; // GCC 3.1 and later
54 # endif
55 # endif
56 # define unordered_map Sgi::hash_map
57 # endif
58 #else // ... there are other compilers, right?
59 namespace Sgi = std;
60 # define unordered_map Sgi::hash_map
61 #endif
62
63 using std::string;
64 using std::cout;
65 using std::vector;
66 using std::endl;
67 using std::iterator;
68 using std::list;
69 using std::deque;
70
71 extern GtkBuilder *main_builder, *argumentrules_builder, *csvimport_builder, *csvexport_builder, *datasetedit_builder, *datasets_builder, *setbase_builder, *decimals_builder;
72 extern GtkBuilder *functionedit_builder, *functions_builder, *matrixedit_builder, *matrix_builder, *namesedit_builder, *nbases_builder, *plot_builder, *precision_builder;
73 extern GtkBuilder *shortcuts_builder, *preferences_builder, *unitedit_builder, *units_builder, *unknownedit_builder, *variableedit_builder, *variables_builder, *buttonsedit_builder;
74 extern GtkBuilder *periodictable_builder, *simplefunctionedit_builder, *percentage_builder, *calendarconversion_builder, *floatingpoint_builder;
75 extern vector<mode_struct> modes;
76
77 GtkWidget *mainwindow;
78
79 GtkWidget *tFunctionCategories;
80 GtkWidget *tFunctions;
81 GtkListStore *tFunctions_store;
82 GtkTreeModel *tFunctions_store_filter;
83 GtkTreeStore *tFunctionCategories_store;
84
85 GtkWidget *tVariableCategories;
86 GtkWidget *tVariables;
87 GtkListStore *tVariables_store;
88 GtkTreeModel *tVariables_store_filter;
89 GtkTreeStore *tVariableCategories_store;
90
91 GtkWidget *tUnitCategories;
92 GtkWidget *tUnits;
93 GtkListStore *tUnits_store;
94 GtkTreeModel *tUnits_store_filter, *units_convert_filter;
95 GtkTreeStore *tUnitCategories_store;
96 GtkWidget *units_convert_view, *units_convert_window, *units_convert_scrolled;
97 GtkCellRenderer *units_convert_flag_renderer;
98
99 GtkWidget *tUnitSelectorCategories;
100 GtkWidget *tUnitSelector;
101 GtkListStore *tUnitSelector_store;
102 GtkTreeModel *tUnitSelector_store_filter;
103 GtkTreeStore *tUnitSelectorCategories_store;
104
105 GtkWidget *tDatasets;
106 GtkWidget *tDataObjects;
107 GtkListStore *tDatasets_store;
108 GtkListStore *tDataObjects_store;
109
110 GtkWidget *tDataProperties;
111 GtkListStore *tDataProperties_store;
112
113 GtkWidget *tNames;
114 GtkListStore *tNames_store;
115
116 GtkWidget *tShortcuts, *tShortcutsType;
117 GtkListStore *tShortcuts_store, *tShortcutsType_store;
118
119 GtkWidget *tButtonsEditType, *tButtonsEdit;
120 GtkListStore *tButtonsEditType_store, *tButtonsEdit_store;
121
122 GtkWidget *tabs, *expander_keypad, *expander_history, *expander_stack, *expander_convert;
123 GtkEntryCompletion *completion;
124 GtkWidget *completion_view, *completion_window, *completion_scrolled;
125 GtkTreeModel *completion_filter, *completion_sort;
126 GtkListStore *completion_store;
127
128 GtkWidget *tFunctionArguments;
129 GtkListStore *tFunctionArguments_store;
130 GtkWidget *tSubfunctions;
131 GtkListStore *tSubfunctions_store;
132
133 GtkWidget *tPlotFunctions;
134 GtkListStore *tPlotFunctions_store;
135
136 GtkWidget *item_factorize, *item_simplify;
137
138 GtkWidget *tMatrixEdit, *tMatrix;
139 GtkListStore *tMatrixEdit_store, *tMatrix_store;
140 extern vector<GtkTreeViewColumn*> matrix_edit_columns, matrix_columns;
141
142 GtkCellRenderer *history_renderer, *history_index_renderer, *ans_renderer, *register_renderer;
143 GtkTreeViewColumn *register_column, *history_column, *history_index_column, *flag_column, *units_flag_column;
144
145 GtkWidget *expressiontext;
146 GtkTextBuffer *expressionbuffer;
147 GtkTextTag *expression_par_tag;
148 GtkWidget *resultview;
149 GtkWidget *historyview;
150 GtkListStore *historystore;
151 GtkWidget *stackview;
152 GtkListStore *stackstore;
153 GtkWidget *statuslabel_l, *statuslabel_r, *result_bases, *keypad;
154 GtkWidget *f_menu ,*v_menu, *u_menu, *u_menu2, *recent_menu;
155 GtkAccelGroup *accel_group;
156
157 gint history_scroll_width = 16;
158
159 GtkCssProvider *topframe_provider, *expression_provider, *resultview_provider, *statuslabel_l_provider, *statuslabel_r_provider, *keypad_provider, *box_rpnl_provider, *app_provider, *app_provider_theme, *statusframe_provider;
160
161 extern bool show_keypad, show_history, show_stack, show_convert, continuous_conversion, set_missing_prefixes, persistent_keypad, minimal_mode;
162 extern bool save_mode_on_exit, save_defs_on_exit, load_global_defs, hyp_is_on, inv_is_on, fetch_exchange_rates_at_startup, clear_history_on_exit;
163 extern int allow_multiple_instances;
164 extern int title_type;
165 extern bool display_expression_status;
166 extern int expression_lines;
167 extern int use_dark_theme;
168 extern bool use_custom_result_font, use_custom_expression_font, use_custom_status_font, use_custom_keypad_font, use_custom_app_font;
169 extern string custom_result_font, custom_expression_font, custom_status_font, custom_keypad_font, custom_app_font;
170 extern string status_error_color, status_warning_color;
171 extern bool status_error_color_set, status_warning_color_set;
172 extern int auto_update_exchange_rates;
173 extern bool copy_separator;
174 extern bool ignore_locale;
175 extern bool caret_as_xor;
176 extern int visible_keypad;
177 extern bool auto_calculate, chain_mode;
178 extern bool complex_angle_form;
179 extern bool check_version;
180 extern int max_plot_time;
181 extern gint autocalc_history_delay;
182 extern int default_fraction_fraction;
183 extern bool use_systray_icon, hide_on_startup;
184
185 extern string nbases_error_color, nbases_warning_color;
186
187 extern PrintOptions printops;
188 extern EvaluationOptions evalops;
189
190 extern bool rpn_mode, rpn_keys, adaptive_interval_display, use_e_notation;
191
192 extern vector<GtkWidget*> mode_items;
193 extern vector<GtkWidget*> popup_result_mode_items;
194
195 extern deque<string> expression_undo_buffer;
196
197 gint win_height, win_width, win_x, win_y, history_height, variables_width, variables_height, variables_position, units_width, units_height, units_position, functions_width, functions_height, functions_hposition, functions_vposition, datasets_width, datasets_height, datasets_hposition, datasets_vposition1, datasets_vposition2;
198 extern bool remember_position;
199 extern gint minimal_width;
200
201 extern Unit *latest_button_unit, *latest_button_currency;
202 extern string latest_button_unit_pre, latest_button_currency_pre;
203
204 extern int completion_min, completion_min2;
205 extern bool enable_completion, enable_completion2;
206 extern int completion_delay;
207
208 gchar history_error_color[8];
209 gchar history_warning_color[8];
210 gchar history_parse_color[8];
211 gchar history_bookmark_color[8];
212
213 extern unordered_map<string, GdkPixbuf*> flag_images;
214
215 extern unordered_map<guint64, keyboard_shortcut> keyboard_shortcuts;
216 extern vector<custom_button> custom_buttons;
217
218 extern string fix_history_string(const string &str);
219
compare_categories(gconstpointer a,gconstpointer b)220 gint compare_categories(gconstpointer a, gconstpointer b) {
221 return strcasecmp((const char*) a, (const char*) b);
222 }
223
224 bool border_tested = false;
225 gint hidden_x = -1, hidden_y = -1;
226
227 #ifdef _WIN32
228 # include <gdk/gdkwin32.h>
229 # define WIN_TRAY_ICON_ID 1000
230 # define WIN_TRAY_ICON_MESSAGE WM_APP + WIN_TRAY_ICON_ID
231 static NOTIFYICONDATA nid;
232 static HWND hwnd = NULL;
233
tray_window_proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)234 INT_PTR CALLBACK tray_window_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
235 if(message == WIN_TRAY_ICON_MESSAGE && (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONUP)) {
236 if(hidden_x >= 0) {
237 gtk_widget_show(mainwindow);
238 gtk_window_move(GTK_WINDOW(mainwindow), hidden_x, hidden_y);
239 hidden_x = -1;
240 }
241 gtk_window_present_with_time(GTK_WINDOW(mainwindow), GDK_CURRENT_TIME);
242 }
243 return DefWindowProc(hWnd, message, wParam, lParam);
244 }
destroy_systray_icon()245 void destroy_systray_icon() {
246 if(hwnd == NULL) return;
247 Shell_NotifyIcon(NIM_DELETE, &nid);
248 DestroyWindow(hwnd);
249 hwnd = NULL;
250 }
create_systray_icon()251 void create_systray_icon() {
252
253 if(hwnd != NULL) return;
254
255 WNDCLASSEX wcex;
256 TCHAR wname[32];
257 strcpy(wname, "QalculateTrayWin");
258 wcex.cbSize = sizeof(WNDCLASSEX);
259
260 wcex.style = 0;
261 wcex.lpfnWndProc = (WNDPROC) tray_window_proc;
262 wcex.cbClsExtra = 0;
263 wcex.cbWndExtra = 0;
264 wcex.hInstance = GetModuleHandle(NULL);
265 wcex.hIcon = NULL;
266 wcex.hCursor = NULL,
267 wcex.hbrBackground = NULL;
268 wcex.lpszMenuName = NULL;
269 wcex.lpszClassName = wname;
270 wcex.hIconSm = NULL;
271
272 if(RegisterClassEx(&wcex)) {
273 hwnd = CreateWindow(wname, "", 0, 0, 0, 0, 0, (HWND) gdk_win32_window_get_handle(gtk_widget_get_window(mainwindow)), NULL, GetModuleHandle(NULL), 0);
274 }
275 if(hwnd != NULL) {
276 UpdateWindow(hwnd);
277 memset(&nid, 0, sizeof(nid));
278 nid.cbSize = sizeof(NOTIFYICONDATA);
279 nid.hWnd = hwnd;
280 nid.uID = WIN_TRAY_ICON_ID;
281 nid.uFlags = NIF_ICON | NIF_MESSAGE;
282 nid.uCallbackMessage = WIN_TRAY_ICON_MESSAGE;
283 strcpy(nid.szTip, "Qalculate!");
284 nid.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(100));
285 Shell_NotifyIcon(NIM_ADD, &nid);
286 }
287 }
has_systray_icon()288 bool has_systray_icon() {
289 return hwnd != NULL;
290 }
291 #else
has_systray_icon()292 bool has_systray_icon() {
293 return false;
294 }
295 #endif
296
test_border()297 void test_border() {
298 #ifndef _WIN32
299 if(border_tested) return;
300 GdkWindow *window = gtk_widget_get_window(mainwindow);
301 GdkRectangle rect;
302 gdk_window_get_frame_extents(window, &rect);
303 gint window_border = (rect.width - gtk_widget_get_allocated_width(mainwindow)) / 2;
304 if(window_border > 0) {
305 gchar *gstr = gtk_css_provider_to_string(topframe_provider);
306 string topframe_css = gstr;
307 g_free(gstr);
308 gsub("border-left-width: 0;", "", topframe_css);
309 gsub("border-right-width: 0;", "", topframe_css);
310 gtk_css_provider_load_from_data(topframe_provider, topframe_css.c_str(), -1, NULL);
311 border_tested = true;
312 } else if(rect.x != 0 || rect.y != 0) {
313 border_tested = true;
314 }
315 #endif
316 }
317
set_assumptions_items(AssumptionType at,AssumptionSign as)318 void set_assumptions_items(AssumptionType at, AssumptionSign as) {
319 switch(as) {
320 case ASSUMPTION_SIGN_POSITIVE: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_positive")), TRUE); break;}
321 case ASSUMPTION_SIGN_NONPOSITIVE: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_nonpositive")), TRUE); break;}
322 case ASSUMPTION_SIGN_NEGATIVE: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_negative")), TRUE); break;}
323 case ASSUMPTION_SIGN_NONNEGATIVE: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_nonnegative")), TRUE); break;}
324 case ASSUMPTION_SIGN_NONZERO: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_nonzero")), TRUE); break;}
325 default: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_unknown")), TRUE);}
326 }
327 switch(at) {
328 case ASSUMPTION_TYPE_INTEGER: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_integer")), TRUE); break;}
329 case ASSUMPTION_TYPE_RATIONAL: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_rational")), TRUE); break;}
330 case ASSUMPTION_TYPE_REAL: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_real")), TRUE); break;}
331 case ASSUMPTION_TYPE_COMPLEX: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_complex")), TRUE); break;}
332 case ASSUMPTION_TYPE_NUMBER: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_number")), TRUE); break;}
333 case ASSUMPTION_TYPE_NONMATRIX: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_nonmatrix")), TRUE); break;}
334 default: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assumptions_none")), TRUE);}
335 }
336 }
337
set_mode_items(const PrintOptions & po,const EvaluationOptions & eo,AssumptionType at,AssumptionSign as,bool in_rpn_mode,int precision,bool interval,bool variable_units,bool id_adaptive,int keypad,bool autocalc,bool chainmode,bool caf,bool initial_update)338 void set_mode_items(const PrintOptions &po, const EvaluationOptions &eo, AssumptionType at, AssumptionSign as, bool in_rpn_mode, int precision, bool interval, bool variable_units, bool id_adaptive, int keypad, bool autocalc, bool chainmode, bool caf, bool initial_update) {
339
340 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_autocalc")), autocalc && (!initial_update || !in_rpn_mode));
341 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_chain_mode")), chainmode && (!initial_update || !in_rpn_mode));
342 auto_calculate = autocalc;
343 chain_mode = chainmode;
344 if(initial_update) gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_item_autocalc")), !in_rpn_mode);
345 if(initial_update) gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_item_chain_mode")), !in_rpn_mode);
346 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_rpn_mode")), in_rpn_mode);
347 switch(eo.approximation) {
348 case APPROXIMATION_EXACT: {
349 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_always_exact")), TRUE);
350 if(initial_update) {
351 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_exact")), TRUE);
352 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_exact")), TRUE);
353 }
354 break;
355 }
356 case APPROXIMATION_TRY_EXACT: {
357 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_try_exact")), TRUE);
358 if(initial_update) {
359 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_exact")), FALSE);
360 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_exact")), FALSE);
361 }
362 break;
363 }
364 default: {
365 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_approximate")), TRUE);
366 if(initial_update) {
367 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_exact")), FALSE);
368 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_exact")), FALSE);
369 }
370 break;
371 }
372 }
373 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_interval_arithmetic")), interval);
374
375 switch(eo.interval_calculation) {
376 case INTERVAL_CALCULATION_VARIANCE_FORMULA: {
377 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_ic_variance")), TRUE);
378 break;
379 }
380 case INTERVAL_CALCULATION_INTERVAL_ARITHMETIC: {
381 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_ic_interval_arithmetic")), TRUE);
382 break;
383 }
384 case INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC: {
385 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_ic_simple")), TRUE);
386 break;
387 }
388 case INTERVAL_CALCULATION_NONE: {
389 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_ic_none")), TRUE);
390 break;
391 }
392 }
393
394 switch(eo.auto_post_conversion) {
395 case POST_CONVERSION_OPTIMAL: {
396 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_post_conversion_optimal")), TRUE);
397 break;
398 }
399 case POST_CONVERSION_OPTIMAL_SI: {
400 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_post_conversion_optimal_si")), TRUE);
401 break;
402 }
403 case POST_CONVERSION_BASE: {
404 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_post_conversion_base")), TRUE);
405 break;
406 }
407 default: {
408 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_post_conversion_none")), TRUE);
409 break;
410 }
411 }
412
413 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_mixed_units_conversion")), eo.mixed_units_conversion != MIXED_UNITS_CONVERSION_NONE);
414
415 switch(eo.parse_options.angle_unit) {
416 case ANGLE_UNIT_DEGREES: {
417 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_degrees")), TRUE);
418 break;
419 }
420 case ANGLE_UNIT_RADIANS: {
421 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_radians")), TRUE);
422 break;
423 }
424 case ANGLE_UNIT_GRADIANS: {
425 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_gradians")), TRUE);
426 break;
427 }
428 default: {
429 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_no_default_angle_unit")), TRUE);
430 break;
431 }
432 }
433 if(initial_update) update_mb_angles(eo.parse_options.angle_unit);
434
435 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_read_precision")), eo.parse_options.read_precision != DONT_READ_PRECISION);
436 if(initial_update) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_read_precision")), eo.parse_options.read_precision != DONT_READ_PRECISION);
437 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_limit_implicit_multiplication")), eo.parse_options.limit_implicit_multiplication);
438 switch(eo.parse_options.parsing_mode) {
439 case PARSING_MODE_IMPLICIT_MULTIPLICATION_FIRST: {
440 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_ignore_whitespace")), TRUE);
441 if(initial_update) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_ignore_whitespace")), TRUE);
442 break;
443 }
444 case PARSING_MODE_CONVENTIONAL: {
445 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_no_special_implicit_multiplication")), TRUE);
446 if(initial_update) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_no_special_implicit_multiplication")), TRUE);
447 break;
448 }
449 case PARSING_MODE_CHAIN: {
450 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_chain_syntax")), TRUE);
451 if(initial_update) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_chain_syntax")), TRUE);
452 break;
453 }
454 case PARSING_MODE_RPN: {
455 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_rpn_syntax")), TRUE);
456 if(initial_update) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_rpn_syntax")), TRUE);
457 break;
458 }
459 default: {
460 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_adaptive_parsing")), TRUE);
461 if(initial_update) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_status_adaptive_parsing")), TRUE);
462 break;
463 }
464 }
465 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_assume_nonzero_denominators")), eo.assume_denominators_nonzero);
466 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_warn_about_denominators_assumed_nonzero")), eo.warn_about_denominators_assumed_nonzero);
467
468 switch(eo.structuring) {
469 case STRUCTURING_FACTORIZE: {
470 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_algebraic_mode_factorize")), TRUE);
471 break;
472 }
473 default: {
474 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_algebraic_mode_simplify")), TRUE);
475 break;
476 }
477 }
478
479 switch(po.base) {
480 case BASE_BINARY: {
481 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 0);
482 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_binary")), TRUE);
483 break;
484 }
485 case BASE_OCTAL: {
486 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 1);
487 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_octal")), TRUE);
488 break;
489 }
490 case BASE_DECIMAL: {
491 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 2);
492 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_decimal")), TRUE);
493 break;
494 }
495 case 12: {
496 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 3);
497 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_duodecimal")), TRUE);
498 break;
499 }
500 case BASE_HEXADECIMAL: {
501 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 4);
502 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_hexadecimal")), TRUE);
503 break;
504 }
505 case BASE_ROMAN_NUMERALS: {
506 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 7);
507 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_roman")), TRUE);
508 break;
509 }
510 case BASE_SEXAGESIMAL: {
511 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 5);
512 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_sexagesimal")), TRUE);
513 break;
514 }
515 case BASE_TIME: {
516 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 6);
517 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_time_format")), TRUE);
518 break;
519 }
520 default: {
521 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_base")), 8);
522 if(initial_update) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_custom_base")), TRUE);
523 printops.base = po.base;
524 output_base_updated_from_menu();
525 }
526 }
527
528 switch(po.min_exp) {
529 case EXP_PRECISION: {
530 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_numerical_display")), 0);
531 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_normal")), TRUE);
532 break;
533 }
534 case EXP_BASE_3: {
535 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_numerical_display")), 1);
536 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_engineering")), TRUE);
537 break;
538 }
539 case EXP_SCIENTIFIC: {
540 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_numerical_display")), 2);
541 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_scientific")), TRUE);
542 break;
543 }
544 case EXP_PURE: {
545 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_numerical_display")), 3);
546 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_purely_scientific")), TRUE);
547 break;
548 }
549 case EXP_NONE: {
550 if(initial_update) gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(main_builder, "combobox_numerical_display")), 4);
551 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_non_scientific")), TRUE);
552 break;
553 }
554 }
555
556 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_indicate_infinite_series")), po.indicate_infinite_series);
557 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_show_ending_zeroes")), po.show_ending_zeroes);
558 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_round_halfway_to_even")), po.round_halfway_to_even);
559 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_negative_exponents")), po.negative_exponents);
560 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_sort_minus_last")), po.sort_options.minus_last);
561
562 if(!po.use_unit_prefixes) {
563 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_no_prefixes")), TRUE);
564 } else if(po.use_prefixes_for_all_units) {
565 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_prefixes_for_all_units")), TRUE);
566 } else if(po.use_prefixes_for_currencies) {
567 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_prefixes_for_currencies")), TRUE);
568 } else {
569 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_display_prefixes_for_selected_units")), TRUE);
570 }
571
572 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_all_prefixes")), po.use_all_prefixes);
573 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_denominator_prefixes")), po.use_denominator_prefix);
574 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_place_units_separately")), po.place_units_separately);
575 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_abbreviate_names")), po.abbreviate_names);
576
577 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_enable_variables")), eo.parse_options.variables_enabled);
578 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_enable_functions")), eo.parse_options.functions_enabled);
579 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_enable_units")), eo.parse_options.units_enabled);
580 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_enable_unknown_variables")), eo.parse_options.unknowns_enabled);
581 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_enable_variable_units")), variable_units);
582 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_calculate_variables")), eo.calculate_variables);
583 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_allow_complex")), eo.allow_complex);
584 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_allow_infinite")), eo.allow_infinite);
585
586 int dff = default_fraction_fraction;
587 switch(po.number_fraction_format) {
588 case FRACTION_DECIMAL: {
589 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_fraction_decimal")), TRUE);
590 if(initial_update) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_fraction")), FALSE);
591 break;
592 }
593 case FRACTION_DECIMAL_EXACT: {
594 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_fraction_decimal_exact")), TRUE);
595 if(initial_update) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_fraction")), FALSE);
596 break;
597 }
598 case FRACTION_COMBINED: {
599 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_fraction_combined")), TRUE);
600 if(initial_update) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_fraction")), TRUE);
601 break;
602 }
603 case FRACTION_FRACTIONAL: {
604 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_fraction_fraction")), TRUE);
605 if(initial_update) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_fraction")), TRUE);
606 break;
607 }
608 }
609 default_fraction_fraction = dff;
610
611 switch(eo.complex_number_form) {
612 case COMPLEX_NUMBER_FORM_RECTANGULAR: {
613 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_complex_rectangular")), TRUE);
614 break;
615 }
616 case COMPLEX_NUMBER_FORM_EXPONENTIAL: {
617 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_complex_exponential")), TRUE);
618 break;
619 }
620 case COMPLEX_NUMBER_FORM_POLAR: {
621 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_complex_polar")), TRUE);
622 break;
623 }
624 case COMPLEX_NUMBER_FORM_CIS: {
625 if(caf) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_complex_angle")), TRUE);
626 else gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_complex_polar")), TRUE);
627 break;
628 }
629 }
630
631 if(id_adaptive) {
632 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_interval_adaptive")), TRUE);
633 } else {
634 switch(po.interval_display) {
635 case INTERVAL_DISPLAY_INTERVAL: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_interval_interval")), TRUE); break;}
636 case INTERVAL_DISPLAY_PLUSMINUS: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_interval_plusminus")), TRUE); break;}
637 case INTERVAL_DISPLAY_MIDPOINT: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_interval_midpoint")), TRUE); break;}
638 default: {gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "menu_item_interval_significant")), TRUE); break;}
639 }
640 }
641
642 set_assumptions_items(at, as);
643
644 if(!initial_update) {
645 if(decimals_builder) {
646 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(decimals_builder, "decimals_dialog_checkbutton_min")), po.use_min_decimals);
647 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(decimals_builder, "decimals_dialog_checkbutton_max")), po.use_max_decimals);
648 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(decimals_builder, "decimals_dialog_spinbutton_min")), po.min_decimals);
649 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(decimals_builder, "decimals_dialog_spinbutton_max")), po.max_decimals);
650 } else {
651 printops.max_decimals = po.max_decimals;
652 printops.use_max_decimals = po.use_max_decimals;
653 printops.max_decimals = po.min_decimals;
654 printops.use_min_decimals = po.use_min_decimals;
655 }
656 if(precision_builder) {
657 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(precision_builder, "precision_dialog_spinbutton_precision")), precision);
658 } else {
659 CALCULATOR->setPrecision(precision);
660 }
661 printops.spacious = po.spacious;
662 printops.short_multiplication = po.short_multiplication;
663 printops.excessive_parenthesis = po.excessive_parenthesis;
664 evalops.calculate_functions = eo.calculate_functions;
665 if(setbase_builder) {
666 switch(eo.parse_options.base) {
667 case BASE_BINARY: {
668 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_binary")), TRUE);
669 break;
670 }
671 case BASE_OCTAL: {
672 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_octal")), TRUE);
673 break;
674 }
675 case BASE_DECIMAL: {
676 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_decimal")), TRUE);
677 break;
678 }
679 case 12: {
680 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_duodecimal")), TRUE);
681 break;
682 }
683 case BASE_HEXADECIMAL: {
684 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_hexadecimal")), TRUE);
685 break;
686 }
687 case BASE_ROMAN_NUMERALS: {
688 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_roman")), TRUE);
689 break;
690 }
691 default: {
692 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
693 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_spinbutton_input_other")), eo.parse_options.base);
694 }
695 }
696 } else {
697 evalops.parse_options.base = eo.parse_options.base;
698 }
699 }
700 update_keypad_bases();
701 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "button_programmers_keypad")), keypad & PROGRAMMING_KEYPAD);
702 visible_keypad = keypad;
703
704 if(!initial_update) {
705 if(keypad & HIDE_LEFT_KEYPAD) {
706 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "stack_left_buttons")));
707 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "event_hide_right_buttons")));
708 gint h;
709 gtk_window_get_size(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), NULL, &h);
710 gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), 1, 1);
711 } else if(keypad & HIDE_RIGHT_KEYPAD) {
712 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_right_buttons")));
713 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "event_hide_left_buttons")));
714 gint h;
715 gtk_window_get_size(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), NULL, &h);
716 gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), 1, 1);
717 }
718 }
719 }
720
completion_row_separator_func(GtkTreeModel * model,GtkTreeIter * iter,gpointer)721 gboolean completion_row_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer) {
722 gint i;
723 gtk_tree_model_get(model, iter, 4, &i, -1);
724 return i == 3;
725 }
history_row_separator_func(GtkTreeModel * model,GtkTreeIter * iter,gpointer)726 gboolean history_row_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer) {
727 gint hindex = -1;
728 gtk_tree_model_get(model, iter, 1, &hindex, -1);
729 return hindex < 0;
730 }
731
getBuilder(const char * filename)732 GtkBuilder *getBuilder(const char *filename) {
733 string resstr = "/qalculate-gtk/ui/";
734 resstr += filename;
735 return gtk_builder_new_from_resource(resstr.c_str());
736 }
737
738 #define SUP_STRING(X) string("<span size=\"x-small\" rise=\"" + i2s((int) (pango_font_description_get_size(font_desc) / 1.5)) + "\">") + string(X) + "</span>"
739
set_keypad_tooltip(const gchar * w,const char * s1,const char * s2=NULL,const char * s3=NULL,bool b_markup=false,bool b_longpress=true)740 void set_keypad_tooltip(const gchar *w, const char *s1, const char *s2 = NULL, const char *s3 = NULL, bool b_markup = false, bool b_longpress = true) {
741 string str;
742 if(s1) str += s1;
743 if(s2) {
744 if(s1) str += "\n\n";
745 if(b_longpress) str += _("Right-click/long press: %s");
746 else str += _("Right-click: %s");
747 gsub("%s", s2, str);
748 }
749 if(s3) {
750 if(s2) str += "\n";
751 else if(s1) str += "\n\n";
752 str += _("Middle-click: %s");
753 gsub("%s", s3, str);
754 }
755 if(b_markup) gtk_widget_set_tooltip_markup(GTK_WIDGET(gtk_builder_get_object(main_builder, w)), str.c_str());
756 else gtk_widget_set_tooltip_text(GTK_WIDGET(gtk_builder_get_object(main_builder, w)), str.c_str());
757 g_signal_connect(gtk_builder_get_object(main_builder, w), "clicked", G_CALLBACK(hide_tooltip), NULL);
758 }
759
760 #define SET_LABEL_AND_TOOLTIP_2(i, w1, w2, l, t1, t2) \
761 if(index == i || index < 0) {\
762 if(index >= 0 || !custom_buttons[i].text.empty()) gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, w1)), custom_buttons[i].text.empty() ? l : custom_buttons[i].text.c_str()); \
763 set_keypad_tooltip(w2, custom_buttons[i].type[0] == -1 ? t1 : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0], true) : custom_buttons[i].value[0].c_str()), custom_buttons[i].type[1] == -1 ? t2 : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1], true) : custom_buttons[i].value[1].c_str()), custom_buttons[i].type[2] == -1 ? (custom_buttons[i].type[1] == -1 ? NULL : t2) : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2], true) : custom_buttons[i].value[2].c_str()));\
764 }
765
766 #define SET_LABEL_AND_TOOLTIP_2NL(i, w2, t1, t2) \
767 if(index == i || index < 0) {\
768 set_keypad_tooltip(w2, custom_buttons[i].type[0] == -1 ? t1 : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0], true) : custom_buttons[i].value[0].c_str()), custom_buttons[i].type[1] == -1 ? t2 : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1], true) : custom_buttons[i].value[1].c_str()), custom_buttons[i].type[2] == -1 ? (custom_buttons[i].type[1] == -1 ? NULL : t2) : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2], true) : custom_buttons[i].value[2].c_str()));\
769 }
770
771 #define SET_LABEL_AND_TOOLTIP_3(i, w1, w2, l, t1, t2, t3) \
772 if(index == i || index < 0) {\
773 if(index >= 0 || !custom_buttons[i].text.empty()) gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, w1)), custom_buttons[i].text.empty() ? l : custom_buttons[i].text.c_str()); \
774 set_keypad_tooltip(w2, custom_buttons[i].type[0] == -1 ? t1 : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0], true) : custom_buttons[i].value[0].c_str()), custom_buttons[i].type[1] == -1 ? t2 : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1], true) : custom_buttons[i].value[1].c_str()), custom_buttons[i].type[2] == -1 ? t3 : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2], true) : custom_buttons[i].value[2].c_str()));\
775 }
776
777 #define SET_LABEL_AND_TOOLTIP_3NP(i, w1, w2, l, t1, t2, t3) \
778 if(index == i || index < 0) {\
779 if(index >= 0 || !custom_buttons[i].text.empty()) gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, w1)), custom_buttons[i].text.empty() ? l : custom_buttons[i].text.c_str()); \
780 set_keypad_tooltip(w2, custom_buttons[i].type[0] == -1 ? t1 : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0], true) : custom_buttons[i].value[0].c_str()), custom_buttons[i].type[1] == -1 ? t2 : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1], true) : custom_buttons[i].value[1].c_str()), custom_buttons[i].type[2] == -1 ? t3 : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2], true) : custom_buttons[i].value[2].c_str()), false, custom_buttons[i].type[0] == -1);\
781 }
782
783 #define SET_LABEL_AND_TOOLTIP_3M(i, w1, w2, l, t1, t2, t3) \
784 if(index == i || index < 0) {\
785 if(index >= 0 || !custom_buttons[i].text.empty()) gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, w1)), custom_buttons[i].text.empty() ? l : custom_buttons[i].text.c_str()); \
786 set_keypad_tooltip(w2, custom_buttons[i].type[0] == -1 ? t1 : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0], true) : custom_buttons[i].value[0].c_str()), custom_buttons[i].type[1] == -1 ? t2 : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1], true) : custom_buttons[i].value[1].c_str()), custom_buttons[i].type[2] == -1 ? t3 : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2], true) : custom_buttons[i].value[2].c_str()), true);\
787 }
788
789 #define SET_LABEL_AND_TOOLTIP_3NL(i, w2, t1, t2, t3) \
790 if(index == i || index < 0) {\
791 set_keypad_tooltip(w2, custom_buttons[i].type[0] == -1 ? t1 : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0], true) : custom_buttons[i].value[0].c_str()), custom_buttons[i].type[1] == -1 ? t2 : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1], true) : custom_buttons[i].value[1].c_str()), custom_buttons[i].type[2] == -1 ? t3 : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2], true) : custom_buttons[i].value[2].c_str()));\
792 }
793
794 #define SET_LABEL_AND_TOOLTIP_3C(i, w1, w2, l) \
795 if(index == i || index < 0) {\
796 if(index >= 0 || !custom_buttons[i].text.empty()) gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, w1)), custom_buttons[i].text.empty() ? l : custom_buttons[i].text.c_str()); \
797 set_keypad_tooltip(w2, custom_buttons[i].type[0] == -1 ? NULL : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0], true) : custom_buttons[i].value[0].c_str()), custom_buttons[i].type[1] == -1 ? NULL : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1], true) : custom_buttons[i].value[1].c_str()), custom_buttons[i].type[2] == -1 ? NULL : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2], true) : custom_buttons[i].value[2].c_str()));\
798 }
799
update_custom_buttons(int index)800 void update_custom_buttons(int index) {
801 if(index == 0 || index < 0) {
802 if(custom_buttons[0].text.empty()) gtk_stack_set_visible_child(GTK_STACK(gtk_builder_get_object(main_builder, "stack_move")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_move")));
803 else gtk_stack_set_visible_child(GTK_STACK(gtk_builder_get_object(main_builder, "stack_move")), GTK_WIDGET(gtk_builder_get_object(main_builder, "label_move")));
804 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_move")), custom_buttons[0].text.c_str());
805 set_keypad_tooltip("button_move", custom_buttons[0].type[0] == -1 ? _("Cycle through previous expression") : (custom_buttons[0].value[0].empty() ? shortcut_type_text(custom_buttons[0].type[0], true) : custom_buttons[0].value[0].c_str()), custom_buttons[0].type[1] < 0 ? NULL : (custom_buttons[0].value[1].empty() ? shortcut_type_text(custom_buttons[0].type[1], true) : custom_buttons[0].value[1].c_str()), custom_buttons[0].type[2] < 0 ? NULL : (custom_buttons[0].value[2].empty() ? shortcut_type_text(custom_buttons[0].type[2], true) : custom_buttons[0].value[2].c_str()), false, custom_buttons[0].type[0] != -1);
806 }
807 if(index == 1 || index < 0) {
808 if(custom_buttons[1].text.empty()) gtk_stack_set_visible_child(GTK_STACK(gtk_builder_get_object(main_builder, "stack_move2")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_move2")));
809 else gtk_stack_set_visible_child(GTK_STACK(gtk_builder_get_object(main_builder, "stack_move2")), GTK_WIDGET(gtk_builder_get_object(main_builder, "label_move2")));
810 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_move2")), custom_buttons[1].text.c_str());
811 set_keypad_tooltip("button_move2", custom_buttons[1].type[0] == -1 ? _("Move cursor left or right") : (custom_buttons[1].value[0].empty() ? shortcut_type_text(custom_buttons[1].type[0], true) : custom_buttons[1].value[0].c_str()), custom_buttons[1].type[1] == -1 ? _("Move cursor to beginning or end") : (custom_buttons[1].value[1].empty() ? shortcut_type_text(custom_buttons[1].type[1], true) : custom_buttons[1].value[1].c_str()), custom_buttons[1].type[2] == -1 ? (custom_buttons[1].type[1] == -1 ? NULL : _("Move cursor to beginning or end")) : (custom_buttons[1].value[2].empty() ? shortcut_type_text(custom_buttons[1].type[2], true) : custom_buttons[1].value[2].c_str()), false, custom_buttons[1].type[0] != -1);
812 }
813 SET_LABEL_AND_TOOLTIP_2(2, "label_percent", "button_percent", "%", CALCULATOR->v_percent->title(true).c_str(), CALCULATOR->v_permille->title(true).c_str())
814 SET_LABEL_AND_TOOLTIP_3(3, "label_plusminus", "button_plusminus", "±", _("Uncertainty/interval"), _("Relative error"), _("Interval"))
815 SET_LABEL_AND_TOOLTIP_3(4, "label_comma", "button_comma", CALCULATOR->getComma().c_str(), _("Argument separator"), _("Blank space"), _("New line"))
816 SET_LABEL_AND_TOOLTIP_2(5, "label_brace_wrap", "button_brace_wrap", "(x)", _("Smart parentheses"), _("Vector brackets"))
817 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_brace_wrap")), custom_buttons[5].text.empty() ? "(x)" : custom_buttons[5].text.c_str());
818 SET_LABEL_AND_TOOLTIP_2(6, "label_brace_open", "button_brace_open", "(", _("Left parenthesis"), _("Left vector bracket"))
819 SET_LABEL_AND_TOOLTIP_2(7, "label_brace_close", "button_brace_close", ")", _("Right parenthesis"), _("Right vector bracket"))
820 SET_LABEL_AND_TOOLTIP_3M(8, "label_zero", "button_zero", "0", NULL, "x<sup>0</sup>", CALCULATOR->getDegUnit()->title(true).c_str())
821 SET_LABEL_AND_TOOLTIP_3M(9, "label_one", "button_one", "1", NULL, "x<sup>1</sup>", "1/x")
822 SET_LABEL_AND_TOOLTIP_3M(10, "label_two", "button_two", "2", NULL, "x<sup>2</sup>", "1/2")
823 SET_LABEL_AND_TOOLTIP_3M(11, "label_three", "button_three", "3", NULL, "x<sup>3</sup>", "1/3")
824 SET_LABEL_AND_TOOLTIP_3M(12, "label_four", "button_four", "4", NULL, "x<sup>4</sup>", "1/4")
825 SET_LABEL_AND_TOOLTIP_3M(13, "label_five", "button_five", "5", NULL, "x<sup>5</sup>", "1/5")
826 SET_LABEL_AND_TOOLTIP_3M(14, "label_six", "button_six", "6", NULL, "x<sup>6</sup>", "1/6")
827 SET_LABEL_AND_TOOLTIP_3M(15, "label_seven", "button_seven", "7", NULL, "x<sup>7</sup>", "1/7")
828 SET_LABEL_AND_TOOLTIP_3M(16, "label_eight", "button_eight", "8", NULL, "x<sup>8</sup>", "1/8")
829 SET_LABEL_AND_TOOLTIP_3M(17, "label_nine", "button_nine", "9", NULL, "x<sup>9</sup>", "1/9")
830 SET_LABEL_AND_TOOLTIP_3(18, "label_dot", "button_dot", CALCULATOR->getDecimalPoint().c_str(), _("Decimal point"), _("Blank space"), _("New line"))
831 if(index < 0 || index == 19) {
832 MathFunction *f = CALCULATOR->getActiveFunction("exp10");
833 SET_LABEL_AND_TOOLTIP_3M(19, "label_exp", "button_exp", _("EXP"), "10<sup>x</sup> (Ctrl+Shift+E)", CALCULATOR->f_exp->title(true).c_str(), (f ? f->title(true).c_str() : NULL))
834 }
835 if(index == 20 || (index < 0 && !custom_buttons[20].text.empty())) {
836 if(custom_buttons[20].text.empty()) {
837 PangoFontDescription *font_desc = NULL;
838 gtk_style_context_get(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_xy"))), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
839 gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_xy")), (string("x") + SUP_STRING("y")).c_str());
840 pango_font_description_free(font_desc);
841 } else {
842 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_xy")), custom_buttons[20].text.c_str());
843 }
844 }
845 SET_LABEL_AND_TOOLTIP_2NL(20, "button_xy", _("Raise (Ctrl+*)"), CALCULATOR->f_sqrt->title(true).c_str())
846 if(index == 24 || (index < 0 && !custom_buttons[24].text.empty())) {
847 if(custom_buttons[24].text.empty()) {
848 if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MINUS, (void*) gtk_builder_get_object(main_builder, "label_sub"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_sub")), SIGN_MINUS);
849 else gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_sub")), MINUS);
850 } else {
851 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_sub")), custom_buttons[24].text.c_str());
852 }
853 }
854 if(index == 22 || (index < 0 && !custom_buttons[22].text.empty())) {
855 if(custom_buttons[22].text.empty()) {
856 if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) gtk_builder_get_object(main_builder, "label_times"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_times")), SIGN_MULTIPLICATION);
857 else gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_times")), MULTIPLICATION);
858 } else {
859 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_times")), custom_buttons[22].text.c_str());
860 }
861 }
862 if(index == 21 || (index < 0 && !custom_buttons[21].text.empty())) {
863 if(custom_buttons[21].text.empty()) {
864 if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_DIVISION_SLASH, (void*) gtk_builder_get_object(main_builder, "label_divide"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_divide")), SIGN_DIVISION_SLASH);
865 else if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_DIVISION, (void*) gtk_builder_get_object(main_builder, "label_divide"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_divide")), SIGN_DIVISION);
866 else gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_divide")), DIVISION);
867 } else {
868 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_divide")), custom_buttons[21].text.c_str());
869 }
870 }
871 SET_LABEL_AND_TOOLTIP_2NL(21, "button_divide", _("Divide"), "1/x")
872 SET_LABEL_AND_TOOLTIP_2NL(22, "button_times", _("Multiply"), _("Bitwise Exclusive OR"))
873 SET_LABEL_AND_TOOLTIP_3(23, "label_add", "button_add", "+", _("Add"), _("M+ (memory plus)"), _("Bitwise AND"))
874 if(index < 0 || index == 24) {
875 MathFunction *f = CALCULATOR->getActiveFunction("neg");
876 SET_LABEL_AND_TOOLTIP_3NL(24, "button_sub", _("Subtract"), f ? f->title(true).c_str() : NULL, _("Bitwise OR"));
877 }
878 SET_LABEL_AND_TOOLTIP_2(25, "label_ac", "button_ac", _("AC"), _("Clear"), _("MC (memory clear)"))
879 SET_LABEL_AND_TOOLTIP_3NP(26, "label_del", "button_del", _("DEL"), _("Delete"), _("Backspace"), _("M− (memory minus)"))
880 SET_LABEL_AND_TOOLTIP_2(27, "label_ans", "button_ans", _("ANS"), _("Previous result"), _("Previous result (static)"))
881 if(index == 28 || (index < 0 && !custom_buttons[28].text.empty())) {
882 if(custom_buttons[28].text.empty()) {
883 gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_equals")), "<big>=</big>");
884 } else {
885 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_equals")), custom_buttons[28].text.c_str());
886 }
887 }
888 SET_LABEL_AND_TOOLTIP_3NL(28, "button_equals", _("Calculate expression"), _("MR (memory recall)"), _("MS (memory store)"))
889 SET_LABEL_AND_TOOLTIP_3C(29, "label_c1", "button_c1", "C1")
890 SET_LABEL_AND_TOOLTIP_3C(30, "label_c2", "button_c2", "C2")
891 SET_LABEL_AND_TOOLTIP_3C(31, "label_c3", "button_c3", "C3")
892 SET_LABEL_AND_TOOLTIP_3C(32, "label_c4", "button_c4", "C4")
893 SET_LABEL_AND_TOOLTIP_3C(33, "label_c5", "button_c5", "C5")
894 if(index >= 29) {
895 bool b_show = (custom_buttons[29].type[0] >= 0 || custom_buttons[29].type[1] >= 0 || custom_buttons[29].type[2] >= 0 || custom_buttons[30].type[0] >= 0 || custom_buttons[30].type[1] >= 0 || custom_buttons[30].type[2] >= 0 || custom_buttons[31].type[0] >= 0 || custom_buttons[31].type[1] >= 0 || custom_buttons[31].type[2] >= 0 || custom_buttons[32].type[0] >= 0 || custom_buttons[32].type[1] >= 0 || custom_buttons[32].type[2] >= 0 || custom_buttons[33].type[0] >= 0 || custom_buttons[33].type[1] >= 0 || custom_buttons[33].type[2] >= 0);
896 if(b_show != gtk_widget_get_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_custom_buttons")))) {
897 if(!b_show && gtk_expander_get_expanded(GTK_EXPANDER(expander_keypad)) && !minimal_mode) {
898 gint w_c = gtk_widget_get_allocated_width(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_custom_buttons"))) + 6;
899 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_custom_buttons")), b_show);
900 while(gtk_events_pending()) gtk_main_iteration();
901 gint w, h;
902 gtk_window_get_size(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), &w, &h);
903 gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), w - w_c, h);
904 } else {
905 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_custom_buttons")), b_show);
906 }
907 }
908 }
909 }
910
set_custom_buttons()911 void set_custom_buttons() {
912 if(!latest_button_unit_pre.empty()) {
913 latest_button_unit = CALCULATOR->getActiveUnit(latest_button_unit_pre);
914 if(!latest_button_unit) latest_button_unit = CALCULATOR->getCompositeUnit(latest_button_unit_pre);
915 }
916 if(latest_button_unit) {
917 string si_label_str;
918 if(latest_button_unit->subtype() == SUBTYPE_COMPOSITE_UNIT) {
919 si_label_str = ((CompositeUnit*) latest_button_unit)->print(false, true, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressiontext);
920 } else {
921
922 si_label_str = latest_button_unit->preferredDisplayName(true, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressiontext).name;
923 }
924 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_si")), si_label_str.c_str());
925 gtk_widget_set_tooltip_text(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_si")), latest_button_unit->title(true).c_str());
926 }
927 Unit *u_local_currency = CALCULATOR->getLocalCurrency();
928 if(!latest_button_currency_pre.empty()) {
929 latest_button_currency = CALCULATOR->getActiveUnit(latest_button_currency_pre);
930 }
931 if(!latest_button_currency && u_local_currency) latest_button_currency = u_local_currency;
932 if(!latest_button_currency) latest_button_currency = CALCULATOR->u_euro;
933 string unit_label_str;
934 if(latest_button_currency->subtype() == SUBTYPE_COMPOSITE_UNIT) {
935 unit_label_str = ((CompositeUnit*) latest_button_currency)->print(false, true, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressiontext);
936 } else {
937
938 unit_label_str = latest_button_currency->preferredDisplayName(true, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressiontext).name;
939 }
940 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_euro")), unit_label_str.c_str());
941 gtk_widget_set_tooltip_text(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_euro")), latest_button_currency->title(true).c_str());
942 }
943
create_button_menus()944 void create_button_menus() {
945
946 GtkWidget *item, *sub;
947 MathFunction *f;
948
949 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_bases"));
950 MENU_ITEM(_("Bitwise Left Shift"), insert_left_shift)
951 MENU_ITEM(_("Bitwise Right Shift"), insert_right_shift)
952 MENU_ITEM(_("Bitwise AND"), insert_bitwise_and)
953 MENU_ITEM(_("Bitwise OR"), insert_bitwise_or)
954 MENU_ITEM(_("Bitwise Exclusive OR"), insert_bitwise_xor)
955 MENU_ITEM(_("Bitwise NOT"), insert_bitwise_not)
956 MENU_ITEM_WITH_POINTER(CALCULATOR->f_bitcmp->title(true).c_str(), insert_button_function, CALCULATOR->f_bitcmp)
957 f = CALCULATOR->getActiveFunction("bitrot");
958 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f)}
959 MENU_SEPARATOR
960 MENU_ITEM_WITH_POINTER(CALCULATOR->f_base->title(true).c_str(), insert_button_function, CALCULATOR->f_base)
961 MENU_SEPARATOR
962 MENU_ITEM_WITH_POINTER(CALCULATOR->f_ascii->title(true).c_str(), insert_button_function, CALCULATOR->f_ascii)
963 MENU_ITEM_WITH_POINTER(CALCULATOR->f_char->title(true).c_str(), insert_button_function, CALCULATOR->f_char)
964
965 PangoFontDescription *font_desc;
966
967 gtk_style_context_get(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_xy"))), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
968
969 g_signal_connect(gtk_builder_get_object(main_builder, "button_e_var"), "clicked", G_CALLBACK(insert_button_variable), (gpointer) CALCULATOR->v_e);
970 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_e"));
971 MENU_ITEM_WITH_POINTER(CALCULATOR->f_exp->title(true).c_str(), insert_button_function, CALCULATOR->f_exp)
972 f = CALCULATOR->getActiveFunction("cis");
973 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
974
975 pango_font_description_free(font_desc);
976
977 g_signal_connect(gtk_builder_get_object(main_builder, "button_sqrt"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_sqrt);
978 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_sqrt"));
979 MENU_ITEM_WITH_POINTER(CALCULATOR->f_cbrt->title(true).c_str(), insert_button_function, CALCULATOR->f_cbrt);
980 MENU_ITEM_WITH_POINTER(CALCULATOR->f_root->title(true).c_str(), insert_button_function, CALCULATOR->f_root);
981 f = CALCULATOR->getActiveFunction("sqrtpi");
982 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
983
984 g_signal_connect(gtk_builder_get_object(main_builder, "button_ln"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_ln);
985 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_ln"));
986 f = CALCULATOR->getActiveFunction("log10");
987 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
988 f = CALCULATOR->getActiveFunction("log2");
989 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
990 MENU_ITEM_WITH_POINTER(CALCULATOR->f_logn->title(true).c_str(), insert_button_function, CALCULATOR->f_logn)
991
992 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_fac"));
993 MENU_ITEM_WITH_POINTER(CALCULATOR->f_factorial2->title(true).c_str(), insert_button_function, CALCULATOR->f_factorial2)
994 MENU_ITEM_WITH_POINTER(CALCULATOR->f_multifactorial->title(true).c_str(), insert_button_function, CALCULATOR->f_multifactorial)
995 f = CALCULATOR->getActiveFunction("hyperfactorial");
996 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
997 f = CALCULATOR->getActiveFunction("superfactorial");
998 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
999 f = CALCULATOR->getActiveFunction("perm");
1000 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1001 f = CALCULATOR->getActiveFunction("comb");
1002 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1003 f = CALCULATOR->getActiveFunction("derangements");
1004 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1005 MENU_ITEM_WITH_POINTER(CALCULATOR->f_binomial->title(true).c_str(), insert_button_function, CALCULATOR->f_binomial)
1006
1007 g_signal_connect(gtk_builder_get_object(main_builder, "button_mod"), "clicked", G_CALLBACK(insert_function_operator), (gpointer) CALCULATOR->f_mod);
1008 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_mod"));
1009 MENU_ITEM_WITH_POINTER(CALCULATOR->f_rem->title(true).c_str(), insert_function_operator, CALCULATOR->f_rem)
1010 MENU_ITEM_WITH_POINTER(CALCULATOR->f_abs->title(true).c_str(), insert_button_function, CALCULATOR->f_abs)
1011 MENU_ITEM_WITH_POINTER(CALCULATOR->f_gcd->title(true).c_str(), insert_button_function, CALCULATOR->f_gcd)
1012 MENU_ITEM_WITH_POINTER(CALCULATOR->f_lcm->title(true).c_str(), insert_button_function, CALCULATOR->f_lcm)
1013
1014 g_signal_connect(gtk_builder_get_object(main_builder, "button_sine"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_sin);
1015 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_sin"));
1016 MENU_SEPARATOR_PREPEND
1017 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_asinh->title(true).c_str(), insert_button_function, CALCULATOR->f_asinh)
1018 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_asin->title(true).c_str(), insert_button_function, CALCULATOR->f_asin)
1019 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_sinh->title(true).c_str(), insert_button_function, CALCULATOR->f_sinh)
1020
1021 g_signal_connect(gtk_builder_get_object(main_builder, "button_cosine"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_cos);
1022 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_cos"));
1023 MENU_SEPARATOR_PREPEND
1024 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_acosh->title(true).c_str(), insert_button_function, CALCULATOR->f_acosh)
1025 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_acos->title(true).c_str(), insert_button_function, CALCULATOR->f_acos)
1026 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_cosh->title(true).c_str(), insert_button_function, CALCULATOR->f_cosh)
1027
1028 g_signal_connect(gtk_builder_get_object(main_builder, "button_tan"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_tan);
1029 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_tan"));
1030 MENU_SEPARATOR_PREPEND
1031 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_atanh->title(true).c_str(), insert_button_function, CALCULATOR->f_atanh)
1032 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_atan->title(true).c_str(), insert_button_function, CALCULATOR->f_atan)
1033 MENU_ITEM_WITH_POINTER_PREPEND(CALCULATOR->f_tanh->title(true).c_str(), insert_button_function, CALCULATOR->f_tanh)
1034
1035 g_signal_connect(gtk_builder_get_object(main_builder, "button_sum"), "clicked", G_CALLBACK(insert_button_function_norpn), (gpointer) CALCULATOR->f_sum);
1036 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_sum"));
1037 MENU_ITEM_WITH_POINTER(CALCULATOR->f_product->title(true).c_str(), insert_button_function_norpn, CALCULATOR->f_product)
1038 MENU_ITEM_WITH_POINTER(CALCULATOR->f_for->title(true).c_str(), insert_button_function_norpn, CALCULATOR->f_for)
1039 MENU_ITEM_WITH_POINTER(CALCULATOR->f_if->title(true).c_str(), insert_button_function_norpn, CALCULATOR->f_if)
1040
1041
1042 g_signal_connect(gtk_builder_get_object(main_builder, "button_mean"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->getActiveFunction("mean"));
1043 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_mean"));
1044 f = CALCULATOR->getActiveFunction("median");
1045 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1046 f = CALCULATOR->getActiveFunction("var");
1047 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1048 f = CALCULATOR->getActiveFunction("stdev");
1049 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1050 f = CALCULATOR->getActiveFunction("stderr");
1051 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1052 f = CALCULATOR->getActiveFunction("harmmean");
1053 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1054 f = CALCULATOR->getActiveFunction("geomean");
1055 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1056 MENU_SEPARATOR
1057 MENU_ITEM_WITH_POINTER(CALCULATOR->f_rand->title(true).c_str(), insert_button_function, CALCULATOR->f_rand);
1058
1059 g_signal_connect(gtk_builder_get_object(main_builder, "button_pi"), "clicked", G_CALLBACK(insert_button_variable), (gpointer) CALCULATOR->v_pi);
1060
1061 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_xequals"));
1062 MENU_ITEM_WITH_POINTER(CALCULATOR->f_solve->title(true).c_str(), insert_button_function, CALCULATOR->f_solve)
1063 f = CALCULATOR->getActiveFunction("solve2");
1064 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1065 f = CALCULATOR->getActiveFunction("linearfunction");
1066 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1067 MENU_ITEM_WITH_POINTER(CALCULATOR->f_dsolve->title(true).c_str(), insert_button_function, CALCULATOR->f_dsolve)
1068 f = CALCULATOR->getActiveFunction("extremum");
1069 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1070 MENU_SEPARATOR
1071 MENU_ITEM(_("Set unknowns"), on_menu_item_set_unknowns_activate)
1072
1073 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_factorize"));
1074 MENU_ITEM(_("Expand"), on_menu_item_simplify_activate)
1075 item_simplify = item;
1076 MENU_ITEM(_("Factorize"), on_menu_item_factorize_activate)
1077 item_factorize = item;
1078 MENU_ITEM(_("Expand Partial Fractions"), on_menu_item_expand_partial_fractions_activate)
1079 MENU_SEPARATOR
1080 MENU_ITEM_WITH_POINTER(CALCULATOR->f_diff->title(true).c_str(), insert_button_function, CALCULATOR->f_diff)
1081 MENU_ITEM_WITH_POINTER(CALCULATOR->f_integrate->title(true).c_str(), insert_button_function, CALCULATOR->f_integrate)
1082 gtk_widget_set_visible(item_factorize, evalops.structuring != STRUCTURING_SIMPLIFY);
1083 gtk_widget_set_visible(item_simplify, evalops.structuring != STRUCTURING_FACTORIZE);
1084
1085 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_i"));
1086 MENU_ITEM("∠ (Ctrl+Shift+A)", insert_angle_symbol)
1087 MENU_ITEM_WITH_POINTER(CALCULATOR->f_re->title(true).c_str(), insert_button_function, CALCULATOR->f_re)
1088 MENU_ITEM_WITH_POINTER(CALCULATOR->f_im->title(true).c_str(), insert_button_function, CALCULATOR->f_im)
1089 f = CALCULATOR->getActiveFunction("arg");
1090 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1091 f = CALCULATOR->getActiveFunction("conj");
1092 if(f) {MENU_ITEM_WITH_POINTER(f->title(true).c_str(), insert_button_function, f);}
1093
1094 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_si"));
1095 const char *si_units[] = {"m", "g", "s", "A", "K", "N", "Pa", "J", "W", "L", "V", "ohm", "oC", "cd", "mol", "C", "Hz", "F", "S", "Wb", "T", "H", "lm", "lx", "Bq", "Gy", "Sv", "kat"};
1096 vector<Unit*> to_us;
1097 size_t si_i = 0;
1098 size_t i_added = 0;
1099 for(; si_i < 27 && i_added < 12; si_i++) {
1100 Unit * u = CALCULATOR->getActiveUnit(si_units[si_i]);
1101 if(u && !u->isHidden()) {
1102 bool b = false;
1103 for(size_t i2 = 0; i2 < to_us.size(); i2++) {
1104 if(string_is_less(u->title(true), to_us[i2]->title(true))) {
1105 to_us.insert(to_us.begin() + i2, u);
1106 b = true;
1107 break;
1108 }
1109 }
1110 if(!b) to_us.push_back(u);
1111 i_added++;
1112 }
1113 }
1114 for(size_t i = 0; i < to_us.size(); i++) {
1115 MENU_ITEM_WITH_POINTER(to_us[i]->title(true).c_str(), insert_button_unit, to_us[i])
1116 }
1117
1118 // Show further items in a submenu
1119 if(si_i < 27) {SUBMENU_ITEM(_("more"), sub);}
1120
1121 to_us.clear();
1122 for(; si_i < 27; si_i++) {
1123 Unit * u = CALCULATOR->getActiveUnit(si_units[si_i]);
1124 if(u && !u->isHidden()) {
1125 bool b = false;
1126 for(size_t i2 = 0; i2 < to_us.size(); i2++) {
1127 if(string_is_less(u->title(true), to_us[i2]->title(true))) {
1128 to_us.insert(to_us.begin() + i2, u);
1129 b = true;
1130 break;
1131 }
1132 }
1133 if(!b) to_us.push_back(u);
1134 }
1135 }
1136 for(size_t i = 0; i < to_us.size(); i++) {
1137 MENU_ITEM_WITH_POINTER(to_us[i]->title(true).c_str(), insert_button_unit, to_us[i])
1138 }
1139
1140 Unit *u_local_currency = CALCULATOR->getLocalCurrency();
1141 sub = GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_euro"));
1142 const char *currency_units[] = {"USD", "GBP", "JPY"};
1143 to_us.clear();
1144 for(size_t i = 0; i < 5; i++) {
1145 Unit * u;
1146 if(i == 0) u = CALCULATOR->u_euro;
1147 else if(i == 1) u = u_local_currency;
1148 else u = CALCULATOR->getActiveUnit(currency_units[i - 2]);
1149 if(u && (i == 1 || !u->isHidden())) {
1150 bool b = false;
1151 for(size_t i2 = 0; i2 < to_us.size(); i2++) {
1152 if(u == to_us[i2]) {
1153 b = true;
1154 break;
1155 }
1156 if(string_is_less(u->title(true), to_us[i2]->title(true))) {
1157 to_us.insert(to_us.begin() + i2, u);
1158 b = true;
1159 break;
1160 }
1161 }
1162 if(!b) to_us.push_back(u);
1163 }
1164 }
1165 for(size_t i = 0; i < to_us.size(); i++) {
1166 MENU_ITEM_WITH_POINTER_AND_FLAG(to_us[i]->title(true).c_str(), insert_button_currency, to_us[i])
1167 }
1168
1169 i_added = to_us.size();
1170 vector<Unit*> to_us2;
1171 for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
1172 if(CALCULATOR->units[i]->baseUnit() == CALCULATOR->u_euro) {
1173 Unit *u = CALCULATOR->units[i];
1174 if(u->isActive()) {
1175 bool b = false;
1176 if(u->isHidden() && u != u_local_currency) {
1177 for(int i2 = to_us2.size() - 1; i2 >= 0; i2--) {
1178 if(u->title(true) > to_us2[(size_t) i2]->title(true)) {
1179 if((size_t) i2 == to_us2.size() - 1) to_us2.push_back(u);
1180 else to_us2.insert(to_us2.begin() + (size_t) i2 + 1, u);
1181 b = true;
1182 break;
1183 }
1184 }
1185 if(!b) to_us2.insert(to_us2.begin(), u);
1186 } else {
1187 for(size_t i2 = 0; i2 < i_added; i2++) {
1188 if(u == to_us[i2]) {
1189 b = true;
1190 break;
1191 }
1192 }
1193 for(size_t i2 = to_us.size() - 1; !b && i2 >= i_added; i2--) {
1194 if(u->title(true) > to_us[i2]->title(true)) {
1195 if(i2 == to_us.size() - 1) to_us.push_back(u);
1196 else to_us.insert(to_us.begin() + i2 + 1, u);
1197 b = true;
1198 }
1199 }
1200 if(!b) to_us.insert(to_us.begin() + i_added, u);
1201 }
1202 }
1203 }
1204 }
1205 for(size_t i = i_added; i < to_us.size(); i++) {
1206 // Show further items in a submenu
1207 if(i == i_added) {SUBMENU_ITEM(_("more"), sub);}
1208 MENU_ITEM_WITH_POINTER_AND_FLAG(to_us[i]->title(true).c_str(), insert_button_currency, to_us[i])
1209 }
1210 if(to_us2.size() > 0) {SUBMENU_ITEM(_("more"), sub);}
1211 for(size_t i = 0; i < to_us2.size(); i++) {
1212 // Show further items in a submenu
1213 MENU_ITEM_WITH_POINTER_AND_FLAG(to_us2[i]->title(true).c_str(), insert_button_currency, to_us2[i])
1214 }
1215
1216 set_keypad_tooltip("button_e_var", CALCULATOR->v_e->title(true).c_str());
1217 set_keypad_tooltip("button_pi", CALCULATOR->v_pi->title(true).c_str());
1218 set_keypad_tooltip("button_sine", CALCULATOR->f_sin->title(true).c_str());
1219 set_keypad_tooltip("button_cosine", CALCULATOR->f_cos->title(true).c_str());
1220 set_keypad_tooltip("button_tan", CALCULATOR->f_tan->title(true).c_str());
1221 f = CALCULATOR->getActiveFunction("mean");
1222 if(f) set_keypad_tooltip("button_mean", f->title(true).c_str());
1223 set_keypad_tooltip("button_sum", CALCULATOR->f_sum->title(true).c_str());
1224 set_keypad_tooltip("button_mod", CALCULATOR->f_mod->title(true).c_str());
1225 set_keypad_tooltip("button_fac", CALCULATOR->f_factorial->title(true).c_str());
1226 set_keypad_tooltip("button_ln", CALCULATOR->f_ln->title(true).c_str());
1227 set_keypad_tooltip("button_sqrt", CALCULATOR->f_sqrt->title(true).c_str());
1228 set_keypad_tooltip("button_i", CALCULATOR->v_i->title(true).c_str());
1229 gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(main_builder, "label_i")), (string("<i>") + CALCULATOR->v_i->preferredDisplayName(true, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) gtk_builder_get_object(main_builder, "label_i")).name + "</i>").c_str());
1230
1231 g_signal_connect(gtk_builder_get_object(main_builder, "button_cmp"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_bitcmp);
1232 g_signal_connect(gtk_builder_get_object(main_builder, "button_int"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_int);
1233 g_signal_connect(gtk_builder_get_object(main_builder, "button_frac"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_frac);
1234 g_signal_connect(gtk_builder_get_object(main_builder, "button_ln2"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_ln);
1235 g_signal_connect(gtk_builder_get_object(main_builder, "button_sqrt2"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_sqrt);
1236 g_signal_connect(gtk_builder_get_object(main_builder, "button_abs"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_abs);
1237 g_signal_connect(gtk_builder_get_object(main_builder, "button_expf"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_exp);
1238 g_signal_connect(gtk_builder_get_object(main_builder, "button_stamptodate"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_stamptodate);
1239 g_signal_connect(gtk_builder_get_object(main_builder, "button_code"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_ascii);
1240 //g_signal_connect(gtk_builder_get_object(main_builder, "button_rnd"), "clicked", G_CALLBACK(insert_button_function), (gpointer) CALCULATOR->f_rand);
1241 g_signal_connect(gtk_builder_get_object(main_builder, "button_mod2"), "clicked", G_CALLBACK(insert_function_operator), (gpointer) CALCULATOR->f_mod);
1242
1243 f = CALCULATOR->getActiveFunction("exp2");
1244 set_keypad_tooltip("button_expf", CALCULATOR->f_exp->title(true).c_str(), f ? f->title(true).c_str() : NULL);
1245 set_keypad_tooltip("button_mod2", CALCULATOR->f_mod->title(true).c_str(), CALCULATOR->f_rem->title(true).c_str());
1246 set_keypad_tooltip("button_ln2", CALCULATOR->f_ln->title(true).c_str());
1247 set_keypad_tooltip("button_int", CALCULATOR->f_int->title(true).c_str());
1248 set_keypad_tooltip("button_frac", CALCULATOR->f_frac->title(true).c_str());
1249 set_keypad_tooltip("button_stamptodate", CALCULATOR->f_stamptodate->title(true).c_str(), CALCULATOR->f_timestamp->title(true).c_str());
1250 set_keypad_tooltip("button_code", CALCULATOR->f_ascii->title(true).c_str(), CALCULATOR->f_char->title(true).c_str());
1251 f = CALCULATOR->getActiveFunction("log2");
1252 MathFunction *f2 = CALCULATOR->getActiveFunction("log10");
1253 set_keypad_tooltip("button_log2", f ? f->title(true).c_str() : NULL, f2 ? f2->title(true).c_str() : NULL);
1254 if(f) g_signal_connect(gtk_builder_get_object(main_builder, "button_log2"), "clicked", G_CALLBACK(insert_button_function), (gpointer) f);
1255 set_keypad_tooltip("button_reciprocal", "1/x");
1256 f = CALCULATOR->getActiveFunction("div");
1257 if(f) set_keypad_tooltip("button_idiv", f->title(true).c_str());
1258 set_keypad_tooltip("button_sqrt2", CALCULATOR->f_sqrt->title(true).c_str(), CALCULATOR->f_cbrt->title(true).c_str());
1259 set_keypad_tooltip("button_abs", CALCULATOR->f_abs->title(true).c_str());
1260 set_keypad_tooltip("button_fac2", CALCULATOR->f_factorial->title(true).c_str());
1261 //set_keypad_tooltip("button_rnd", CALCULATOR->f_rand->title(true).c_str());
1262 set_keypad_tooltip("button_cmp", CALCULATOR->f_bitcmp->title(true).c_str());
1263 f = CALCULATOR->getActiveFunction("bitrot");
1264 if(f) {
1265 set_keypad_tooltip("button_rot", f->title(true).c_str());
1266 g_signal_connect(gtk_builder_get_object(main_builder, "button_rot"), "clicked", G_CALLBACK(insert_button_function), (gpointer) f);
1267 }
1268
1269 set_keypad_tooltip("button_and", _("Bitwise AND"), _("Logical AND"));
1270 set_keypad_tooltip("button_or", _("Bitwise OR"), _("Logical OR"));
1271 set_keypad_tooltip("button_not", _("Bitwise NOT"), _("Logical NOT"));
1272
1273 set_keypad_tooltip("button_bin", _("Binary"), _("Toggle Result Base"));
1274 set_keypad_tooltip("button_oct", _("Octal"), _("Toggle Result Base"));
1275 set_keypad_tooltip("button_dec", _("Decimal"), _("Toggle Result Base"));
1276 set_keypad_tooltip("button_hex", _("Hexadecimal"), _("Toggle Result Base"));
1277
1278 set_keypad_tooltip("button_store2", _("Store result as a variable"), _("Open menu with stored variables"));
1279
1280 if(caret_as_xor) set_keypad_tooltip("button_xor", _("Bitwise Exclusive OR"));
1281 else set_keypad_tooltip("button_xor", (string(_("Bitwise Exclusive OR")) + " (Ctrl+^)").c_str());
1282
1283 update_mb_fx_menu();
1284 update_mb_sto_menu();
1285 update_mb_units_menu();
1286 update_mb_pi_menu();
1287 update_mb_to_menu();
1288
1289 }
1290
create_main_window(void)1291 void create_main_window(void) {
1292
1293 main_builder = getBuilder("main.ui");
1294 g_assert(main_builder != NULL);
1295
1296 /* make sure we get a valid main window */
1297 g_assert(gtk_builder_get_object(main_builder, "main_window") != NULL);
1298
1299 mainwindow = GTK_WIDGET(gtk_builder_get_object(main_builder, "main_window"));
1300
1301 accel_group = gtk_accel_group_new();
1302 gtk_window_add_accel_group(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), accel_group);
1303
1304 if(win_width > 0) gtk_window_set_default_size(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), win_width, win_height > 0 ? win_height : -1);
1305
1306 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 16
1307 gtk_scrolled_window_set_overlay_scrolling(GTK_SCROLLED_WINDOW(gtk_builder_get_object(main_builder, "scrolled_result")), false);
1308 #endif
1309
1310 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 14
1311 if(!gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), "pan-start-symbolic")) {
1312 GtkWidget *arrow_left = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
1313 gtk_widget_set_size_request(GTK_WIDGET(arrow_left), 18, 18);
1314 gtk_widget_show(arrow_left);
1315 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object(main_builder, "image_hide_left_buttons")));
1316 gtk_container_add(GTK_CONTAINER(gtk_builder_get_object(main_builder, "event_hide_left_buttons")), arrow_left);
1317 }
1318 if(!gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), "pan-end-symbolic")) {
1319 GtkWidget *arrow_right = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT);
1320 gtk_widget_set_size_request(GTK_WIDGET(arrow_right), 18, 18);
1321 gtk_widget_show(arrow_right);
1322 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object(main_builder, "image_hide_right_buttons")));
1323 gtk_container_add(GTK_CONTAINER(gtk_builder_get_object(main_builder, "event_hide_right_buttons")), arrow_right);
1324 }
1325 gtk_grid_set_column_spacing(GTK_GRID(gtk_builder_get_object(main_builder, "grid_buttons")), 0);
1326 gtk_image_set_from_icon_name(GTK_IMAGE(gtk_builder_get_object(main_builder, "image_swap")), "object-flip-vertical-symbolic", GTK_ICON_SIZE_BUTTON);
1327 #endif
1328
1329 #ifdef _WIN32
1330 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_down_image")), 12);
1331 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_up_image")), 12);
1332 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_left_image")), 12);
1333 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_right_image")), 12);
1334 #else
1335 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_down_image")), 14);
1336 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_up_image")), 14);
1337 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_left_image")), 14);
1338 gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "button_right_image")), 14);
1339 #endif
1340
1341 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_sin")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_sin")));
1342 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_cos")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_cos")));
1343 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_tan")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_tan")));
1344 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_sqrt")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_sqrt")));
1345 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_e")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_e")));
1346 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_xequals")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_xequals")));
1347 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_ln")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_ln")));
1348 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_sum")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_sum")));
1349 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_mean")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_mean")));
1350 gtk_menu_button_set_align_widget(GTK_MENU_BUTTON(gtk_builder_get_object(main_builder, "mb_pi")), GTK_WIDGET(gtk_builder_get_object(main_builder, "box_pi")));
1351
1352 char **flags_r = g_resources_enumerate_children("/qalculate-gtk/flags", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
1353 if(flags_r) {
1354 for(size_t i = 0; flags_r[i] != NULL; i++) {
1355 string flag_s = flags_r[i];
1356 size_t i_ext = flag_s.find(".", 1);
1357 if(i_ext != string::npos) {
1358 GdkPixbuf *flagbuf = gdk_pixbuf_new_from_resource((string("/qalculate-gtk/flags/") + flag_s).c_str(), NULL);
1359 if(flagbuf) flag_images[flag_s.substr(0, i_ext)] = flagbuf;
1360 }
1361 }
1362 g_strfreev(flags_r);
1363 }
1364
1365 expressiontext = GTK_WIDGET(gtk_builder_get_object(main_builder, "expressiontext"));
1366 expressionbuffer = GTK_TEXT_BUFFER(gtk_builder_get_object(main_builder, "expressionbuffer"));
1367 resultview = GTK_WIDGET(gtk_builder_get_object(main_builder, "resultview"));
1368 historyview = GTK_WIDGET(gtk_builder_get_object(main_builder, "historyview"));
1369
1370 expression_undo_buffer.push_back("");
1371
1372 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 18
1373 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(expressiontext), 12);
1374 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(expressiontext), 6);
1375 gtk_text_view_set_top_margin(GTK_TEXT_VIEW(expressiontext), 6);
1376 gtk_text_view_set_bottom_margin(GTK_TEXT_VIEW(expressiontext), 6);
1377 #else
1378 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(expressiontext), 12);
1379 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(expressiontext), 6);
1380 gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(expressiontext), GTK_TEXT_WINDOW_TOP, 6);
1381 gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(expressiontext), GTK_TEXT_WINDOW_BOTTOM, 6);
1382 #endif
1383
1384 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION > 22 || (GTK_MINOR_VERSION == 22 && GTK_MICRO_VERSION >= 20)
1385 gtk_text_view_set_input_hints(GTK_TEXT_VIEW(expressiontext), GTK_INPUT_HINT_NO_EMOJI);
1386 #endif
1387
1388 stackview = GTK_WIDGET(gtk_builder_get_object(main_builder, "stackview"));
1389 statuslabel_l = GTK_WIDGET(gtk_builder_get_object(main_builder, "label_status_left"));
1390 statuslabel_r = GTK_WIDGET(gtk_builder_get_object(main_builder, "label_status_right"));
1391 result_bases = GTK_WIDGET(gtk_builder_get_object(main_builder, "label_result_bases"));
1392 keypad = GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons"));
1393 tabs = GTK_WIDGET(gtk_builder_get_object(main_builder, "tabs"));
1394
1395 gtk_widget_set_margin_top(GTK_WIDGET(gtk_builder_get_object(main_builder, "statusbox")), 2);
1396 gtk_widget_set_margin_bottom(GTK_WIDGET(gtk_builder_get_object(main_builder, "statusbox")), 3);
1397 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 12
1398 gtk_widget_set_margin_end(statuslabel_r, 12);
1399 gtk_widget_set_margin_start(statuslabel_l, 9);
1400 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "resultport")), 6);
1401 gtk_widget_set_margin_start(GTK_WIDGET(gtk_builder_get_object(main_builder, "resultport")), 6);
1402 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_equals")), 6);
1403 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_clear")), 6);
1404 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_stop")), 6);
1405 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "message_tooltip_icon")), 6);
1406 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_minimal_mode")), 6);
1407 #else
1408 gtk_widget_set_margin_right(statuslabel_r, 12);
1409 gtk_widget_set_margin_left(statuslabel_l, 9);
1410 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "resultport")), 6);
1411 gtk_widget_set_margin_left(GTK_WIDGET(gtk_builder_get_object(main_builder, "resultport")), 6);
1412 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_equals")), 6);
1413 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_clear")), 6);
1414 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_stop")), 6);
1415 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "message_tooltip_icon")), 6);
1416 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_minimal_mode")), 6);
1417 #endif
1418
1419 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 16
1420 gtk_label_set_xalign(GTK_LABEL(statuslabel_l), 0.0);
1421 gtk_label_set_xalign(GTK_LABEL(result_bases), 1.0);
1422 gtk_label_set_yalign(GTK_LABEL(result_bases), 0.5);
1423 gtk_label_set_yalign(GTK_LABEL(statuslabel_l), 0.5);
1424 gtk_label_set_yalign(GTK_LABEL(statuslabel_r), 0.5);
1425 #else
1426 gtk_misc_set_alignment(GTK_MISC(statuslabel_l), 0.0, 0.5);
1427 gtk_misc_set_alignment(GTK_MISC(result_bases), 1.0, 0.5);
1428 #endif
1429
1430 expression_provider = gtk_css_provider_new();
1431 resultview_provider = gtk_css_provider_new();
1432 statuslabel_l_provider = gtk_css_provider_new();
1433 statuslabel_r_provider = gtk_css_provider_new();
1434 keypad_provider = gtk_css_provider_new();
1435 box_rpnl_provider = gtk_css_provider_new();
1436 app_provider = gtk_css_provider_new();
1437 gtk_style_context_add_provider(gtk_widget_get_style_context(expressiontext), GTK_STYLE_PROVIDER(expression_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1438 gtk_style_context_add_provider(gtk_widget_get_style_context(resultview), GTK_STYLE_PROVIDER(resultview_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1439 gtk_style_context_add_provider(gtk_widget_get_style_context(statuslabel_l), GTK_STYLE_PROVIDER(statuslabel_l_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1440 gtk_style_context_add_provider(gtk_widget_get_style_context(statuslabel_r), GTK_STYLE_PROVIDER(statuslabel_r_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1441 gtk_style_context_add_provider(gtk_widget_get_style_context(keypad), GTK_STYLE_PROVIDER(keypad_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1442 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_rpnl"))), GTK_STYLE_PROVIDER(box_rpnl_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1443 gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(app_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1444
1445 topframe_provider = gtk_css_provider_new();
1446 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "topframe"))), GTK_STYLE_PROVIDER(topframe_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1447 string topframe_css = "* {background-color: ";
1448 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 16
1449 GdkRGBA bg_color;
1450 gtk_style_context_get_background_color(gtk_widget_get_style_context(expressiontext), GTK_STATE_FLAG_NORMAL, &bg_color);
1451 gchar *gstr = gdk_rgba_to_string(&bg_color);
1452 topframe_css += gstr;
1453 g_free(gstr);
1454 #else
1455 topframe_css += "@theme_base_color;";
1456 #endif
1457 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 18
1458 GtkCssProvider *expressionborder_provider = gtk_css_provider_new();
1459 gtk_style_context_add_provider(gtk_widget_get_style_context(expressiontext), GTK_STYLE_PROVIDER(expressionborder_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1460 string border_css = topframe_css; border_css += ";}";
1461 gsub("*", "textview.view > border", border_css);
1462 gtk_css_provider_load_from_data(expressionborder_provider, border_css.c_str(), -1, NULL);
1463 #endif
1464 topframe_css += "; border-left-width: 0; border-right-width: 0; border-radius: 0;}";
1465 gtk_css_provider_load_from_data(topframe_provider, topframe_css.c_str(), -1, NULL);
1466 statusframe_provider = gtk_css_provider_new();
1467 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "statusframe"))), GTK_STYLE_PROVIDER(statusframe_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1468 gtk_css_provider_load_from_data(statusframe_provider, topframe_css.c_str(), -1, NULL);
1469
1470 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 16
1471 # ifdef _WIN32
1472 app_provider_theme = gtk_css_provider_new();
1473 gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(app_provider_theme), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1474 if(use_dark_theme > 0) gtk_css_provider_load_from_resource(app_provider_theme, "/org/gtk/libgtk/theme/Adwaita/gtk-contained-dark.css");
1475 else if(use_dark_theme == 0) gtk_css_provider_load_from_resource(app_provider_theme, "/org/gtk/libgtk/theme/Adwaita/gtk-contained.css");
1476 # endif
1477 #endif
1478
1479 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 12
1480 gtk_widget_set_margin_start(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_result_bases")), 6);
1481 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_result_bases")), 6);
1482 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "convert_label_unit")), 12);
1483 gtk_widget_set_margin_start(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_tabs")), 12);
1484 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_tabs")), 12);
1485 #else
1486 gtk_widget_set_margin_left(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_result_bases")), 6);
1487 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_result_bases")), 6);
1488 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "convert_label_unit")), 12);
1489 gtk_widget_set_margin_left(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_tabs")), 12);
1490 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_tabs")), 12);
1491 #endif
1492 gtk_widget_set_margin_bottom(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_tabs")), 9);
1493 gtk_widget_set_margin_bottom(tabs, 3);
1494 gtk_widget_set_margin_bottom(keypad, 3);
1495
1496 if(visible_keypad & PROGRAMMING_KEYPAD) {
1497 gtk_stack_set_visible_child(GTK_STACK(gtk_builder_get_object(main_builder, "stack_left_buttons")), GTK_WIDGET(gtk_builder_get_object(main_builder, "programmers_keypad")));
1498 gtk_stack_set_visible_child_name(GTK_STACK(gtk_builder_get_object(main_builder, "stack_keypad_top")), "page1");
1499 }
1500
1501 if(visible_keypad & HIDE_LEFT_KEYPAD) {
1502 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "stack_left_buttons")));
1503 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "event_hide_right_buttons")));
1504 } else if(visible_keypad & HIDE_RIGHT_KEYPAD) {
1505 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_right_buttons")));
1506 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "event_hide_left_buttons")));
1507 }
1508
1509 set_mode_items(printops, evalops, CALCULATOR->defaultAssumptions()->type(), CALCULATOR->defaultAssumptions()->sign(), rpn_mode, CALCULATOR->getPrecision(), CALCULATOR->usesIntervalArithmetic(), CALCULATOR->variableUnitsEnabled(), adaptive_interval_display, visible_keypad, auto_calculate, chain_mode, complex_angle_form, true);
1510
1511 if(use_custom_app_font) {
1512 gchar *gstr = font_name_to_css(custom_app_font.c_str());
1513 gtk_css_provider_load_from_data(app_provider, gstr, -1, NULL);
1514 g_free(gstr);
1515 } else {
1516 if(custom_app_font.empty()) {
1517 PangoFontDescription *font_desc;
1518 gtk_style_context_get(gtk_widget_get_style_context(mainwindow), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
1519 custom_app_font = pango_font_description_to_string(font_desc);
1520 pango_font_description_free(font_desc);
1521 }
1522 }
1523 if(use_custom_result_font) {
1524 gchar *gstr = font_name_to_css(custom_result_font.c_str());
1525 gtk_css_provider_load_from_data(resultview_provider, gstr, -1, NULL);
1526 g_free(gstr);
1527 } else {
1528 gtk_css_provider_load_from_data(resultview_provider, "* {font-size: larger;}", -1, NULL);
1529 if(custom_result_font.empty()) {
1530 PangoFontDescription *font_desc;
1531 gtk_style_context_get(gtk_widget_get_style_context(resultview), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
1532 custom_result_font = pango_font_description_to_string(font_desc);
1533 pango_font_description_free(font_desc);
1534 }
1535 }
1536 if(use_custom_expression_font) {
1537 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 20
1538 gchar *gstr = font_name_to_css(custom_expression_font.c_str(), "textview.view");
1539 #else
1540 gchar *gstr = font_name_to_css(custom_expression_font.c_str());
1541 #endif
1542 gtk_css_provider_load_from_data(expression_provider, gstr, -1, NULL);
1543 g_free(gstr);
1544 } else {
1545 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 20
1546 gtk_css_provider_load_from_data(expression_provider, "textview.view {font-size: larger;}", -1, NULL);
1547 #else
1548 gtk_css_provider_load_from_data(expression_provider, "* {font-size: larger;}", -1, NULL);
1549 #endif
1550 if(custom_expression_font.empty()) {
1551 PangoFontDescription *font_desc;
1552 gtk_style_context_get(gtk_widget_get_style_context(expressiontext), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
1553 custom_expression_font = pango_font_description_to_string(font_desc);
1554 pango_font_description_free(font_desc);
1555 }
1556 }
1557 if(use_custom_status_font) {
1558 gchar *gstr = font_name_to_css(custom_status_font.c_str());
1559 gtk_css_provider_load_from_data(statuslabel_l_provider, gstr, -1, NULL);
1560 gtk_css_provider_load_from_data(statuslabel_r_provider, gstr, -1, NULL);
1561 g_free(gstr);
1562 } else {
1563 gtk_css_provider_load_from_data(statuslabel_l_provider, "* {font-size: 90%;}", -1, NULL);
1564 gtk_css_provider_load_from_data(statuslabel_r_provider, "* {font-size: 90%;}", -1, NULL);
1565 if(custom_status_font.empty()) {
1566 PangoFontDescription *font_desc;
1567 gtk_style_context_get(gtk_widget_get_style_context(statuslabel_l), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
1568 custom_status_font = pango_font_description_to_string(font_desc);
1569 pango_font_description_free(font_desc);
1570 }
1571 }
1572 if(use_custom_keypad_font) {
1573 gchar *gstr = font_name_to_css(custom_keypad_font.c_str());
1574 gtk_css_provider_load_from_data(keypad_provider, gstr, -1, NULL);
1575 gtk_css_provider_load_from_data(box_rpnl_provider, gstr, -1, NULL);
1576 g_free(gstr);
1577 } else {
1578 if(custom_keypad_font.empty()) {
1579 PangoFontDescription *font_desc;
1580 gtk_style_context_get(gtk_widget_get_style_context(keypad), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
1581 custom_keypad_font = pango_font_description_to_string(font_desc);
1582 pango_font_description_free(font_desc);
1583 }
1584 }
1585
1586 update_status_text();
1587
1588 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 14
1589
1590 gint scalefactor = gtk_widget_get_scale_factor(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_equals")));
1591 cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 16 * scalefactor, 16 * scalefactor);
1592 cairo_surface_set_device_scale(surface, scalefactor, scalefactor);
1593 cairo_t *cr = cairo_create(surface);
1594 GdkRGBA rgba;
1595 gtk_style_context_get_color(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_equals"))), GTK_STATE_FLAG_NORMAL, &rgba);
1596
1597 PangoLayout *layout_equals = gtk_widget_create_pango_layout(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button_equals")), "=");
1598 PangoFontDescription *font_desc;
1599 gtk_style_context_get(gtk_widget_get_style_context(expressiontext), GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
1600 pango_font_description_set_weight(font_desc, PANGO_WEIGHT_MEDIUM);
1601 pango_font_description_set_absolute_size(font_desc, PANGO_SCALE * 26);
1602 pango_layout_set_font_description(layout_equals, font_desc);
1603
1604 PangoRectangle rect, lrect;
1605 pango_layout_get_pixel_extents(layout_equals, &rect, &lrect);
1606 if(rect.width >= 16) {
1607 pango_font_description_set_absolute_size(font_desc, PANGO_SCALE * 18);
1608 pango_layout_set_font_description(layout_equals, font_desc);
1609 pango_layout_get_pixel_extents(layout_equals, &rect, &lrect);
1610 }
1611
1612 pango_font_description_free(font_desc);
1613
1614 double offset_x = (rect.x - (lrect.width - (rect.x + rect.width))) / 2.0, offset_y = (rect.y - (lrect.height - (rect.y + rect.height))) / 2.0;
1615 cairo_move_to(cr, (16 - lrect.width) / 2.0 - offset_x, (16 - lrect.height) / 2.0 - offset_y);
1616 gdk_cairo_set_source_rgba(cr, &rgba);
1617 pango_cairo_show_layout(cr, layout_equals);
1618 g_object_unref(layout_equals);
1619 cairo_destroy(cr);
1620 gtk_image_set_from_surface(GTK_IMAGE(gtk_builder_get_object(main_builder, "expression_button_equals")), surface);
1621 cairo_surface_destroy(surface);
1622
1623 #endif
1624
1625 set_unicode_buttons();
1626
1627 set_operator_symbols();
1628 GdkRGBA c;
1629 gtk_style_context_get_color(gtk_widget_get_style_context(statuslabel_l), GTK_STATE_FLAG_NORMAL, &c);
1630 if(!status_error_color_set) {
1631 GdkRGBA c_err = c;
1632 if(c_err.red >= 0.8) {
1633 c_err.green /= 1.5;
1634 c_err.blue /= 1.5;
1635 c_err.red = 1.0;
1636 } else {
1637 if(c_err.red >= 0.5) c_err.red = 1.0;
1638 else c_err.red += 0.5;
1639 }
1640 gchar ecs[8];
1641 g_snprintf(ecs, 8, "#%02x%02x%02x", (int) (c_err.red * 255), (int) (c_err.green * 255), (int) (c_err.blue * 255));
1642 status_error_color = ecs;
1643 }
1644
1645 if(!status_warning_color_set) {
1646 GdkRGBA c_warn = c;
1647 if(c_warn.blue >= 0.8) {
1648 c_warn.green /= 1.5;
1649 c_warn.red /= 1.5;
1650 c_warn.blue = 1.0;
1651 } else {
1652 if(c_warn.blue >= 0.3) c_warn.blue = 1.0;
1653 else c_warn.blue += 0.7;
1654 }
1655 gchar wcs[8];
1656 g_snprintf(wcs, 8, "#%02x%02x%02x", (int) (c_warn.red * 255), (int) (c_warn.green * 255), (int) (c_warn.blue * 255));
1657 status_warning_color = wcs;
1658 }
1659
1660 gtk_style_context_get_color(gtk_widget_get_style_context(expressiontext), GTK_STATE_FLAG_NORMAL, &c);
1661 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 16
1662 if(gdk_rgba_equal(&c, &bg_color)) {
1663 gtk_style_context_get_color(gtk_widget_get_style_context(statuslabel_l), GTK_STATE_FLAG_NORMAL, &c);
1664 }
1665 #endif
1666 if(c.green >= 0.8) {
1667 c.red /= 1.5;
1668 c.blue /= 1.5;
1669 c.green = 1.0;
1670 } else {
1671 if(c.green >= 0.5) c.green = 1.0;
1672 else c.green += 0.5;
1673 }
1674 PangoLayout *layout_par = gtk_widget_create_pango_layout(expressiontext, "()");
1675 gint w1 = 0, w2 = 0;
1676 pango_layout_get_pixel_size(layout_par, &w1, NULL);
1677 pango_layout_set_markup(layout_par, "<b>()</b>", -1);
1678 pango_layout_get_pixel_size(layout_par, &w2, NULL);
1679 g_object_unref(layout_par);
1680 if(w1 == w2) expression_par_tag = gtk_text_buffer_create_tag(expressionbuffer, "curpar", "foreground-rgba", &c, "weight", PANGO_WEIGHT_BOLD, NULL);
1681 else expression_par_tag = gtk_text_buffer_create_tag(expressionbuffer, "curpar", "foreground-rgba", &c, NULL);
1682
1683 gtk_widget_grab_focus(expressiontext);
1684 gtk_widget_set_can_default(expressiontext, TRUE);
1685 gtk_widget_grab_default(expressiontext);
1686
1687 expander_keypad = GTK_WIDGET(gtk_builder_get_object(main_builder, "expander_keypad"));
1688 expander_history = GTK_WIDGET(gtk_builder_get_object(main_builder, "expander_history"));
1689 expander_stack = GTK_WIDGET(gtk_builder_get_object(main_builder, "expander_stack"));
1690 expander_convert = GTK_WIDGET(gtk_builder_get_object(main_builder, "expander_convert"));
1691
1692 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_hi")), !persistent_keypad);
1693 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_rpnl")), !persistent_keypad || (show_stack && rpn_mode));
1694 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_rpnr")), !persistent_keypad || (show_stack && rpn_mode));
1695 if(history_height > 0) gtk_widget_set_size_request(tabs, -1, history_height);
1696 if(show_stack && rpn_mode) {
1697 gtk_expander_set_expanded(GTK_EXPANDER(expander_stack), TRUE);
1698 gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs), 1);
1699 gtk_widget_show(tabs);
1700 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons")));
1701 } else if(show_keypad && !persistent_keypad) {
1702 gtk_expander_set_expanded(GTK_EXPANDER(expander_keypad), TRUE);
1703 gtk_widget_hide(tabs);
1704 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons")));
1705 } else if(show_history) {
1706 gtk_expander_set_expanded(GTK_EXPANDER(expander_history), TRUE);
1707 gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs), 0);
1708 gtk_widget_show(tabs);
1709 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons")));
1710 } else if(show_convert) {
1711 gtk_expander_set_expanded(GTK_EXPANDER(expander_convert), TRUE);
1712 gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs), 2);
1713 gtk_widget_show(tabs);
1714 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons")));
1715 } else {
1716 gtk_widget_hide(tabs);
1717 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons")));
1718 gtk_widget_set_vexpand(resultview, TRUE);
1719 }
1720 if(persistent_keypad) {
1721 if(show_keypad) {
1722 gtk_expander_set_expanded(GTK_EXPANDER(expander_keypad), TRUE);
1723 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons")));
1724 gtk_widget_set_vexpand(resultview, FALSE);
1725 }
1726 gtk_image_set_from_icon_name(GTK_IMAGE(gtk_builder_get_object(main_builder, "image_keypad_lock")), "changes-prevent-symbolic", GTK_ICON_SIZE_BUTTON);
1727 if(show_convert) gtk_widget_set_margin_bottom(GTK_WIDGET(gtk_builder_get_object(main_builder, "convert")), 6);
1728 }
1729 GtkRequisition req;
1730 gtk_widget_get_preferred_size(GTK_WIDGET(gtk_builder_get_object(main_builder, "label_keypad")), &req, NULL);
1731 if(req.height < 20) gtk_image_set_pixel_size(GTK_IMAGE(gtk_builder_get_object(main_builder, "image_keypad_lock")), req.height * 0.8);
1732 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_builder_get_object(main_builder, "popup_menu_item_persistent_keypad")), persistent_keypad);
1733 gtk_widget_set_vexpand(GTK_WIDGET(gtk_builder_get_object(main_builder, "buttons")), !persistent_keypad || !gtk_widget_get_visible(tabs));
1734
1735 if(minimal_mode) {
1736 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_tabs")));
1737 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "menubar")));
1738 set_status_bottom_border_visible(false);
1739 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "resultoverlay")));
1740 gtk_widget_set_vexpand(GTK_WIDGET(gtk_builder_get_object(main_builder, "expressionscrolled")), TRUE);
1741 gtk_widget_set_vexpand(resultview, FALSE);
1742 }
1743 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_minimal_mode")), minimal_mode);
1744
1745 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "convert_button_continuous_conversion")), continuous_conversion);
1746 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(main_builder, "convert_button_set_missing_prefixes")), set_missing_prefixes);
1747
1748 #if GTK_MAJOR_VERSION <= 3 && GTK_MINOR_VERSION < 20
1749 # define SET_FOCUS_ON_CLICK(x) gtk_button_set_focus_on_click(GTK_BUTTON(x), FALSE)
1750 #else
1751 # define SET_FOCUS_ON_CLICK(x) gtk_widget_set_focus_on_click(GTK_WIDGET(x), FALSE)
1752 #endif
1753 #define CHILDREN_SET_FOCUS_ON_CLICK(x) list = gtk_container_get_children(GTK_CONTAINER(gtk_builder_get_object(main_builder, x))); \
1754 for(l = list; l != NULL; l = l->next) { \
1755 SET_FOCUS_ON_CLICK(l->data); \
1756 } \
1757 g_list_free(list);
1758 #define CHILDREN_SET_FOCUS_ON_CLICK_2(x, y) list = gtk_container_get_children(GTK_CONTAINER(gtk_builder_get_object(main_builder, x))); \
1759 obj = gtk_builder_get_object(main_builder, y); \
1760 for(l = list; l != NULL; l = l->next) { \
1761 if(l->data != obj) SET_FOCUS_ON_CLICK(l->data); \
1762 } \
1763 g_list_free(list);
1764
1765 GList *l, *l2;
1766 GList *list, *list2;
1767 GObject *obj;
1768 CHILDREN_SET_FOCUS_ON_CLICK_2("table_buttons", "grid_numbers")
1769 CHILDREN_SET_FOCUS_ON_CLICK("box_custom_buttons")
1770 CHILDREN_SET_FOCUS_ON_CLICK("grid_numbers")
1771 CHILDREN_SET_FOCUS_ON_CLICK("grid_programmers_buttons")
1772 CHILDREN_SET_FOCUS_ON_CLICK("box_bases")
1773 CHILDREN_SET_FOCUS_ON_CLICK("box_twos")
1774 CHILDREN_SET_FOCUS_ON_CLICK("historyactions")
1775 SET_FOCUS_ON_CLICK(gtk_builder_get_object(main_builder, "button_history_copy"));
1776 CHILDREN_SET_FOCUS_ON_CLICK("box_ho")
1777 CHILDREN_SET_FOCUS_ON_CLICK("box_rm")
1778 CHILDREN_SET_FOCUS_ON_CLICK("box_re")
1779 SET_FOCUS_ON_CLICK(gtk_builder_get_object(main_builder, "button_clearstack"));
1780 SET_FOCUS_ON_CLICK(gtk_builder_get_object(main_builder, "button_editregister"));
1781 CHILDREN_SET_FOCUS_ON_CLICK("box_ro1")
1782 CHILDREN_SET_FOCUS_ON_CLICK("box_ro2")
1783 SET_FOCUS_ON_CLICK(gtk_builder_get_object(main_builder, "button_rpn_sum"));
1784 list = gtk_container_get_children(GTK_CONTAINER(gtk_builder_get_object(main_builder, "versatile_keypad")));
1785 for(l = list; l != NULL; l = l->next) {
1786 list2 = gtk_container_get_children(GTK_CONTAINER(l->data));
1787 for(l2 = list2; l2 != NULL; l2 = l2->next) {
1788 SET_FOCUS_ON_CLICK(l2->data);
1789 }
1790 g_list_free(list2);
1791 }
1792 g_list_free(list);
1793
1794 gchar *theme_name = NULL;
1795 g_object_get(gtk_settings_get_default(), "gtk-theme-name", &theme_name, NULL);
1796 string themestr;
1797 if(theme_name) themestr = theme_name;
1798
1799 GtkCssProvider *notification_style = gtk_css_provider_new(); gtk_css_provider_load_from_data(notification_style, "* {border-radius: 5px}", -1, NULL);
1800 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "overlaybox"))), GTK_STYLE_PROVIDER(notification_style), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1801
1802 if(themestr.substr(0, 7) == "Adwaita" || themestr.substr(0, 6) == "ooxmox" || themestr == "Breeze" || themestr == "Breeze-Dark" || themestr.substr(0, 4) == "Yaru") {
1803
1804 GtkCssProvider *link_style_top = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_top, "* {border-bottom-left-radius: 0; border-bottom-right-radius: 0;}", -1, NULL);
1805 GtkCssProvider *link_style_bot = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_bot, "* {border-top-left-radius: 0; border-top-right-radius: 0;}", -1, NULL);
1806 GtkCssProvider *link_style_tl = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_tl, "* {border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-top-right-radius: 0;}", -1, NULL);
1807 GtkCssProvider *link_style_tr = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_tr, "* {border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-top-left-radius: 0;}", -1, NULL);
1808 GtkCssProvider *link_style_bl = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_bl, "* {border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-right-radius: 0;}", -1, NULL);
1809 GtkCssProvider *link_style_br = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_br, "* {border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-left-radius: 0;}", -1, NULL);
1810 GtkCssProvider *link_style_mid = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_mid, "* {border-radius: 0;}", -1, NULL);
1811
1812 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_zero"))), GTK_STYLE_PROVIDER(link_style_bl), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1813 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_dot"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1814 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_exp"))), GTK_STYLE_PROVIDER(link_style_br), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1815 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_one"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1816 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_two"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1817 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_three"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1818 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_four"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1819 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_five"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1820 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_six"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1821 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_seven"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1822 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_eight"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1823 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_nine"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1824 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_brace_open"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1825 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_brace_close"))), GTK_STYLE_PROVIDER(link_style_tr), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1826 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_brace_wrap"))), GTK_STYLE_PROVIDER(link_style_tl), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1827 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_comma"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1828 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_move"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1829 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_move2"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1830 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_percent"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1831 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_plusminus"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1832 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_xy"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1833 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_divide"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1834 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_times"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1835 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_sub"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1836 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_add"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1837 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_ac"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1838 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_del"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1839 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_ans"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1840 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_equals"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1841 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_c1"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1842 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_c2"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1843 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_c3"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1844 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_c4"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1845 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_c5"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1846
1847 if(themestr == "Breeze" || themestr == "Breeze-Dark") {
1848
1849 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_ro1"))), "linked");
1850 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_ro2"))), "linked");
1851 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_rm"))), "linked");
1852 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_re"))), "linked");
1853 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_hi"))), "linked");
1854 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_ho"))), "linked");
1855
1856 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_insert_value"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1857 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_insert_text"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1858 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_add"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1859 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_sub"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1860 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_times"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1861 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_divide"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1862 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_xy"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1863 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_history_sqrt"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1864
1865 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_add"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1866 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_sub"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1867 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_times"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1868 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_divide"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1869 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_xy"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1870 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_negate"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1871 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_reciprocal"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1872 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_rpn_sqrt"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1873 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_registerup"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1874 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_registerdown"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1875 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_registerswap"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1876 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_copyregister"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1877 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_lastx"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1878 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_deleteregister"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1879 }
1880 }
1881
1882 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_custom_buttons")), custom_buttons[29].type[0] >= 0 || custom_buttons[29].type[1] >= 0 || custom_buttons[29].type[2] >= 0 || custom_buttons[30].type[0] >= 0 || custom_buttons[30].type[1] >= 0 || custom_buttons[30].type[2] >= 0 || custom_buttons[31].type[0] >= 0 || custom_buttons[31].type[1] >= 0 || custom_buttons[31].type[2] >= 0 || custom_buttons[32].type[0] >= 0 || custom_buttons[32].type[1] >= 0 || custom_buttons[32].type[2] >= 0 || custom_buttons[33].type[0] >= 0 || custom_buttons[33].type[1] >= 0 || custom_buttons[33].type[2] >= 0);
1883
1884 if(!gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), "document-edit-symbolic")) {
1885 gtk_image_set_from_icon_name(GTK_IMAGE(gtk_builder_get_object(main_builder, "image_edit")), "gtk-edit", GTK_ICON_SIZE_BUTTON);
1886 #if GTK_MAJOR_VERSION <= 3 && GTK_MINOR_VERSION <= 18
1887 if(themestr == "Ambiance" || themestr == "Radiance") {
1888 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_re"))), "linked");
1889 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_rm"))), "linked");
1890 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_ro1"))), "linked");
1891 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_ro2"))), "linked");
1892 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "historyactions"))), "linked");
1893 gtk_style_context_remove_class(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "box_ho"))), "linked");
1894 }
1895 #endif
1896 }
1897
1898 gtk_builder_connect_signals(main_builder, NULL);
1899
1900 gtk_style_context_get_color(gtk_widget_get_style_context(historyview), GTK_STATE_FLAG_NORMAL, &c);
1901 GdkRGBA c_red = c;
1902 if(c_red.red >= 0.8) {
1903 c_red.green /= 1.5;
1904 c_red.blue /= 1.5;
1905 c_red.red = 1.0;
1906 } else {
1907 if(c_red.red >= 0.5) c_red.red = 1.0;
1908 else c_red.red += 0.5;
1909 }
1910 g_snprintf(history_error_color, 8, "#%02x%02x%02x", (int) (c_red.red * 255), (int) (c_red.green * 255), (int) (c_red.blue * 255));
1911
1912 GdkRGBA c_blue = c;
1913 if(c_blue.blue >= 0.8) {
1914 c_blue.green /= 1.5;
1915 c_blue.red /= 1.5;
1916 c_blue.blue = 1.0;
1917 } else {
1918 if(c_blue.blue >= 0.4) c_blue.blue = 1.0;
1919 else c_blue.blue += 0.6;
1920 }
1921 g_snprintf(history_warning_color, 8, "#%02x%02x%02x", (int) (c_blue.red * 255), (int) (c_blue.green * 255), (int) (c_blue.blue * 255));
1922
1923 GdkRGBA c_green = c;
1924 if(c_green.green >= 0.8) {
1925 c_green.blue /= 1.5;
1926 c_green.red /= 1.5;
1927 c_green.green = 0.8;
1928 } else {
1929 if(c_green.green >= 0.4) c_green.green = 0.8;
1930 else c_green.green += 0.4;
1931 }
1932 g_snprintf(history_bookmark_color, 8, "#%02x%02x%02x", (int) (c_green.red * 255), (int) (c_green.green * 255), (int) (c_green.blue * 255));
1933
1934 GdkRGBA c_gray = c;
1935 if(c_gray.blue + c_gray.green + c_gray.red > 1.5) {
1936 c_gray.green /= 1.5;
1937 c_gray.red /= 1.5;
1938 c_gray.blue /= 1.5;
1939 } else if(c_gray.blue + c_gray.green + c_gray.red > 0.3) {
1940 c_gray.green += 0.235;
1941 c_gray.red += 0.235;
1942 c_gray.blue += 0.235;
1943 } else if(c_gray.blue + c_gray.green + c_gray.red > 0.15) {
1944 c_gray.green += 0.3;
1945 c_gray.red += 0.3;
1946 c_gray.blue += 0.3;
1947 } else {
1948 c_gray.green += 0.4;
1949 c_gray.red += 0.4;
1950 c_gray.blue += 0.4;
1951 }
1952 g_snprintf(history_parse_color, 8, "#%02x%02x%02x", (int) (c_gray.red * 255), (int) (c_gray.green * 255), (int) (c_gray.blue * 255));
1953
1954 historystore = gtk_list_store_new(8, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_FLOAT, G_TYPE_INT);
1955 gtk_tree_view_set_model(GTK_TREE_VIEW(historyview), GTK_TREE_MODEL(historystore));
1956 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(historyview));
1957 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
1958 history_index_renderer = gtk_cell_renderer_text_new();
1959 history_index_column = gtk_tree_view_column_new_with_attributes(_("Index"), history_index_renderer, "text", 2, "ypad", 4, NULL);
1960 gtk_tree_view_column_set_expand(history_index_column, FALSE);
1961 gtk_tree_view_column_set_min_width(history_index_column, 30);
1962 g_object_set(G_OBJECT(history_index_renderer), "ypad", 0, "yalign", 0.0, "xalign", 0.5, "foreground-rgba", &c_gray, NULL);
1963 gtk_tree_view_append_column(GTK_TREE_VIEW(historyview), history_index_column);
1964 history_renderer = gtk_cell_renderer_text_new();
1965 history_column = gtk_tree_view_column_new_with_attributes(_("History"), history_renderer, "markup", 0, "ypad", 4, "xpad", 5, "xalign", 6, "alignment", 7, NULL);
1966 gtk_tree_view_column_set_expand(history_column, TRUE);
1967 GtkWidget *scrollbar = gtk_scrolled_window_get_vscrollbar(GTK_SCROLLED_WINDOW(gtk_builder_get_object(main_builder, "historyscrolled")));
1968 if(scrollbar) gtk_widget_get_preferred_width(scrollbar, NULL, &history_scroll_width);
1969 if(history_scroll_width == 0) history_scroll_width = 3;
1970 history_scroll_width += 1;
1971 gtk_tree_view_append_column(GTK_TREE_VIEW(historyview), history_column);
1972 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_historyview_selection_changed), NULL);
1973 gtk_tree_view_set_row_separator_func(GTK_TREE_VIEW(historyview), history_row_separator_func, NULL, NULL);
1974
1975 completion_view = GTK_WIDGET(gtk_builder_get_object(main_builder, "completionview"));
1976 gtk_style_context_add_provider(gtk_widget_get_style_context(completion_view), GTK_STYLE_PROVIDER(expression_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1977
1978 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 20
1979
1980 // Fix for breeze-gtk and Ubuntu theme
1981 if(themestr.substr(0, 7) != "Adwaita" && themestr.substr(0, 6) != "ooxmox" && themestr != "Yaru") {
1982 GtkCssProvider *historyview_provider = gtk_css_provider_new();
1983 gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(historyview), GTK_TREE_VIEW_GRID_LINES_NONE);
1984 gtk_style_context_add_provider(gtk_widget_get_style_context(historyview), GTK_STYLE_PROVIDER(historyview_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1985 GtkCssProvider *expression_provider2 = gtk_css_provider_new();
1986 gtk_style_context_add_provider(gtk_widget_get_style_context(completion_view), GTK_STYLE_PROVIDER(expression_provider2), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1987 if(themestr == "Breeze") {
1988 gtk_css_provider_load_from_data(historyview_provider, "treeview.view {-GtkTreeView-horizontal-separator: 0;}\ntreeview.view.separator {min-height: 2px; color: #cecece;}", -1, NULL);
1989 gtk_css_provider_load_from_data(expression_provider2, "treeview.view {-GtkTreeView-horizontal-separator: 0;}\ntreeview.view.separator {min-height: 2px; color: #cecece;}", -1, NULL);
1990 } else if(themestr == "Breeze-Dark") {
1991 gtk_css_provider_load_from_data(historyview_provider, "treeview.view {-GtkTreeView-horizontal-separator: 0;}\ntreeview.view.separator {min-height: 2px; color: #313131;}", -1, NULL);
1992 gtk_css_provider_load_from_data(expression_provider2, "treeview.view {-GtkTreeView-horizontal-separator: 0;}\ntreeview.view.separator {min-height: 2px; color: #313131;}", -1, NULL);
1993 } else {
1994 gtk_css_provider_load_from_data(historyview_provider, "treeview.view {-GtkTreeView-horizontal-separator: 0;}\ntreeview.view.separator {min-height: 2px;}", -1, NULL);
1995 gtk_css_provider_load_from_data(expression_provider2, "treeview.view {-GtkTreeView-horizontal-separator: 0;}\ntreeview.view.separator {min-height: 2px;}", -1, NULL);
1996 }
1997 }
1998
1999 #endif
2000
2001 if(theme_name) g_free(theme_name);
2002
2003 stackstore = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
2004 gtk_tree_view_set_model(GTK_TREE_VIEW(stackview), GTK_TREE_MODEL(stackstore));
2005 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(stackview));
2006 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2007 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
2008 g_object_set (G_OBJECT(renderer), "xalign", 0.5, NULL);
2009 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Index"), renderer, "text", 0, NULL);
2010 gtk_tree_view_append_column(GTK_TREE_VIEW(stackview), column);
2011 register_renderer = gtk_cell_renderer_text_new();
2012 g_object_set(G_OBJECT(register_renderer), "editable", TRUE, "ellipsize", PANGO_ELLIPSIZE_END, "xalign", 1.0, "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL);
2013 g_signal_connect((gpointer) register_renderer, "edited", G_CALLBACK(on_stackview_item_edited), NULL);
2014 g_signal_connect((gpointer) register_renderer, "editing-started", G_CALLBACK(on_stackview_item_editing_started), NULL);
2015 g_signal_connect((gpointer) register_renderer, "editing-canceled", G_CALLBACK(on_stackview_item_editing_canceled), NULL);
2016 register_column = gtk_tree_view_column_new_with_attributes(_("Value"), register_renderer, "text", 1, NULL);
2017 gtk_tree_view_append_column(GTK_TREE_VIEW(stackview), register_column);
2018 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_stackview_selection_changed), NULL);
2019 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(stackview), TRUE);
2020 g_signal_connect((gpointer) stackstore, "row-deleted", G_CALLBACK(on_stackstore_row_deleted), NULL);
2021 g_signal_connect((gpointer) stackstore, "row-inserted", G_CALLBACK(on_stackstore_row_inserted), NULL);
2022
2023 if(rpn_mode) {
2024 gtk_label_set_angle(GTK_LABEL(gtk_builder_get_object(main_builder, "label_equals")), 90.0);
2025 // RPN Enter (calculate and add to stack)
2026 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(main_builder, "label_equals")), _("ENTER"));
2027 gtk_widget_set_tooltip_text(GTK_WIDGET(gtk_builder_get_object(main_builder, "button_equals")), _("Calculate expression and add to stack"));
2028 gtk_widget_set_tooltip_text(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button")), _("Calculate expression and add to stack"));
2029 } else {
2030 gtk_widget_hide(expander_stack);
2031 }
2032
2033 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_item_save_image")), FALSE);
2034 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(main_builder, "popup_menu_item_save_image")), FALSE);
2035
2036 /* Completion */
2037 completion_scrolled = GTK_WIDGET(gtk_builder_get_object(main_builder, "completionscrolled"));
2038 gtk_widget_set_size_request(gtk_scrolled_window_get_vscrollbar(GTK_SCROLLED_WINDOW(completion_scrolled)), -1, 0);
2039 completion_window = GTK_WIDGET(gtk_builder_get_object(main_builder, "completionwindow"));
2040 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 20
2041 GtkCssProvider *completion_provider = gtk_css_provider_new();
2042 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(main_builder, "completionview"))), GTK_STYLE_PROVIDER(completion_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
2043 gtk_css_provider_load_from_data(completion_provider, "* {font-size: medium;}", -1, NULL);
2044 #endif
2045 completion_store = gtk_list_store_new(9, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_UINT, G_TYPE_INT);
2046 completion_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(completion_store), NULL);
2047 gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(completion_filter), 3);
2048 completion_sort = gtk_tree_model_sort_new_with_model(completion_filter);
2049 gtk_tree_view_set_model(GTK_TREE_VIEW(completion_view), completion_sort);
2050 gtk_tree_view_set_row_separator_func(GTK_TREE_VIEW(completion_view), completion_row_separator_func, NULL, NULL);
2051
2052 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2053 renderer = gtk_cell_renderer_text_new();
2054 GtkCellArea *area = gtk_cell_area_box_new();
2055 gtk_cell_area_box_set_spacing(GTK_CELL_AREA_BOX(area), 12);
2056 column = gtk_tree_view_column_new_with_area(area);
2057 gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(area), renderer, TRUE, TRUE, TRUE);
2058 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(area), renderer, "markup", 0, "weight", 6, NULL);
2059 renderer = gtk_cell_renderer_pixbuf_new();
2060 gtk_cell_renderer_set_padding(renderer, 2, 0);
2061 gtk_cell_area_box_pack_end(GTK_CELL_AREA_BOX(area), renderer, FALSE, TRUE, TRUE);
2062 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(area), renderer, "pixbuf", 5, NULL);
2063 renderer = gtk_cell_renderer_text_new();
2064 g_object_set(G_OBJECT(renderer), "style", PANGO_STYLE_ITALIC, NULL);
2065 gtk_cell_area_box_pack_end(GTK_CELL_AREA_BOX(area), renderer, FALSE, TRUE, TRUE);
2066 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(area), renderer, "markup", 1, "weight", 6, NULL);
2067 gtk_tree_view_append_column(GTK_TREE_VIEW(completion_view), column);
2068 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(completion_store), 1, string_sort_func, GINT_TO_POINTER(1), NULL);
2069 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(completion_store), 1, GTK_SORT_ASCENDING);
2070 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(completion_sort), 1, completion_sort_func, GINT_TO_POINTER(1), NULL);
2071 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(completion_sort), 1, GTK_SORT_ASCENDING);
2072
2073 for(size_t i = 0; i < modes.size(); i++) {
2074 GtkWidget *item = gtk_menu_item_new_with_label(modes[i].name.c_str());
2075 gtk_widget_show(item);
2076 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(on_menu_item_meta_mode_activate), (gpointer) modes[i].name.c_str());
2077 g_signal_connect(G_OBJECT(item), "button-press-event", G_CALLBACK(on_menu_item_meta_mode_button_press), (gpointer) modes[i].name.c_str());
2078 g_signal_connect(G_OBJECT(item), "popup-menu", G_CALLBACK(on_menu_item_meta_mode_popup_menu), (gpointer) modes[i].name.c_str());
2079 gtk_menu_shell_insert(GTK_MENU_SHELL(gtk_builder_get_object(main_builder, "menu_meta_modes")), item, (gint) i);
2080 mode_items.push_back(item);
2081 item = gtk_menu_item_new_with_label(modes[i].name.c_str());
2082 gtk_widget_show(item);
2083 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(on_menu_item_meta_mode_activate), (gpointer) modes[i].name.c_str());
2084 g_signal_connect(G_OBJECT(item), "button-press-event", G_CALLBACK(on_menu_item_meta_mode_button_press), (gpointer) modes[i].name.c_str());
2085 g_signal_connect(G_OBJECT(item), "popup-menu", G_CALLBACK(on_menu_item_meta_mode_popup_menu), (gpointer) modes[i].name.c_str());
2086 gtk_menu_shell_insert(GTK_MENU_SHELL(gtk_builder_get_object(main_builder, "menu_result_popup_meta_modes")), item, (gint) i);
2087 popup_result_mode_items.push_back(item);
2088 }
2089 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(main_builder, "menu_item_meta_mode_delete")), modes.size() > 2);
2090
2091 tUnitSelectorCategories = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert_treeview_category"));
2092 tUnitSelector = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert_treeview_unit"));
2093
2094 tUnitSelector_store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN);
2095 tUnitSelector_store_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(tUnitSelector_store), NULL);
2096 gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(tUnitSelector_store_filter), 3);
2097 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tUnitSelector_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2098 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tUnitSelector_store), 0, GTK_SORT_ASCENDING);
2099 gtk_tree_view_set_model(GTK_TREE_VIEW(tUnitSelector), GTK_TREE_MODEL(tUnitSelector_store_filter));
2100 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tUnitSelector));
2101 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2102 renderer = gtk_cell_renderer_pixbuf_new();
2103 gtk_cell_renderer_set_padding(renderer, 4, 0);
2104 flag_column = gtk_tree_view_column_new_with_attributes(_("Flag"), renderer, "pixbuf", 2, NULL);
2105 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnitSelector), flag_column);
2106 renderer = gtk_cell_renderer_text_new();
2107 column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 0, NULL);
2108 gtk_tree_view_column_set_sort_column_id(column, 0);
2109 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnitSelector), column);
2110 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tUnitSelector_selection_changed), NULL);
2111 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tUnitSelector), FALSE);
2112
2113 tUnitSelectorCategories_store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
2114 gtk_tree_view_set_model(GTK_TREE_VIEW(tUnitSelectorCategories), GTK_TREE_MODEL(tUnitSelectorCategories_store));
2115 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tUnitSelectorCategories));
2116 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2117 renderer = gtk_cell_renderer_text_new();
2118 column = gtk_tree_view_column_new_with_attributes(_("Category"), renderer, "text", 0, NULL);
2119 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnitSelectorCategories), column);
2120 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tUnitSelectorCategories_selection_changed), NULL);
2121 gtk_tree_view_column_set_sort_column_id(column, 0);
2122 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tUnitSelectorCategories_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2123 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tUnitSelectorCategories_store), 0, GTK_SORT_ASCENDING);
2124
2125 set_result_size_request();
2126 set_expression_size_request();
2127 gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(main_builder, "expression_button")), FALSE);
2128
2129 if(win_height <= 0) gtk_window_get_size(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), NULL, &win_height);
2130 if(minimal_mode && minimal_width > 0) gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), minimal_width, win_height);
2131 else if(win_width > 0) gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), win_width, win_height);
2132
2133 if(remember_position) gtk_window_move(GTK_WINDOW(gtk_builder_get_object(main_builder, "main_window")), win_x, win_y);
2134
2135 g_signal_connect_after(gtk_builder_get_object(main_builder, "historyscrolled"), "size-allocate", G_CALLBACK(on_history_resize), NULL);
2136
2137 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(main_builder, "main_window")));
2138
2139 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 18
2140 set_expression_size_request();
2141 #endif
2142 if(history_height > 0) gtk_widget_set_size_request(tabs, -1, -1);
2143
2144 #ifdef _WIN32
2145 if(use_systray_icon) create_systray_icon();
2146 #endif
2147 if(hide_on_startup) gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(main_builder, "main_window")));
2148
2149 }
2150
get_functions_dialog(void)2151 GtkWidget* get_functions_dialog(void) {
2152
2153 if(!functions_builder) {
2154
2155 functions_builder = getBuilder("functions.ui");
2156 g_assert(functions_builder != NULL);
2157
2158 g_assert (gtk_builder_get_object(functions_builder, "functions_dialog") != NULL);
2159
2160 tFunctionCategories = GTK_WIDGET(gtk_builder_get_object(functions_builder, "functions_treeview_category"));
2161 tFunctions = GTK_WIDGET(gtk_builder_get_object(functions_builder, "functions_treeview_function"));
2162
2163 tFunctions_store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
2164 tFunctions_store_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(tFunctions_store), NULL);
2165 gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(tFunctions_store_filter), 2);
2166 gtk_tree_view_set_model(GTK_TREE_VIEW(tFunctions), GTK_TREE_MODEL(tFunctions_store_filter));
2167 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tFunctions));
2168 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2169 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
2170 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Function"), renderer, "text", 0, NULL);
2171 gtk_tree_view_column_set_sort_column_id(column, 0);
2172 gtk_tree_view_append_column(GTK_TREE_VIEW(tFunctions), column);
2173 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tFunctions_selection_changed), NULL);
2174 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tFunctions_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2175 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tFunctions_store), 0, GTK_SORT_ASCENDING);
2176
2177 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tFunctions), FALSE);
2178
2179 tFunctionCategories_store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
2180 gtk_tree_view_set_model(GTK_TREE_VIEW(tFunctionCategories), GTK_TREE_MODEL(tFunctionCategories_store));
2181 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tFunctionCategories));
2182 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2183 renderer = gtk_cell_renderer_text_new();
2184 column = gtk_tree_view_column_new_with_attributes(_("Category"), renderer, "text", 0, NULL);
2185 gtk_tree_view_append_column(GTK_TREE_VIEW(tFunctionCategories), column);
2186 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tFunctionCategories_selection_changed), NULL);
2187 gtk_tree_view_column_set_sort_column_id(column, 0);
2188 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tFunctionCategories_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2189 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tFunctionCategories_store), 0, GTK_SORT_ASCENDING);
2190
2191 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(functions_builder, "functions_textview_description")));
2192 gtk_text_buffer_create_tag(buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL);
2193 gtk_text_buffer_create_tag(buffer, "italic", "style", PANGO_STYLE_ITALIC, NULL);
2194
2195 if(functions_width > 0 && functions_height > 0) gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(functions_builder, "functions_dialog")), functions_width, functions_height);
2196 if(functions_hposition > 0) gtk_paned_set_position(GTK_PANED(gtk_builder_get_object(functions_builder, "functions_hpaned")), functions_hposition);
2197 if(functions_vposition > 0) gtk_paned_set_position(GTK_PANED(gtk_builder_get_object(functions_builder, "functions_vpaned")), functions_vposition);
2198
2199 gtk_builder_connect_signals(functions_builder, NULL);
2200
2201 update_functions_tree();
2202
2203 }
2204
2205 return GTK_WIDGET(gtk_builder_get_object(functions_builder, "functions_dialog"));
2206 }
2207
get_variables_dialog(void)2208 GtkWidget* get_variables_dialog(void) {
2209 if(!variables_builder) {
2210
2211 variables_builder = getBuilder("variables.ui");
2212 g_assert(variables_builder != NULL);
2213
2214 g_assert (gtk_builder_get_object(variables_builder, "variables_dialog") != NULL);
2215
2216 tVariableCategories = GTK_WIDGET(gtk_builder_get_object(variables_builder, "variables_treeview_category"));
2217 tVariables = GTK_WIDGET(gtk_builder_get_object(variables_builder, "variables_treeview_variable"));
2218
2219 tVariables_store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
2220 tVariables_store_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(tVariables_store), NULL);
2221 gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(tVariables_store_filter), 3);
2222 gtk_tree_view_set_model(GTK_TREE_VIEW(tVariables), GTK_TREE_MODEL(tVariables_store_filter));
2223 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tVariables));
2224 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2225 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
2226 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Variable"), renderer, "text", 0, NULL);
2227 gtk_tree_view_column_set_sort_column_id(column, 0);
2228 gtk_tree_view_append_column(GTK_TREE_VIEW(tVariables), column);
2229 renderer = gtk_cell_renderer_text_new();
2230 column = gtk_tree_view_column_new_with_attributes(_("Value"), renderer, "text", 1, NULL);
2231 //g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_NONE, NULL);
2232 gtk_tree_view_column_set_sort_column_id(column, 1);
2233 gtk_tree_view_append_column(GTK_TREE_VIEW(tVariables), column);
2234 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tVariables_selection_changed), NULL);
2235 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tVariables_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2236 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tVariables_store), 1, int_string_sort_func, GINT_TO_POINTER(1), NULL);
2237 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tVariables_store), 0, GTK_SORT_ASCENDING);
2238
2239 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tVariables), FALSE);
2240
2241 tVariableCategories_store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
2242 gtk_tree_view_set_model(GTK_TREE_VIEW(tVariableCategories), GTK_TREE_MODEL(tVariableCategories_store));
2243 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tVariableCategories));
2244 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2245 renderer = gtk_cell_renderer_text_new();
2246 column = gtk_tree_view_column_new_with_attributes(_("Category"), renderer, "text", 0, NULL);
2247 gtk_tree_view_append_column(GTK_TREE_VIEW(tVariableCategories), column);
2248 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tVariableCategories_selection_changed), NULL);
2249 gtk_tree_view_column_set_sort_column_id(column, 0);
2250 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tVariableCategories_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2251 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tVariableCategories_store), 0, GTK_SORT_ASCENDING);
2252
2253 if(variables_width > 0 && variables_height > 0) gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(variables_builder, "variables_dialog")), variables_width, variables_height);
2254 if(variables_position > 0) gtk_paned_set_position(GTK_PANED(gtk_builder_get_object(variables_builder, "variables_hpaned")), variables_position);
2255
2256 gtk_builder_connect_signals(variables_builder, NULL);
2257
2258 update_variables_tree();
2259
2260 }
2261
2262 return GTK_WIDGET(gtk_builder_get_object(variables_builder, "variables_dialog"));
2263 }
2264
get_units_dialog(void)2265 GtkWidget* get_units_dialog(void) {
2266
2267 if(!units_builder) {
2268
2269 units_builder = getBuilder("units.ui");
2270 g_assert(units_builder != NULL);
2271
2272 g_assert (gtk_builder_get_object(units_builder, "units_dialog") != NULL);
2273
2274 tUnitCategories = GTK_WIDGET(gtk_builder_get_object(units_builder, "units_treeview_category"));
2275 tUnits = GTK_WIDGET(gtk_builder_get_object(units_builder, "units_treeview_unit"));
2276
2277 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 14
2278 if(!gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), "pan-down-symbolic")) {
2279 GtkWidget *arrow_down = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
2280 gtk_widget_set_size_request(GTK_WIDGET(arrow_down), 18, 18);
2281 gtk_widget_show(arrow_down);
2282 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object(units_builder, "image_to_unit")));
2283 gtk_container_add(GTK_CONTAINER(gtk_builder_get_object(units_builder, "units_to_box")), arrow_down);
2284 }
2285 #endif
2286
2287 tUnits_store = gtk_list_store_new(UNITS_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
2288 tUnits_store_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(tUnits_store), NULL);
2289 gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(tUnits_store_filter), UNITS_VISIBLE_COLUMN);
2290 gtk_tree_view_set_model(GTK_TREE_VIEW(tUnits), GTK_TREE_MODEL(tUnits_store_filter));
2291 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tUnits));
2292 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2293 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
2294 gtk_cell_renderer_set_padding(renderer, 4, 0);
2295 units_flag_column = gtk_tree_view_column_new_with_attributes(_("Flag"), renderer, "pixbuf", UNITS_FLAG_COLUMN, NULL);
2296 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnits), units_flag_column);
2297 renderer = gtk_cell_renderer_text_new();
2298 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", UNITS_TITLE_COLUMN, NULL);
2299 gtk_tree_view_column_set_sort_column_id(column, UNITS_TITLE_COLUMN);
2300 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnits), column);
2301 renderer = gtk_cell_renderer_text_new();
2302 column = gtk_tree_view_column_new_with_attributes(_("Unit"), renderer, "text", UNITS_NAMES_COLUMN, NULL);
2303 gtk_tree_view_column_set_sort_column_id(column, UNITS_NAMES_COLUMN);
2304 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnits), column);
2305 renderer = gtk_cell_renderer_text_new();
2306 column = gtk_tree_view_column_new_with_attributes(_("Unit"), renderer, "text", UNITS_BASE_COLUMN, NULL);
2307 gtk_tree_view_column_set_sort_column_id(column, UNITS_BASE_COLUMN);
2308 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnits), column);
2309 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tUnits_selection_changed), NULL);
2310 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tUnits_store), UNITS_TITLE_COLUMN, string_sort_func, GINT_TO_POINTER(UNITS_TITLE_COLUMN), NULL);
2311 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tUnits_store), UNITS_NAMES_COLUMN, string_sort_func, GINT_TO_POINTER(UNITS_NAMES_COLUMN), NULL);
2312 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tUnits_store), UNITS_BASE_COLUMN, string_sort_func, GINT_TO_POINTER(UNITS_BASE_COLUMN), NULL);
2313 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tUnits_store), UNITS_TITLE_COLUMN, GTK_SORT_ASCENDING);
2314
2315 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tUnits), FALSE);
2316
2317 tUnitCategories_store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
2318 gtk_tree_view_set_model(GTK_TREE_VIEW(tUnitCategories), GTK_TREE_MODEL(tUnitCategories_store));
2319 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tUnitCategories));
2320 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2321 renderer = gtk_cell_renderer_text_new();
2322 column = gtk_tree_view_column_new_with_attributes(_("Category"), renderer, "text", 0, NULL);
2323 gtk_tree_view_append_column(GTK_TREE_VIEW(tUnitCategories), column);
2324 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tUnitCategories_selection_changed), NULL);
2325 gtk_tree_view_column_set_sort_column_id(column, 0);
2326 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tUnitCategories_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2327 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tUnitCategories_store), 0, GTK_SORT_ASCENDING);
2328
2329 units_convert_window = GTK_WIDGET(gtk_builder_get_object(units_builder, "units_convert_window"));
2330 units_convert_scrolled = GTK_WIDGET(gtk_builder_get_object(units_builder, "units_convert_scrolled"));
2331 units_convert_view = GTK_WIDGET(gtk_builder_get_object(units_builder, "units_convert_view"));
2332 units_convert_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(tUnits_store), NULL);
2333 gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(units_convert_filter), UNITS_VISIBLE_COLUMN_CONVERT);
2334 gtk_tree_view_set_model(GTK_TREE_VIEW(units_convert_view), GTK_TREE_MODEL(units_convert_filter));
2335 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(units_convert_view));
2336 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2337 units_convert_flag_renderer = gtk_cell_renderer_pixbuf_new();
2338 GtkCellArea *area = gtk_cell_area_box_new();
2339 gtk_cell_area_box_set_spacing(GTK_CELL_AREA_BOX(area), 12);
2340 gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(area), units_convert_flag_renderer, FALSE, TRUE, TRUE);
2341 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(area), units_convert_flag_renderer, "pixbuf", UNITS_FLAG_COLUMN, NULL);
2342 renderer = gtk_cell_renderer_text_new();
2343 gtk_cell_area_box_pack_start(GTK_CELL_AREA_BOX(area), renderer, TRUE, TRUE, TRUE);
2344 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(area), renderer, "text", UNITS_TITLE_COLUMN, NULL);
2345 column = gtk_tree_view_column_new_with_area(area);
2346 gtk_tree_view_column_set_sort_column_id(column, UNITS_TITLE_COLUMN);
2347 gtk_tree_view_append_column(GTK_TREE_VIEW(units_convert_view), column);
2348
2349 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 16
2350 gtk_label_set_width_chars(GTK_LABEL(gtk_builder_get_object(units_builder, "units_label_to_unit")), 20);
2351 gtk_label_set_xalign(GTK_LABEL(gtk_builder_get_object(units_builder, "units_label_to_unit")), 0.0);
2352 #else
2353 gint w;
2354 PangoLayout *layout = gtk_widget_create_pango_layout(GTK_WIDGET((gtk_builder_get_object(units_builder, "units_label_to_unit"))), "AAAAAAAAAAAAAAAAAAAA");
2355 pango_layout_get_pixel_size(layout, &w, NULL);
2356 gtk_widget_set_size_request(GTK_WIDGET(gtk_builder_get_object(units_builder, "units_to_box")), w + 16, -1);
2357 #endif
2358
2359 if(units_width > 0 && units_height > 0) gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(units_builder, "units_dialog")), units_width, units_height);
2360 if(units_position > 0) gtk_paned_set_position(GTK_PANED(gtk_builder_get_object(units_builder, "units_hpaned")), units_position);
2361
2362 gtk_builder_connect_signals(units_builder, NULL);
2363
2364 update_units_tree();
2365
2366 gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object(units_builder, "units_entry_from_val")), "1");
2367 gtk_entry_set_text (GTK_ENTRY (gtk_builder_get_object(units_builder, "units_entry_to_val")), "1");
2368 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(units_builder, "units_entry_from_val")), 1.0);
2369 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(units_builder, "units_entry_to_val")), 1.0);
2370
2371 }
2372
2373 return GTK_WIDGET(gtk_builder_get_object(units_builder, "units_dialog"));
2374 }
2375
get_datasets_dialog(void)2376 GtkWidget* get_datasets_dialog(void) {
2377
2378 if(!datasets_builder) {
2379
2380 datasets_builder = getBuilder("datasets.ui");
2381 g_assert(datasets_builder != NULL);
2382
2383 g_assert (gtk_builder_get_object(datasets_builder, "datasets_dialog") != NULL);
2384
2385 tDatasets = GTK_WIDGET(gtk_builder_get_object(datasets_builder, "datasets_treeview_datasets"));
2386 tDataObjects = GTK_WIDGET(gtk_builder_get_object(datasets_builder, "datasets_treeview_objects"));
2387
2388 tDataObjects_store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
2389 gtk_tree_view_set_model(GTK_TREE_VIEW(tDataObjects), GTK_TREE_MODEL(tDataObjects_store));
2390 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tDataObjects));
2391 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2392 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
2393 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("Key 1", renderer, "text", 0, NULL);
2394 gtk_tree_view_column_set_sort_column_id(column, 0);
2395 gtk_tree_view_append_column(GTK_TREE_VIEW(tDataObjects), column);
2396 renderer = gtk_cell_renderer_text_new();
2397 column = gtk_tree_view_column_new_with_attributes("Key 2", renderer, "text", 1, NULL);
2398 gtk_tree_view_column_set_sort_column_id(column, 1);
2399 gtk_tree_view_append_column(GTK_TREE_VIEW(tDataObjects), column);
2400 renderer = gtk_cell_renderer_text_new();
2401 column = gtk_tree_view_column_new_with_attributes("Key 3", renderer, "text", 2, NULL);
2402 gtk_tree_view_column_set_sort_column_id(column, 2);
2403 gtk_tree_view_append_column(GTK_TREE_VIEW(tDataObjects), column);
2404 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tDataObjects_selection_changed), NULL);
2405 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tDataObjects_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2406 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tDataObjects_store), 0, GTK_SORT_ASCENDING);
2407
2408 tDatasets_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
2409 gtk_tree_view_set_model(GTK_TREE_VIEW(tDatasets), GTK_TREE_MODEL(tDatasets_store));
2410 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tDatasets));
2411 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2412 renderer = gtk_cell_renderer_text_new();
2413 column = gtk_tree_view_column_new_with_attributes(_("Data Set"), renderer, "text", 0, NULL);
2414 gtk_tree_view_append_column(GTK_TREE_VIEW(tDatasets), column);
2415 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tDatasets_selection_changed), NULL);
2416 gtk_tree_view_column_set_sort_column_id(column, 0);
2417 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tDatasets_store), 0, string_sort_func, GINT_TO_POINTER(0), NULL);
2418 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tDatasets_store), 0, GTK_SORT_ASCENDING);
2419
2420 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(datasets_builder, "datasets_textview_description")));
2421 gtk_text_buffer_create_tag(buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL);
2422 gtk_text_buffer_create_tag(buffer, "italic", "style", PANGO_STYLE_ITALIC, NULL);
2423
2424 if(datasets_width > 0 && datasets_height > 0) gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(datasets_builder, "datasets_dialog")), datasets_width, datasets_height);
2425 if(datasets_hposition > 0) gtk_paned_set_position(GTK_PANED(gtk_builder_get_object(datasets_builder, "datasets_hpaned")), datasets_hposition);
2426 if(datasets_vposition1 > 0) gtk_paned_set_position(GTK_PANED(gtk_builder_get_object(datasets_builder, "datasets_vpaned1")), datasets_vposition1);
2427 if(datasets_vposition2 > 0) gtk_paned_set_position(GTK_PANED(gtk_builder_get_object(datasets_builder, "datasets_vpaned2")), datasets_vposition2);
2428
2429 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 12
2430 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(datasets_builder, "vbox1")), 6);
2431 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(datasets_builder, "vbox2")), 6);
2432 #else
2433 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(datasets_builder, "vbox1")), 6);
2434 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(datasets_builder, "vbox2")), 6);
2435 #endif
2436
2437
2438 gtk_builder_connect_signals(datasets_builder, NULL);
2439
2440 update_datasets_tree();
2441
2442 }
2443
2444 return GTK_WIDGET(gtk_builder_get_object(datasets_builder, "datasets_dialog"));
2445 }
2446
get_preferences_dialog(void)2447 GtkWidget* get_preferences_dialog(void) {
2448 if(!preferences_builder) {
2449
2450 preferences_builder = getBuilder("preferences.ui");
2451 g_assert(preferences_builder != NULL);
2452
2453 g_assert (gtk_builder_get_object(preferences_builder, "preferences_dialog") != NULL);
2454 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_display_expression_status")), display_expression_status);
2455 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_expression_lines_spin_button")), (double) (expression_lines < 1 ? 3 : expression_lines));
2456 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_fetch_exchange_rates")), fetch_exchange_rates_at_startup);
2457 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_local_currency_conversion")), evalops.local_currency_conversion);
2458 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_save_mode")), save_mode_on_exit);
2459 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_clear_history")), clear_history_on_exit);
2460 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_allow_multiple_instances")), allow_multiple_instances > 0);
2461 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_ignore_locale")), ignore_locale);
2462 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_check_version")), check_version);
2463 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_remember_position")), remember_position);
2464 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_persistent_keypad")), persistent_keypad);
2465 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(preferences_builder, "preferences_combo_title")), title_type);
2466 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_unicode_signs")), printops.use_unicode_signs);
2467 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_copy_separator")), copy_separator);
2468 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_lower_case_numbers")), printops.lower_case_numbers);
2469 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_e_notation")), use_e_notation);
2470 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_lower_case_e")), printops.lower_case_e);
2471 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_imaginary_j")), CALCULATOR->v_i->hasName("j") > 0);
2472 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_alternative_base_prefixes")), printops.base_display == BASE_DISPLAY_ALTERNATIVE);
2473 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_twos_complement")), printops.twos_complement);
2474 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_hexadecimal_twos_complement")), printops.hexadecimal_twos_complement);
2475 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_spell_out_logical_operators")), printops.spell_out_logical_operators);
2476 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_caret_as_xor")), caret_as_xor);
2477 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_binary_prefixes")), CALCULATOR->usesBinaryPrefixes() > 0);
2478 switch(CALCULATOR->getTemperatureCalculationMode()) {
2479 case TEMPERATURE_CALCULATION_ABSOLUTE: {
2480 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_temp_abs")), TRUE);
2481 break;
2482 }
2483 case TEMPERATURE_CALCULATION_RELATIVE: {
2484 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_temp_rel")), TRUE);
2485 break;
2486 }
2487 default: {
2488 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_temp_hybrid")), TRUE);
2489 break;
2490 }
2491 }
2492 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_save_defs")), save_defs_on_exit);
2493 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_rpn_keys")), rpn_keys);
2494 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_decimal_comma")), CALCULATOR->getDecimalPoint() == COMMA);
2495 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_dot_as_separator")), evalops.parse_options.dot_as_separator);
2496 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_comma_as_separator")), evalops.parse_options.comma_as_separator);
2497 if(CALCULATOR->getDecimalPoint() == DOT) gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_dot_as_separator")));
2498 if(CALCULATOR->getDecimalPoint() == COMMA) gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_comma_as_separator")));
2499 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_custom_result_font")), use_custom_result_font);
2500 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_custom_expression_font")), use_custom_expression_font);
2501 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_custom_status_font")), use_custom_status_font);
2502 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_custom_keypad_font")), use_custom_keypad_font);
2503 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_custom_app_font")), use_custom_app_font);
2504 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_button_result_font")), use_custom_result_font);
2505 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(gtk_builder_get_object(preferences_builder, "preferences_button_result_font")), custom_result_font.c_str());
2506 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_button_expression_font")), use_custom_expression_font);
2507 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(gtk_builder_get_object(preferences_builder, "preferences_button_expression_font")), custom_expression_font.c_str());
2508 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_button_status_font")), use_custom_status_font);
2509 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(gtk_builder_get_object(preferences_builder, "preferences_button_status_font")), custom_status_font.c_str());
2510 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_button_keypad_font")), use_custom_keypad_font);
2511 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(gtk_builder_get_object(preferences_builder, "preferences_button_keypad_font")), custom_keypad_font.c_str());
2512 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_button_app_font")), use_custom_app_font);
2513 gtk_font_chooser_set_font(GTK_FONT_CHOOSER(gtk_builder_get_object(preferences_builder, "preferences_button_app_font")), custom_app_font.c_str());
2514 GdkRGBA c;
2515 gdk_rgba_parse(&c, status_error_color.c_str());
2516 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(gtk_builder_get_object(preferences_builder, "colorbutton_status_error_color")), &c);
2517 gdk_rgba_parse(&c, status_warning_color.c_str());
2518 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(gtk_builder_get_object(preferences_builder, "colorbutton_status_warning_color")), &c);
2519 gtk_button_set_label(GTK_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_dot")), SIGN_MULTIDOT);
2520 gtk_button_set_label(GTK_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_altdot")), SIGN_MIDDLEDOT);
2521 gtk_button_set_label(GTK_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_ex")), SIGN_MULTIPLICATION);
2522 switch(printops.multiplication_sign) {
2523 case MULTIPLICATION_SIGN_DOT: {
2524 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_dot")), TRUE);
2525 break;
2526 }
2527 case MULTIPLICATION_SIGN_ALTDOT: {
2528 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_altdot")), TRUE);
2529 break;
2530 }
2531 case MULTIPLICATION_SIGN_X: {
2532 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_ex")), TRUE);
2533 break;
2534 }
2535 default: {
2536 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_asterisk")), TRUE);
2537 break;
2538 }
2539 }
2540 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_asterisk")), printops.use_unicode_signs);
2541 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_ex")), printops.use_unicode_signs);
2542 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_dot")), printops.use_unicode_signs);
2543 gtk_button_set_label(GTK_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_division_slash")), " " SIGN_DIVISION_SLASH " ");
2544 gtk_button_set_label(GTK_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_division")), SIGN_DIVISION);
2545 switch(printops.division_sign) {
2546 case DIVISION_SIGN_DIVISION_SLASH: {
2547 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_division_slash")), TRUE);
2548 break;
2549 }
2550 case DIVISION_SIGN_DIVISION: {
2551 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_division")), TRUE);
2552 break;
2553 }
2554 default: {
2555 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_slash")), TRUE);
2556 break;
2557 }
2558 }
2559 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_slash")), printops.use_unicode_signs);
2560 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_division_slash")), printops.use_unicode_signs);
2561 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_division")), printops.use_unicode_signs);
2562 switch(printops.digit_grouping) {
2563 case DIGIT_GROUPING_STANDARD: {
2564 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_digit_grouping_standard")), TRUE);
2565 break;
2566 }
2567 case DIGIT_GROUPING_LOCALE: {
2568 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_digit_grouping_locale")), TRUE);
2569 break;
2570 }
2571 default: {
2572 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_radiobutton_digit_grouping_none")), TRUE);
2573 break;
2574 }
2575 }
2576 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_autocalc_history")), autocalc_history_delay >= 0);
2577 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), autocalc_history_delay >= 0);
2578 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "label_autocalc_history")), autocalc_history_delay >= 0);
2579 Number nr(autocalc_history_delay); nr.cbrt();
2580 gtk_range_set_value(GTK_RANGE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), autocalc_history_delay < 0 ? 12.599 : nr.floatValue());
2581 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 6.3, GTK_POS_BOTTOM, NULL);
2582 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 7.937, GTK_POS_BOTTOM, (string("0") + CALCULATOR->getDecimalPoint() + "5 s").c_str());
2583 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 10.0, GTK_POS_BOTTOM, "1 s");
2584 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 11.447, GTK_POS_BOTTOM, NULL);
2585 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 12.599, GTK_POS_BOTTOM, "2 s");
2586 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 14.422, GTK_POS_BOTTOM, NULL);
2587 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 15.874, GTK_POS_BOTTOM, NULL);
2588 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 17.1, GTK_POS_BOTTOM, "5 s");
2589 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_autocalc_history")), 21.544, GTK_POS_BOTTOM, "10 s");
2590
2591 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), 0.0, GTK_POS_BOTTOM, "1 s");
2592 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), 2.0, GTK_POS_BOTTOM, "5 s");
2593 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), 3.0, GTK_POS_BOTTOM, "10 s");
2594 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), 4.0, GTK_POS_BOTTOM, "20 s");
2595 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), 5.58, GTK_POS_BOTTOM, "60 s");
2596 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), 7.17, GTK_POS_BOTTOM, "180 s");
2597 gtk_scale_add_mark(GTK_SCALE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), 8.91, GTK_POS_BOTTOM, "600 s");
2598 nr.set(max_plot_time); nr.log(2);
2599 gtk_range_set_value(GTK_RANGE(gtk_builder_get_object(preferences_builder, "preferences_scale_plot_time")), nr.floatValue() - 0.322);
2600 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 16
2601 # ifdef _WIN32
2602 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_dark_theme")), use_dark_theme > 0);
2603 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_dark_theme")));
2604 # endif
2605 #endif
2606 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_use_systray_icon")), use_systray_icon);
2607 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_hide_on_startup")), hide_on_startup);
2608 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_hide_on_startup")), use_systray_icon);
2609 #ifdef _WIN32
2610 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_use_systray_icon")));
2611 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_hide_on_startup")));
2612 #endif
2613 gtk_builder_connect_signals(preferences_builder, NULL);
2614
2615 }
2616
2617 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_update_exchange_rates_spin_button")), (double) auto_update_exchange_rates);
2618
2619 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_enable_completion")), enable_completion);
2620 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_enable_completion2")), enable_completion2);
2621 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_label_completion_min")), enable_completion);
2622 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_spin_completion_min")), enable_completion);
2623 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_spin_completion_min")), (double) completion_min);
2624 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_checkbutton_enable_completion2")), enable_completion);
2625 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_label_completion_min2")), enable_completion && enable_completion2);
2626 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_spin_completion_min2")), enable_completion && enable_completion2);
2627 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_spin_completion_min2")), (double) completion_min2);
2628 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_label_completion_delay")), enable_completion);
2629 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_spin_completion_delay")), enable_completion);
2630 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(preferences_builder, "preferences_spin_completion_delay")), (double) completion_delay);
2631
2632 return GTK_WIDGET(gtk_builder_get_object(preferences_builder, "preferences_dialog"));
2633 }
2634
get_unit_edit_dialog(void)2635 GtkWidget* get_unit_edit_dialog(void) {
2636
2637 if(!unitedit_builder) {
2638
2639 unitedit_builder = getBuilder("unitedit.ui");
2640 g_assert(unitedit_builder != NULL);
2641
2642 g_assert (gtk_builder_get_object(unitedit_builder, "unit_edit_dialog") != NULL);
2643
2644 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(unitedit_builder, "unit_edit_combobox_class")), 0);
2645
2646 gtk_builder_connect_signals(unitedit_builder, NULL);
2647
2648 }
2649
2650 /* populate combo menu */
2651
2652 GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
2653 GList *items = NULL;
2654 for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
2655 if(!CALCULATOR->units[i]->category().empty()) {
2656 //add category if not present
2657 if(g_hash_table_lookup(hash, (gconstpointer) CALCULATOR->units[i]->category().c_str()) == NULL) {
2658 items = g_list_insert_sorted(items, (gpointer) CALCULATOR->units[i]->category().c_str(), (GCompareFunc) compare_categories);
2659 //remember added categories
2660 g_hash_table_insert(hash, (gpointer) CALCULATOR->units[i]->category().c_str(), (gpointer) hash);
2661 }
2662 }
2663 }
2664 for(GList *l = items; l != NULL; l = l->next) {
2665 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk_builder_get_object(unitedit_builder, "unit_edit_combo_category")), (const gchar*) l->data);
2666 }
2667 g_hash_table_destroy(hash);
2668 g_list_free(items);
2669
2670 return GTK_WIDGET(gtk_builder_get_object(unitedit_builder, "unit_edit_dialog"));
2671 }
2672
get_function_edit_dialog(void)2673 GtkWidget* get_function_edit_dialog(void) {
2674
2675 if(!functionedit_builder) {
2676
2677 functionedit_builder = getBuilder("functionedit.ui");
2678 g_assert(functionedit_builder != NULL);
2679
2680 g_assert (gtk_builder_get_object(functionedit_builder, "function_edit_dialog") != NULL);
2681
2682 tFunctionArguments = GTK_WIDGET(gtk_builder_get_object(functionedit_builder, "function_edit_treeview_arguments"));
2683 tFunctionArguments_store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
2684 gtk_tree_view_set_model(GTK_TREE_VIEW(tFunctionArguments), GTK_TREE_MODEL(tFunctionArguments_store));
2685 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tFunctionArguments));
2686 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2687 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
2688 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 0, NULL);
2689 gtk_tree_view_append_column(GTK_TREE_VIEW(tFunctionArguments), column);
2690 renderer = gtk_cell_renderer_text_new();
2691 column = gtk_tree_view_column_new_with_attributes(_("Type"), renderer, "text", 1, NULL);
2692 gtk_tree_view_append_column(GTK_TREE_VIEW(tFunctionArguments), column);
2693 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tFunctionArguments_selection_changed), NULL);
2694
2695 tSubfunctions = GTK_WIDGET(gtk_builder_get_object(functionedit_builder, "function_edit_treeview_subfunctions"));
2696 tSubfunctions_store = gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
2697 gtk_tree_view_set_model(GTK_TREE_VIEW(tSubfunctions), GTK_TREE_MODEL(tSubfunctions_store));
2698 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tSubfunctions));
2699 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2700 renderer = gtk_cell_renderer_text_new();
2701 column = gtk_tree_view_column_new_with_attributes(_("Reference"), renderer, "text", 0, NULL);
2702 gtk_tree_view_append_column(GTK_TREE_VIEW(tSubfunctions), column);
2703 renderer = gtk_cell_renderer_text_new();
2704 column = gtk_tree_view_column_new_with_attributes(_("Expression"), renderer, "text", 1, NULL);
2705 gtk_tree_view_append_column(GTK_TREE_VIEW(tSubfunctions), column);
2706 renderer = gtk_cell_renderer_text_new();
2707 column = gtk_tree_view_column_new_with_attributes(_("Precalculate"), renderer, "text", 2, NULL);
2708 gtk_tree_view_append_column(GTK_TREE_VIEW(tSubfunctions), column);
2709 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tSubfunctions_selection_changed), NULL);
2710
2711 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(functionedit_builder, "function_edit_combobox_argument_type")), 0);
2712
2713 g_signal_connect((gpointer) gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(functionedit_builder, "function_edit_textview_description"))), "changed", G_CALLBACK(on_function_changed), NULL);
2714 g_signal_connect((gpointer) gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(functionedit_builder, "function_edit_textview_expression"))), "changed", G_CALLBACK(on_function_changed), NULL);
2715
2716 gtk_builder_connect_signals(functionedit_builder, NULL);
2717
2718 }
2719
2720 /* populate combo menu */
2721
2722 GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
2723 GList *items = NULL;
2724 for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
2725 if(!CALCULATOR->functions[i]->category().empty()) {
2726 //add category if not present
2727 if(g_hash_table_lookup(hash, (gconstpointer) CALCULATOR->functions[i]->category().c_str()) == NULL) {
2728 items = g_list_insert_sorted(items, (gpointer) CALCULATOR->functions[i]->category().c_str(), (GCompareFunc) compare_categories);
2729 //remember added categories
2730 g_hash_table_insert(hash, (gpointer) CALCULATOR->functions[i]->category().c_str(), (gpointer) hash);
2731 }
2732 }
2733 }
2734 for(GList *l = items; l != NULL; l = l->next) {
2735 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk_builder_get_object(functionedit_builder, "function_edit_combo_category")), (const gchar*) l->data);
2736 }
2737 g_hash_table_destroy(hash);
2738 g_list_free(items);
2739
2740 return GTK_WIDGET(gtk_builder_get_object(functionedit_builder, "function_edit_dialog"));
2741 }
2742
get_simple_function_edit_dialog(void)2743 GtkWidget* get_simple_function_edit_dialog(void) {
2744
2745 if(!simplefunctionedit_builder) {
2746
2747 simplefunctionedit_builder = getBuilder("simplefunctionedit.ui");
2748 g_assert(simplefunctionedit_builder != NULL);
2749
2750 g_assert(gtk_builder_get_object(simplefunctionedit_builder, "simple_function_edit_dialog") != NULL);
2751
2752 g_signal_connect((gpointer) gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(simplefunctionedit_builder, "simple_function_edit_textview_expression"))), "changed", G_CALLBACK(on_simple_function_changed), NULL);
2753
2754 gtk_builder_connect_signals(simplefunctionedit_builder, NULL);
2755
2756 }
2757
2758 return GTK_WIDGET(gtk_builder_get_object(simplefunctionedit_builder, "simple_function_edit_dialog"));
2759 }
2760
get_variable_edit_dialog(void)2761 GtkWidget* get_variable_edit_dialog(void) {
2762
2763 if(!variableedit_builder) {
2764
2765 variableedit_builder = getBuilder("variableedit.ui");
2766 g_assert(variableedit_builder != NULL);
2767
2768 g_assert (gtk_builder_get_object(variableedit_builder, "variable_edit_dialog") != NULL);
2769
2770 gtk_builder_connect_signals(variableedit_builder, NULL);
2771
2772 }
2773 /* populate combo menu */
2774
2775 GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
2776 GList *items = NULL;
2777 for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
2778 if(!CALCULATOR->variables[i]->category().empty()) {
2779 //add category if not present
2780 if(g_hash_table_lookup(hash, (gconstpointer) CALCULATOR->variables[i]->category().c_str()) == NULL) {
2781 items = g_list_insert_sorted(items, (gpointer) CALCULATOR->variables[i]->category().c_str(), (GCompareFunc) compare_categories);
2782 //remember added categories
2783 g_hash_table_insert(hash, (gpointer) CALCULATOR->variables[i]->category().c_str(), (gpointer) hash);
2784 }
2785 }
2786 }
2787 for(GList *l = items; l != NULL; l = l->next) {
2788 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk_builder_get_object(variableedit_builder, "variable_edit_combo_category")), (const gchar*) l->data);
2789 }
2790 g_hash_table_destroy(hash);
2791 g_list_free(items);
2792
2793 return GTK_WIDGET(gtk_builder_get_object(variableedit_builder, "variable_edit_dialog"));
2794 }
2795
get_unknown_edit_dialog(void)2796 GtkWidget* get_unknown_edit_dialog(void) {
2797
2798 if(!unknownedit_builder) {
2799
2800 unknownedit_builder = getBuilder("unknownedit.ui");
2801 g_assert(unknownedit_builder != NULL);
2802
2803 g_assert (gtk_builder_get_object(unknownedit_builder, "unknown_edit_dialog") != NULL);
2804
2805 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(unknownedit_builder, "unknown_edit_combobox_type")), 0);
2806 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(unknownedit_builder, "unknown_edit_combobox_sign")), 0);
2807
2808 gtk_builder_connect_signals(unknownedit_builder, NULL);
2809
2810 }
2811
2812 /* populate combo menu */
2813
2814 GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
2815 GList *items = NULL;
2816 for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
2817 if(!CALCULATOR->variables[i]->category().empty()) {
2818 //add category if not present
2819 if(g_hash_table_lookup(hash, (gconstpointer) CALCULATOR->variables[i]->category().c_str()) == NULL) {
2820 items = g_list_insert_sorted(items, (gpointer) CALCULATOR->variables[i]->category().c_str(), (GCompareFunc) compare_categories);
2821 //remember added categories
2822 g_hash_table_insert(hash, (gpointer) CALCULATOR->variables[i]->category().c_str(), (gpointer) hash);
2823 }
2824 }
2825 }
2826 for(GList *l = items; l != NULL; l = l->next) {
2827 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk_builder_get_object(unknownedit_builder, "unknown_edit_combo_category")), (const gchar*) l->data);
2828 }
2829 g_hash_table_destroy(hash);
2830 g_list_free(items);
2831
2832 return GTK_WIDGET(gtk_builder_get_object(unknownedit_builder, "unknown_edit_dialog"));
2833 }
2834
get_matrix_edit_dialog(void)2835 GtkWidget* get_matrix_edit_dialog(void) {
2836 if(!matrixedit_builder) {
2837
2838 matrixedit_builder = getBuilder("matrixedit.ui");
2839 g_assert(matrixedit_builder != NULL);
2840
2841 g_assert (gtk_builder_get_object(matrixedit_builder, "matrix_edit_dialog") != NULL);
2842
2843 GType types[200];
2844 for(gint i = 0; i < 200; i += 1) {
2845 types[i] = G_TYPE_STRING;
2846 }
2847 tMatrixEdit_store = gtk_list_store_newv(200, types);
2848 tMatrixEdit = GTK_WIDGET(gtk_builder_get_object(matrixedit_builder, "matrix_edit_view"));
2849 gtk_tree_view_set_model (GTK_TREE_VIEW(tMatrixEdit), GTK_TREE_MODEL(tMatrixEdit_store));
2850 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tMatrixEdit));
2851 gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);
2852
2853 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(gtk_builder_get_object(matrixedit_builder, "matrix_edit_combo_category")))), _("Matrices"));
2854
2855 gtk_builder_connect_signals(matrixedit_builder, NULL);
2856
2857 }
2858
2859 /* populate combo menu */
2860
2861 GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
2862 GList *items = NULL;
2863 for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
2864 if(!CALCULATOR->variables[i]->category().empty()) {
2865 //add category if not present
2866 if(g_hash_table_lookup(hash, (gconstpointer) CALCULATOR->variables[i]->category().c_str()) == NULL) {
2867 items = g_list_insert_sorted(items, (gpointer) CALCULATOR->variables[i]->category().c_str(), (GCompareFunc) compare_categories);
2868 //remember added categories
2869 g_hash_table_insert(hash, (gpointer) CALCULATOR->variables[i]->category().c_str(), (gpointer) hash);
2870 }
2871 }
2872 }
2873 for(GList *l = items; l != NULL; l = l->next) {
2874 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk_builder_get_object(matrixedit_builder, "matrix_edit_combo_category")), (const gchar*) l->data);
2875 }
2876 g_hash_table_destroy(hash);
2877 g_list_free(items);
2878
2879
2880 return GTK_WIDGET(gtk_builder_get_object(matrixedit_builder, "matrix_edit_dialog"));
2881 }
get_matrix_dialog(void)2882 GtkWidget* get_matrix_dialog(void) {
2883 if(!matrix_builder) {
2884
2885 matrix_builder = getBuilder("matrix.ui");
2886 g_assert(matrix_builder != NULL);
2887
2888 g_assert (gtk_builder_get_object(matrix_builder, "matrix_dialog") != NULL);
2889
2890 GType types[10000];
2891 for(gint i = 0; i < 10000; i++) {
2892 types[i] = G_TYPE_STRING;
2893 }
2894 tMatrix_store = gtk_list_store_newv(10000, types);
2895 tMatrix = GTK_WIDGET(gtk_builder_get_object(matrix_builder, "matrix_view"));
2896 gtk_tree_view_set_model (GTK_TREE_VIEW(tMatrix), GTK_TREE_MODEL(tMatrix_store));
2897 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tMatrix));
2898 gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);
2899
2900 gtk_builder_connect_signals(matrix_builder, NULL);
2901
2902 }
2903
2904 return GTK_WIDGET(gtk_builder_get_object(matrix_builder, "matrix_dialog"));
2905
2906 }
2907
get_dataobject_edit_dialog(void)2908 GtkWidget* get_dataobject_edit_dialog(void) {
2909
2910 return GTK_WIDGET(gtk_builder_get_object(datasets_builder, "dataobject_edit_dialog"));
2911 }
2912
get_dataset_edit_dialog(void)2913 GtkWidget* get_dataset_edit_dialog(void) {
2914
2915 if(!datasetedit_builder) {
2916
2917 datasetedit_builder = getBuilder("datasetedit.ui");
2918 g_assert(datasetedit_builder != NULL);
2919
2920 g_assert (gtk_builder_get_object(datasetedit_builder, "dataset_edit_dialog") != NULL);
2921
2922 tDataProperties = GTK_WIDGET(gtk_builder_get_object(datasetedit_builder, "dataset_edit_treeview_properties"));
2923 tDataProperties_store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
2924 gtk_tree_view_set_model(GTK_TREE_VIEW(tDataProperties), GTK_TREE_MODEL(tDataProperties_store));
2925 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tDataProperties));
2926 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2927 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
2928 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Title"), renderer, "text", 0, NULL);
2929 gtk_tree_view_append_column(GTK_TREE_VIEW(tDataProperties), column);
2930 renderer = gtk_cell_renderer_text_new();
2931 column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 1, NULL);
2932 gtk_tree_view_append_column(GTK_TREE_VIEW(tDataProperties), column);
2933 renderer = gtk_cell_renderer_text_new();
2934 column = gtk_tree_view_column_new_with_attributes(_("Type"), renderer, "text", 2, NULL);
2935 gtk_tree_view_append_column(GTK_TREE_VIEW(tDataProperties), column);
2936 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tDataProperties_selection_changed), NULL);
2937 g_signal_connect((gpointer) gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(datasetedit_builder, "dataset_edit_textview_description"))), "changed", G_CALLBACK(on_dataset_changed), NULL);
2938 g_signal_connect((gpointer) gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(datasetedit_builder, "dataset_edit_textview_copyright"))), "changed", G_CALLBACK(on_dataset_changed), NULL);
2939 g_signal_connect((gpointer) gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(datasetedit_builder, "dataproperty_edit_textview_description"))), "changed", G_CALLBACK(on_dataproperty_changed), NULL);
2940 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(datasetedit_builder, "dataproperty_edit_combobox_type")), 0);
2941
2942 gtk_builder_connect_signals(datasetedit_builder, NULL);
2943
2944 }
2945
2946 return GTK_WIDGET(gtk_builder_get_object(datasetedit_builder, "dataset_edit_dialog"));
2947 }
2948
get_dataproperty_edit_dialog(void)2949 GtkWidget* get_dataproperty_edit_dialog(void) {
2950 return GTK_WIDGET(gtk_builder_get_object(datasetedit_builder, "dataproperty_edit_dialog"));
2951 }
2952
2953
get_names_edit_dialog(void)2954 GtkWidget* get_names_edit_dialog(void) {
2955 if(!namesedit_builder) {
2956
2957 namesedit_builder = getBuilder("namesedit.ui");
2958 g_assert(namesedit_builder != NULL);
2959
2960 g_assert (gtk_builder_get_object(namesedit_builder, "names_edit_dialog") != NULL);
2961
2962 tNames = GTK_WIDGET(gtk_builder_get_object(namesedit_builder, "names_edit_treeview"));
2963
2964 tNames_store = gtk_list_store_new(NAMES_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
2965 gtk_tree_view_set_model(GTK_TREE_VIEW(tNames), GTK_TREE_MODEL(tNames_store));
2966 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tNames));
2967 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
2968 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
2969 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", NAMES_NAME_COLUMN, NULL);
2970 gtk_tree_view_column_set_sort_column_id(column, NAMES_NAME_COLUMN);
2971 gtk_tree_view_column_set_expand(column, TRUE);
2972 gtk_tree_view_append_column(GTK_TREE_VIEW(tNames), column);
2973 renderer = gtk_cell_renderer_text_new();
2974 column = gtk_tree_view_column_new_with_attributes(_("Abbreviation"), renderer, "text", NAMES_ABBREVIATION_STRING_COLUMN, NULL);
2975 gtk_tree_view_column_set_sort_column_id(column, NAMES_ABBREVIATION_STRING_COLUMN);
2976 gtk_tree_view_append_column(GTK_TREE_VIEW(tNames), column);
2977 renderer = gtk_cell_renderer_text_new();
2978 column = gtk_tree_view_column_new_with_attributes(_("Plural"), renderer, "text", NAMES_PLURAL_STRING_COLUMN, NULL);
2979 gtk_tree_view_column_set_sort_column_id(column, NAMES_PLURAL_STRING_COLUMN);
2980 gtk_tree_view_append_column(GTK_TREE_VIEW(tNames), column);
2981 renderer = gtk_cell_renderer_text_new();
2982 column = gtk_tree_view_column_new_with_attributes(_("Reference"), renderer, "text", NAMES_REFERENCE_STRING_COLUMN, NULL);
2983 gtk_tree_view_column_set_sort_column_id(column, NAMES_REFERENCE_STRING_COLUMN);
2984 gtk_tree_view_append_column(GTK_TREE_VIEW(tNames), column);
2985 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tNames_selection_changed), NULL);
2986
2987 gtk_builder_connect_signals(namesedit_builder, NULL);
2988
2989 }
2990
2991 return GTK_WIDGET(gtk_builder_get_object(namesedit_builder, "names_edit_dialog"));
2992 }
2993
get_csv_import_dialog(void)2994 GtkWidget* get_csv_import_dialog(void) {
2995
2996 if(!csvimport_builder) {
2997
2998 csvimport_builder = getBuilder("csvimport.ui");
2999 g_assert(csvimport_builder != NULL);
3000
3001 g_assert (gtk_builder_get_object(csvimport_builder, "csv_import_dialog") != NULL);
3002
3003 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(csvimport_builder, "csv_import_combobox_delimiter")), 0);
3004
3005 gtk_builder_connect_signals(csvimport_builder, NULL);
3006
3007 }
3008 /* populate combo menu */
3009
3010 GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
3011 GList *items = NULL;
3012 for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
3013 if(!CALCULATOR->variables[i]->category().empty()) {
3014 //add category if not present
3015 if(g_hash_table_lookup(hash, (gconstpointer) CALCULATOR->variables[i]->category().c_str()) == NULL) {
3016 items = g_list_append(items, (gpointer) CALCULATOR->variables[i]->category().c_str());
3017 //remember added categories
3018 g_hash_table_insert(hash, (gpointer) CALCULATOR->variables[i]->category().c_str(), (gpointer) hash);
3019 }
3020 }
3021 }
3022 for(GList *l = items; l != NULL; l = l->next) {
3023 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gtk_builder_get_object(csvimport_builder, "csv_import_combo_category")), (const gchar*) l->data);
3024 }
3025 g_hash_table_destroy(hash);
3026 g_list_free(items);
3027
3028 return GTK_WIDGET(gtk_builder_get_object(csvimport_builder, "csv_import_dialog"));
3029 }
3030
get_csv_export_dialog(void)3031 GtkWidget* get_csv_export_dialog(void) {
3032
3033 if(!csvexport_builder) {
3034
3035 csvexport_builder = getBuilder("csvexport.ui");
3036 g_assert(csvexport_builder != NULL);
3037
3038 g_assert (gtk_builder_get_object(csvexport_builder, "csv_export_dialog") != NULL);
3039
3040 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(csvexport_builder, "csv_export_combobox_delimiter")), 0);
3041
3042 gtk_builder_connect_signals(csvexport_builder, NULL);
3043
3044 }
3045
3046 return GTK_WIDGET(gtk_builder_get_object(csvexport_builder, "csv_export_dialog"));
3047
3048 }
3049 extern string prev_output_base, prev_input_base;
get_set_base_dialog(void)3050 GtkWidget* get_set_base_dialog(void) {
3051 if(!setbase_builder) {
3052
3053 setbase_builder = getBuilder("setbase.ui");
3054 g_assert(setbase_builder != NULL);
3055
3056 g_assert (gtk_builder_get_object(setbase_builder, "set_base_dialog") != NULL);
3057
3058 PrintOptions po = printops;
3059 po.number_fraction_format = FRACTION_DECIMAL_EXACT;
3060 po.interval_display = INTERVAL_DISPLAY_PLUSMINUS;
3061 po.preserve_precision = true;
3062 po.base = 10;
3063 if(printops.base >= BASE_CUSTOM && !CALCULATOR->customOutputBase().isZero()) gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), CALCULATOR->customOutputBase().print(po).c_str());
3064 if(evalops.parse_options.base >= BASE_CUSTOM && !CALCULATOR->customInputBase().isZero()) gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), CALCULATOR->customInputBase().print(po).c_str());
3065 switch(evalops.parse_options.base) {
3066 case BASE_BINARY: {
3067 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_binary")), TRUE);
3068 break;
3069 }
3070 case BASE_OCTAL: {
3071 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_octal")), TRUE);
3072 break;
3073 }
3074 case BASE_DECIMAL: {
3075 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_decimal")), TRUE);
3076 break;
3077 }
3078 case 12: {
3079 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_duodecimal")), TRUE);
3080 break;
3081 }
3082 case BASE_HEXADECIMAL: {
3083 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_hexadecimal")), TRUE);
3084 break;
3085 }
3086 case BASE_ROMAN_NUMERALS: {
3087 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_roman")), TRUE);
3088 break;
3089 }
3090 case BASE_UNICODE: {
3091 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3092 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), "Unicode");
3093 break;
3094 }
3095 case BASE_E: {
3096 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3097 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), "e");
3098 break;
3099 }
3100 case BASE_PI: {
3101 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3102 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), "π");
3103 break;
3104 }
3105 case BASE_GOLDEN_RATIO: {
3106 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3107 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), "φ");
3108 break;
3109 }
3110 case BASE_SUPER_GOLDEN_RATIO: {
3111 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3112 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), "ψ");
3113 break;
3114 }
3115 case BASE_SQRT2: {
3116 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3117 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), "√2");
3118 break;
3119 }
3120 case BASE_BIJECTIVE_26: {
3121 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3122 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), _("Bijective base-26"));
3123 break;
3124 }
3125 case BASE_CUSTOM: {
3126 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_input_other")), TRUE);
3127 break;
3128 }
3129 default: {
3130 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3131 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_input_other")), i2s(evalops.parse_options.base).c_str());
3132 }
3133 }
3134 switch(printops.base) {
3135 case BASE_BINARY: {
3136 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_binary")), TRUE);
3137 break;
3138 }
3139 case BASE_OCTAL: {
3140 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_octal")), TRUE);
3141 break;
3142 }
3143 case BASE_DECIMAL: {
3144 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_decimal")), TRUE);
3145 break;
3146 }
3147 case 12: {
3148 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_duodecimal")), TRUE);
3149 break;
3150 }
3151 case BASE_HEXADECIMAL: {
3152 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_hexadecimal")), TRUE);
3153 break;
3154 }
3155 case BASE_SEXAGESIMAL: {
3156 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_sexagesimal")), TRUE);
3157 break;
3158 }
3159 case BASE_TIME: {
3160 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_time")), TRUE);
3161 break;
3162 }
3163 case BASE_ROMAN_NUMERALS: {
3164 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_roman")), TRUE);
3165 break;
3166 }
3167 case BASE_UNICODE: {
3168 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3169 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "Unicode");
3170 break;
3171 }
3172 case BASE_E: {
3173 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3174 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "e");
3175 break;
3176 }
3177 case BASE_PI: {
3178 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3179 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "π");
3180 break;
3181 }
3182 case BASE_GOLDEN_RATIO: {
3183 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3184 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "φ");
3185 break;
3186 }
3187 case BASE_SUPER_GOLDEN_RATIO: {
3188 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3189 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "ψ");
3190 break;
3191 }
3192 case BASE_SQRT2: {
3193 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3194 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "sqrt(2)");
3195 break;
3196 }
3197 case BASE_BIJECTIVE_26: {
3198 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3199 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), _("Bijective base-26"));
3200 break;
3201 }
3202 case BASE_FP16: {
3203 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3204 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "fp16");
3205 break;
3206 }
3207 case BASE_FP32: {
3208 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3209 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "float");
3210 break;
3211 }
3212 case BASE_FP64: {
3213 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3214 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "double");
3215 break;
3216 }
3217 case BASE_FP80: {
3218 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3219 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "fp80");
3220 break;
3221 }
3222 case BASE_FP128: {
3223 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3224 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), "fp128");
3225 break;
3226 }
3227 case BASE_CUSTOM: {
3228 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3229 break;
3230 }
3231 default: {
3232 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(setbase_builder, "set_base_radiobutton_output_other")), TRUE);
3233 gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(setbase_builder, "set_base_entry_output_other")), i2s(printops.base).c_str());
3234 }
3235 }
3236
3237 SET_FOCUS_ON_CLICK(gtk_builder_get_object(setbase_builder, "button_close"));
3238
3239 gtk_builder_connect_signals(setbase_builder, NULL);
3240
3241 }
3242 prev_output_base = ""; prev_input_base = "";
3243 return GTK_WIDGET(gtk_builder_get_object(setbase_builder, "set_base_dialog"));
3244 }
3245
get_nbases_dialog(void)3246 GtkWidget* get_nbases_dialog(void) {
3247 if(!nbases_builder) {
3248
3249 nbases_builder = getBuilder("nbases.ui");
3250 g_assert(nbases_builder != NULL);
3251
3252 g_assert (gtk_builder_get_object(nbases_builder, "nbases_dialog") != NULL);
3253
3254 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(nbases_builder, "nbases_entry_binary")), 1.0);
3255 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(nbases_builder, "nbases_entry_octal")), 1.0);
3256 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(nbases_builder, "nbases_entry_decimal")), 1.0);
3257 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(nbases_builder, "nbases_entry_hexadecimal")), 1.0);
3258 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(nbases_builder, "nbases_entry_duo")), 1.0);
3259 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(nbases_builder, "nbases_entry_roman")), 1.0);
3260
3261 if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MINUS, (void*) gtk_builder_get_object(nbases_builder, "nbases_label_sub"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(nbases_builder, "nbases_label_sub")), SIGN_MINUS);
3262 else gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(nbases_builder, "nbases_label_sub")), MINUS);
3263 if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) gtk_builder_get_object(nbases_builder, "nbases_label_times"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(nbases_builder, "nbases_label_times")), SIGN_MULTIPLICATION);
3264 else gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(nbases_builder, "nbases_label_times")), MULTIPLICATION);
3265 if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_DIVISION_SLASH, (void*) gtk_builder_get_object(nbases_builder, "nbases_label_divide"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(nbases_builder, "nbases_label_divide")), SIGN_DIVISION_SLASH);
3266 else if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_DIVISION, (void*) gtk_builder_get_object(nbases_builder, "nbases_label_divide"))) gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(nbases_builder, "nbases_label_divide")), SIGN_DIVISION);
3267 else gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(nbases_builder, "nbases_label_divide")), DIVISION);
3268
3269 gchar *theme_name = NULL;
3270 g_object_get(gtk_settings_get_default(), "gtk-theme-name", &theme_name, NULL);
3271 string themestr;
3272 if(theme_name) {
3273 themestr = theme_name;
3274 g_free(theme_name);
3275 }
3276
3277 if(themestr.substr(0, 7) == "Adwaita" || themestr.substr(0, 6) == "ooxmox" || themestr == "Breeze" || themestr == "Breeze-Dark" || themestr == "Yaru") {
3278 GtkCssProvider *link_style_top = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_top, "* {border-bottom-left-radius: 0; border-bottom-right-radius: 0}", -1, NULL);
3279 GtkCssProvider *link_style_bot = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_bot, "* {border-top-left-radius: 0; border-top-right-radius: 0}", -1, NULL);
3280 GtkCssProvider *link_style_tl = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_tl, "* {border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-top-right-radius: 0;}", -1, NULL);
3281 GtkCssProvider *link_style_tr = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_tr, "* {border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-top-left-radius: 0;}", -1, NULL);
3282 GtkCssProvider *link_style_bl = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_bl, "* {border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-right-radius: 0;}", -1, NULL);
3283 GtkCssProvider *link_style_br = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_br, "* {border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-left-radius: 0;}", -1, NULL);
3284 GtkCssProvider *link_style_mid = gtk_css_provider_new(); gtk_css_provider_load_from_data(link_style_mid, "* {border-radius: 0;}", -1, NULL);
3285
3286 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_zero"))), GTK_STYLE_PROVIDER(link_style_bl), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3287 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_one"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3288 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_two"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3289 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_three"))), GTK_STYLE_PROVIDER(link_style_br), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3290 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_four"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3291 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_five"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3292 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_six"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3293 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_seven"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3294 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_eight"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3295 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_nine"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3296 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_a"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3297 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_b"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3298 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_c"))), GTK_STYLE_PROVIDER(link_style_tl), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3299 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_d"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3300 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_e"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3301 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_f"))), GTK_STYLE_PROVIDER(link_style_tr), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3302 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_and"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3303 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_or"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3304 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_xor"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3305 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_not"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3306 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_divide"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3307 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_times"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3308 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_sub"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3309 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_add"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3310 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_left_shift"))), GTK_STYLE_PROVIDER(link_style_top), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3311 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_right_shift"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3312 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_del"))), GTK_STYLE_PROVIDER(link_style_mid), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3313 gtk_style_context_add_provider(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_button_ac"))), GTK_STYLE_PROVIDER(link_style_bot), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3314 }
3315
3316 GdkRGBA c;
3317 gtk_style_context_get_color(gtk_widget_get_style_context(GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_label_decimal"))), GTK_STATE_FLAG_NORMAL, &c);
3318 GdkRGBA c_err = c;
3319 if(c_err.red >= 0.8) {
3320 c_err.green /= 1.5;
3321 c_err.blue /= 1.5;
3322 c_err.red = 1.0;
3323 } else {
3324 if(c_err.red >= 0.5) c_err.red = 1.0;
3325 else c_err.red += 0.5;
3326 }
3327 gchar ecs[8];
3328 g_snprintf(ecs, 8, "#%02x%02x%02x", (int) (c_err.red * 255), (int) (c_err.green * 255), (int) (c_err.blue * 255));
3329 nbases_error_color = ecs;
3330
3331 GdkRGBA c_warn = c;
3332 if(c_warn.blue >= 0.8) {
3333 c_warn.green /= 1.5;
3334 c_warn.red /= 1.5;
3335 c_warn.blue = 1.0;
3336 } else {
3337 if(c_warn.blue >= 0.3) c_warn.blue = 1.0;
3338 else c_warn.blue += 0.7;
3339 }
3340 gchar wcs[8];
3341 g_snprintf(wcs, 8, "#%02x%02x%02x", (int) (c_warn.red * 255), (int) (c_warn.green * 255), (int) (c_warn.blue * 255));
3342 nbases_warning_color = wcs;
3343
3344 gtk_builder_connect_signals(nbases_builder, NULL);
3345
3346 }
3347
3348 return GTK_WIDGET(gtk_builder_get_object(nbases_builder, "nbases_dialog"));
3349 }
get_percentage_dialog(void)3350 GtkWidget* get_percentage_dialog(void) {
3351 if(!percentage_builder) {
3352
3353 percentage_builder = getBuilder("percentage.ui");
3354 g_assert(percentage_builder != NULL);
3355
3356 g_assert (gtk_builder_get_object(percentage_builder, "percentage_dialog") != NULL);
3357
3358 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(percentage_builder, "percentage_entry_1")), 1.0);
3359 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(percentage_builder, "percentage_entry_2")), 1.0);
3360 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(percentage_builder, "percentage_entry_3")), 1.0);
3361 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(percentage_builder, "percentage_entry_4")), 1.0);
3362 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(percentage_builder, "percentage_entry_5")), 1.0);
3363 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(percentage_builder, "percentage_entry_6")), 1.0);
3364 gtk_entry_set_alignment(GTK_ENTRY(gtk_builder_get_object(percentage_builder, "percentage_entry_7")), 1.0);
3365
3366 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(gtk_builder_get_object(percentage_builder, "percentage_description")), 12);
3367 gtk_text_view_set_right_margin(GTK_TEXT_VIEW(gtk_builder_get_object(percentage_builder, "percentage_description")), 12);
3368 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 18
3369 gtk_text_view_set_top_margin(GTK_TEXT_VIEW(gtk_builder_get_object(percentage_builder, "percentage_description")), 12);
3370 gtk_text_view_set_bottom_margin(GTK_TEXT_VIEW(gtk_builder_get_object(percentage_builder, "percentage_description")), 12);
3371 #else
3372 gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(gtk_builder_get_object(percentage_builder, "percentage_description")), 12);
3373 #endif
3374
3375 gtk_builder_connect_signals(percentage_builder, NULL);
3376
3377 }
3378
3379 return GTK_WIDGET(gtk_builder_get_object(percentage_builder, "percentage_dialog"));
3380 }
3381
3382 unordered_map<size_t, GtkWidget*> cal_year, cal_month, cal_day, cal_label;
3383 GtkWidget *chinese_stem, *chinese_branch;
3384
get_calendarconversion_dialog(void)3385 GtkWidget* get_calendarconversion_dialog(void) {
3386 if(!calendarconversion_builder) {
3387
3388 calendarconversion_builder = getBuilder("calendarconversion.ui");
3389 g_assert(calendarconversion_builder != NULL);
3390
3391 g_assert(gtk_builder_get_object(calendarconversion_builder, "calendar_dialog") != NULL);
3392
3393 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_1")), _("Gregorian"));
3394 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_8")), _("Revised Julian (Milanković)"));
3395 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_7")), _("Julian"));
3396 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_3")), _("Islamic (Hijri)"));
3397 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_2")), _("Hebrew"));
3398 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_6")), _("Chinese"));
3399 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_4")), _("Persian (Solar Hijri)"));
3400 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_9")), _("Coptic"));
3401 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_10")), _("Ethiopian"));
3402 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(calendarconversion_builder, "label_5")), _("Indian (National)"));
3403
3404 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 12
3405 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_1")), 12);
3406 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_2")), 12);
3407 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_3")), 12);
3408 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_4")), 12);
3409 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_5")), 12);
3410 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_6")), 12);
3411 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_7")), 12);
3412 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_8")), 12);
3413 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_9")), 12);
3414 gtk_widget_set_margin_end(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_10")), 12);
3415 #else
3416 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_1")), 12);
3417 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_2")), 12);
3418 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_3")), 12);
3419 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_4")), 12);
3420 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_5")), 12);
3421 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_6")), 12);
3422 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_7")), 12);
3423 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_8")), 12);
3424 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_9")), 12);
3425 gtk_widget_set_margin_right(GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_10")), 12);
3426 #endif
3427
3428 cal_year[CALENDAR_GREGORIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_1"));
3429 cal_month[CALENDAR_GREGORIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_1"));
3430 cal_day[CALENDAR_GREGORIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_1"));
3431 cal_label[CALENDAR_GREGORIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_1"));
3432 cal_year[CALENDAR_HEBREW] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_2"));
3433 cal_month[CALENDAR_HEBREW] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_2"));
3434 cal_day[CALENDAR_HEBREW] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_2"));
3435 cal_label[CALENDAR_HEBREW] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_2"));
3436 cal_year[CALENDAR_ISLAMIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_3"));
3437 cal_month[CALENDAR_ISLAMIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_3"));
3438 cal_day[CALENDAR_ISLAMIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_3"));
3439 cal_label[CALENDAR_ISLAMIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_3"));
3440 cal_year[CALENDAR_PERSIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_4"));
3441 cal_month[CALENDAR_PERSIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_4"));
3442 cal_day[CALENDAR_PERSIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_4"));
3443 cal_label[CALENDAR_PERSIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_4"));
3444 cal_year[CALENDAR_INDIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_5"));
3445 cal_month[CALENDAR_INDIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_5"));
3446 cal_day[CALENDAR_INDIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_5"));
3447 cal_label[CALENDAR_INDIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_5"));
3448 cal_year[CALENDAR_CHINESE] = NULL;
3449 chinese_stem = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "stem_6"));
3450 chinese_branch = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "branch_6"));
3451 cal_month[CALENDAR_CHINESE] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_6"));
3452 cal_day[CALENDAR_CHINESE] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_6"));
3453 cal_label[CALENDAR_CHINESE] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_6"));
3454 cal_year[CALENDAR_JULIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_7"));
3455 cal_month[CALENDAR_JULIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_7"));
3456 cal_day[CALENDAR_JULIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_7"));
3457 cal_label[CALENDAR_JULIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_7"));
3458 cal_year[CALENDAR_MILANKOVIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_8"));
3459 cal_month[CALENDAR_MILANKOVIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_8"));
3460 cal_day[CALENDAR_MILANKOVIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_8"));
3461 cal_label[CALENDAR_MILANKOVIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_8"));
3462 cal_year[CALENDAR_COPTIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_9"));
3463 cal_month[CALENDAR_COPTIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_9"));
3464 cal_day[CALENDAR_COPTIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_9"));
3465 cal_label[CALENDAR_COPTIC] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_9"));
3466 cal_year[CALENDAR_ETHIOPIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "year_10"));
3467 cal_month[CALENDAR_ETHIOPIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "month_10"));
3468 cal_day[CALENDAR_ETHIOPIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "day_10"));
3469 cal_label[CALENDAR_ETHIOPIAN] = GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "label_10"));
3470
3471 for(size_t i = 0; i < NUMBER_OF_CALENDARS; i++) {
3472 if(cal_day.count(i) > 0) {
3473 if(i == CALENDAR_CHINESE) {
3474 for(size_t i2 = 1; i2 <= 5; i2++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(chinese_stem), chineseStemName(i2 * 2).c_str());
3475 for(size_t i2 = 1; i2 <= 12; i2++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(chinese_branch), chineseBranchName(i2).c_str());
3476 } else {
3477 gtk_spin_button_set_range(GTK_SPIN_BUTTON(cal_year[i]), G_MININT, G_MAXINT);
3478 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(cal_year[i]), TRUE);
3479 gtk_spin_button_set_increments(GTK_SPIN_BUTTON(cal_year[i]), 1.0, 10.0);
3480 gtk_spin_button_set_digits(GTK_SPIN_BUTTON(cal_year[i]), 0);
3481 gtk_entry_set_alignment(GTK_ENTRY(cal_year[i]), 1.0);
3482 }
3483 for(size_t i2 = 1; i2 <= (size_t) numberOfMonths((CalendarSystem) i); i2++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cal_month[i]), monthName(i2, (CalendarSystem) i, true).c_str());
3484 for(size_t i2 = 1; i2 <= 31; i2++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cal_day[i]), i2s(i2).c_str());
3485 }
3486 }
3487
3488 QalculateDateTime date;
3489 date.setToCurrentDate();
3490 gtk_spin_button_set_value(GTK_SPIN_BUTTON(cal_year[CALENDAR_GREGORIAN]), date.year());
3491 gtk_combo_box_set_active(GTK_COMBO_BOX(cal_month[CALENDAR_GREGORIAN]), date.month() - 1);
3492
3493 for(size_t i = 0; i < NUMBER_OF_CALENDARS; i++) {
3494 if(cal_day.count(i) > 0) {
3495 if(i == CALENDAR_CHINESE) {
3496 g_signal_connect(chinese_stem, "changed", G_CALLBACK(calendar_changed), GINT_TO_POINTER((gint) i));
3497 g_signal_connect(chinese_branch, "changed", G_CALLBACK(calendar_changed), GINT_TO_POINTER((gint) i));
3498 } else {
3499 g_signal_connect(cal_year[i], "value-changed", G_CALLBACK(calendar_changed), GINT_TO_POINTER((gint) i));
3500 }
3501 g_signal_connect(cal_month[i], "changed", G_CALLBACK(calendar_changed), GINT_TO_POINTER((gint) i));
3502 g_signal_connect(cal_day[i], "changed", G_CALLBACK(calendar_changed), GINT_TO_POINTER((gint) i));
3503 }
3504 }
3505
3506 gtk_builder_connect_signals(calendarconversion_builder, NULL);
3507
3508 gtk_combo_box_set_active(GTK_COMBO_BOX(cal_day[CALENDAR_GREGORIAN]), date.day() - 1);
3509
3510 }
3511
3512 return GTK_WIDGET(gtk_builder_get_object(calendarconversion_builder, "calendar_dialog"));
3513 }
3514
create_InfoWidget(const gchar * text)3515 GtkWidget *create_InfoWidget(const gchar *text) {
3516
3517 GtkWidget *hbox, *image, *infolabel;
3518
3519 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
3520 gtk_widget_show(hbox);
3521 gtk_widget_set_halign(hbox, GTK_ALIGN_START);
3522 //gtk_widget_set_valign(hbox, GTK_ALIGN_CENTER);
3523
3524 image = gtk_image_new_from_icon_name("dialog-information", GTK_ICON_SIZE_BUTTON);
3525 gtk_widget_show(image);
3526 gtk_box_pack_start (GTK_BOX(hbox), image, FALSE, TRUE, 0);
3527
3528 infolabel = gtk_label_new(text);
3529 gtk_widget_show(infolabel);
3530 gtk_box_pack_start(GTK_BOX(hbox), infolabel, FALSE, FALSE, 0);
3531 gtk_label_set_justify(GTK_LABEL(infolabel), GTK_JUSTIFY_LEFT);
3532 gtk_label_set_line_wrap(GTK_LABEL(infolabel), TRUE);
3533
3534 return hbox;
3535 }
3536
get_argument_rules_dialog(void)3537 GtkWidget* get_argument_rules_dialog(void) {
3538
3539 if(!argumentrules_builder) {
3540
3541 argumentrules_builder = getBuilder("argumentrules.ui");
3542 g_assert(argumentrules_builder != NULL);
3543
3544 g_assert (gtk_builder_get_object(argumentrules_builder, "argument_rules_dialog") != NULL);
3545
3546 gtk_builder_connect_signals(argumentrules_builder, NULL);
3547
3548 }
3549
3550 return GTK_WIDGET(gtk_builder_get_object(argumentrules_builder, "argument_rules_dialog"));
3551 }
get_decimals_dialog(void)3552 GtkWidget* get_decimals_dialog(void) {
3553 if(!decimals_builder) {
3554
3555 decimals_builder = getBuilder("decimals.ui");
3556 g_assert(decimals_builder != NULL);
3557
3558 g_assert (gtk_builder_get_object(decimals_builder, "decimals_dialog") != NULL);
3559
3560 gtk_builder_connect_signals(decimals_builder, NULL);
3561
3562 }
3563
3564 return GTK_WIDGET(gtk_builder_get_object(decimals_builder, "decimals_dialog"));
3565 }
get_plot_dialog(void)3566 GtkWidget* get_plot_dialog(void) {
3567 if(!plot_builder) {
3568
3569 if(!CALCULATOR->canPlot()) return NULL;
3570
3571 plot_builder = getBuilder("plot.ui");
3572 g_assert(plot_builder != NULL);
3573
3574 g_assert (gtk_builder_get_object(plot_builder, "plot_dialog") != NULL);
3575
3576 tPlotFunctions = GTK_WIDGET(gtk_builder_get_object(plot_builder, "plot_treeview_data"));
3577 tPlotFunctions_store = gtk_list_store_new(10, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING);
3578 gtk_tree_view_set_model(GTK_TREE_VIEW(tPlotFunctions), GTK_TREE_MODEL(tPlotFunctions_store));
3579 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tPlotFunctions));
3580 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
3581 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
3582 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Title"), renderer, "text", 0, NULL);
3583 gtk_tree_view_append_column(GTK_TREE_VIEW(tPlotFunctions), column);
3584 renderer = gtk_cell_renderer_text_new();
3585 column = gtk_tree_view_column_new_with_attributes(_("Expression"), renderer, "text", 1, NULL);
3586 gtk_tree_view_append_column(GTK_TREE_VIEW(tPlotFunctions), column);
3587 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tPlotFunctions_selection_changed), NULL);
3588
3589 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(plot_builder, "plot_button_save")), false);
3590
3591 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(plot_builder, "plot_combobox_style")), 0);
3592 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(plot_builder, "plot_combobox_smoothing")), 0);
3593 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(plot_builder, "plot_combobox_legend_place")), 0);
3594
3595 gtk_builder_connect_signals(plot_builder, NULL);
3596
3597 }
3598
3599 return GTK_WIDGET(gtk_builder_get_object(plot_builder, "plot_dialog"));
3600 }
get_precision_dialog(void)3601 GtkWidget* get_precision_dialog(void) {
3602 if(!precision_builder) {
3603
3604 precision_builder = getBuilder("precision.ui");
3605 g_assert(precision_builder != NULL);
3606
3607 g_assert (gtk_builder_get_object(precision_builder, "precision_dialog") != NULL);
3608
3609 gtk_builder_connect_signals(precision_builder, NULL);
3610
3611 }
3612
3613 return GTK_WIDGET(gtk_builder_get_object(precision_builder, "precision_dialog"));
3614 }
get_periodic_dialog(void)3615 GtkWidget* get_periodic_dialog(void) {
3616 if(!periodictable_builder) {
3617
3618 periodictable_builder = getBuilder("periodictable.ui");
3619 g_assert(periodictable_builder != NULL);
3620
3621 g_assert (gtk_builder_get_object(periodictable_builder, "periodic_dialog") != NULL);
3622
3623 gtk_builder_connect_signals(periodictable_builder, NULL);
3624
3625 DataSet *dc = CALCULATOR->getDataSet("atom");
3626 if(!dc) {
3627 return GTK_WIDGET(gtk_builder_get_object(periodictable_builder, "periodic_dialog"));
3628 }
3629
3630 DataObject *e;
3631 GtkWidget *e_button;
3632 GtkGrid *e_table = GTK_GRID(gtk_builder_get_object(periodictable_builder, "periodic_table"));
3633 string tip;
3634 GtkCssProvider *e_style[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
3635 GtkCssProvider *l_style = NULL;
3636 DataProperty *p_xpos = dc->getProperty("x_pos");
3637 DataProperty *p_ypos = dc->getProperty("y_pos");
3638 DataProperty *p_weight = dc->getProperty("weight");
3639 DataProperty *p_number = dc->getProperty("number");
3640 DataProperty *p_symbol = dc->getProperty("symbol");
3641 DataProperty *p_class = dc->getProperty("class");
3642 DataProperty *p_name = dc->getProperty("name");
3643 int x_pos = 0, y_pos = 0, group = 0;
3644 string weight;
3645 l_style = gtk_css_provider_new();
3646 for(size_t i3 = 0; i3 < 12; i3++) {
3647 e_style[i3] = gtk_css_provider_new();
3648 }
3649 for(size_t i = 1; i < 120; i++) {
3650 e = dc->getObject(i2s(i));
3651 if(e) {
3652 x_pos = s2i(e->getProperty(p_xpos));
3653 y_pos = s2i(e->getProperty(p_ypos));
3654 }
3655 if(e && x_pos > 0 && x_pos <= 18 && y_pos > 0 && y_pos <= 10) {
3656 e_button = gtk_button_new();
3657 gtk_button_set_relief(GTK_BUTTON(e_button), GTK_RELIEF_HALF);
3658 gtk_container_add(GTK_CONTAINER(e_button), gtk_label_new(e->getProperty(p_symbol).c_str()));
3659 group = s2i(e->getProperty(p_class));
3660 if(group > 0 && group <= 11) gtk_style_context_add_provider(gtk_widget_get_style_context(e_button), GTK_STYLE_PROVIDER(e_style[group - 1]), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3661 else gtk_style_context_add_provider(gtk_widget_get_style_context(e_button), GTK_STYLE_PROVIDER(e_style[11]), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
3662 if(x_pos > 2) gtk_grid_attach(e_table, e_button, x_pos + 1, y_pos, 1, 1);
3663 else gtk_grid_attach(e_table, e_button, x_pos, y_pos, 1, 1);
3664 tip = e->getProperty(p_number);
3665 tip += " ";
3666 tip += e->getProperty(p_name);
3667 weight = e->getPropertyDisplayString(p_weight);
3668 if(!weight.empty() && weight != "-") {
3669 tip += "\n";
3670 tip += weight;
3671 }
3672 gtk_widget_set_tooltip_text(e_button, tip.c_str());
3673 gtk_widget_show_all(e_button);
3674 g_signal_connect((gpointer) e_button, "clicked", G_CALLBACK(on_element_button_clicked), (gpointer) e);
3675 }
3676 }
3677 gtk_css_provider_load_from_data(l_style, "* {color: #000000;}", -1, NULL);
3678 gtk_css_provider_load_from_data(e_style[0], "* {color: #000000; background-image: none; background-color: #eeccee;}", -1, NULL);
3679 gtk_css_provider_load_from_data(e_style[1], "* {color: #000000; background-image: none; background-color: #ddccee;}", -1, NULL);
3680 gtk_css_provider_load_from_data(e_style[2], "* {color: #000000; background-image: none; background-color: #ccddff;}", -1, NULL);
3681 gtk_css_provider_load_from_data(e_style[3], "* {color: #000000; background-image: none; background-color: #ddeeff;}", -1, NULL);
3682 gtk_css_provider_load_from_data(e_style[4], "* {color: #000000; background-image: none; background-color: #cceeee;}", -1, NULL);
3683 gtk_css_provider_load_from_data(e_style[5], "* {color: #000000; background-image: none; background-color: #bbffbb;}", -1, NULL);
3684 gtk_css_provider_load_from_data(e_style[6], "* {color: #000000; background-image: none; background-color: #eeffdd;}", -1, NULL);
3685 gtk_css_provider_load_from_data(e_style[7], "* {color: #000000; background-image: none; background-color: #ffffaa;}", -1, NULL);
3686 gtk_css_provider_load_from_data(e_style[8], "* {color: #000000; background-image: none; background-color: #ffddaa;}", -1, NULL);
3687 gtk_css_provider_load_from_data(e_style[9], "* {color: #000000; background-image: none; background-color: #ffccdd;}", -1, NULL);
3688 gtk_css_provider_load_from_data(e_style[10], "* {color: #000000; background-image: none; background-color: #aaeedd;}", -1, NULL);
3689 gtk_css_provider_load_from_data(e_style[11], "* {color: #000000; background-image: none;}", -1, NULL);
3690 }
3691
3692 return GTK_WIDGET(gtk_builder_get_object(periodictable_builder, "periodic_dialog"));
3693 }
3694
get_shortcuts_dialog(void)3695 GtkWidget* get_shortcuts_dialog(void) {
3696 if(!shortcuts_builder) {
3697
3698 shortcuts_builder = getBuilder("shortcuts.ui");
3699 g_assert(shortcuts_builder != NULL);
3700
3701 g_assert(gtk_builder_get_object(shortcuts_builder, "shortcuts_dialog") != NULL);
3702
3703 tShortcuts = GTK_WIDGET(gtk_builder_get_object(shortcuts_builder, "shortcuts_treeview"));
3704
3705 tShortcuts_store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64);
3706 gtk_tree_view_set_model(GTK_TREE_VIEW(tShortcuts), GTK_TREE_MODEL(tShortcuts_store));
3707 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tShortcuts));
3708 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
3709 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
3710 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer, "text", 0, NULL);
3711 gtk_tree_view_column_set_sort_column_id(column, 0);
3712 gtk_tree_view_append_column(GTK_TREE_VIEW(tShortcuts), column);
3713 renderer = gtk_cell_renderer_text_new();
3714 column = gtk_tree_view_column_new_with_attributes(_("Value"), renderer, "text", 1, NULL);
3715 gtk_tree_view_column_set_sort_column_id(column, 1);
3716 gtk_tree_view_append_column(GTK_TREE_VIEW(tShortcuts), column);
3717 renderer = gtk_cell_renderer_text_new();
3718 column = gtk_tree_view_column_new_with_attributes(_("Key combination"), renderer, "text", 2, NULL);
3719 gtk_tree_view_column_set_sort_column_id(column, 2);
3720 gtk_tree_view_append_column(GTK_TREE_VIEW(tShortcuts), column);
3721 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tShortcuts_selection_changed), NULL);
3722
3723 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tShortcuts_store), 0, GTK_SORT_ASCENDING);
3724
3725 tShortcutsType = GTK_WIDGET(gtk_builder_get_object(shortcuts_builder, "shortcuts_type_treeview"));
3726
3727 tShortcutsType_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
3728 gtk_tree_view_set_model(GTK_TREE_VIEW(tShortcutsType), GTK_TREE_MODEL(tShortcutsType_store));
3729 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tShortcutsType));
3730 gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
3731 renderer = gtk_cell_renderer_text_new();
3732 column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer, "text", 0, NULL);
3733 gtk_tree_view_column_set_sort_column_id(column, 0);
3734 gtk_tree_view_append_column(GTK_TREE_VIEW(tShortcutsType), column);
3735 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tShortcutsType_selection_changed), NULL);
3736
3737 for(int i = 0; i <= SHORTCUT_TYPE_QUIT; i++) {
3738 GtkTreeIter iter;
3739 gtk_list_store_append(tShortcutsType_store, &iter);
3740 gtk_list_store_set(tShortcutsType_store, &iter, 0, shortcut_type_text(i), 1, i, -1);
3741 if(i == SHORTCUT_TYPE_RPN_MODE) {
3742 gtk_list_store_append(tShortcutsType_store, &iter);
3743 gtk_list_store_set(tShortcutsType_store, &iter, 0, shortcut_type_text(SHORTCUT_TYPE_CHAIN_MODE), 1, SHORTCUT_TYPE_CHAIN_MODE, -1);
3744 }
3745 if(i == 0) gtk_tree_selection_select_iter(selection, &iter);
3746 }
3747
3748 for(unordered_map<guint64, keyboard_shortcut>::iterator it = keyboard_shortcuts.begin(); it != keyboard_shortcuts.end(); ++it) {
3749 GtkTreeIter iter;
3750 gtk_list_store_insert(tShortcuts_store, &iter, 0);
3751 gtk_list_store_set(tShortcuts_store, &iter, 0, shortcut_type_text(it->second.type), 1, it->second.value.c_str(), 2, shortcut_to_text(it->second.key, it->second.modifier).c_str(), 3, (guint64) it->second.key + (guint64) G_MAXUINT32 * (guint64) it->second.modifier, -1);
3752 }
3753
3754 gtk_builder_connect_signals(shortcuts_builder, NULL);
3755
3756 }
3757
3758 return GTK_WIDGET(gtk_builder_get_object(shortcuts_builder, "shortcuts_dialog"));
3759 }
get_floatingpoint_dialog(void)3760 GtkWidget* get_floatingpoint_dialog(void) {
3761 if(!floatingpoint_builder) {
3762
3763 floatingpoint_builder = getBuilder("floatingpoint.ui");
3764 g_assert(floatingpoint_builder != NULL);
3765
3766 g_assert (gtk_builder_get_object(floatingpoint_builder, "floatingpoint_dialog") != NULL);
3767
3768 #if GTK_MAJOR_VERSION > 3 || GTK_MINOR_VERSION >= 18
3769 gtk_text_view_set_top_margin(GTK_TEXT_VIEW(gtk_builder_get_object(floatingpoint_builder, "fp_textedit_bin")), 6);
3770 gtk_text_view_set_bottom_margin(GTK_TEXT_VIEW(gtk_builder_get_object(floatingpoint_builder, "fp_textedit_bin")), 6);
3771 #else
3772 gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(gtk_builder_get_object(floatingpoint_builder, "fp_textedit_bin")), 6);
3773 #endif
3774
3775 gtk_builder_connect_signals(floatingpoint_builder, NULL);
3776
3777 }
3778
3779 return GTK_WIDGET(gtk_builder_get_object(floatingpoint_builder, "floatingpoint_dialog"));
3780 }
3781
3782 #define SET_BUTTONS_EDIT_ITEM_3(l, t1, t2, t3) \
3783 {gtk_list_store_set(tButtonsEdit_store, &iter, 1, custom_buttons[i].text.empty() ? l : custom_buttons[i].text.c_str(), 2, custom_buttons[i].type[0] == -1 ? t1 : (custom_buttons[i].value[0].empty() ? shortcut_type_text(custom_buttons[i].type[0]) : custom_buttons[i].value[0].c_str()), 3, custom_buttons[i].type[1] == -1 ? t2 : (custom_buttons[i].value[1].empty() ? shortcut_type_text(custom_buttons[i].type[1]) : custom_buttons[i].value[1].c_str()), 4, custom_buttons[i].type[2] == -1 ? t3 : (custom_buttons[i].value[2].empty() ? shortcut_type_text(custom_buttons[i].type[2]) : custom_buttons[i].value[2].c_str()), -1);\
3784 if(index >= 0) break;}
3785
3786 #define SET_BUTTONS_EDIT_ITEM_3B(l, t1, t2, t3) SET_BUTTONS_EDIT_ITEM_3(gtk_label_get_text(GTK_LABEL(gtk_builder_get_object(main_builder, l))), t1, t2, t3)
3787 #define SET_BUTTONS_EDIT_ITEM_2(l, t1, t2) SET_BUTTONS_EDIT_ITEM_3(l, t1, t2, t2)
3788 #define SET_BUTTONS_EDIT_ITEM_2B(l, t1, t2) SET_BUTTONS_EDIT_ITEM_3(gtk_label_get_text(GTK_LABEL(gtk_builder_get_object(main_builder, l))), t1, t2, t2)
3789 #define SET_BUTTONS_EDIT_ITEM_C(l) SET_BUTTONS_EDIT_ITEM_3(l, "-", "-", "-")
3790
update_custom_buttons_edit(int index,bool update_label_entry)3791 void update_custom_buttons_edit(int index, bool update_label_entry) {
3792 GtkTreeIter iter;
3793 gtk_tree_model_get_iter_first(GTK_TREE_MODEL(tButtonsEdit_store), &iter);
3794 int i = 0;
3795 do {
3796 gtk_tree_model_get(GTK_TREE_MODEL(tButtonsEdit_store), &iter, 0, &i, -1);
3797 if(i == 0 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2("↑ ↓", _("Cycle through previous expression"), "-")
3798 else if(i == 1 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2("← →", _("Move cursor left or right"), _("Move cursor to beginning or end"))
3799 else if(i == 2 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2("%", CALCULATOR->v_percent->title(true).c_str(), CALCULATOR->v_permille->title(true).c_str())
3800 else if(i == 3 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("±", _("Uncertainty/interval"), _("Relative error"), _("Interval"))
3801 else if(i == 4 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3B("label_comma", _("Argument separator"), _("Blank space"), _("New line"))
3802 else if(i == 5 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2("(x)", _("Smart parentheses"), _("Vector brackets"))
3803 else if(i == 6 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2("(", _("Left parenthesis"), _("Left vector bracket"))
3804 else if(i == 7 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2(")", _("Right parenthesis"), _("Right vector bracket"))
3805 else if(i == 8 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("0", "0", "x^0", CALCULATOR->getDegUnit()->title(true).c_str())
3806 else if(i == 9 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("1", "1", "x^1", "1/x")
3807 else if(i == 10 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("2", "2", "x^2", "1/2")
3808 else if(i == 11 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("3", "3", "x^3", "1/3")
3809 else if(i == 12 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("4", "4", "x^4", "1/4")
3810 else if(i == 13 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("5", "5", "x^5", "1/5")
3811 else if(i == 14 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("6", "6", "x^6", "1/6")
3812 else if(i == 15 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("7", "7", "x^7", "1/7")
3813 else if(i == 16 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("8", "8", "x^8", "1/8")
3814 else if(i == 17 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("9", "9", "x^9", "1/9")
3815 else if(i == 18 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3B("label_dot", _("Decimal point"), _("Blank space"), _("New line"))
3816 else if(i == 19 && (index == i || index < 0)) {
3817 MathFunction *f = CALCULATOR->getActiveFunction("exp10");
3818 SET_BUTTONS_EDIT_ITEM_3B("label_exp", "10^x", CALCULATOR->f_exp->title(true).c_str(), (f ? f->title(true).c_str() : "-"));
3819 } else if(i == 20 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2("x^y", _("Raise"), CALCULATOR->f_sqrt->title(true).c_str())
3820 else if(i == 21 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2B("label_divide", _("Divide"), "1/x")
3821 else if(i == 22 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2B("label_times", _("Multiply"), _("Bitwise Exclusive OR"))
3822 else if(i == 23 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3B("label_add", _("Add"), _("M+ (memory plus)"), _("Bitwise AND"))
3823 else if(i == 24 && (index == i || index < 0)) {
3824 MathFunction *f = CALCULATOR->getActiveFunction("neg");
3825 SET_BUTTONS_EDIT_ITEM_3B("label_sub", _("Subtract"), f ? f->title(true).c_str() : "-", _("Bitwise OR"));
3826 } else if(i == 25 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2B("label_ac", _("Clear"), _("MC (memory clear)"))
3827 else if(i == 26 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3B("label_del", _("Delete"), _("Backspace"), _("M− (memory minus)"))
3828 else if(i == 27 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_2B("label_ans", _("Previous result"), _("Previous result (static)"))
3829 else if(i == 28 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_3("=", _("Calculate expression"), _("MR (memory recall)"), _("MS (memory store)"))
3830 else if(i == 29 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_C("C1")
3831 else if(i == 30 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_C("C2")
3832 else if(i == 31 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_C("C3")
3833 else if(i == 32 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_C("C4")
3834 else if(i == 33 && (index == i || index < 0)) SET_BUTTONS_EDIT_ITEM_C("C5")
3835 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(tButtonsEdit_store), &iter));
3836 on_tButtonsEdit_update_selection(gtk_tree_view_get_selection(GTK_TREE_VIEW(tButtonsEdit)), update_label_entry);
3837 }
get_buttons_edit_dialog(void)3838 GtkWidget* get_buttons_edit_dialog(void) {
3839 if(!buttonsedit_builder) {
3840
3841 buttonsedit_builder = getBuilder("buttonsedit.ui");
3842 g_assert(buttonsedit_builder != NULL);
3843
3844 g_assert(gtk_builder_get_object(buttonsedit_builder, "buttons_edit_dialog") != NULL);
3845
3846 tButtonsEdit = GTK_WIDGET(gtk_builder_get_object(buttonsedit_builder, "buttons_edit_treeview"));
3847
3848 tButtonsEdit_store = gtk_list_store_new(5, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
3849 gtk_tree_view_set_model(GTK_TREE_VIEW(tButtonsEdit), GTK_TREE_MODEL(tButtonsEdit_store));
3850 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tButtonsEdit));
3851 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
3852 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
3853 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Label"), renderer, "text", 1, NULL);
3854 gtk_tree_view_append_column(GTK_TREE_VIEW(tButtonsEdit), column);
3855 renderer = gtk_cell_renderer_text_new();
3856 column = gtk_tree_view_column_new_with_attributes(_("Left-click"), renderer, "text", 2, NULL);
3857 gtk_tree_view_append_column(GTK_TREE_VIEW(tButtonsEdit), column);
3858 renderer = gtk_cell_renderer_text_new();
3859 column = gtk_tree_view_column_new_with_attributes(_("Right-click"), renderer, "text", 3, NULL);
3860 gtk_tree_view_append_column(GTK_TREE_VIEW(tButtonsEdit), column);
3861 renderer = gtk_cell_renderer_text_new();
3862 column = gtk_tree_view_column_new_with_attributes(_("Middle-click"), renderer, "text", 4, NULL);
3863 gtk_tree_view_append_column(GTK_TREE_VIEW(tButtonsEdit), column);
3864 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tButtonsEdit_selection_changed), NULL);
3865
3866 GtkTreeIter iter;
3867 for(int i = 29; i < 34; i++) {
3868 gtk_list_store_append(tButtonsEdit_store, &iter);
3869 gtk_list_store_set(tButtonsEdit_store, &iter, 0, i, -1);
3870 }
3871 for(int i = 0; i < 20; i++) {
3872 gtk_list_store_append(tButtonsEdit_store, &iter);
3873 gtk_list_store_set(tButtonsEdit_store, &iter, 0, i, -1);
3874 }
3875 gtk_tree_selection_unselect_all(selection);
3876
3877 update_custom_buttons_edit();
3878
3879 tButtonsEditType = GTK_WIDGET(gtk_builder_get_object(buttonsedit_builder, "shortcuts_type_treeview"));
3880
3881 tButtonsEditType_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
3882 gtk_tree_view_set_model(GTK_TREE_VIEW(tButtonsEditType), GTK_TREE_MODEL(tButtonsEditType_store));
3883 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tButtonsEditType));
3884 gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
3885 renderer = gtk_cell_renderer_text_new();
3886 column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer, "text", 0, NULL);
3887 gtk_tree_view_column_set_sort_column_id(column, 0);
3888 gtk_tree_view_append_column(GTK_TREE_VIEW(tButtonsEditType), column);
3889 g_signal_connect((gpointer) selection, "changed", G_CALLBACK(on_tButtonsEditType_selection_changed), NULL);
3890
3891 gtk_list_store_append(tButtonsEditType_store, &iter);
3892 gtk_list_store_set(tButtonsEditType_store, &iter, 0, _("None"), 1, -2, -1);
3893 for(int i = 0; i <= SHORTCUT_TYPE_QUIT; i++) {
3894 gtk_list_store_append(tButtonsEditType_store, &iter);
3895 gtk_list_store_set(tButtonsEditType_store, &iter, 0, shortcut_type_text(i), 1, i, -1);
3896 if(i == SHORTCUT_TYPE_RPN_MODE) {
3897 gtk_list_store_append(tButtonsEditType_store, &iter);
3898 gtk_list_store_set(tButtonsEditType_store, &iter, 0, shortcut_type_text(SHORTCUT_TYPE_CHAIN_MODE), 1, SHORTCUT_TYPE_CHAIN_MODE, -1);
3899 }
3900 if(i == 0) gtk_tree_selection_select_iter(selection, &iter);
3901 }
3902
3903 gtk_builder_connect_signals(buttonsedit_builder, NULL);
3904
3905 }
3906
3907 return GTK_WIDGET(gtk_builder_get_object(buttonsedit_builder, "buttons_edit_dialog"));
3908 }
3909
3910