1/* 2 * Copyright (C) 2008-2012 Robert Ancell 3 * 4 * This program is free software: you can redistribute it and/or modify it under 5 * the terms of the GNU General Public License as published by the Free Software 6 * Foundation, either version 3 of the License, or (at your option) any later 7 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the 8 * license. 9 */ 10 11public enum ButtonMode 12{ 13 BASIC, 14 ADVANCED, 15 FINANCIAL, 16 PROGRAMMING, 17 KEYBOARD 18} 19 20public class MathButtons : Gtk.Box 21{ 22 private MathEquation equation; 23 24 private ButtonMode _mode; 25 public ButtonMode mode 26 { 27 get { return _mode; } 28 set 29 { 30 if (_mode == value) 31 return; 32 _mode = value; 33 34 if (mode == ButtonMode.PROGRAMMING) 35 equation.number_base = _programming_base; 36 else 37 equation.number_base = 10; 38 39 load_buttons (); 40 41 converter.set_visible (mode == ButtonMode.ADVANCED || mode == ButtonMode.FINANCIAL); 42 if (mode == ButtonMode.ADVANCED) 43 { 44 converter.set_category (null); 45 converter.set_conversion (equation.source_units, equation.target_units); 46 } 47 else if (mode == ButtonMode.FINANCIAL) 48 { 49 converter.set_category ("currency"); 50 converter.set_conversion (equation.source_currency, equation.target_currency); 51 } 52 53 update_view_more_visible (); 54 converter.view_more_active = false; 55 if (prog_view_more_button != null) 56 prog_view_more_button.active = false; 57 if (adv_panel != null) 58 (adv_panel as Hdy.Leaflet).visible_child_name = "basic"; 59 if (fin_panel != null) 60 (fin_panel as Hdy.Leaflet).visible_child_name = "basic"; 61 if (prog_leaflet != null) 62 prog_leaflet.visible_child_name = "basic"; 63 } 64 } 65 private int _programming_base = 10; 66 67 private MathConverter converter; 68 69 private Gtk.Builder basic_ui; 70 private Gtk.Builder advanced_ui; 71 private Gtk.Builder financial_ui; 72 private Gtk.Builder programming_ui; 73 74 private Gtk.Widget bas_panel; 75 private Gtk.Widget adv_panel; 76 private Gtk.Widget fin_panel; 77 private Gtk.Widget prog_panel; 78 private Gtk.Widget? active_panel = null; 79 80 private Hdy.Leaflet prog_leaflet; 81 private Gtk.ToggleButton prog_view_more_button; 82 83 private Gtk.ComboBox base_combo; 84 private Gtk.Label base_label; 85 private Gtk.Label word_size_label; 86 private Gtk.Widget bit_panel; 87 private List<Gtk.Button> toggle_bit_buttons; 88 89 private Gtk.Dialog character_code_dialog; 90 private Gtk.Entry character_code_entry; 91 92 /* The names of each field in the dialogs for the financial functions */ 93 private const string[] ctrm_entries = {"ctrm_pint", "ctrm_fv", "ctrm_pv"}; 94 private const string[] ddb_entries = {"ddb_cost", "ddb_life", "ddb_period"}; 95 private const string[] fv_entries = {"fv_pmt", "fv_pint", "fv_n"}; 96 private const string[] gpm_entries = {"gpm_cost", "gpm_margin"}; 97 private const string[] pmt_entries = {"pmt_prin", "pmt_pint", "pmt_n"}; 98 private const string[] pv_entries = {"pv_pmt", "pv_pint", "pv_n"}; 99 private const string[] rate_entries = {"rate_fv", "rate_pv", "rate_n"}; 100 private const string[] sln_entries = {"sln_cost", "sln_salvage", "sln_life"}; 101 private const string[] syd_entries = {"syd_cost", "syd_salvage", "syd_life", "syd_period" }; 102 private const string[] term_entries = {"term_pmt","term_fv", "term_pint"}; 103 104 private SimpleActionGroup action_group = new SimpleActionGroup (); 105 private const ActionEntry[] action_entries = { 106 {"insert-general", on_insert, "s" }, 107 {"insert-digit", on_insert_digit, "i" }, 108 {"subtract", on_subtract }, 109 {"square", on_square }, 110 {"undo", on_undo }, 111 {"solve", on_solve }, 112 {"clear", on_clear }, 113 {"factorize", on_factorize }, 114 {"insert-exponent", on_insert_exponent }, 115 {"bitshift", on_bitshift, "i" }, 116 {"set-word-size", on_set_word_size, "i" }, 117 {"toggle-bit", on_toggle_bit, "i" }, 118 {"insert-character", on_insert_character }, 119 {"insert-numeric-point", on_insert_numeric_point }, 120 {"set-number-mode", on_set_number_mode, "s", "'normal'" }, 121 {"launch-finc-dialog", on_launch_finc_dialog, "s" } 122 }; 123 124 public MathButtons (MathEquation equation) 125 { 126 Object (orientation: Gtk.Orientation.VERTICAL, vexpand_set: true); 127 show.connect (load_buttons); 128 this.equation = equation; 129 130 action_group.add_action_entries (action_entries, this); 131 insert_action_group ("cal", action_group); 132 133 equation.notify["display"].connect ((pspec) => { update_bit_panel (); }); 134 equation.notify["number-mode"].connect ((pspec) => { number_mode_changed_cb (); }); 135 equation.notify["angle-units"].connect ((pspec) => { update_bit_panel (); }); 136 equation.notify["number-format"].connect ((pspec) => { update_bit_panel (); }); 137 equation.notify["word-size"].connect ((pspec) => { word_size_changed_cb (); }); 138 number_mode_changed_cb (); 139 update_bit_panel (); 140 } 141 142 private void load_finc_dialogs () 143 { 144 load_finc_dialog ("ctrm_dialog", ctrm_entries, FinancialDialog.CTRM_DIALOG); 145 load_finc_dialog ("ddb_dialog", ddb_entries, FinancialDialog.DDB_DIALOG); 146 load_finc_dialog ("fv_dialog", fv_entries, FinancialDialog.FV_DIALOG); 147 load_finc_dialog ("gpm_dialog", gpm_entries, FinancialDialog.GPM_DIALOG); 148 load_finc_dialog ("pmt_dialog", pmt_entries, FinancialDialog.PMT_DIALOG); 149 load_finc_dialog ("pv_dialog", pv_entries, FinancialDialog.PV_DIALOG); 150 load_finc_dialog ("rate_dialog", rate_entries, FinancialDialog.RATE_DIALOG); 151 load_finc_dialog ("sln_dialog", sln_entries, FinancialDialog.SLN_DIALOG); 152 load_finc_dialog ("syd_dialog", syd_entries, FinancialDialog.SYD_DIALOG); 153 load_finc_dialog ("term_dialog", term_entries, FinancialDialog.TERM_DIALOG); 154 } 155 156 private void load_finc_dialog (string name, string[] entry_names, FinancialDialog function) 157 { 158 var dialog = financial_ui.get_object (name) as Gtk.Dialog; 159 dialog.set_data<int> ("finc-function", function); 160 dialog.response.connect (finc_response_cb); 161 for (var i = 0; i < entry_names.length; i++) 162 { 163 var entry = financial_ui.get_object (entry_names[i]) as Gtk.Entry; 164 if (i != entry_names.length - 1) 165 entry.set_data<Gtk.Entry> ("next-entry", financial_ui.get_object (entry_names[i+1]) as Gtk.Entry); 166 entry.activate.connect (finc_activate_cb); 167 } 168 } 169 170 private void on_insert (SimpleAction action, Variant? param) 171 { 172 equation.insert (param.get_string ()); 173 } 174 175 private void on_insert_digit (SimpleAction action, Variant? param) 176 { 177 equation.insert_digit (param.get_int32 ()); 178 } 179 180 private void on_subtract (SimpleAction action, Variant? param) 181 { 182 equation.insert_subtract (); 183 } 184 185 private void on_square (SimpleAction action, Variant? param) 186 { 187 equation.insert_square (); 188 } 189 190 private void on_undo (SimpleAction action, Variant? param) 191 { 192 equation.undo (); 193 } 194 195 private void on_solve (SimpleAction action, Variant? param) 196 { 197 equation.solve (); 198 } 199 200 private void on_clear (SimpleAction action, Variant? param) 201 { 202 equation.clear (); 203 } 204 205 private void on_factorize (SimpleAction action, Variant? param) 206 { 207 equation.factorize (); 208 } 209 210 private void on_insert_exponent (SimpleAction action, Variant? param) 211 { 212 equation.insert_exponent (); 213 } 214 215 private void on_bitshift (SimpleAction action, Variant? param) 216 { 217 equation.insert_shift (param.get_int32 ()); 218 } 219 220 private void on_set_word_size (SimpleAction action, Variant? param) 221 { 222 equation.word_size = (param.get_int32 ()); 223 string format = ngettext("%d-bit", "%d-bit", param.get_int32 ()); 224 word_size_label.set_label(format.printf(param.get_int32 ())); 225 } 226 227 private void on_insert_numeric_point (SimpleAction action, Variant? param) 228 { 229 equation.insert_numeric_point (); 230 } 231 232 private void update_bit_panel () 233 { 234 if (bit_panel == null) 235 return; 236 237 var x = equation.number; 238 239 uint64 bits = 0; 240 var enabled = x != null; 241 if (enabled) 242 { 243 var max = new Number.unsigned_integer (uint64.MAX); 244 var fraction = x.fractional_part (); 245 if (x.is_negative () || x.compare (max) > 0 || !fraction.is_zero ()) 246 enabled = false; 247 else 248 bits = x.to_unsigned_integer (); 249 } 250 251 bit_panel.set_sensitive (enabled); 252 base_label.set_sensitive (enabled); 253 254 if (!enabled) 255 return; 256 257 var i = 0; 258 foreach (var button in toggle_bit_buttons) 259 { 260 var text = "0"; 261 if ((bits & (1ULL << i)) != 0) 262 text = "1"; 263 button.label = text; 264 i++; 265 } 266 267 var number_base = equation.number_base; 268 var label = ""; 269 if (number_base != 8) 270 label += "%llo₈".printf (bits); 271 if (number_base != 10) 272 { 273 if (label != "") 274 label += " = "; 275 label += "%llu₁₀".printf (bits); 276 } 277 if (number_base != 16) 278 { 279 if (label != "") 280 label += " = "; 281 label += "%llX₁₆".printf (bits); 282 } 283 284 base_label.set_text (label); 285 } 286 287 private void base_combobox_changed_cb (Gtk.ComboBox combo) 288 { 289 programming_base = int.parse (combo.active_id); 290 } 291 292 private void base_changed_cb () 293 { 294 if (mode != ButtonMode.PROGRAMMING) 295 return; 296 297 _programming_base = equation.number_base; 298 299 base_combo.active_id = _programming_base.to_string (); 300 update_bit_panel (); 301 302 } 303 304 private void update_view_more_visible () 305 { 306 bool visible; 307 308 switch (mode) 309 { 310 default: 311 case ButtonMode.BASIC: 312 visible = false; 313 break; 314 case ButtonMode.ADVANCED: 315 visible = adv_panel != null && (adv_panel as Hdy.Leaflet).folded; 316 break; 317 case ButtonMode.FINANCIAL: 318 visible = fin_panel != null && (fin_panel as Hdy.Leaflet).folded; 319 break; 320 case ButtonMode.PROGRAMMING: 321 visible = prog_leaflet != null && prog_leaflet.folded; 322 break; 323 } 324 325 converter.view_more_visible = visible; 326 if (prog_view_more_button != null) 327 prog_view_more_button.visible = visible; 328 } 329 330 private void update_view_more_active () 331 { 332 switch (mode) 333 { 334 default: 335 case ButtonMode.BASIC: 336 break; 337 case ButtonMode.ADVANCED: 338 if (adv_panel != null) 339 converter.view_more_active = prog_view_more_button.active = (adv_panel as Hdy.Leaflet).visible_child_name == "advanced"; 340 break; 341 case ButtonMode.FINANCIAL: 342 if (fin_panel != null) 343 converter.view_more_active = prog_view_more_button.active = (fin_panel as Hdy.Leaflet).visible_child_name == "advanced"; 344 break; 345 case ButtonMode.PROGRAMMING: 346 if (prog_panel != null) 347 converter.view_more_active = prog_view_more_button.active = prog_leaflet.visible_child_name == "advanced"; 348 break; 349 } 350 } 351 352 private Gtk.Widget load_mode (ButtonMode mode) 353 { 354 Gtk.Builder builder; 355 string builder_resource; 356 switch (mode) 357 { 358 default: 359 case ButtonMode.BASIC: 360 if (bas_panel != null) 361 return bas_panel; 362 builder = basic_ui = new Gtk.Builder (); 363 builder_resource = "buttons-basic.ui"; 364 break; 365 case ButtonMode.ADVANCED: 366 if (adv_panel != null) 367 return adv_panel; 368 builder = advanced_ui = new Gtk.Builder (); 369 builder_resource = "buttons-advanced.ui"; 370 break; 371 case ButtonMode.FINANCIAL: 372 if (fin_panel != null) 373 return fin_panel; 374 builder = financial_ui = new Gtk.Builder (); 375 builder_resource = "buttons-financial.ui"; 376 break; 377 case ButtonMode.PROGRAMMING: 378 if (prog_panel != null) 379 return prog_panel; 380 builder = programming_ui = new Gtk.Builder (); 381 builder_resource = "buttons-programming.ui"; 382 break; 383 } 384 385 try 386 { 387 builder.add_from_resource ("/org/gnome/calculator/%s".printf(builder_resource)); 388 } 389 catch (Error e) 390 { 391 error ("Error loading button UI: %s", e.message); 392 } 393 394 var panel = builder.get_object ("button_panel") as Gtk.Widget; 395 pack_end (panel, true, true, 0); 396 397 switch (mode) 398 { 399 default: 400 case ButtonMode.BASIC: 401 bas_panel = panel; 402 break; 403 case ButtonMode.ADVANCED: 404 adv_panel = panel; 405 406 converter.bind_property ("view-more-active", panel, "visible-child-name", 407 BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL, 408 (binding, from, ref to) => { to.set_string (from.get_boolean () ? "advanced" : "basic"); return true; }, 409 (binding, from, ref to) => { to.set_boolean (from.get_string () == "advanced"); return true; }); 410 adv_panel.notify["folded"].connect (update_view_more_visible); 411 break; 412 case ButtonMode.FINANCIAL: 413 fin_panel = panel; 414 415 converter.bind_property ("view-more-active", panel, "visible-child-name", 416 BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL, 417 (binding, from, ref to) => { to.set_string (from.get_boolean () ? "advanced" : "basic"); return true; }, 418 (binding, from, ref to) => { to.set_boolean (from.get_string () == "advanced"); return true; }); 419 fin_panel.notify["folded"].connect (update_view_more_visible); 420 break; 421 case ButtonMode.PROGRAMMING: 422 prog_panel = panel; 423 prog_leaflet = builder.get_object ("leaflet") as Hdy.Leaflet; 424 425 prog_view_more_button = builder.get_object ("view_more_button") as Gtk.ToggleButton; 426 prog_view_more_button.bind_property ("active", prog_leaflet, "visible-child-name", 427 BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL, 428 (binding, from, ref to) => { to.set_string (from.get_boolean () ? "advanced" : "basic"); return true; }, 429 (binding, from, ref to) => { to.set_boolean (from.get_string () == "advanced"); return true; }); 430 prog_leaflet.notify["folded"].connect (update_view_more_visible); 431 break; 432 } 433 434 /* Configure buttons */ 435 var button = builder.get_object ("calc_numeric_point_button") as Gtk.Button; 436 if (button != null) 437 button.set_label (equation.serializer.get_radix ().to_string ()); 438 439 var menu_button = builder.get_object ("calc_shift_left_button") as Gtk.MenuButton; 440 if (menu_button != null) 441 menu_button.menu_model = create_shift_menu (true); 442 menu_button = builder.get_object ("calc_shift_right_button") as Gtk.MenuButton; 443 if (menu_button != null) 444 menu_button.menu_model = create_shift_menu (false); 445 menu_button = builder.get_object ("calc_word_size_button") as Gtk.MenuButton; 446 if (menu_button != null) 447 menu_button.menu_model = create_word_size_menu (); 448 menu_button = builder.get_object ("calc_memory_button") as Gtk.MenuButton; 449 if (menu_button != null) 450 menu_button.popover = new MathVariablePopover (equation); 451 menu_button = builder.get_object ("calc_function_button") as Gtk.MenuButton; 452 if (menu_button != null) 453 menu_button.popover = new MathFunctionPopover (equation); 454 455 if (mode == ButtonMode.PROGRAMMING) 456 { 457 base_label = builder.get_object ("base_label") as Gtk.Label; 458 character_code_dialog = builder.get_object ("character_code_dialog") as Gtk.Dialog; 459 character_code_dialog.response.connect (character_code_dialog_response_cb); 460 character_code_dialog.delete_event.connect (character_code_dialog_delete_cb); 461 character_code_entry = builder.get_object ("character_code_entry") as Gtk.Entry; 462 character_code_entry.activate.connect (character_code_dialog_activate_cb); 463 464 bit_panel = builder.get_object ("bit_table") as Gtk.Widget; 465 toggle_bit_buttons = new List<Gtk.Button> (); 466 var i = 0; 467 while (true) 468 { 469 var name = "toggle_bit_%d_button".printf (i); 470 var toggle_bit_button = builder.get_object (name) as Gtk.Button; 471 if (toggle_bit_button == null) 472 break; 473 toggle_bit_buttons.append (toggle_bit_button); 474 i++; 475 } 476 toggle_bit_buttons.reverse (); 477 word_size_label = builder.get_object ("word_size_label") as Gtk.Label; 478 base_combo = builder.get_object ("base_combo") as Gtk.ComboBox; 479 base_combo.changed.connect (base_combobox_changed_cb); 480 equation.notify["number-base"].connect ((pspec) => { base_changed_cb (); } ); 481 base_changed_cb (); 482 word_size_changed_cb (); 483 } 484 485 /* Setup financial functions */ 486 if (mode == ButtonMode.FINANCIAL) 487 load_finc_dialogs (); 488 489 builder.connect_signals (this); 490 491 update_bit_panel (); 492 update_view_more_visible (); 493 494 return panel; 495 } 496 497 private void converter_changed_cb () 498 { 499 Unit from_unit, to_unit; 500 converter.get_conversion (out from_unit, out to_unit); 501 if (mode == ButtonMode.FINANCIAL) 502 { 503 equation.source_currency = from_unit.name; 504 equation.target_currency = to_unit.name; 505 } 506 else 507 { 508 equation.source_units = from_unit.name; 509 equation.target_units = to_unit.name; 510 } 511 } 512 513 private void load_buttons () 514 { 515 if (!get_visible ()) 516 return; 517 518 if (converter == null) 519 { 520 converter = new MathConverter (equation); 521 converter.changed.connect (converter_changed_cb); 522 pack_start (converter, false, true, 0); 523 converter.notify["view-more-active"].connect (() => { 524 if (adv_panel != null) 525 (adv_panel as Hdy.Leaflet).visible_child_name = converter.view_more_active ? "advanced" : "basic"; 526 if (fin_panel != null) 527 (fin_panel as Hdy.Leaflet).visible_child_name = converter.view_more_active ? "advanced" : "basic"; 528 }); 529 } 530 531 var panel = load_mode (mode); 532 if (active_panel == panel) 533 return; 534 535 /* Hide old buttons */ 536 if (active_panel != null) 537 active_panel.hide (); 538 539 /* Load and display new buttons */ 540 active_panel = panel; 541 if (panel != null) 542 panel.show (); 543 } 544 545 public int programming_base 546 { 547 get { return _programming_base; } 548 set 549 { 550 if (_programming_base == value) 551 return; 552 553 _programming_base = value; 554 555 if (mode == ButtonMode.PROGRAMMING) 556 equation.number_base = value; 557 } 558 } 559 560 private Menu create_shift_menu (bool shift_left) 561 { 562 var shift_menu = new Menu (); 563 564 for (var i = 1; i < 16; i++) 565 { 566 string format = ngettext ("%d place", "%d places", i); 567 if (i < 10) // Provide mnemonic for shifting [0..9] places 568 format = "_" + format; 569 570 var positions = (shift_left) ? i : -i; 571 shift_menu.append (format.printf (i), "cal.bitshift(%d)".printf (positions)); 572 } 573 574 return shift_menu; 575 } 576 577 private Menu create_word_size_menu () 578 { 579 var word_size_menu = new Menu (); 580 var i = 64; 581 string format = ngettext ("%d-bit", "%d-bit", i); 582 word_size_menu.append(format.printf (i), "cal.set-word-size(%d)".printf (i)); 583 i = 32; 584 word_size_menu.append(format.printf (i), "cal.set-word-size(%d)".printf (i)); 585 i = 16; 586 word_size_menu.append(format.printf (i), "cal.set-word-size(%d)".printf (i)); 587 i = 8; 588 word_size_menu.append(format.printf (i), "cal.set-word-size(%d)".printf (i)); 589 590 return word_size_menu; 591 } 592 593 private void word_size_changed_cb () 594 { 595 var size = equation.word_size; 596 string format = ngettext ("%d-bit", "%d-bit", size); 597 word_size_label.set_label (format.printf(size)); 598 update_bit_button_sensitivities (); 599 } 600 601 private void update_bit_button_sensitivities () 602 { 603 var i = 0; 604 foreach (var button in toggle_bit_buttons) 605 { 606 if (i < equation.word_size) 607 { 608 button.set_sensitive (true); 609 } 610 else 611 { 612 if (button.label == "1") 613 { 614 equation.toggle_bit (63-i); 615 } 616 button.set_sensitive (false); 617 } 618 i++; 619 } 620 } 621 private void on_launch_finc_dialog (SimpleAction action, Variant? param) 622 { 623 var name = param.get_string (); 624 var dialog = financial_ui.get_object (name) as Gtk.Dialog; 625 dialog.run (); 626 dialog.hide (); 627 } 628 629 private void on_insert_character (SimpleAction action, Variant? param) 630 { 631 character_code_dialog.present (); 632 } 633 634 private void finc_activate_cb (Gtk.Widget widget) 635 { 636 var next_entry = widget.get_data<Gtk.Entry> ("next-entry"); 637 if (next_entry == null) 638 { 639 var dialog = widget.get_toplevel () as Gtk.Dialog; 640 if (dialog.is_toplevel ()) 641 { 642 dialog.response (Gtk.ResponseType.OK); 643 return; 644 } 645 } 646 else 647 next_entry.grab_focus (); 648 } 649 650 private void finc_response_cb (Gtk.Widget widget, int response_id) 651 { 652 if (response_id != Gtk.ResponseType.OK) 653 return; 654 655 var function = (FinancialDialog) widget.get_data<int> ("finc-function"); 656 var entries = new string[0]; 657 switch (function) 658 { 659 case FinancialDialog.CTRM_DIALOG: 660 entries = ctrm_entries; 661 break; 662 case FinancialDialog.DDB_DIALOG: 663 entries = ddb_entries; 664 break; 665 case FinancialDialog.FV_DIALOG: 666 entries = fv_entries; 667 break; 668 case FinancialDialog.GPM_DIALOG: 669 entries = gpm_entries; 670 break; 671 case FinancialDialog.PMT_DIALOG: 672 entries = pmt_entries; 673 break; 674 case FinancialDialog.PV_DIALOG: 675 entries = pv_entries; 676 break; 677 case FinancialDialog.RATE_DIALOG: 678 entries = rate_entries; 679 break; 680 case FinancialDialog.SLN_DIALOG: 681 entries = sln_entries; 682 break; 683 case FinancialDialog.SYD_DIALOG: 684 entries = syd_entries; 685 break; 686 case FinancialDialog.TERM_DIALOG: 687 entries = term_entries; 688 break; 689 } 690 691 Number arg[4] = { new Number.integer (0), new Number.integer (0), new Number.integer (0), new Number.integer (0) }; 692 for (var i = 0; i < entries.length; i++) 693 { 694 var entry = financial_ui.get_object (entries[i]) as Gtk.Entry; 695 arg[i] = mp_set_from_string (entry.get_text ()); 696 entry.set_text ("0"); 697 } 698 var first_entry = financial_ui.get_object (entries[0]) as Gtk.Entry; 699 first_entry.grab_focus (); 700 701 do_finc_expression (equation, function, arg[0], arg[1], arg[2], arg[3]); 702 } 703 704 private void character_code_dialog_response_cb (Gtk.Widget dialog, int response_id) 705 { 706 string text = character_code_entry.get_text (); 707 if (response_id == Gtk.ResponseType.OK) 708 { 709 var x = new Number.integer (0); 710 var decoded = text.data; 711 var len = decoded.length; 712 for (var i = 0; i < len; i++) 713 { 714 x = x.add (new Number.integer (decoded[i])); 715 if(i != (len - 1)) 716 { 717 x = x.shift (8); 718 } 719 } 720 equation.insert_number (x); 721 } 722 723 dialog.hide (); 724 } 725 726 private void character_code_dialog_activate_cb (Gtk.Widget entry) 727 { 728 character_code_dialog_response_cb (character_code_dialog, Gtk.ResponseType.OK); 729 } 730 731 private bool character_code_dialog_delete_cb (Gtk.Widget dialog, Gdk.EventAny event) 732 { 733 character_code_dialog_response_cb (dialog, Gtk.ResponseType.CANCEL); 734 return true; 735 } 736 737 private void on_toggle_bit (SimpleAction action, Variant? param) 738 { 739 equation.toggle_bit (param.get_int32 ()); 740 } 741 742 private void on_set_number_mode (SimpleAction action, Variant? param) 743 { 744 if (param.get_string () == action.state.get_string ()) 745 equation.number_mode = NumberMode.NORMAL; 746 else if (param.get_string () == "superscript") 747 { 748 equation.number_mode = NumberMode.SUPERSCRIPT; 749 if (!equation.has_selection) 750 equation.remove_trailing_spaces (); 751 } 752 else if (param.get_string () == "subscript") 753 { 754 equation.number_mode = NumberMode.SUBSCRIPT; 755 if (!equation.has_selection) 756 equation.remove_trailing_spaces (); 757 } 758 } 759 760 private void number_mode_changed_cb () 761 { 762 if (equation.number_mode == NumberMode.SUPERSCRIPT) 763 action_group.change_action_state ("set-number-mode", "superscript"); 764 else if (equation.number_mode == NumberMode.SUBSCRIPT) 765 action_group.change_action_state ("set-number-mode", "subscript"); 766 else 767 action_group.change_action_state ("set-number-mode", "normal"); 768 } 769} 770