From 47aa8b00b2b11df13a100489e0f904a4947177ef Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Tue, 8 May 2018 15:59:31 +0200 Subject: Import Upstream version 1.4.7 --- lib/configdialogues/compiler_config.tcl | 2058 +++++++++++++++++++++ lib/configdialogues/configdialogues.tcl | 60 + lib/configdialogues/custom_commands_config.tcl | 454 +++++ lib/configdialogues/editor_config.tcl | 2308 ++++++++++++++++++++++++ lib/configdialogues/global_config.tcl | 535 ++++++ lib/configdialogues/rightpanel_config.tcl | 505 ++++++ lib/configdialogues/shortcuts_config.tcl | 1035 +++++++++++ lib/configdialogues/simulator_config.tcl | 547 ++++++ lib/configdialogues/terminal_config.tcl | 396 ++++ lib/configdialogues/toolbar_config.tcl | 734 ++++++++ 10 files changed, 8632 insertions(+) create mode 100644 lib/configdialogues/compiler_config.tcl create mode 100644 lib/configdialogues/configdialogues.tcl create mode 100644 lib/configdialogues/custom_commands_config.tcl create mode 100644 lib/configdialogues/editor_config.tcl create mode 100644 lib/configdialogues/global_config.tcl create mode 100644 lib/configdialogues/rightpanel_config.tcl create mode 100644 lib/configdialogues/shortcuts_config.tcl create mode 100644 lib/configdialogues/simulator_config.tcl create mode 100644 lib/configdialogues/terminal_config.tcl create mode 100644 lib/configdialogues/toolbar_config.tcl (limited to 'lib/configdialogues') diff --git a/lib/configdialogues/compiler_config.tcl b/lib/configdialogues/compiler_config.tcl new file mode 100644 index 0000000..2f261ea --- /dev/null +++ b/lib/configdialogues/compiler_config.tcl @@ -0,0 +1,2058 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _COMPILER_CONFIG_TCL ] } { +set _COMPILER_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements compilers configuration dialog +# -------------------------------------------------------------------------- + +namespace eval compiler { + + variable win ;# ID of toplevel dialog window + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + variable conf_affected ;# Array of Bool: Affected parts of configuration + + # List of default settings + variable defaults { + {_symbols 0} + {_print 0} + {_object 0} + + {_nomod 0} + {_paging 0} + {_pagelength 0} + {_pagewidth 0} + {_title 0} + {_date 0} + {_list 0} + + {CREATE_SIM_FILE 1} + {CREATE_BIN_FILE 1} + {QUIET 0} + {optim_ena 0} + } + + # Option variables + variable option__symbols ;# Table of symbols (in *.lst) + variable option__print ;# Generate code listing + variable option__object ;# Generate object code (ihex8) + variable option__nomod ;# Ignore controls: $NOMOD + variable option__paging ;# Ignore controls: $PAGING, $NOPAGING + variable option__pagelength ;# Ignore controls: $PAGELENGTH + variable option__pagewidth ;# Ignore controls: $PAGEWIDTH + variable option__title ;# Ignore controls: $TITLE + variable option__date ;# Ignore controls: $DATE + variable option__list ;# Ignore controls: $LIST, $NOLIST, LIST, NOLIST + variable option_CREATE_SIM_FILE ;# Generate code for simulator + variable option_CREATE_BIN_FILE ;# Generate binary object code + variable option_QUIET ;# Verbose + variable opt_WARNING_LEVEL ;# Warning level + variable option_optim_ena ;# Enable optimization + variable max_ihex_rec_length ;# Int: Maximum length of IHEX-8 record + + variable primary_tab_asm ;# Widget: Tab "Assembly language" + variable primary_tab_c ;# Widget: Tab "C language" + variable assembler_tab_compiler ;# Widget: Tab "Compiler" + variable assembler_tab_M8I ;# Widget: Tab "MCU8051IDE" + variable assembler_tab_ASEM51 ;# Widget: Tab "ASEM-51" + variable assembler_tab_ASL ;# Widget: Tab "ASL" + variable assembler_tab_AS31 ;# Widget: Tab "AS31" + variable tertialy_tab_General ;# Widget: Tab "MAIN/C language/General" + variable tertialy_tab_Code ;# Widget: Tab "MAIN/C language/Code generation" + variable tertialy_tab_Optim ;# Widget: Tab "MAIN/C language/Optimization" + variable tertialy_tab_Linker ;# Widget: Tab "MAIN/C language/Linker" + variable tertialy_tab_Custom ;# Widget: Tab "MAIN/C language/Custom" + variable sdcc_custom_opts_text ;# Widget: Text widget "Custom options for SDCC" + variable asm51_custom_opts_text ;# Widget: Text widget "Custom options for ASEM-51" + variable asl_custom_opts_text ;# Widget: Text widget "Custom options for ASL" + variable as31_custom_opts_text ;# Widget: Text widget "Custom options for AS31" + + # External assembler configuration + variable selected_assembler ;# Int: Preferred assembler (0==MCU8051IDE;1==ASEM-51;2==ASL;3==AS31) + variable assembler_ASEM51_config;# Array: ASEM-51 configuration + variable assembler_ASEM51_addcfg;# Array: ASEM-51 additional configuration + variable assembler_ASL_config ;# Array: ASL configuration + variable assembler_ASL_addcfg ;# Array: ASL additional configuration + variable assembler_AS31_config ;# Array: AS31 configuration + variable assembler_AS31_addcfg ;# Array: AS31 additional configuration + + # SDCC Configuration + variable sdcc_bool_opt ;# Array: SDCC configuration + variable sdcc_str_opt ;# Array: SDCC configuration + variable sdcc_opt_str_opt ;# Array: SDCC configuration + variable sdcc_scs_str_opt ;# Array: SDCC configuration + + # GNU Make utility configuration + variable makeutil_config ;# Array: Make utility configuration + + ## Create the dialog + # @return void + proc mkDialog {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable conf_affected ;# Array of Bool: Affected parts of configuration + + variable primary_tab_asm ;# Widget: Tab "MAIN/Assembly language" + variable primary_tab_c ;# Widget: Tab "MAIN/C language" + variable primary_tab_make ;# Widget: Tab "MAIN/GNU make" + variable assembler_tab_compiler ;# Widget: Tab "Assembly language/Compiler" + variable assembler_tab_M8I ;# Widget: Tab "MCU8051IDE" + variable assembler_tab_ASEM51 ;# Widget: Tab "ASEM-51" + variable assembler_tab_ASL ;# Widget: Tab "ASL" + variable assembler_tab_AS31 ;# Widget: Tab "AS31" + + variable sdcc_custom_opts_text ;# Widget: Text widget "Custom options for SDCC" + variable asm51_custom_opts_text ;# Widget: Text widget "Custom options for ASEM-51" + variable asl_custom_opts_text ;# Widget: Text widget "Custom options for ASL" + variable as31_custom_opts_text ;# Widget: Text widget "Custom options for AS31" + + set sdcc_custom_opts_text {} + set asm51_custom_opts_text {} + set asl_custom_opts_text {} + set as31_custom_opts_text {} + + + # Destroy the dialog if it's already opened + if {$dialog_opened} { + destroy .compiler_config_dialog + } + set dialog_opened 1 + + # Initialize array conf_affected + foreach key { + MCU8051IDE ASEM51 ASL + SDCC_Custom SDCC_Linker SDCC_Optimization + SDCC_Code SDCC_General Compiler + AS31 + } { + set conf_affected($key) 0 + } + + # Get settings from Compiler NS + getSettings + + # Create toplevel window + set win [toplevel .compiler_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -image ::ICONS::32::exec \ + -text [mc "Compiler configuration"] \ + -font [font create \ + -size [expr {int(-20 * $::font_size_factor)}] \ + ] + + # Create primary notebook and its tabs + set primaryNB [ModernNoteBook $win.nb_p] + + # Tab: Assembly language + set primary_tab_asm [$primaryNB insert end primary_tab_asm \ + -text [mc "Assembly language"] \ + -image ::ICONS::16::asm \ + ] + + # Tab: C language -- SDCC + set primary_tab_c [$primaryNB insert end primary_tab_c \ + -text [mc "C language -- SDCC"] \ + -image ::ICONS::16::source_c \ + -createcmd {::configDialogues::compiler::create_C_tab} \ + ] + + if {!$::MICROSOFT_WINDOWS} { + # Tab: GNU make utility + set primary_tab_make [$primaryNB insert end primary_tab_make \ + -text [mc "GNU make utility"] \ + -image ::ICONS::16::text_x_makefile \ + -createcmd {::configDialogues::compiler::create_make_tab} \ + ] + } + + + # Create notebook "Assembly language" and its pages + set secondaryNB [ModernNoteBook $primary_tab_asm.secondaryNB] + + set assembler_tab_compiler [$secondaryNB insert end assembler_tab_compiler -text [mc "Assembler"] -createcmd {::configDialogues::compiler::create_compiler_tab}] + set assembler_tab_M8I [$secondaryNB insert end assembler_tab_M8I -text "MCU8051IDE" -createcmd {::configDialogues::compiler::create_asm_tab}] + set assembler_tab_ASEM51 [$secondaryNB insert end assembler_tab_ASEM51 -text "ASEM-51" -createcmd {::configDialogues::compiler::create_ASEM51_tab}] + if {!$::MICROSOFT_WINDOWS} { ;# There is no support for these external assemblers on Microsoft Windows + set assembler_tab_ASL [$secondaryNB insert end assembler_tab_ASL -text "ASL" -createcmd {::configDialogues::compiler::create_ASL_tab}] + set assembler_tab_AS31 [$secondaryNB insert end assembler_tab_AS31 -text "AS31" -createcmd {::configDialogues::compiler::create_AS31_tab}] + } + pack [$secondaryNB get_nb] -fill both -expand 1 + + # Raise pages in notebooks + $primaryNB raise primary_tab_asm + $secondaryNB raise assembler_tab_compiler + + ## Button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Reset" + pack [ttk::button $but_frame.but_default \ + -text [mc "Reset to defaults"] \ + -command {::configDialogues::compiler::DEFAULTS}\ + + ] -side left + DynamicHelp::add $but_frame.but_default \ + -text [mc "Reset all settings to defaults"] + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::compiler::OK} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_ok \ + -text [mc "Commit new settings"] + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::compiler::CANCEL} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_cancel \ + -text [mc "Take changes back and close dialog"] + + # Pack frames and notebook + pack $but_frame -side bottom -fill x -anchor s -padx 5 -pady 5 + pack $win.header_label -side top -pady 6 + pack [$primaryNB get_nb] -side top -fill both -padx 5 -expand 1 + + # Set window attributes + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Configure compiler - %s" ${::APPNAME}] + wm geometry $win 470x510 + wm resizable $win 0 0 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::compiler::CANCEL + } + tkwait window $win + } + + ## Create tab "GNU make utility" + # @return void + proc create_make_tab {} { + variable primary_tab_make ;# Widget: Tab "MAIN/GNU make" + + if {!${::PROGRAM_AVAILABLE(make)}} { + pack [label $primary_tab_make.warning_lbl \ + -fg {#DD0000} \ + -text [mc "Make utility is not available, please install GNU make and restart the IDE."] \ + ] -pady 10 + return + } + + set primary_tab_make [frame $primary_tab_make.f] + pack $primary_tab_make -side top -anchor w -padx 5 -pady 10 -fill both -expand 1 + + # + ## C compiler + # + grid [checkbutton $primary_tab_make.chb_c_ena \ + -text [mc "Use this Makefile instead of calling C compiler directly:"] \ + -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::makeutil_config(c_ena) \ + -command [list ::configDialogues::compiler::make_tab__chb_ena c] \ + ] -column 0 -row 0 -sticky w -padx 5 -columnspan 4 + + grid [ttk::label $primary_tab_make.clng_make_label \ + -text [mc "Makefile:"] + ] -column 0 -row 1 -padx 5 -pady 5 -sticky w + grid [ttk::button \ + $primary_tab_make.clng_clear_but \ + -style Flat.TButton \ + -takefocus 0 \ + -image ::ICONS::16::locationbar_erase \ + -command [list ::configDialogues::compiler::make_tab__clr_but c]\ + -state disabled \ + ] -column 1 -row 1 + DynamicHelp::add $primary_tab_make.clng_clear_but -text [mc "Clear the entrybox"] + grid [ttk::entry $primary_tab_make.clng_make_entry \ + -width 0 -validate all \ + -textvariable ::configDialogues::compiler::makeutil_config(c_file) \ + -validatecommand [list ::configDialogues::compiler::make_tab__entry_validator c %P] \ + ] -column 2 -row 1 -sticky we + grid [ttk::button $primary_tab_make.clng_flsel_but \ + -style Flat.TButton \ + -takefocus 0 \ + -image ::ICONS::16::fileopen \ + -command [list ::configDialogues::compiler::make_tab__flsel_but c] \ + ] -row 1 -column 3 -sticky e + DynamicHelp::add $primary_tab_make.clng_flsel_but -text [mc "Select Makefile"] + + grid [ttk::label $primary_tab_make.copt_make_label \ + -text [mc "Options:"] + ] -column 0 -row 2 -padx 5 -pady 5 -sticky w + grid [ttk::button \ + $primary_tab_make.colng_clear_but \ + -style Flat.TButton \ + -takefocus 0 \ + -image ::ICONS::16::locationbar_erase \ + -command [list ::configDialogues::compiler::make_tab__clr_but co]\ + -state disabled \ + ] -column 1 -row 2 + DynamicHelp::add $primary_tab_make.colng_clear_but -text [mc "Clear the entrybox"] + grid [ttk::entry $primary_tab_make.copt_make_entry \ + -width 0 -validate all \ + -textvariable ::configDialogues::compiler::makeutil_config(co_file) \ + -validatecommand [list ::configDialogues::compiler::make_tab__entry_validator co %P] \ + ] -column 2 -row 2 -sticky we + + grid [ttk::label $primary_tab_make.ctrg_make_label \ + -text [mc "Targets:"] + ] -column 0 -row 3 -padx 5 -pady 5 -sticky w + grid [ttk::button \ + $primary_tab_make.ctlng_clear_but \ + -style Flat.TButton \ + -takefocus 0 \ + -image ::ICONS::16::locationbar_erase \ + -command [list ::configDialogues::compiler::make_tab__clr_but ct]\ + -state disabled \ + ] -column 1 -row 3 + DynamicHelp::add $primary_tab_make.ctlng_clear_but -text [mc "Clear the entrybox"] + grid [ttk::entry $primary_tab_make.ctrg_make_entry \ + -width 0 -validate all \ + -textvariable ::configDialogues::compiler::makeutil_config(ct_file) \ + -validatecommand [list ::configDialogues::compiler::make_tab__entry_validator ct %P] \ + ] -column 2 -row 3 -sticky we + + grid columnconfigure $primary_tab_make 2 -weight 1 + + # Adjust GUI to the current config + make_tab__adjust_gui + + update idletasks + focus $primary_tab_make.clng_make_entry + } + + ## Enable or disable widgets related to Makefile usage configuration + # according to content of certain configuration variables. + # @return void + proc make_tab__adjust_gui {} { + # Enable of disable (other) widgets for configuration related to makefiles + make_tab__chb_ena c + } + + ## Enable or disable widgets for further configuration + # + # Enable them only if usage of Makefile instead of direct call of a + # compiler/assembler was enabled. + # @parm Char lang -'c' == C language + # @return void + proc make_tab__chb_ena {lang} { + variable primary_tab_make ;# Widget: Tab "MAIN/GNU make" + + if {$::configDialogues::compiler::makeutil_config(${lang}_ena) && ${::PROGRAM_AVAILABLE(make)}} { + make_tab__entry_validator $lang $::configDialogues::compiler::makeutil_config(${lang}_file) + make_tab__entry_validator ${lang}o $::configDialogues::compiler::makeutil_config(${lang}o_file) + make_tab__entry_validator ${lang}t $::configDialogues::compiler::makeutil_config(${lang}t_file) + set state {normal} + } else { + set state {disabled} + } + + if {[winfo exists $primary_tab_make.f]} { + $primary_tab_make.${lang}lng_make_entry configure -state $state + $primary_tab_make.${lang}lng_flsel_but configure -state $state + $primary_tab_make.${lang}opt_make_entry configure -state $state + $primary_tab_make.${lang}trg_make_entry configure -state $state + } + } + + ## Invoke file selection dialog for the Makefile entrybox + # @parm Char lang -'c' == C language + # @return void + proc make_tab__flsel_but {lang} { + variable primary_tab_make ;# Widget: Tab "MAIN/GNU make" + + catch {delete object ::fsd} + KIFSD::FSD ::fsd \ + -initialfile $::configDialogues::compiler::makeutil_config(${lang}_file) \ + -directory [file dirname $::configDialogues::compiler::makeutil_config(${lang}_file)] \ + -title [mc "Select Makefile - %s - MCU 8051 IDE" $::X::actualProject] \ + -defaultmask 0 -multiple 0 -filetypes [list \ + [list [mc "All files"] {*} ] \ + ] + ::fsd setokcmd [subst { + set uri \[::fsd get\] + set ::configDialogues::compiler::makeutil_config(${lang}_file) \$uri + ::configDialogues::compiler::make_tab__entry_validator $lang \$uri + }] + fsd activate + } + + ## Clear the Makefile entrybox (action for the Clear button) + # @parm Char lang -'c' == C language + # @return void + proc make_tab__clr_but {lang} { + variable primary_tab_make ;# Widget: Tab "MAIN/GNU make" + + set ::configDialogues::compiler::makeutil_config(${lang}_file) {} + make_tab__entry_validator $lang {} + } + + ## Disable the clear button if the entrybox is empty, enable it otherwise + # @parm Char lang -'c' == C language + # @parm String content - Content of the entrybox + # @return void + proc make_tab__entry_validator {lang content} { + variable primary_tab_make ;# Widget: Tab "MAIN/GNU make" + + if {$content == {}} { + set state disabled + } else { + set state normal + } + + $primary_tab_make.${lang}lng_clear_but configure -state $state + + return 1 + } + + ## Create tab "C language" + # @return void + proc create_C_tab {} { + variable primary_tab_c ;# Widget: Tab "MAIN/C language" + variable tertialy_tab_General ;# Widget: Tab "MAIN/C language/General" + variable tertialy_tab_Code ;# Widget: Tab "MAIN/C language/Code generation" + variable tertialy_tab_Optim ;# Widget: Tab "MAIN/C language/Optimization" + variable tertialy_tab_Linker ;# Widget: Tab "MAIN/C language/Linker" + variable tertialy_tab_Custom ;# Widget: Tab "MAIN/C language/Custom" + + # Create notebook + set tertialyNB [ModernNoteBook $primary_tab_c.nb_t] + + # Create notebook tabs + foreach tab { + General Code + Optimization Linker + Custom + } var { + General Code + Optim Linker + Custom + } text { + General {Code generation} + Optimization Linker + Custom + } \ + { + set frame [$tertialyNB insert end $tab \ + -createcmd [list ::configDialogues::compiler::create_T_tab $tab] \ + -text [mc $text] \ + ] + set tertialy_tab_$var $frame + } + + # Finalize + $tertialyNB raise {General} + pack [$tertialyNB get_nb] -fill both -expand 1 + } + + ## Create certain tab in notebook "C language" + # @parm String tab - Tab name + # @return void + proc create_T_tab {tab} { + variable tertialy_tab_General ;# Widget: Tab "MAIN/C language/General" + variable tertialy_tab_Code ;# Widget: Tab "MAIN/C language/Code generation" + variable tertialy_tab_Optim ;# Widget: Tab "MAIN/C language/Optimization" + variable tertialy_tab_Linker ;# Widget: Tab "MAIN/C language/Linker" + variable tertialy_tab_Custom ;# Widget: Tab "MAIN/C language/Custom" + variable sdcc_custom_opts_text ;# Widget: Text widget "Custom options for SDCC" + variable conf_affected ;# Array of Bool: Affected parts of configuration + variable sdcc_str_opt ;# Array: SDCC configuration + + set row 0 + switch -- $tab { + {General} { + set conf_affected(SDCC_General) 1 + set frame $tertialy_tab_General + set names { + --verbose -V + -S --compile-only + --preprocessonly --c1mode + --print-search-dirs --use-stdout + --nostdlib --nostdinc + --less-pedantic --debug + --cyclomatic --fdollars-in-identifiers + --funsigned-char + } + set helptexts { + {Trace calls to the preprocessor, assembler and linker} + {Execute verbosely. Show sub commands as they are run} + {Compile only; do not assemble or link} + {Compile and assemble, but do not link} + {Preprocess only, do not compile} + {Act in c1 mode. The standard input is preprocessed code, the output is assembly code.} + {Display the directories in the compiler's search path} + {Send errors to stdout instead of stderr} + {Do not include the standard library directory in the search path} + {Do not include the standard include directory in the search path} + {Disable some of the more pedantic warnings} + {Enable debugging symbol output} + {Display complexity of compiled functions} + {Permit '$' as an identifier character} + {Make "char" unsigned by default} + } + + set local_frame [frame $frame.local_frame_0] + pack $local_frame -side top -anchor w + grid columnconfigure $local_frame 0 -minsize 25 + grid columnconfigure $local_frame 3 -minsize 20 + grid [label $local_frame.c_standard -text [mc "Standard:"]] \ + -columnspan 6 -column 0 -row 0 -sticky w + + set local_row 1 + set col 1 + foreach name { + {--std-c89} {--std-sdcc89} + {--std-c99} {--std-sdcc99} + } helptext { + {Use C89 standard only} + {Use C89 standard with SDCC extensions} + {Use C99 standard only (incomplete)} + {Use C99 standard with SDCC extensions (incomplete)} + } \ + { + grid [radiobutton $local_frame.chb_${local_row}_$col \ + -value $name -text $name \ + -variable ::configDialogues::compiler::sdcc_str_opt(standard) \ + ] -column $col -row $local_row -sticky w -padx 5 + DynamicHelp::add $local_frame.chb_${local_row}_$col -text [mc $helptext] + incr col + + if {$col >= 3} { + set col 1 + incr local_row + } + } + + pack [ttk::separator $frame.sep_0 -orient horizontal] -fill x -pady 5 + + set local_row 0 + set local_frame [frame $frame.local_frame_1] + pack $local_frame -side top -fill x + + grid [Label $local_frame.lbl_$local_row -anchor w \ + -text [mc "Include path"] \ + -helptext [mc "Add to the include path, as in -Ipath\nPaths are separated by semicolons (`;')"] \ + ] -column 0 -row $local_row -sticky w -padx 5 + grid [ttk::entry $local_frame.chb_$local_row \ + -width 0 \ + -textvariable ::configDialogues::compiler::sdcc_scs_str_opt(-I) \ + ] -column 1 -row $local_row -sticky we -padx 5 + DynamicHelp::add $local_frame.chb_$local_row \ + -text [mc "Add to the include path, as in -Ipath\nPaths are separated by semicolons (`;')"] + incr local_row + + grid [Label $local_frame.lbl_$local_row -anchor w \ + -text [mc "Disable warning"] \ + -helptext [mc "Disable specific warning (--disable-warning)\nNumbers are separated by semicolons (`;')"] \ + ] -column 0 -row $local_row -sticky w -padx 5 + grid [ttk::entry $local_frame.chb_$local_row \ + -width 0 \ + -textvariable ::configDialogues::compiler::sdcc_scs_str_opt(--disable-warning) \ + ] -column 1 -row $local_row -sticky we -padx 5 + DynamicHelp::add $local_frame.chb_$local_row -text [mc "Disable specific warning (--disable-warning)\nNumbers are separated by semicolons (`;')"] \ + incr local_row + + grid columnconfigure $local_frame 1 -weight 1 + pack [ttk::separator $frame.sep_1 -orient horizontal] -fill x -pady 5 + } + {Code} { + set conf_affected(SDCC_Code) 1 + set frame $tertialy_tab_Code + set names { + --xstack --int-long-reent + --float-reent --main-return + --xram-movc --profile + --fommit-frame-pointer --all-callee-saves + --stack-probe --parms-in-bank1 + --no-xinit-opt --no-c-code-in-asm + --no-peep-comments --fverbose-asm + --short-is-8bits --stack-auto + } + set helptexts { + {Use external stack} + {Use reenterant calls on the int and long support functions} + {Use reenterant calls on the float support functions} + {Issue a return after main()} + {Use movc instead of movx to read xram (xdata)} + {On supported ports, generate extra profiling information} + {Leave out the frame pointer.} + {Callee will always save registers used} + {Insert call to function __stack_probe at each function prologue} + {Use Bank1 for parameter passing} + {Don't memcpy initialized xram from code} + {Don't include c-code as comments in the asm file} + {Don't include peephole optimizer comments} + {Include code generator comments} + {Make short 8 bits (for old times sake)} + {Stack automatic variables} + } + + set local_frame [frame $frame.local_frame_0] + pack $local_frame -side top -anchor w + grid columnconfigure $local_frame 0 -minsize 25 + grid columnconfigure $local_frame 3 -minsize 20 + grid [label $local_frame.c_standard -text [mc "Model:"]] \ + -columnspan 6 -column 0 -row 0 -sticky w -padx 5 + + set local_row 1 + set col 1 + foreach name { + {--model-large} + {--model-medium} + {--model-small} + } helptext { + {External data space is used} + {External paged data space is used} + {Internal data space is used} + } \ + { + grid [radiobutton $local_frame.chb_${local_row}_$col \ + -value $name -text $name \ + -variable ::configDialogues::compiler::sdcc_str_opt(model) \ + ] -column $col -row $local_row -sticky w -padx 5 + DynamicHelp::add $local_frame.chb_${local_row}_$col -text [mc $helptext] + incr col + + if {$col >= 3} { + set col 1 + incr local_row + } + } + + pack [ttk::separator $frame.sep_0 -orient horizontal] -fill x -pady 5 -padx 5 + + set local_row 0 + set local_frame [frame $frame.local_frame_1] + pack $local_frame -side top -fill x + + grid [Label $local_frame.lbl_$local_row -anchor w \ + -text {--codeseg} \ + -helptext [mc "Use this name for the code segment"] \ + ] -column 0 -row $local_row -sticky w -padx 5 + grid [ttk::entry $local_frame.chb_$local_row \ + -width 0 \ + -textvariable ::configDialogues::compiler::sdcc_opt_str_opt(--codeseg) \ + ] -column 1 -row $local_row -sticky we -padx 5 + DynamicHelp::add $local_frame.chb_$local_row \ + -text [mc "Use this name for the code segment"] + incr local_row + + grid [Label $local_frame.lbl_$local_row -anchor w \ + -text {--constseg} \ + -helptext [mc "Use this name for the const segment"] \ + ] -column 0 -row $local_row -sticky w -padx 5 + grid [ttk::entry $local_frame.chb_$local_row \ + -width 0 \ + -textvariable ::configDialogues::compiler::sdcc_opt_str_opt(--constseg) \ + ] -column 1 -row $local_row -sticky we -padx 5 + DynamicHelp::add $local_frame.chb_$local_row -text [mc "Use this name for the const segment"] \ + incr local_row + + grid columnconfigure $local_frame 1 -weight 1 + pack [ttk::separator $frame.sep_1 -orient horizontal] -fill x -pady 5 -padx 5 + } + {Optimization} { + set conf_affected(SDCC_Optimization) 1 + set frame $tertialy_tab_Optim + set names { + --nooverlay --nogcse + --nolabelopt --noinvariant + --noinduction --nojtbound + --noloopreverse --no-peep + --no-reg-params --peep-asm + --opt-code-speed --opt-code-size + } + set helptexts { + {Disable overlaying leaf function auto variables} + {Disable the GCSE optimisation} + {Disable label optimisation} + {Disable optimisation of invariants} + {Disable loop variable induction} + {Don't generate boundary check for jump tables} + {Disable the loop reverse optimisation} + {Disable the peephole assembly file optimisation} + {On some ports, disable passing some parameters in registers} + {Enable peephole optimization on inline assembly} + {Optimize for code speed rather than size} + {Optimize for code size rather than speed} + } + } + {Linker} { + set conf_affected(SDCC_Linker) 1 + set frame $tertialy_tab_Linker + set names { + --out-fmt-ihx --out-fmt-s19 + } + set helptexts { + {Output in Intel hex format} + {Output in S19 hex format} + } + + set local_row 0 + set local_frame [frame $frame.local_frame_1] + pack $local_frame -side top -fill x + grid columnconfigure $local_frame 1 -weight 1 + foreach name { + -l -L + } helptext { + {Include the given library in the link\nPaths are separated by semicolons (`;')} + {Add the next field to the library search path\nPaths are separated by semicolons (`;')} + } \ + { + grid [Label $local_frame.lbl_$local_row -anchor w \ + -text $name -helptext [mc [subst $helptext]] \ + ] -column 0 -row $local_row -sticky w -padx 5 + grid [ttk::entry $local_frame.chb_$local_row \ + -width 0 \ + -textvariable ::configDialogues::compiler::sdcc_scs_str_opt($name) \ + ] -column 1 -row $local_row -sticky we -padx 5 + DynamicHelp::add $local_frame.chb_$local_row \ + -text [mc [subst $helptext]] + incr local_row + } + foreach name { + --lib-path --xram-loc + --xstack-loc --code-loc + --stack-loc --data-loc + --stack-size + } helptext { + {Use this path to search for libraries} + {External Ram start location} + {External Stack start location} + {Code Segment Location} + {Stack pointer initial value} + {Direct data start location} + {Tells the linker to allocate this space for stack} + } \ + { + grid [Label $local_frame.lbl_$local_row -anchor w \ + -text $name -helptext [mc $helptext] \ + ] -column 0 -row $local_row -sticky w -padx 5 + grid [ttk::entry $local_frame.chb_$local_row \ + -width 0 \ + -textvariable ::configDialogues::compiler::sdcc_opt_str_opt($name) \ + ] -column 1 -row $local_row -sticky we -padx 5 + DynamicHelp::add $local_frame.chb_$local_row -text [mc $helptext] + incr local_row + } + + pack [ttk::separator $frame.sep_0 -orient horizontal] -fill x -pady 5 -padx 5 + set local_frame [frame $frame.local_frame_0] + pack $local_frame -side top -anchor w + grid columnconfigure $local_frame 0 -minsize 25 + pack [ttk::separator $frame.sep_1 -orient horizontal] -fill x -pady 5 -padx 5 + grid [label $local_frame.c_standard -text [mc "Stack:"]] \ + -columnspan 3 -column 0 -row 0 -sticky w + } + {Custom} { + set conf_affected(SDCC_Custom) 1 + set frame $tertialy_tab_Custom + } + } + + set main_frame [frame $frame.frame] + if {$tab == {Custom}} { + set sdcc_custom_opts_text [text $main_frame.text \ + -bg white -width 0 -height 0 -wrap word \ + -yscrollcommand "$main_frame.scrollbar set" \ + ] + pack [ttk::scrollbar $main_frame.scrollbar \ + -orient vertical \ + -command "$main_frame.text yview" \ + ] -side right -fill y + pack $sdcc_custom_opts_text -fill both -expand 1 -side left + $sdcc_custom_opts_text insert end $sdcc_str_opt(custom) + + pack $main_frame -side top -fill both -expand 1 + } else { + set col 0 + foreach name $names helptext $helptexts { + grid [checkbutton $main_frame.chb_${row}_$col \ + -text $name -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::sdcc_bool_opt($name) \ + ] -column $col -row $row -sticky w -padx 5 + DynamicHelp::add $main_frame.chb_${row}_$col -text [mc $helptext] + incr col + + if {$col >= 2} { + set col 0 + incr row + } + } + grid columnconfigure $main_frame 0 -weight 1 + pack $main_frame -side top -fill x + } + } + + ## Create tab "Compiler" + # @return void + proc create_compiler_tab {} { + variable assembler_tab_compiler ;# Widget: Tab "Compiler" + variable conf_affected ;# Array of Bool: Affected parts of configuration + + set conf_affected(Compiler) 1 + set main_frame [frame $assembler_tab_compiler.frame] + # Preferred editor + grid [label $main_frame.editor_lbl \ + -text [mc "Preferred assembler:"] -anchor w \ + ] -row 0 -column 0 -sticky w -padx 10 -pady 10 + set row 1 + set i 0 + foreach text { + {MCU 8051 IDE} + {ASEM-51} + {ASL} + {AS31} + } helptext { + {MCU 8051 IDE native assembler - Sophisticated but slow} + {Sophisticated and very fast assembler written by W.W. Heinz} + {Multiplatform assembler written by Alfred Arnold} + {Simple 8051 assembler} + } { + grid [radiobutton $main_frame.rabut_$i \ + -variable ::configDialogues::compiler::selected_assembler \ + -value $i -text $text -state disabled \ + ] -column 0 -padx 25 -row $row -sticky w + DynamicHelp::add $main_frame.rabut_$i -text [mc $helptext] + incr i + incr row + } + $main_frame.rabut_0 configure -state normal + if {${::PROGRAM_AVAILABLE(asem)}} { + $main_frame.rabut_1 configure -state normal + } + if {${::PROGRAM_AVAILABLE(asl)}} { + $main_frame.rabut_2 configure -state normal + } + if {${::PROGRAM_AVAILABLE(as31)}} { + $main_frame.rabut_3 configure -state normal + } + + grid [ttk::separator $main_frame.sep -orient horizontal] \ + -row $row -column 0 -sticky we -columnspan 2 -padx 10 -pady 10 + incr row + + grid [text $main_frame.notes \ + -bg ${::COMMON_BG_COLOR} -bd 0 -highlightthickness 0 -wrap word \ + -font [font create \ + -family {helvetiva} \ + -size [expr {int(-12 * $::font_size_factor)}] \ + ] \ + ] -row $row -column 0 -sticky we -columnspan 2 -padx 10 + + $main_frame.notes insert end [mc "Notes to assemblers:\n"] + $main_frame.notes insert end [mc " a) MCU 8051 IDE has its own native assembler\n"] + $main_frame.notes insert end [mc " b) ASEM-51 is a great assembler written by W.W. Heinz.\n"] + $main_frame.notes insert end [mc " You can find it at http://plit.de/asem-51/home.htm\n"] + $main_frame.notes insert end [mc " c) ASL: http://linux.maruhn.com/sec/asl.html\n"] + $main_frame.notes insert end [mc " d) AS31: http://www.pjrc.com/tech/8051\n"] + create_link_tag_in_text_widget $main_frame.notes + convert_all_https_to_links $main_frame.notes + + $main_frame.notes configure -state disabled + + # Configure grid and pack main frame + grid columnconfigure $main_frame 0 -minsize 200 + grid columnconfigure $main_frame 1 -weight 1 + pack $main_frame -side top -fill x + } + + ## Create tab "ASEM51" + # @return void + proc create_ASEM51_tab {} { + variable assembler_tab_ASEM51 ;# Widget: Tab "ASX8051" + variable asm51_custom_opts_text ;# Widget: Text widget "Custom options for ASEM-51" + variable conf_affected ;# Array of Bool: Affected parts of configuration + + # Set flag "Configuration affected" + set conf_affected(ASEM51) 1 + + # Create main frame + set main_frame [frame $assembler_tab_ASEM51.frame0] + + set i 0 + foreach name { + --omf-51 + --columns + --verbose + } helptext { + {Generate an object file in absolute OMF-51 format} + {Output additional column numbers after the line numbers of program error messages} + {Output additional product, version, and error summary information} + } \ + { + pack [checkbutton $main_frame.checkbutton_$i \ + -text [mc $name] -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::assembler_ASEM51_config($name) \ + ] -anchor nw -padx 5 + DynamicHelp::add $main_frame.checkbutton_$i -text [mc $helptext] + incr i + } + pack $main_frame -fill x -padx 5 + + # Additional options + set main_frame [frame $assembler_tab_ASEM51.frame_a] + set i 0 + foreach var { + adf + } text { + {Generate MCU 8051 IDE debug file} + } helptext { + {Generate .adb (MCU 8051 IDE Assembler Debug File) from .lst} + } \ + { + set helptext [mc [subst $helptext]] + pack [checkbutton $main_frame.chb_$i \ + -text [mc $text] -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::assembler_ASEM51_addcfg($var) \ + ] -anchor w -padx 5 + DynamicHelp::add $main_frame.chb_$i -text $helptext + incr i + } + pack $main_frame -fill x -padx 5 + pack [ttk::separator $assembler_tab_ASEM51.sep_1 -orient horizontal] -fill x -pady 5 + + # Create second frame (Include path and custom flags) + set main_frame [frame $assembler_tab_ASEM51.frame1] + # Include path + grid [Label $main_frame.lbl_0 -anchor w \ + -text [mc "Include paths:"] \ + -helptext [mc "Option -i\nSeparate directories by colons (`:')"] \ + ] -column 0 -row 0 -sticky w -padx 5 + grid [ttk::entry $main_frame.entry \ + -textvariable ::configDialogues::compiler::assembler_ASEM51_config(-i) \ + ] -column 1 -row 0 -sticky we -padx 5 + DynamicHelp::add $main_frame.entry \ + -text [mc "Option -i\nSeparate directories by colons (`:')"] + grid [Label $main_frame.lbl_1 \ + -anchor w \ + -text [mc "Custom options:"] \ + ] -column 0 -row 1 -sticky w -padx 5 + + # Configure grid and pack main frame 1 + grid columnconfigure $main_frame 1 -weight 1 + pack $main_frame -fill x -padx 5 + + # Text widget "Custom options" + set main_frame [frame $assembler_tab_ASEM51.frame2] + set asm51_custom_opts_text [text $main_frame.text \ + -bg white -width 0 -height 0 \ + -yscrollcommand "$main_frame.scrollbar set" \ + ] + pack $asm51_custom_opts_text -side left -fill both -expand 1 + pack [ttk::scrollbar $main_frame.scrollbar \ + -orient vertical \ + -command "$asm51_custom_opts_text yview" \ + ] -side right -fill y + $asm51_custom_opts_text insert end \ + $::configDialogues::compiler::assembler_ASEM51_config(custom) + pack $main_frame -fill both -expand 1 -pady 5 + } + + ## Create tab "AS31" + # @return void + proc create_AS31_tab {} { + variable assembler_tab_AS31 ;# Widget: Tab "AS31" + variable as31_custom_opts_text ;# Widget: Text widget "Custom options for AS31" + variable conf_affected ;# Array of Bool: Affected parts of configuration + + # Set flag "Configuration affected" + set conf_affected(AS31) 1 + + # Create main frame + set main_frame [frame $assembler_tab_AS31.frame0] + set i 0 + set row 0 + set col 0 + foreach name { + -l + } text { + {Generate a listing file, option `-l'} + } helptext { + {This option tells the assembler to generate a listing file.\n\nTHIS OPTION IS REQUIRED BY THIS IDE TO GENERATE DEBUG FILE !} + } \ + { + set helptext [mc [subst $helptext]] + grid [checkbutton $main_frame.checkbutton_$i \ + -text [mc $text] -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::assembler_AS31_config($name) \ + ] -sticky w -row $row -column $col -padx 5 + DynamicHelp::add $main_frame.checkbutton_$i -text $helptext + + incr i + incr col + if {$col > 3} { + set col 0 + incr row + } + } + for {set i 0} {$i < 4} {incr i} { + grid columnconfigure $main_frame $i -weight 1 + } + pack $main_frame -fill x -padx 5 + + # Additional options + set main_frame [frame $assembler_tab_AS31.frame_a] + set i 0 + foreach var { + adf + } text { + {Generate MCU 8051 IDE debug file} + } helptext { + {Generate .adb (MCU 8051 IDE Assembler Debug File)\nfrom .lst} + } \ + { + set helptext [mc [subst $helptext]] + pack [checkbutton $main_frame.chb_$i \ + -text [mc $text] -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::assembler_AS31_addcfg($var) \ + ] -anchor w -padx 5 + DynamicHelp::add $main_frame.chb_$i -text $helptext + incr i + } + pack $main_frame -fill x -padx 5 + pack [ttk::separator $assembler_tab_AS31.sep_1 -orient horizontal] -fill x + + # Create second frame (EntryBoxes and ComboBoxes) + set main_frame [frame $assembler_tab_AS31.frame1] + set row 0 + foreach name { + -F + } helptext { + {This options specifies the output format that is to be used.\n\nSee AS31 manual page for more details ...} + } values { + {hex tdr byte od srec2 srec3 srec4} + } \ + { + set helptext [mc [subst $helptext]] + grid [Label $main_frame.lbl_$row -anchor w \ + -text $name -helptext [mc $helptext] \ + ] -column 0 -row $row -sticky w -padx 5 + grid [ttk::combobox $main_frame.entry_$row \ + -state readonly \ + -values $values \ + -textvariable ::configDialogues::compiler::assembler_AS31_config($name) \ + ] -column 1 -row $row -sticky we -padx 5 + DynamicHelp::add $main_frame.entry_$row -text $helptext + incr row + } + foreach name { + -A + } helptext { + {This option specifies a format specific string which is\npassed to the format generator. Both format "tdr" and the\nsrecord formats use this option.} + } \ + { + set helptext [mc [subst $helptext]] + grid [Label $main_frame.lbl_$row -anchor w \ + -text $name -helptext $helptext \ + ] -column 0 -row $row -sticky w -padx 5 + grid [ttk::entry $main_frame.entry_$row \ + -textvariable ::configDialogues::compiler::assembler_AS31_config($name) \ + ] -column 1 -row $row -sticky we -padx 5 + DynamicHelp::add $main_frame.entry_$row \ + -text $helptext + incr row + } + + # Custom flags + grid [Label $main_frame.lbl_$row -anchor w \ + -text [mc "Custom options:"] \ + ] -column 0 -row $row -sticky w -padx 5 + + # Configure grid and pack main frame 1 + grid columnconfigure $main_frame 1 -weight 1 + pack $main_frame -fill x -padx 5 + + # Text widget "Custom options" + set main_frame [frame $assembler_tab_AS31.frame2] + set as31_custom_opts_text [text $main_frame.text \ + -bg white -width 0 -height 0 \ + -yscrollcommand "$main_frame.scrollbar set" \ + ] + pack $as31_custom_opts_text -side left -fill both -expand 1 + pack [ttk::scrollbar $main_frame.scrollbar \ + -orient vertical \ + -command "$as31_custom_opts_text yview" \ + ] -side right -fill y + $as31_custom_opts_text insert end \ + $::configDialogues::compiler::assembler_AS31_config(custom) + pack $main_frame -fill both -expand 1 + } + + ## Create tab "ASL" + # @return void + proc create_ASL_tab {} { + variable assembler_tab_ASL ;# Widget: Tab "ASL" + variable asl_custom_opts_text ;# Widget: Text widget "Custom options for ASL" + variable conf_affected ;# Array of Bool: Affected parts of configuration + + # Set flag "Configuration affected" + set conf_affected(ASL) 1 + + # Create main frame + set main_frame [frame $assembler_tab_ASL.frame0] + set i 0 + set row 0 + set col 0 + foreach name { + -A -a -C -c -h -I -L -M -P -n -quiet -s -u -U -w -x + } helptext { + {Change the data structure that is internally used to store\nthe symbol table. By default, AS uses binary trees to store\nmacro and symbol definitions. Turning this option on will\nchange this to AVL-balanced trees. Depending on the ratio\nof symbol entries and lookups, this might speed up assembly.\nUsing AVL-balanced trees helps also reducing the stack usage,\nwhich is however irrelevant for the C version of AS.} + {Instruct AS to write out the shared symbol definitions in\na format suitable for including into an AS assembler program.\nThe file's name is constructed by replacing the source file's\nextension with '.inc'. See the user manual for more\ninformation about symbol sharing.} + {Add a cross reference table to the assembler listing. A cross\nreference table lists all symbols that have been referenced\nat least once during assembly, including the source line\nnumber(s) and count of every reference. This option only makes\nsense when the generation of an assembly listing has been\nturned on via the -L or -l parameters. } + {Instruct AS to write out the shared symbol definitions in a\nformat suitable for including into a C program. The file's\nname is constructed by replacing the source file's extension\nwith '.h'. See the user manual for more information about\nsymbol sharing.} + {Force AS to print all hexadecimal constants with lowercase\nletters, rather than with uppercase letters A..F which is\nthe default.} + {Add an include file list to the assembly listing. An include\nfile list contains all files that have been included while\nassembling the source files, including multiple and nested\ninclusion. Nesting of inclusion is identified by different\nindention. This option only makes sense when the generation of\nan assembly listing has been turned on via the -L or -l parameters.} + {Turn on generation of an assembly listing and send it to a\nfile whose name is constructed by replacing the source\nfile's extension with '.lst'.} + {Turn on generation of a macro definition file. A macro\ndefinition file is a file that contains all macro definitions\nthat have been detected during assembly, in a format suitable\nfor an inclusion into another file. The macro definition file's\nname is constructed by replacing the source file's extension\nwith '.mac'.} + {Turn on generation of a macro output file. A macro output\nfile contains the intermediate source code that remains after\nmacro expansion and conditional assembly. The macro output\nfile's name is constructed by replacing the source file's\nextension with '.i'.} + {Force AS to extend all error and warning messages with their\ninternal error resp. warning number.} + {Turn on silent assembly mode. In silent compilation mode, AS\nwill not do any console output except for warning and\nerror messages.} + {Add a section list to the assembly listing. A section list\ncontains all sections that have been defined in the source\nfiles, marking their nesting level by different levels of\nindentation. This option only makes sense when the generation\nof an assembly listing has been turned on via the\n-L or -l parameters.} + {Tell AS to do additional bookkeeping about which address\nranges have been used by the assembled program. This option\nenables the detection of overlapping memory usage. If an\nassembly listing has been turned on via the -L or -l parameters,\nit will also contain a list of all used memory areas.} + {Force AS to operate in case-sensitive mode. By default,\nnames of symbols, macros, user-defined functions and sections\nare treated in a case-insensitive manner.} + {Suppress output of warnings.} + {Turn on extended error reporting. With extended error\nreporting, several error and warning messages will also\nprint the item that created the message, e.g. the name of\nan unknown instruction. When this option is given twice,\nthe erroneous source line is additinally printed.} + } \ + { + set helptext [mc [subst $helptext]] + grid [checkbutton $main_frame.checkbutton_$i \ + -text $name -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::assembler_ASL_config($name) \ + ] -sticky w -row $row -column $col -padx 5 + DynamicHelp::add $main_frame.checkbutton_$i -text $helptext + + incr i + incr col + if {$col > 3} { + set col 0 + incr row + } + } + for {set i 0} {$i < 4} {incr i} { + grid columnconfigure $main_frame $i -weight 1 + } + pack $main_frame -fill x -padx 5 + pack [ttk::separator $assembler_tab_ASL.sep_0 -orient horizontal] -fill x + + # Additional options + set main_frame [frame $assembler_tab_ASL.frame_a] + set i 0 + foreach var { + ihex adf + } text { + {Generate IHEX file} + {Generate MCU 8051 IDE debug file} + } helptext { + {Use program p2hex to convert .p to .hex} + {Generate .adb (MCU 8051 IDE Assembler Debug File)\nfrom .hex and .map} + } \ + { + set helptext [mc [subst $helptext]] + pack [checkbutton $main_frame.chb_$i \ + -text [mc $text] -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::assembler_ASL_addcfg($var) \ + ] -anchor w + DynamicHelp::add $main_frame.chb_$i -text $helptext + incr i + } + pack $main_frame -fill x -padx 5 + pack [ttk::separator $assembler_tab_ASL.sep_1 -orient horizontal] -fill x + + # Create second frame (EntryBoxes and ComboBoxes) + set main_frame [frame $assembler_tab_ASL.frame1] + set row 0 + foreach name { + -cpu -g + } helptext { + {Set the target processor to .\nUse this option if the source file does\nnot contain a CPU statement.} + {-g \[MAP|Atmel|NoICE\]\n\tInstruct AS to write an additional file containing\n\tdebug information. This information covers the symbol\n\ttable and the relation between source line numbers\n\tand machine addresses. The argument specifies whether\n\tdebug info shall be written in AS's own MAP format,\n\tthe object format for Atmel's AVR tools, or a command\n\tfile suitable for John Hartman's NoICE. If no argument\n\tis given, MAP will be chosen. The file's name is\n\tconstructed by replacing the source file's extension\n\twith '.map', '.obj', or '.noi' respectively.\n\nMCU 8051 IDE requires MAP to be selected\nhere to generate debug file} + } values { + { + 8021 8022 8039 80C39 8048 80C48 8041 8042 + 87C750 8051 8052 80C320 80C501 80C502 80C504 80515 + 80517 80C251 + } { + {} MAP Atmel NoICE + } + } \ + { + set helptext [mc [subst $helptext]] + grid [Label $main_frame.lbl_$row -anchor w \ + -text $name -helptext [mc $helptext] \ + ] -column 0 -row $row -sticky w -padx 5 + grid [ttk::combobox $main_frame.entry_$row \ + -state readonly \ + -values $values \ + -textvariable ::configDialogues::compiler::assembler_ASL_config($name) \ + ] -column 1 -row $row -sticky we -padx 5 + DynamicHelp::add $main_frame.entry_$row -text $helptext + incr row + } + foreach name { + -r -i + } helptext { + {-r \[pass number\]\n\tTell AS to output warnings when a situation appears\n\tin a source file that forces another pass of assembly.\n\tSuch situations either take place when a symbol is\n\tundefined in the first pass or a symbol's value has\n\tchanged compared to the previous pass. This option\n\tis useful to track down sources of excessive\n\tmulti-passing, but be aware that it might yield a\n\tfairly large number of warnings, especially in the\n\tfirst pass. Optionally, a pass number may be added\n\tto this option to inhibit output until a certain\n\tpass is reached.} + {-i \tAdd new entries to the list of paths that are\n\tsearched for include files. New entries are\n\tprepended to the current include path list,\n\tso if multiple paths are given with one\n\tcommand-line parameter, they will be entered\n\tinto the path list in reverse order.} + } \ + { + set helptext [mc [subst $helptext]] + grid [Label $main_frame.lbl_$row -anchor w \ + -text $name -helptext [mc $helptext] \ + ] -column 0 -row $row -sticky w -padx 5 + grid [ttk::entry $main_frame.entry_$row \ + -textvariable ::configDialogues::compiler::assembler_ASL_config($name) \ + ] -column 1 -row $row -sticky we -padx 5 + DynamicHelp::add $main_frame.entry_$row -text $helptext + incr row + } + + # Custom flags + grid [Label $main_frame.lbl_$row -anchor w \ + -text [mc "Custom options:"] \ + ] -column 0 -row $row -sticky w -padx 5 + + # Configure grid and pack main frame 1 + grid columnconfigure $main_frame 1 -weight 1 + pack $main_frame -fill x -padx 5 + + # Text widget "Custom options" + set main_frame [frame $assembler_tab_ASL.frame2] + set asl_custom_opts_text [text $main_frame.text \ + -bg white -width 0 -height 0 \ + -yscrollcommand "$main_frame.scrollbar set" \ + ] + pack $asl_custom_opts_text -side left -fill both -expand 1 + pack [ttk::scrollbar $main_frame.scrollbar \ + -orient vertical \ + -command "$asl_custom_opts_text yview" \ + ] -side right -fill y + $asl_custom_opts_text insert end \ + $::configDialogues::compiler::assembler_ASL_config(custom) + pack $main_frame -fill both -expand 1 + } + + ## Create tab "MCU8051IDE" + # @return void + proc create_asm_tab {} { + variable conf_affected ;# Array of Bool: Affected parts of configuration + variable assembler_tab_M8I ;# Widget: Tab "MCU8051IDE" + + # Set flag "Configuration affected" + set conf_affected(MCU8051IDE) 1 + + ## Create notebook + set nb0 [ModernNoteBook $assembler_tab_M8I.nb_m] + + # Tab "Output" + set ouput_tab [$nb0 insert end ouput_tab -text [mc "Output"]] + # Tab "Directives" + set directives_tab [$nb0 insert end directives_tab -text [mc "Directives"]] + + # + ## Tab "Output" + # + + # Header + grid [Label $ouput_tab.source_label \ + -text [mc "Source"] -anchor c \ + -helptext [mc "Use value defined in source code"] \ + ] -column 2 -row 0 -sticky we -padx 5 + grid [Label $ouput_tab.always_label \ + -text [mc "Always"] -anchor c \ + -helptext [mc "Generate always"] \ + ] -column 3 -row 0 -sticky we -padx 5 + grid [Label $ouput_tab.never_label \ + -text [mc "Never"] -anchor c \ + -helptext [mc "Never generate"] \ + ] -column 4 -row 0 -sticky we -padx 5 + + # Code listing + grid [Label $ouput_tab.lst_label -anchor w \ + -text [mc "Generate code listing"] \ + -helptext [mc "Should compiler generate *.lst files"] \ + ] -column 1 -row 1 -sticky we -padx 5 + grid [radiobutton $ouput_tab.lst_radio0 -value 0 \ + -variable ::configDialogues::compiler::option__print \ + ] -column 2 -row 1 -padx 5 + grid [radiobutton $ouput_tab.lst_radio1 -value 1 \ + -variable ::configDialogues::compiler::option__print \ + ] -column 3 -row 1 -padx 5 + grid [radiobutton $ouput_tab.lst_radio2 -value 2 \ + -variable ::configDialogues::compiler::option__print \ + ] -column 4 -row 1 -padx 5 + + # Table of symbols + grid [Label $ouput_tab.sym_label -anchor w \ + -text [mc "Table of symbols (in *.lst)"] \ + -helptext [mc "Include table of used symbolic names to code listing"] \ + ] -column 1 -row 2 -sticky we -padx 5 + grid [radiobutton $ouput_tab.sym_radio0 -value 0 \ + -variable ::configDialogues::compiler::option__symbols \ + ] -column 2 -row 2 -padx 5 + grid [radiobutton $ouput_tab.sym_radio1 -value 1 \ + -variable ::configDialogues::compiler::option__symbols \ + ] -column 3 -row 2 -padx 5 + grid [radiobutton $ouput_tab.sym_radio2 -value 2 \ + -variable ::configDialogues::compiler::option__symbols \ + ] -column 4 -row 2 -padx 5 + + # Hex object code + grid [Label $ouput_tab.hex_label -anchor w \ + -text [mc "Generate object code (ihex8)"] \ + -helptext [mc "Generate object code in format Intel Hex 8 (*.hex)"] \ + ] -column 1 -row 3 -sticky we -padx 5 + grid [radiobutton $ouput_tab.hex_radio0 -value 0 \ + -variable ::configDialogues::compiler::option__object \ + ] -column 2 -row 3 -padx 5 + grid [radiobutton $ouput_tab.hex_radio1 -value 1 \ + -variable ::configDialogues::compiler::option__object \ + ] -column 3 -row 3 -padx 5 + grid [radiobutton $ouput_tab.hex_radio2 -value 2 \ + -variable ::configDialogues::compiler::option__object \ + ] -column 4 -row 3 -padx 5 + + grid [ttk::separator $ouput_tab.sep0 \ + -orient horizontal \ + ] -column 0 -row 4 -columnspan 5 -sticky we -pady 5 -padx 5 + + # Sim object code + grid [Label $ouput_tab.sim_label -anchor w \ + -text [mc "Generate code for simulator"] \ + -helptext [mc "Generate *.sim file for simulator"] \ + ] -column 1 -row 5 -sticky we -padx 5 + grid [checkbutton $ouput_tab.sim_check \ + -variable ::configDialogues::compiler::option_CREATE_SIM_FILE \ + ] -column 2 -row 5 -sticky w -columnspan 3 -padx 5 + + # Bin object code + grid [Label $ouput_tab.bin_label -anchor w \ + -text [mc "Generate binary object code"] \ + -helptext [mc "Generate binary object code (*.bin)"] \ + ] -column 1 -row 6 -sticky we -padx 5 + grid [checkbutton $ouput_tab.bin_check \ + -variable ::configDialogues::compiler::option_CREATE_BIN_FILE \ + ] -column 2 -row 6 -sticky w -columnspan 3 -padx 5 + + grid [ttk::separator $ouput_tab.sep1 \ + -orient horizontal \ + ] -column 0 -row 7 -columnspan 5 -sticky we -pady 5 -padx 5 + + # Compier warning level + grid [Label $ouput_tab.warning_label -anchor w \ + -text [mc "Warning level"] \ + -helptext [mc "What kind of messages should be included in compiler log output"] \ + ] -column 1 -row 8 -sticky we -padx 5 + grid [ttk::combobox $ouput_tab.warning_combo \ + -textvariable ::configDialogues::compiler::opt_WARNING_LEVEL \ + -values [list \ + [mc "All"] \ + [mc "Errors + Warnings"] \ + [mc "Errros only"] \ + [mc "Nothing"] \ + ] \ + -state readonly -width 17 \ + ] -column 2 -row 8 -sticky w -columnspan 3 -padx 5 + DynamicHelp::add $ouput_tab.warning_combo \ + -text [mc "What kind of messages should be included in compiler log output"] + + # Verbose + grid [Label $ouput_tab.verbose_label -anchor w \ + -text [mc "Verbose"] \ + -helptext [mc "Should compiler inform user about what it is doing"] \ + ] -column 1 -row 9 -sticky we -padx 5 + grid [checkbutton $ouput_tab.verbose_check \ + -onvalue 0 -offvalue 1 \ + -variable ::configDialogues::compiler::option_QUIET \ + ] -column 2 -row 9 -sticky w -columnspan 3 -padx 5 + + grid [ttk::separator $ouput_tab.sep2 \ + -orient horizontal \ + ] -column 0 -row 10 -columnspan 5 -sticky we -pady 5 -padx 5 + + # Enable optimization + grid [Label $ouput_tab.optim_label -anchor w \ + -text [mc "Enable optimization"] \ + -helptext [mc "Enable peephole optimization"]\ + ] -column 1 -row 11 -sticky we -padx 5 + grid [checkbutton $ouput_tab.optim_check \ + -onvalue 1 -offvalue 0 \ + -variable ::configDialogues::compiler::option_optim_ena \ + ] -column 2 -row 11 -sticky w -columnspan 3 -padx 5 + + # Maximum length of IHEX-8 record + grid [Label $ouput_tab.ih8_max_len_lbl -anchor w \ + -text [mc "Maximum HEX record data length"] \ + -helptext [mc "Maximum length of Intel HEX 8 record data field.\n\nGenerally it doesn't matter what is set here. But some (badly written)\nprogrammers may refuse to load files containing records which exceeds\ncertain length.\n\nHigher value also results in smaller .hex files\n\nValue equal to 0 will be treated as 1"] \ + ] -column 1 -row 12 -sticky we -padx 5 + grid [ttk::spinbox $ouput_tab.ih8_max_len_spbox \ + -from 0 -to 255 -validate all -width 4 \ + -textvariable ::configDialogues::compiler::max_ihex_rec_length \ + -validatecommand "::configDialogues::compiler::ih8_max_len_spbox_val %P" \ + ] -column 2 -row 12 -sticky w -columnspan 3 -padx 5 + + + # + ## Tab "Directives" + # + + # Header + grid [label $directives_tab.header \ + -anchor w -text [mc "Ignore directives"] \ + -font [font create \ + -family {helvetica} \ + -size [expr {int(-17 * $::font_size_factor)}] \ + -weight bold \ + ] \ + ] -column 0 -row 0 -columnspan 3 -sticky we -pady 10 -padx 10 + grid [label $directives_tab.accept_label \ + -text [mc "Accept"] -anchor w \ + ] -column 1 -row 1 -padx 5 + grid [label $directives_tab.ignore_label \ + -text [mc "Ignore"] -anchor w \ + ] -column 2 -row 1 -padx 5 + + # Create matrix of radio buttons + set row 2 + foreach var { + nomod paging pagelength + pagewidth title date + list + } txt { + $nomod {$nopaging, $paging} $pagelength + $pagewidth $title $date + {$list, $nolist, list, nolist} + } helptext { + {} + {} + {} + {} + {} + {} + {} + } \ + { + # Label + grid [Label $directives_tab.${var}_label \ + -text $txt -anchor w -highlightthickness 0 -bd 0 \ + -helptext $helptext \ + ] -column 0 -row $row -sticky we -padx 5 + # Accept + grid [radiobutton $directives_tab.${var}_radio0 -value 0 \ + -variable ::configDialogues::compiler::option__${var} \ + ] -column 1 -row $row -padx 5 + # Ignore + grid [radiobutton $directives_tab.${var}_radio1 -value 1 \ + -variable ::configDialogues::compiler::option__${var} \ + ] -column 2 -row $row -padx 5 + + incr row + } + + $nb0 raise ouput_tab + pack [$nb0 get_nb] -side top -fill both -expand 1 + } + + ## Validate content of spinbox "Max length of IHEX-8 record" + # @parm String string - String to validate + # @return Bool - Validation result + proc ih8_max_len_spbox_val {string} { + if {![string length $string]} { + return 1 + } + if {![string is digit -strict $string]} { + return 0 + } + if {$string > 255 || $string < 0} { + return 0 + } + return 1 + } + + ## Retrieve settings from Compiler NS and X NS + # @return void + proc getSettings {} { + variable defaults ;# List of default settings + variable opt_WARNING_LEVEL ;# Warning level + variable max_ihex_rec_length ;# Int: Maximum length of IHEX-8 record + + variable selected_assembler ;# Int: Preferred assembler (0==MCU8051IDE;1==ASEM-51;2==ASL) + variable assembler_ASEM51_config;# Array: ASEM-51 configuration + variable assembler_ASEM51_addcfg;# Array: ASEM-51 additional configuration + variable assembler_ASL_config ;# Array: ASL configuration + variable assembler_ASL_addcfg ;# Array: ASL additional configuration + variable assembler_AS31_config ;# Array: AS31 configuration + variable assembler_AS31_addcfg ;# Array: AS31 additional configuration + + variable sdcc_bool_opt ;# Array: SDCC configuration + variable sdcc_str_opt ;# Array: SDCC configuration + variable sdcc_opt_str_opt ;# Array: SDCC configuration + variable sdcc_scs_str_opt ;# Array: SDCC configuration + + variable makeutil_config ;# Array: Make utility configuration + + + ## Assembler: MCU8051IDE + # Set local option variables + foreach var $defaults { + set var [lindex $var 0] + set ::configDialogues::compiler::option_${var} [subst -nocommands "\$::Compiler::Settings::$var"] + } + set max_ihex_rec_length ${::Compiler::Settings::max_ihex_rec_length} + + # Set warning level + set tmp [mc "All"] + switch -- ${::Compiler::Settings::WARNING_LEVEL} { + 0 {set tmp [mc "All"]} + 1 {set tmp [mc "Errors + Warnings"]} + 2 {set tmp [mc "Errros only"]} + 3 {set tmp [mc "Nothing"]} + default {puts stderr "Invalid WARNING_LEVEL value"} + } + set opt_WARNING_LEVEL $tmp + + ## Preferred assembler + set selected_assembler $::ExternalCompiler::selected_assembler + ## ASEM-51 + array set assembler_ASEM51_config [array get ::ExternalCompiler::assembler_ASEM51_config] + array set assembler_ASEM51_addcfg [array get ::ExternalCompiler::assembler_ASEM51_addcfg] + ## ASL + array set assembler_ASL_config [array get ::ExternalCompiler::assembler_ASL_config] + array set assembler_ASL_addcfg [array get ::ExternalCompiler::assembler_ASL_addcfg] + ## AS31 + array set assembler_AS31_config [array get ::ExternalCompiler::assembler_AS31_config] + array set assembler_AS31_addcfg [array get ::ExternalCompiler::assembler_AS31_addcfg] + + ## SDCC + # Copy boolean options + array set sdcc_bool_opt [array get ::ExternalCompiler::sdcc_bool_options] + # Copy string options + array set sdcc_str_opt [array get ::ExternalCompiler::sdcc_string_options] + # Copy optional strings + array set sdcc_opt_str_opt [array get ::ExternalCompiler::sdcc_optional_string_options] + # Copy semicolon separated optional string options + array set sdcc_scs_str_opt [array get ::ExternalCompiler::sdcc_scs_string_options] + + ## GNU Make utility configuration + # General options + foreach key [array names ::ExternalCompiler::makeutil_config] { + set makeutil_config($key) $::ExternalCompiler::makeutil_config($key) + } + } + + ## Set compiler according to local settings + # @return void + proc use_settings {} { + variable defaults ;# List of default settings + variable opt_WARNING_LEVEL ;# Warning level + variable conf_affected ;# Array of Bool: Affected parts of configuration + + variable max_ihex_rec_length ;# Int: Maximum length of IHEX-8 record + variable selected_assembler ;# Int: Preferred assembler (0==MCU8051IDE;1==ASEM-51;2==ASL) + variable assembler_ASEM51_config;# Array: ASEM-51 configuration + variable assembler_ASEM51_addcfg;# Array: ASEM-51 additional configuration + variable assembler_ASL_config ;# Array: ASL configuration + variable assembler_ASL_addcfg ;# Array: ASL additional configuration + variable assembler_AS31_config ;# Array: AS31 configuration + variable assembler_AS31_addcfg ;# Array: AS31 additional configuration + + variable asm51_custom_opts_text ;# Widget: Text widget "Custom options for ASEM-51" + variable asl_custom_opts_text ;# Widget: Text widget "Custom options for ASL" + variable as31_custom_opts_text ;# Widget: Text widget "Custom options for AS31" + variable sdcc_custom_opts_text ;# Widget: Text widget "Custom options for SDCC" + + variable sdcc_bool_opt ;# Array: SDCC configuration + variable sdcc_str_opt ;# Array: SDCC configuration + variable sdcc_opt_str_opt ;# Array: SDCC configuration + variable sdcc_scs_str_opt ;# Array: SDCC configuration + + variable makeutil_config ;# Array: Make utility configuration + + ## Assembler: MCU8051IDE + if {$conf_affected(MCU8051IDE)} { + # Set option variables + foreach var $defaults { + set var [lindex $var 0] + set ::Compiler::Settings::$var [subst -nocommands "\$::configDialogues::compiler::option_${var}"] + } + if {![string length $max_ihex_rec_length]} { + set max_ihex_rec_length 0 + } + set Compiler::Settings::max_ihex_rec_length $max_ihex_rec_length + + # Set warning level + set tmp ${::Compiler::Settings::WARNING_LEVEL} + switch -- $opt_WARNING_LEVEL [subst { + {[mc "All"]} { + set tmp 0 + } + [mc "Errors + Warnings"] { + set tmp 1 + } + {[mc "Errros only"]} { + set tmp 2 + } + {[mc "Nothing"]} { + set tmp 3 + } + default { + puts stderr "Invalid WARNING_LEVEL value" + } + }] + set ::Compiler::Settings::WARNING_LEVEL $tmp + } + + ## Preferred assembler + if {$conf_affected(Compiler)} { + set ::ExternalCompiler::selected_assembler $selected_assembler + } + + ## Assembler: ASEM51 + if {$conf_affected(ASEM51)} { + array set ::ExternalCompiler::assembler_ASEM51_addcfg \ + [array get assembler_ASEM51_addcfg] + array set ::ExternalCompiler::assembler_ASEM51_config \ + [array get assembler_ASEM51_config] + set ::ExternalCompiler::assembler_ASEM51_config(custom) \ + [regsub {\n$} [$asm51_custom_opts_text get 1.0 end] {}] + } + + ## Assembler: ASL + if {$conf_affected(ASL)} { + array set ::ExternalCompiler::assembler_ASL_addcfg \ + [array get assembler_ASL_addcfg] + array set ::ExternalCompiler::assembler_ASL_config \ + [array get assembler_ASL_config] + set ::ExternalCompiler::assembler_ASL_config(custom) \ + [regsub {\n$} [$asl_custom_opts_text get 1.0 end] {}] + } + + ## Assembler: AS31 + if {$conf_affected(AS31)} { + array set ::ExternalCompiler::assembler_AS31_addcfg \ + [array get assembler_AS31_addcfg] + array set ::ExternalCompiler::assembler_AS31_config \ + [array get assembler_AS31_config] + set ::ExternalCompiler::assembler_AS31_config(custom) \ + [regsub {\n$} [$as31_custom_opts_text get 1.0 end] {}] + } + + ## SDCC Custom options + if {$conf_affected(SDCC_Custom)} { + set sdcc_str_opt(custom) [regsub {\n$} [$sdcc_custom_opts_text get 1.0 end] {}] + set ::ExternalCompiler::sdcc_string_options(custom) $sdcc_str_opt(custom) + } + + ## SDCC Configuration + if { + $conf_affected(SDCC_Linker) || $conf_affected(SDCC_Optimization) || + $conf_affected(SDCC_Code) || $conf_affected(SDCC_General) + } then { + # Copy boolean options + array set ::ExternalCompiler::sdcc_bool_options [array get sdcc_bool_opt] + # Copy string options + array set ::ExternalCompiler::sdcc_string_options [array get sdcc_str_opt] + # Copy optional strings + array set ::ExternalCompiler::sdcc_optional_string_options [array get sdcc_opt_str_opt] + # Copy semicolon separated optional string options + array set ::ExternalCompiler::sdcc_scs_string_options [array get sdcc_scs_str_opt] + } + + ## GNU Make utility configuration + # General options + foreach key [array names ::ExternalCompiler::makeutil_config] { + set ::ExternalCompiler::makeutil_config($key) $makeutil_config($key) + } + + ${::X::actualProject} retrieve_compiler_settings + } + + ## Save settings to config file + # @return void + proc save_config {} { + variable max_ihex_rec_length ;# Int: Maximum length of IHEX-8 record + variable defaults ;# List of default settings + + ## Assembler: MCU8051IDE + # Save option variables + foreach var $defaults { + set var [lindex $var 0] + ::settings setValue \ + "Compiler/$var" \ + [subst -nocommands "\$::Compiler::Settings::${var}"] + } + ::settings setValue "Compiler/max_ihex_rec_length" \ + ${::Compiler::Settings::max_ihex_rec_length} + # Save warning level + ::settings setValue "Compiler/WARNING_LEVEL" \ + ${::Compiler::Settings::WARNING_LEVEL} + + ## Preferred assembler + ::settings setValue "Compiler/selected_assembler" \ + $::ExternalCompiler::selected_assembler + + ## Assembler: ASEM-51 + ::settings setValue "Compiler/assembler_ASEM51_addcfg" \ + [array get ::ExternalCompiler::assembler_ASEM51_addcfg] + ::settings setValue "Compiler/assembler_ASEM51_config" \ + [array get ::ExternalCompiler::assembler_ASEM51_config] + + ## Assembler: ASL + ::settings setValue "Compiler/assembler_ASL_addcfg" \ + [array get ::ExternalCompiler::assembler_ASL_addcfg] + ::settings setValue "Compiler/assembler_ASL_config" \ + [array get ::ExternalCompiler::assembler_ASL_config] + + ## Assembler: AS31 + ::settings setValue "Compiler/assembler_AS31_addcfg" \ + [array get ::ExternalCompiler::assembler_AS31_addcfg] + ::settings setValue "Compiler/assembler_AS31_config" \ + [array get ::ExternalCompiler::assembler_AS31_config] + + ## SDCC + foreach array { + sdcc_bool_options sdcc_string_options + sdcc_optional_string_options sdcc_scs_string_options + } { + ::settings setValue "Compiler/$array" \ + [array get ::ExternalCompiler::$array] + } + + ## GNU Make utility configuration + # General options + foreach key [array names ::ExternalCompiler::makeutil_config] { + ::settings setValue "Compiler/make_${key}" \ + $::ExternalCompiler::makeutil_config($key) + } + + # Synchronize + ::settings saveConfig + } + + ## Load settings from config file + # @return void + proc load_config {} { + variable defaults ;# List of default settings + variable max_ihex_rec_length ;# Int: Maximum length of IHEX-8 record + + ## Assembler: MCU8051IDE + # Load normal options + foreach item $defaults { + set var [lindex $item 0] + set val [lindex $item 1] + set ::Compiler::Settings::${var} \ + [::settings getValue "Compiler/$var" $val] + } + set ::Compiler::Settings::max_ihex_rec_length \ + [ ::settings getValue \ + "Compiler/max_ihex_rec_length" \ + ${::Compiler::Settings::max_ihex_rec_length} \ + ] + if { + ![string is digit -strict ${::Compiler::Settings::max_ihex_rec_length}] || + ${::Compiler::Settings::max_ihex_rec_length} < 0 || + ${::Compiler::Settings::max_ihex_rec_length} > 255 + } then { + set ::Compiler::Settings::max_ihex_rec_length 255 + } + # Load warning level + set ::Compiler::Settings::WARNING_LEVEL \ + [ ::settings getValue \ + "Compiler/WARNING_LEVEL" \ + ${::Compiler::Settings::WARNING_LEVEL} \ + ] + + ## Preferred assembler + set ::ExternalCompiler::selected_assembler [::settings getValue \ + "Compiler/selected_assembler" \ + $::ExternalCompiler::selected_assembler_def \ + ] + + ## Assembler: ASEM51 + # Base config + set conf [::settings getValue "Compiler/assembler_ASEM51_config" \ + $::ExternalCompiler::assembler_ASEM51_config_def \ + ] + set len [llength $conf] + for {set i 0} {$i < $len} {incr i} { + set key [lindex $conf $i] + incr i + set val [lindex $conf $i] + + if {[llength [array names ::ExternalCompiler::assembler_ASEM51_config -exact $key]]} { + set ::ExternalCompiler::assembler_ASEM51_config($key) $val + } + } + # Additional config + set conf [::settings getValue "Compiler/assembler_ASEM51_addcfg" \ + $::ExternalCompiler::assembler_ASEM51_addcfg_def \ + ] + set len [llength $conf] + for {set i 0} {$i < $len} {incr i} { + set key [lindex $conf $i] + incr i + set val [lindex $conf $i] + + if {[llength [array names ::ExternalCompiler::assembler_ASEM51_addcfg -exact $key]]} { + set ::ExternalCompiler::assembler_ASEM51_addcfg($key) $val + } + } + + ## Assembler: ASL + # Base config + set conf [::settings getValue "Compiler/ASL" \ + $::ExternalCompiler::assembler_ASL_config_def \ + ] + set len [llength $conf] + for {set i 0} {$i < $len} {incr i} { + set key [lindex $conf $i] + incr i + set val [lindex $conf $i] + + if {[llength [array names ::ExternalCompiler::assembler_ASL_config -exact $key]]} { + set ::ExternalCompiler::assembler_ASL_config($key) $val + } + } + # Additional config + set conf [::settings getValue "Compiler/ASL" \ + $::ExternalCompiler::assembler_ASL_addcfg_def \ + ] + set len [llength $conf] + for {set i 0} {$i < $len} {incr i} { + set key [lindex $conf $i] + incr i + set val [lindex $conf $i] + + if {[llength [array names ::ExternalCompiler::assembler_ASL_addcfg -exact $key]]} { + set ::ExternalCompiler::assembler_ASL_addcfg($key) $val + } + } + + ## Assembler: AS31 + # Base config + set conf [::settings getValue "Compiler/AS31" \ + $::ExternalCompiler::assembler_AS31_config_def \ + ] + set len [llength $conf] + for {set i 0} {$i < $len} {incr i} { + set key [lindex $conf $i] + incr i + set val [lindex $conf $i] + + if {[llength [array names ::ExternalCompiler::assembler_AS31_config -exact $key]]} { + set ::ExternalCompiler::assembler_AS31_config($key) $val + } + } + # Additional config + set conf [::settings getValue "Compiler/AS31" \ + $::ExternalCompiler::assembler_AS31_addcfg_def \ + ] + set len [llength $conf] + for {set i 0} {$i < $len} {incr i} { + set key [lindex $conf $i] + incr i + set val [lindex $conf $i] + + if {[llength [array names ::ExternalCompiler::assembler_AS31_addcfg -exact $key]]} { + set ::ExternalCompiler::assembler_AS31_addcfg($key) $val + } + } + + ## SDCC + foreach array { + sdcc_bool_options sdcc_string_options + sdcc_optional_string_options sdcc_scs_string_options + } { + set conf [::settings getValue \ + "Compiler/$array" [subst -nocommands "\$::ExternalCompiler::${array}_def"] \ + ] + set len [llength $conf] + for {set i 0} {$i < $len} {incr i} { + set key [lindex $conf $i] + incr i + set val [lindex $conf $i] + + if {[llength [array names ::ExternalCompiler::$array -exact $key]]} { + set ::ExternalCompiler::${array}($key) $val + } + } + } + + ## GNU Make utility configuration + # General options + foreach {key def_value} ${::ExternalCompiler::makeutil_config_def} { + set conf [::settings getValue \ + "Compiler/make_${key}" $def_value \ + ] + set ::ExternalCompiler::makeutil_config($key) $conf + } + } + + ## Destroy the dialog + # @return void + proc CANCEL {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Destroy dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Use settings and destroy the dialog + # @return void + proc OK {} { + variable win ;# ID of toplevel dialog window + + # Use and save settings + use_settings + save_config + + # Destroy dialog window + CANCEL + } + + ## Restrore defaults + # @return void + proc DEFAULTS {} { + variable win ;# ID of toplevel dialog window + variable defaults ;# List of default settings + variable opt_WARNING_LEVEL ;# Warning level + variable max_ihex_rec_length ;# Int: Maximum length of IHEX-8 record + + # Text widgets + variable sdcc_custom_opts_text ;# Widget: Text widget "Custom options for SDCC" + variable asm51_custom_opts_text ;# Widget: Text widget "Custom options for ASEM-51" + variable asl_custom_opts_text ;# Widget: Text widget "Custom options for ASL" + variable as31_custom_opts_text ;# Widget: Text widget "Custom options for AS31" + + # External assembler configuration + variable selected_assembler ;# Int: Preferred assembler (0==MCU8051IDE;1==ASEM-51;2==ASL) + variable assembler_ASEM51_config;# Array: ASEM-51 configuration + variable assembler_ASEM51_addcfg;# Array: ASEM-51 additional configuration + variable assembler_ASL_config ;# Array: ASL configuration + variable assembler_ASL_addcfg ;# Array: ASL additional configuration + variable assembler_AS31_config ;# Array: AS31 configuration + variable assembler_AS31_addcfg ;# Array: AS31 additional configuration + + # SDCC Configuration + variable sdcc_bool_opt ;# Array: SDCC configuration + variable sdcc_str_opt ;# Array: SDCC configuration + variable sdcc_opt_str_opt ;# Array: SDCC configuration + variable sdcc_scs_str_opt ;# Array: SDCC configuration + + # GNU Make utility configuration + variable makeutil_config ;# Array: Make utility configuration + + # Confirmation dialog + if { + [tk_messageBox \ + -parent $win \ + -type yesno \ + -icon question \ + -title [mc "Restore defaults"] \ + -message [mc "Are you sure that you want restore default settings ?"] \ + ] != {yes} + } then { + return + } + + ## Preferred assembler + set selected_assembler $::ExternalCompiler::selected_assembler_def + ## Assembler MCU8051IDE + # Restore normal options + foreach item $defaults { + set var [lindex $item 0] + set val [lindex $item 1] + set ::configDialogues::compiler::option_${var} $val + } + set max_ihex_rec_length 16 + # Warning level + set opt_WARNING_LEVEL [mc "All"] + ## ASEM-51 + array set assembler_ASEM51_addcfg $::ExternalCompiler::assembler_ASEM51_addcfg_def + array set assembler_ASEM51_config $::ExternalCompiler::assembler_ASEM51_config_def + # Custom options + if {[winfo exists $asm51_custom_opts_text]} { + $asm51_custom_opts_text delete 1.0 end + $asm51_custom_opts_text insert end $assembler_ASEM51_config(custom) + } + ## ASL + array set assembler_ASL_addcfg $::ExternalCompiler::assembler_ASL_addcfg_def + array set assembler_ASL_config $::ExternalCompiler::assembler_ASL_config_def + # Custom options + if {[winfo exists $asl_custom_opts_text]} { + $asl_custom_opts_text delete 1.0 end + $asl_custom_opts_text insert end $assembler_ASL_config(custom) + } + ## AS31 + array set assembler_AS31_addcfg $::ExternalCompiler::assembler_AS31_addcfg_def + array set assembler_AS31_config $::ExternalCompiler::assembler_AS31_config_def + # Custom options + if {[winfo exists $as31_custom_opts_text]} { + $as31_custom_opts_text delete 1.0 end + $as31_custom_opts_text insert end $assembler_AS31_config(custom) + } + + ## SDCC + # Copy boolean options + array set sdcc_bool_opt ${::ExternalCompiler::sdcc_bool_options_def} + # Copy string options + array set sdcc_str_opt ${::ExternalCompiler::sdcc_string_options_def} + # Copy optional strings + array set sdcc_opt_str_opt ${::ExternalCompiler::sdcc_optional_string_options_def} + # Copy semicolon separated optional string options + array set sdcc_scs_str_opt ${::ExternalCompiler::sdcc_scs_string_options_def} + # Custom options + if {[winfo exists $sdcc_custom_opts_text]} { + $sdcc_custom_opts_text delete 1.0 end + $sdcc_custom_opts_text insert end $sdcc_str_opt(custom) + } + + ## GNU Make utility configuration + # General options + foreach {key value} ${::ExternalCompiler::makeutil_config_def} { + set makeutil_config($key) $value + } + # Adjust GUI to the current config + make_tab__adjust_gui + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/configdialogues.tcl b/lib/configdialogues/configdialogues.tcl new file mode 100644 index 0000000..7dba24e --- /dev/null +++ b/lib/configdialogues/configdialogues.tcl @@ -0,0 +1,60 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _CONFIGDIALOGUES_TCL ] } { +set _CONFIGDIALOGUES_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements various configuration dialogues +# +# Currently implemented: +# - Editor configuration +# - Compiler configuration +# - Right panel configuration +# - Main toolbar configuration +# - Custom commands configuration +# - Shortcuts configuration +# - Global configuration +# - Simulator configuration +# - Terminal configuration +# -------------------------------------------------------------------------- + +namespace eval configDialogues { + # Load all available configuration dialogues into one common namespace + source "${::LIB_DIRNAME}/configdialogues/editor_config.tcl" ;# Editor configuration dialog + source "${::LIB_DIRNAME}/configdialogues/compiler_config.tcl" ;# Compiler configuration dialog + source "${::LIB_DIRNAME}/configdialogues/rightpanel_config.tcl" ;# Right panel configuration dialog + source "${::LIB_DIRNAME}/configdialogues/toolbar_config.tcl" ;# Main toolbar configuration dialog + source "${::LIB_DIRNAME}/configdialogues/custom_commands_config.tcl" ;# Custom commands configuration dialog + source "${::LIB_DIRNAME}/configdialogues/shortcuts_config.tcl" ;# Shortcuts configuration dialog + source "${::LIB_DIRNAME}/configdialogues/global_config.tcl" ;# Global configuration dialog + source "${::LIB_DIRNAME}/configdialogues/simulator_config.tcl" ;# Simulator configuration dialog + source "${::LIB_DIRNAME}/configdialogues/terminal_config.tcl" ;# Terminal configuration dialog +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/custom_commands_config.tcl b/lib/configdialogues/custom_commands_config.tcl new file mode 100644 index 0000000..0919d21 --- /dev/null +++ b/lib/configdialogues/custom_commands_config.tcl @@ -0,0 +1,454 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _CUSTOM_COMMANDS_CONFIG_TCL ] } { +set _CUSTOM_COMMANDS_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements custom commands configuration dialog +# -------------------------------------------------------------------------- + +namespace eval custom_commands { + variable win ;# ID of toplevel dialog window + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + + # Font for text widgets + variable cmd_font [font create \ + -family $::DEFAULT_FIXED_FONT \ + -size [expr {int(-12 * $::font_size_factor)}] \ + -weight bold \ + ] + + variable text_0 ;# ID of text widget for command 0 + variable text_1 ;# ID of text widget for command 1 + variable text_2 ;# ID of text widget for command 2 + + variable description ;# Array: Command description (-textvariable) (idx: 0..2) + variable cmfr_dialog ;# Array of Bool: Variable for checkbutton "Confirmation dialog" + variable results_dialog ;# Array of Bool: Variable for checkbutton "Show results" + variable ignore_errors ;# Array of Bool: Variable for checkbutton "Ignore errors" + variable run_in_term ;# Array of Bool: Variable for checkbutton "Ignore errors" + + ## Create the dialog + # @parm Int tab_number=0 - number of tab to raise + # @return void + proc mkDialog {{tab_number 0}} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable cmd_font ;# Font for text widgets + + variable text_0 ;# ID of text widget for command 0 + variable text_1 ;# ID of text widget for command 1 + variable text_2 ;# ID of text widget for command 2 + + variable description ;# Array: Command description (-textvariable) (idx: 0..2) + variable cmfr_dialog ;# Array of Bool: Variable for checkbutton "Confirmation dialog" + variable results_dialog ;# Array of Bool: Variable for checkbutton "Show results" + variable ignore_errors ;# Array of Bool: Variable for checkbutton "Ignore errors" + variable run_in_term ;# Array of Bool: Variable for checkbutton "Ignore errors" + + # Destroy the dialog if it's already opened + if {$dialog_opened} { + destroy .custom_commands_config_dialog + } + set dialog_opened 1 + + # Create toplevel window + set win [toplevel .custom_commands_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -image ::ICONS::22::gear \ + -text [mc "Edit custom commands"] \ + -font [font create -size [expr {int(-20 * $::font_size_factor)}]] + + # Create notebook + set nb [ModernNoteBook $win.nb] + + # Create notebook tabs + for {set idx 0} {$idx < 3} {incr idx} { + # Create tab + set tab [$nb insert end tab_$idx -image ::ICONS::22::gear$idx] + + # Create "Short description" (entry and label) + pack [Label $tab.desc_label \ + -text [mc "Short description"] \ + -helptext [mc "This string will be used as status bar tip (max. 100 chars)"] + ] -anchor w -padx 5 -pady 5 + pack [ttk::entry $tab.desc_entry \ + -validate key \ + -textvariable ::configDialogues::custom_commands::description($idx) \ + -validatecommand {::configDialogues::custom_commands::desc_validate %P} \ + ] -fill x -padx 5 + + ## Create options labelframe + label $tab.labelframe_label -compound left -image ::ICONS::16::configure -text [mc "Options"] + set frame [ttk::labelframe $tab.labelframe -labelwidget $tab.labelframe_label] + # Create checkbutton "Confirmation dialog" + set button [checkbutton $frame.cmfr_cbutton -anchor w \ + -text [mc "Confirmation dialog"] \ + -variable ::configDialogues::custom_commands::cmfr_dialog($idx) \ + ] + grid $button -sticky w -row 1 -column 1 -padx 5 -pady 2 + DynamicHelp::add $button -text [mc "Invoke dialog to confirm command execution."] + # Create checkbutton "Show results" + set button [checkbutton $frame.results_cbutton \ + -text [mc "Show results"] -anchor w \ + -variable ::configDialogues::custom_commands::results_dialog($idx) \ + ] + grid $button -sticky w -row 2 -column 1 -padx 5 -pady 2 + DynamicHelp::add $button -text [mc "After finish show dialog with results."] + # Create checkbutton "Ignore errors" + set button [checkbutton $frame.ignore_cbutton \ + -text [mc "Ignore errors"] -anchor w \ + -variable ::configDialogues::custom_commands::ignore_errors($idx) \ + ] + grid $button -sticky w -row 1 -column 2 -padx 5 -pady 2 + DynamicHelp::add $button -text [mc "Do not invoke error dialog if the process fails."] + # Create checkbutton "Run in terminal" + set button [checkbutton $frame.run_in_term_button \ + -text [mc "Run in terminal"] -anchor w \ + -variable ::configDialogues::custom_commands::run_in_term($idx) \ + ] + grid $button -sticky w -row 2 -column 2 -padx 5 -pady 2 + DynamicHelp::add $button -text [mc "Run interactively in terminal emulator."] + if {!$::PROGRAM_AVAILABLE(urxvt)} { + $button configure -state disabled + } + pack $frame -fill x -pady 10 -padx 5 + + # Create label "Commands to execute" and help button + set frame [frame $tab.cmd_label_frame] + pack [label $frame.label \ + -text [mc "Bash script to execute."] \ + ] -side left -padx 5 + pack [ttk::button $frame.button \ + -image ::ICONS::16::help \ + -style Flat.TButton \ + -command {::configDialogues::custom_commands::show_help} \ + ] -side right + DynamicHelp::add $frame.button \ + -text [mc "Show help"] + pack $frame -fill x + + # Create text for entering commands + set frame [frame $tab.text_frame] + set text [text $frame.text \ + -background {#FFFFFF} \ + -width 1 -height 1 \ + -font $cmd_font -undo 1 \ + -yscrollcommand "$frame.scrollbar set" \ + ] + pack $text -side left -fill both -expand 1 + pack [ttk::scrollbar $frame.scrollbar \ + -orient vertical \ + -command "$text yview" \ + ] -side right -fill y + pack $frame -fill both -expand 1 -padx 5 + + # Set NS variable -- text widget reference + set text_$idx $text + + # Get settins from the program + if {[regexp {\s*[01]\s+[01]\s+[01]\s+[01]\s*} $::X::custom_command_options($idx)]} { + set cmfr_dialog($idx) [lindex $::X::custom_command_options($idx) 0] + set results_dialog($idx) [lindex $::X::custom_command_options($idx) 1] + set ignore_errors($idx) [lindex $::X::custom_command_options($idx) 2] + set run_in_term($idx) [lindex $::X::custom_command_options($idx) 3] + } + + set description($idx) $::X::custom_command_desc($idx) + $text insert end $::X::custom_command_cmd($idx) + } + + # Raise tab + $nb raise [lindex [$nb pages] $tab_number] + + # Create button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::custom_commands::OK} \ + ] -side right -padx 2 -pady 2 + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::custom_commands::CANCEL} \ + ] -side right -padx 2 -pady 2 + + # Pack frames and notebook + pack $but_frame -side bottom -fill x -expand 0 -anchor s -padx 10 -pady 5 + pack $win.header_label -side top -pady 6 + pack [$nb get_nb] -side top -fill both -expand 1 -padx 10 + + # Finalize dialog creation + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Edit custom commands - %s" ${::APPNAME}] + wm minsize $win 460 400 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::custom_commands::CANCEL + } + tkwait window $win + } + + ## Show help window + # @return void + proc show_help {} { + # Destroy previous help window + if {[winfo exists .custom_commands_help]} { + destroy .custom_commands_help + return + } + set x [expr {[winfo pointerx .] - 400}] + set y [winfo pointery .] + + # Create new help window + set win [toplevel .custom_commands_help -class {Help} -bg ${::COMMON_BG_COLOR}] + set frame [frame $win.f -bg {#555555} -bd 0 -padx 1 -pady 1] + wm overrideredirect $win 1 + + # Click to close + bind $win "grab release $win; destroy $win" + + # Create header "-- click to close --" + pack [label $frame.lbl_header \ + -text [mc "-- click to close --"] \ + -bg {#FFFF55} -font $::smallfont \ + -fg {#000000} -anchor c \ + ] -side top -anchor c -fill x + + # Create text widget + set text [text $frame.text \ + -bg {#FFFFCC} \ + -exportselection 0 \ + -takefocus 0 \ + -cursor left_ptr \ + -bd 0 -relief flat \ + ] + + pack $frame -fill both -expand 1 + + # Create text tags + $text tag configure tag_bold_small \ + -font [font create \ + -weight bold \ + -size [expr {int(-12 * $::font_size_factor)}] \ + -family $::DEFAULT_FIXED_FONT \ + ] + $text tag configure tag_bold_big \ + -foreground {#0000DD} -underline 1 \ + -font [font create \ + -weight bold \ + -size [expr {int(-14 * $::font_size_factor)}] \ + -family $::DEFAULT_FIXED_FONT \ + ] + + # Fill in the text widget + $text insert end [mc "VARIABLES:"] + $text tag add tag_bold_big {insert linestart} {insert lineend} + $text insert end "\n %URI" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tThe full URI of the current file\n"] + $text insert end " %URIS" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tList of the URIs of all open documents\n"] + $text insert end " %directory" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tProject directory\n"] + $text insert end " %filename" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tThe file name of the current document\n"] + $text insert end " %basename" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tSame as %filename, but without extension\n"] + $text insert end " %mainfile" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tName of project main file\n"] + $text insert end " %line" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tNumber of the current line\n"] + $text insert end " %column" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tNumber of the current column\n"] + $text insert end " %selection" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tThe selected text in the current file\n"] + $text insert end " %text" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tThe full text of the current file\n"] + $text insert end " %%" + $text tag add tag_bold_small {insert linestart} {insert lineend} + $text insert end [mc "\t\tPercent sign\n\n"] + $text insert end [mc "Variables %line, %column, %selection and %text"] + foreach start {10 17 26 41} end {15 24 36 46} { + $text tag add tag_bold_small \ + [list insert linestart+${start}c] \ + [list insert linestart+${end}c] + } + $text insert end [mc "\nare not available if external editor is used"] + + # Show the text widget + $text configure -state disabled + pack $text -side bottom -fill both -expand 1 + + # Set window attributes + wm geometry $win "=420x330+$x+$y" + wm protocol $win WM_DELETE_WINDOW " + grab release $win + destroy $win + grab .custom_commands_config_dialog" + wm transient $win .custom_commands_config_dialog + raise $win + update + catch { + grab -global $win + } + tkwait window $win + } + + ## Validate content of entry "Description" + # @parm String content - String to validate + # @return Bool - result + proc desc_validate {content} { + if {[string length $content] > 100} { + return 0 + } else { + return 1 + } + } + + ## Change content of configuration variables + # @return void + proc use_settings {} { + variable description ;# Array: Command description (-textvariable) (idx: 0..2) + variable cmfr_dialog ;# Array of Bool: Variable for checkbutton "Confirmation dialog" + variable results_dialog ;# Array of Bool: Variable for checkbutton "Show results" + variable ignore_errors ;# Array of Bool: Variable for checkbutton "Ignore errors" + variable run_in_term ;# Array of Bool: Variable for checkbutton "Ignore errors" + + variable text_0 ;# ID of text widget for command 0 + variable text_1 ;# ID of text widget for command 1 + variable text_2 ;# ID of text widget for command 2 + + for {set i 0} {$i < 3} {incr i} { + # Change content of configuration variables + set ::X::custom_command_options($i) \ + "$cmfr_dialog($i) $results_dialog($i) $ignore_errors($i) $run_in_term($i)" + set ::X::custom_command_desc($i) $description($i) + set ::X::custom_command_cmd($i) [regsub {\n$} [[subst -nocommands "\$text_${i}"] get 1.0 end] {}] + + # Change status tips + if {[winfo exists .mainIconBar.custom$i]} { + setStatusTip \ + -widget .mainIconBar.custom$i \ + -text [mc "Custom command %s: %s" $i $description($i)] + ::DynamicHelp::add .mainIconBar.custom$i -text [mc "Custom command %s: %s" $i $description($i)] + } + } + } + + ## Save configuration to config file + # @return void + proc save_config {} { + # Save settings + for {set i 0} {$i < 3} {incr i} { + ::settings setValue "Custom command $i/options" \ + $::X::custom_command_options($i) + ::settings setValue "Custom command $i/description" \ + $::X::custom_command_desc($i) + ::settings setValue "Custom command $i/command" \ + $::X::custom_command_cmd($i) + } + + # Commit + ::settings saveConfig + } + + ## Load configuratin from config file + # @return void + proc load_config {} { + for {set i 0} {$i < 3} {incr i} { + # Options + set def_options $::X::custom_command_options($i) + set ::X::custom_command_options($i) [::settings \ + getValue "Custom command $i/options" \ + $::X::custom_command_options($i)] + if {![regexp {\s*[01]\s+[01]\s+[01]\s+[01]\s*} $::X::custom_command_options($i)]} { + puts stderr "Invalid custom command options, setting to defaults." + set ::X::custom_command_options($i) $def_options + } + if {!$::PROGRAM_AVAILABLE(urxvt)} { + set ::X::custom_command_options($i) [lreplace $::X::custom_command_options($i) 3 3 0] + } + # Description + set ::X::custom_command_desc($i) [::settings \ + getValue "Custom command $i/description" \ + $::X::custom_command_desc($i)] + # Command + set ::X::custom_command_cmd($i) [::settings \ + getValue "Custom command $i/command" \ + $::X::custom_command_cmd($i)] + } + } + + ## Take back changes and destroy dialog window + # @return void + proc CANCEL {} { + variable win ;# ID of dialog toplevel window + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Get rid of dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Apply changes and destroy dialog window + # @return void + proc OK {} { + variable win ;# ID of dialog toplevel window + + # Apply new settings + use_settings ;# Adjust NS variables + save_config ;# Save new config + + # Get rid of the dialog window + CANCEL + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/editor_config.tcl b/lib/configdialogues/editor_config.tcl new file mode 100644 index 0000000..7936eda --- /dev/null +++ b/lib/configdialogues/editor_config.tcl @@ -0,0 +1,2308 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _EDITOR_CONFIG_TCL ] } { +set _EDITOR_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements editor configuration dialog +# -------------------------------------------------------------------------- + +namespace eval editor { + + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + variable row 0 ;# General purpose variable (some row somewhere) + variable win ;# ID of dialog toplevel window + variable button_index 0 ;# Button index (for creating many buttons) + + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable changed ;# Bool: Settings changed + variable apply_button ;# ID of button "Apply" + + variable autocompletion_turned_on 0 + + # Notebook related + variable nb ;# Widget: Notebook itself + variable editor_tab ;# Widget: Tab "Editor" + variable general_tab ;# Widget: Tab "General" + variable colors_tab ;# Widget: Tab "Colors" + variable fonts_tab ;# Widget: Tab "Fonts" + variable highlight_tab ;# Widget: Tab "Syntax highlight" + variable highlight_tab_asm ;# Widget: Tab "Syntax highlight"/"Assembler" + variable highlight_tab_C ;# Widget: Tab "Syntax highlight"/"C language" + variable highlight_tab_lst ;# Widget: Tab "Syntax highlight"/"Code listing" + + ## Tab "Editor" + ## Int: Editor to use + # 0 - Native editor + # 1 - Vim + # 2 - Emacs + # 3 - Nano + # 4 - dav + # 5 - le + variable editor_to_use + + # Tab "General" + variable default_encoding ;# Default encoding for opening files + variable default_eol ;# Default EOL character + variable intentation_mode ;# Editor indentation mode + variable spaces_no_tabs ;# Bool: Use spaces instead of tabs + variable number_of_spaces ;# Int: Number of spaces to use instead of tab + variable tab_width ;# Int: Tab width + variable autosave ;# Int: Autosave interval in minutes (0 == disabled) + variable auto_brackets ;# Automaticaly insert oposite brackets, quotes, etc. + variable hg_trailing_sp ;# Bool: Highlight trailing space + variable auto_completion ;# Bool: Enable popup-based completion + variable cline_completion ;# Bool: Enable popup-based completion for command line + variable available_encodings { + utf-8 iso8859-1 iso8859-2 + iso8859-3 iso8859-4 iso8859-5 + iso8859-6 iso8859-7 iso8859-8 + iso8859-9 iso8859-10 iso8859-13 + iso8859-14 iso8859-15 iso8859-16 + cp1250 cp1251 cp1252 + cp1253 cp1254 cp1255 + cp1256 cp1257 cp1258 + } + + # Tab "Colors" + variable color_normal_text ;# RGB: Editor backgound color + variable color_selected_text ;# RGB: Backgound color for selected text + variable color_current_line ;# RGB: Backgound color for current line + variable color_bookmark ;# RGB: Backgound color for bookmarks + variable color_breakpoint ;# RGB: Backgound color for breakpoints + variable color_breakpoint_I ;# RGB: Backgound color for invalid breakpoints + variable color_simulator_line ;# RGB: Backgound color for simulator line + variable color_error_line ;# RGB: Backgound color for line containing an error + variable color_trailing_space ;# RGB: Backgound color for trailing space + variable color_iconBorder_bg ;# RGB: Backgound color for icon border + variable color_lineNumbers_bg ;# RGB: Backgound color for line numbers + variable color_lineNumbers_fg ;# RGB: Foregound color for line numbers + + # Tab "Fonts" + variable sample_text ;# ID of text widget for sample text + variable sample_text_size ;# Font size + variable sample_text_family ;# Font family + + ## Tab "Assembler syntax highlight" + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable list_of_tags_asm ;# List: Highlighting tags + variable highlight_tab_scr_text_asm ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + # List of checkbuttons affected by changing cursor position in sample text + variable highlight_tab_checkbuttons_asm + + ## Tab "C" syntax highlight" + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable list_of_tags_C ;# List: Highlighting tags + variable highlight_tab_scr_text_C ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_C ;# ID of text widget for sample text + # List of checkbuttons affected by changing cursor position in sample text + variable highlight_tab_checkbuttons_C + + ## Tab "LST" syntax highlight" + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + variable list_of_tags_lst ;# List: Highlighting tags + variable highlight_tab_scr_text_lst ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_lst ;# ID of text widget for sample text + # List of checkbuttons affected by changing cursor position in sample text + variable highlight_tab_checkbuttons_lst + + + ## Create the dialog + # @parm String tab_to_raise={} - Tab to raise on start up + # @return void + proc mkDialog {{tab_to_raise {}}} { + variable nb ;# Widget: Notebook itself + variable editor_tab ;# Widget: Tab "Editor" + variable general_tab ;# Widget: Tab "General" + variable colors_tab ;# Widget: Tab "Colors" + variable fonts_tab ;# Widget: Tab "Fonts" + variable highlight_tab ;# Widget: Tab "Syntax highlight" + variable highlight_tab_asm ;# Widget: Tab "Syntax highlight"/"Assembler" + variable highlight_tab_C ;# Widget: Tab "Syntax highlight"/"C language" + variable highlight_tab_lst ;# Widget: Tab "Syntax highlight"/"Code listing" + + variable apply_button ;# ID of button "Apply" + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable changed ;# Bool: Settings changed + variable editor_to_use ;# Int: Prefred editor + variable sample_text ;# ID of text widget for sample text + variable sample_text_size ;# Font size + variable sample_text_family ;# Font family + variable row ;# General purpose variable (some row somewhere) + variable win ;# ID of dialog toplevel window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable button_index ;# Button index (for creating many buttons) + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + + + set button_index 0 + + # Destroy dialog windows if it is already opened + if {$dialog_opened} { + destroy .editor_config_dialog + } + set dialog_opened 1 + set changed 0 + set anything_modified 0 + # Get settings from the program + getSettings + # Create toplevel window + set win [toplevel .editor_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -image ::ICONS::32::configure \ + -text [mc "Editor configuration"] \ + -font [font create -size [expr {int(-20 * $::font_size_factor)}]] + + # Create button "Apply" in advance + set but_frame [frame $win.button_frame] + set apply_button [ttk::button $but_frame.but_apply \ + -text [mc "Apply"] \ + -state disabled \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::editor::APPLY} \ + ] + + # Create notebook + set nb [ModernNoteBook $win.nb] + set ::configDialogues::editor::tab_created_so_far [list] + # Create Tab "Editor" + if {!$::MICROSOFT_WINDOWS} { ;# External editors are not available on Microsoft Windows + set editor_tab [$nb insert end editor_tab -text [mc "Editor"] -createcmd {::configDialogues::editor::create_tab editor}] + } + # Create Tab "General" + set general_tab [$nb insert end general_tab \ + -text [mc "General"] \ + -createcmd {::configDialogues::editor::create_tab general} \ + ] + # Create Tab "Colors" + set colors_tab [$nb insert end colors_tab \ + -text [mc "Colors"] \ + -createcmd {::configDialogues::editor::create_tab colors} \ + ] + # Create Tab "Fonts" + set fonts_tab [$nb insert end fonts_tab \ + -text [mc "Fonts"] \ + -createcmd {::configDialogues::editor::create_tab fonts} \ + ] + # Create Tab "Highlight" + set highlight_tab [$nb insert end highlight_tab \ + -text [mc "Syntax highlight"] \ + -createcmd {::configDialogues::editor::create_tab highlight} \ + ] + + # + ## Finalize + # + + if {[string length $tab_to_raise]} { + if {!$::MICROSOFT_WINDOWS} { ;# External editors are not available on Microsoft Windows + $nb raise [lindex [$nb pages] \ + [lsearch [list {Editor} {General} {Colors} {Fonts} {Highlight}] $tab_to_raise]] + } else { + $nb raise [lindex [$nb pages] \ + [lsearch [list {General} {Colors} {Fonts} {Highlight}] $tab_to_raise]] + } + } else { + if {!$::MICROSOFT_WINDOWS} { ;# External editors are not available on Microsoft Windows + if {$editor_to_use} { + foreach tab [list highlight_tab general_tab] { + $nb itemconfigure $tab -state disabled + } + $nb raise editor_tab + } else { + $nb raise general_tab + } + } else { + $nb raise general_tab + } + } + + # Create button frame at the bottom + pack $apply_button -side left + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::editor::OK} \ + ] -side right -padx 2 + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::editor::CANCEL} \ + ] -side right -padx 2 + + # Pack frames and notebook + pack $but_frame -side bottom -fill x -expand 0 -anchor s -padx 10 -pady 5 + pack $win.header_label -side top -pady 6 + pack [$nb get_nb] -side top -fill both -expand 1 -padx 10 + + # Finalize creation of the dialog + wm transient $win . + wm iconphoto $win ::ICONS::16::configure + wm title $win [mc "Editor configuration - %s" ${::APPNAME}] + wm geometry $win =350x500 + wm resizable $win 0 1 + wm minsize $win 350 470 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::editor::CANCEL + } + tkwait window $win + } + + ## Create tab in notebook + # @parm String tab_name - Name of tab to create + # @return void + proc create_tab {tab_name} { + variable nb ;# Widget: Notebook itself + variable editor_tab ;# Widget: Tab "Editor" + variable general_tab ;# Widget: Tab "General" + variable colors_tab ;# Widget: Tab "Colors" + variable fonts_tab ;# Widget: Tab "Fonts" + variable available_encodings ;# available encodings + variable highlight_tab ;# Widget: Tab "Syntax highlight" + variable highlight_tab_asm ;# Widget: Tab "Syntax highlight"/"Assembler" + variable highlight_tab_C ;# Widget: Tab "Syntax highlight"/"C language" + variable highlight_tab_lst ;# Widget: Tab "Syntax highlight"/"Code listing" + + variable editor_to_use ;# Int: Prefred editor + variable sample_text ;# ID of text widget for sample text + variable sample_text_size ;# Font size + variable sample_text_family ;# Font family + variable row ;# General purpose variable (some row somewhere) + variable win ;# ID of dialog toplevel window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable button_index ;# Button index (for creating many buttons) + + switch -- $tab_name { + {editor} { ;# Tab "Editor selection" + set editor_top_frame [frame $editor_tab.top_frame] + # Preferred editor + grid [label $editor_top_frame.editor_lbl \ + -text [mc "Preferred editor:"] -anchor w \ + ] -row 0 -column 0 -sticky w -pady 10 -padx 10 + set row 1 + set i 0 + foreach text [list \ + [mc "Native editor"] \ + {Vim} \ + {Emacs} \ + {Nano} \ + {dav} \ + {le} \ + ] { + grid [radiobutton $editor_top_frame.rabut_$i \ + -variable ::configDialogues::editor::editor_to_use \ + -value $i -text $text -state disabled \ + -command ::configDialogues::editor::editor_to_use_changed \ + ] -column 0 -padx 25 -row $row -sticky w + incr i + incr row + } + $editor_top_frame.rabut_0 configure -state normal + if {${::PROGRAM_AVAILABLE(urxvt)}} { + if {${::PROGRAM_AVAILABLE(vim)}} { + $editor_top_frame.rabut_1 configure -state normal + } + if {${::PROGRAM_AVAILABLE(emacs)}} { + $editor_top_frame.rabut_2 configure -state normal + } + if {${::PROGRAM_AVAILABLE(nano)}} { + $editor_top_frame.rabut_3 configure -state normal + } + if {${::PROGRAM_AVAILABLE(dav)}} { + $editor_top_frame.rabut_4 configure -state normal + } + if {${::PROGRAM_AVAILABLE(le)}} { + $editor_top_frame.rabut_5 configure -state normal + } + } + grid [label $editor_top_frame.editor_note \ + -fg {#555555} -font [font create \ + -family {helvetica} \ + -size [expr {int(-14 * $::font_size_factor)}] \ + -slant italic \ + ] \ + -text [mc "(This change will take effect upon next start.)"] \ + ] -row 20 -column 0 -columnspan 2 -sticky w + + # Finalize + grid columnconfigure $editor_top_frame 0 -minsize 200 + grid columnconfigure $editor_top_frame 1 -weight 1 + pack $editor_top_frame -side top -anchor nw -padx 5 -fill x + } + {general} { ;# Tab "General" + # Create label frames + set editing_labelframe [ttk::labelframe $general_tab.labelframe_edit \ + -text [mc "Editing"] \ + ] + set open_labelframe [ttk::labelframe $general_tab.labelframe_open \ + -text [mc "File opening, saving, etc."] \ + ] + set cmd_labelframe [ttk::labelframe $general_tab.labelframe_cmd \ + -text [mc "Command line"] \ + ] + + ## Labelframe "Editing" + # Item: "Auto brackets" + grid [Label $editing_labelframe.autob_lbl \ + -text [mc "Auto brackets"] \ + -helptext [mc "If you type a left bracket, editor\nwill automatically insert right bracket"] \ + ] -row 1 -column 0 -sticky w -padx 5 + grid [checkbutton $editing_labelframe.autob_chbutton \ + -variable ::configDialogues::editor::auto_brackets \ + -command ::configDialogues::editor::settings_changed \ + ] -row 1 -column 1 -sticky w -padx 5 + DynamicHelp::add $editing_labelframe.autob_chbutton \ + -text [mc "When you type a left bracket editor\nwill automatically insert right bracket"] + # Item: "Indentation mode" + grid [Label $editing_labelframe.imode_lbl \ + -text [mc "Indentation mode"] \ + -helptext [mc "What to do when you press enter\n\tnone\t- start on the beginning of the next line\n\tnormal\t- keep indention of the previous line"] \ + ] -row 2 -column 0 -sticky w -padx 5 + grid [ttk::combobox $editing_labelframe.imode_cb \ + -values [list [mc "none"] [mc "normal"]] \ + -state readonly \ + -width 0 \ + -textvariable ::configDialogues::editor::intentation_mode \ + ] -row 2 -column 1 -sticky we -padx 5 + bind $editing_labelframe.imode_cb <> \ + {::configDialogues::editor::settings_changed} + DynamicHelp::add $editing_labelframe.imode_cb \ + -text [mc "What to do when you press enter\n\tnone\t- start on the beginning of the next line\n\tnormal\t- keep indention of the previous line"] + # Item: "Tab width" + grid [Label $editing_labelframe.tabw_lbl\ + -text [mc "Tab width"] \ + -helptext [mc "Maximum width of the tab character, measured in number of spaces"] \ + ] -row 3 -column 0 -sticky w -padx 5 + grid [ttk::spinbox $editing_labelframe.tabw_spinbox \ + -from 1 -to 40 -validate all \ + -validatecommand "::configDialogues::editor::tabw_spinbox_val %P" \ + -textvariable ::configDialogues::editor::tab_width \ + -command ::configDialogues::editor::settings_changed \ + ] -row 3 -column 1 -sticky we -padx 5 + DynamicHelp::add $editing_labelframe.tabw_spinbox \ + -text [mc "Maximum width of the tab character, measured in number of spaces"] + # Item: "Insert spaces instead of tabs" + grid [Label $editing_labelframe.tabis_lbl \ + -text [mc "Insert spaces instead of tabs"] \ + -helptext [mc "Use spaces instead of tabs"] \ + ] -row 4 -column 0 -sticky w -padx 5 + grid [checkbutton $editing_labelframe.tabis_chbutton \ + -variable ::configDialogues::editor::spaces_no_tabs \ + -command ::configDialogues::editor::settings_changed \ + ] -row 4 -column 1 -sticky w -padx 5 + DynamicHelp::add $editing_labelframe.tabis_chbutton \ + -text [mc "Use spaces instead of tabs"] + # Item: "Number of spaces" + grid [Label $editing_labelframe.nofs_lbl \ + -text [mc "Number of spaces"] \ + -helptext [mc "Number of spaces to use instead of tabs"] \ + ] -row 5 -column 0 -sticky w -padx 5 + grid [ttk::spinbox $editing_labelframe.nofs_spinbox \ + -from 1 -to 16 -validate all \ + -validatecommand "::configDialogues::editor::nofs_spinbox_val %P" \ + -textvariable ::configDialogues::editor::number_of_spaces \ + -command ::configDialogues::editor::settings_changed \ + ] -row 5 -column 1 -sticky we -padx 5 + DynamicHelp::add $editing_labelframe.nofs_spinbox \ + -text [mc "Number of spaces to use instead of tabs"] + # Item: "Enable autocompletion" + grid [Label $editing_labelframe.completion_lbl \ + -text [mc "Enable autocompletion"] \ + -helptext [mc "Enable popup-based autocompletion"] \ + ] -row 6 -column 0 -sticky w -padx 5 + grid [checkbutton $editing_labelframe.completion_chbutton \ + -variable ::configDialogues::editor::auto_completion \ + -command ::configDialogues::editor::settings_changed \ + ] -row 6 -column 1 -sticky w -padx 5 + DynamicHelp::add $editing_labelframe.completion_chbutton \ + -text [mc "Enable popup-based autocompletion"] + # Item: "Highlight trailing space" + grid [Label $editing_labelframe.trail_sp_lbl \ + -text [mc "Highlight trailing space"] \ + ] -row 7 -column 0 -sticky w -padx 5 + grid [checkbutton $editing_labelframe.trail_sp_chbutton \ + -variable ::configDialogues::editor::hg_trailing_sp \ + -command ::configDialogues::editor::settings_changed \ + ] -row 7 -column 1 -sticky w -padx 5 + # Finalize + grid columnconfigure $editing_labelframe 0 -minsize 200 + grid columnconfigure $editing_labelframe 1 -weight 1 + + ## Labelframe "File opening & saving" + # Item: "Show tab bar" + grid [Label $open_labelframe.show_editor_tab_bar_lbl \ + -text [mc "Show tab bar"] \ + ] -row 0 -column 0 -sticky w -padx 5 + grid [checkbutton $open_labelframe.show_editor_tab_bar_chb \ + -onvalue 1 -offvalue 0 \ + -variable ::CONFIG(SHOW_EDITOR_TAB_BAR) \ + -command ::configDialogues::editor::settings_changed \ + ] -row 0 -column 1 -sticky w -padx 5 + + # Item: "Default charset" + grid [Label $open_labelframe.charset_lbl \ + -text [mc "Default encoding"] \ + -helptext [mc "When you open file with unknown encoding\nthis encoding will be used"] \ + ] -row 1 -column 0 -sticky w -padx 5 + grid [ttk::combobox $open_labelframe.charset_cb \ + -width 0 \ + -state readonly \ + -values $available_encodings \ + -textvariable ::configDialogues::editor::default_encoding \ + ] -row 1 -column 1 -sticky we -padx 5 + bind $open_labelframe.charset_cb <> \ + {::configDialogues::editor::settings_changed} + DynamicHelp::add $open_labelframe.charset_cb \ + -text [mc "When you open file with unknown encoding\nthis encoding will be used"] + # Item: "Default EOL" + grid [Label $open_labelframe.eol_lbl \ + -text [mc "Default EOL"] \ + -helptext [mc "When you open file with unknown\nEOL (End Of Line) this EOL will be used"] \ + ] -row 2 -column 0 -sticky w -padx 5 + grid [ttk::combobox $open_labelframe.eol_cb \ + -textvariable ::configDialogues::editor::default_eol \ + -width 0 \ + -state readonly \ + -values {{lf} {cr} {crlf}} \ + ] -row 2 -column 1 -sticky we -padx 5 + bind $open_labelframe.eol_cb <> \ + {::configDialogues::editor::settings_changed} + DynamicHelp::add $open_labelframe.eol_cb \ + -text [mc "When you open file with unknown\nEOL (End Of Line) this EOL will be used"] + # Item: "Autosave" + grid [Label $open_labelframe.autosave_lbl \ + -text [mc "Autosave interval \[minutes\]"] \ + -helptext [mc "Autosave interval in minutes (0 means disabled)"] \ + ] -row 3 -column 0 -sticky w -padx 5 + grid [ttk::combobox $open_labelframe.autosave_cb \ + -width 0 \ + -state readonly \ + -values {0 1 2 5 10 15 20 30 45 60} \ + -textvariable ::configDialogues::editor::autosave \ + ] -row 3 -column 1 -sticky we -padx 5 + bind $open_labelframe.autosave_cb <> \ + {::configDialogues::editor::settings_changed} + DynamicHelp::add $open_labelframe.autosave_cb \ + -text [mc "Autosave interval in minutes (0 means disabled)"] + # Finalize + grid columnconfigure $open_labelframe 0 -minsize 200 + grid columnconfigure $open_labelframe 1 -weight 1 + + ## Labelframe "Command line" + # Item: "Enable autocompletion" + grid [Label $cmd_labelframe.completion_lbl \ + -text [mc "Enable autocompletion"] \ + -helptext [mc "Enable popup-based autocompletion"] \ + ] -row 0 -column 0 -sticky w -padx 5 + grid [checkbutton $cmd_labelframe.completion_chbutton \ + -variable ::configDialogues::editor::cline_completion \ + -command ::configDialogues::editor::settings_changed \ + ] -row 0 -column 1 -sticky w -padx 5 + # Finalize + grid columnconfigure $cmd_labelframe 0 -minsize 200 + grid columnconfigure $cmd_labelframe 1 -weight 1 + + # Pack label frames of tab "General" + pack $editing_labelframe -fill both -expand 1 -padx 5 -pady 5 + pack $open_labelframe -fill both -expand 1 -padx 5 -pady 5 + pack $cmd_labelframe -fill both -expand 1 -padx 5 -pady 5 + } + {colors} { ;# Tab "Colors" + # Create label frames + set frm_textAreaBackfround [ttk::labelframe \ + $colors_tab.textAreaBackfround \ + -text [mc "Text area background"] \ + -padding 5 \ + ] + set frm_additionalElements [ttk::labelframe \ + $colors_tab.additionalElements \ + -text [mc "Additional elements"] \ + -padding 5 \ + ] + + # Create buttons in label frame "Text area background" + set row 0 + foreach name { + normal_text selected_text current_line + bookmark simulator_line breakpoint + breakpoint_I error_line trailing_space + } text [list \ + [mc "Normal text"] [mc "Selected text"] \ + [mc "Current line"] [mc "Bookmark"] \ + [mc "Simulator line"] [mc "Breakpoint"] \ + [mc "Invalid breakpoint"] [mc "Line with an error"] \ + [mc "Trailing space"] \ + ] { + + mk_button_select_menu \ + $frm_textAreaBackfround \ + "::configDialogues::editor::color_$name" \ + $name \ + $text + } + + grid columnconfigure $frm_textAreaBackfround 1 -minsize 200 + + # Create buttons in label frame "Text area background" + set row 0 + foreach name { + iconBorder_bg lineNumbers_bg + lineNumbers_fg + } text [list \ + [mc "Icon border background"] \ + [mc "Line numbers background"] \ + [mc "Line numbers foreground"] \ + ] { + + mk_button_select_menu \ + $frm_additionalElements \ + "::configDialogues::editor::color_$name" \ + $name \ + $text + + grid columnconfigure $frm_additionalElements 1 -minsize 200 + } + + # Pack label frames + pack $frm_textAreaBackfround -fill both -expand 1 -pady 5 -padx 5 + pack $frm_additionalElements -fill both -expand 1 -pady 5 -padx 5 + } + {fonts} { ;# Tab "Fonts" + # Create frames + set top_frame [frame $fonts_tab.frm_top_frame] + set bottom_frame [frame $fonts_tab.frm_bottom_frame] + set top_left_frame [frame $top_frame.frm_left] + set top_right_frame [frame $top_frame.frm_right] + + # Create fonts listbox + set scrollbar [ttk::scrollbar $top_left_frame.scrollbar \ + -orient vertical \ + -command "$top_left_frame.list_box yview" \ + ] + set listBox [ListBox $top_left_frame.list_box \ + -bg white \ + -yscrollcommand "$scrollbar set" \ + -selectfill 1 \ + -selectbackground #8888FF \ + -highlightthickness 0 \ + -height 15 \ + -width 25 \ + -font [font create \ + -size -13 \ + -family {helvetica} \ + ] \ + ] + pack $scrollbar -side right -fill y + pack $listBox -side left -fill both -expand 1 + $listBox bindText <1> {::configDialogues::editor::select_font_family %W} + if {[winfo exists $listBox.c]} { + bind $listBox.c {%W yview scroll +5 units; break} + bind $listBox.c {%W yview scroll -5 units; break} + } + + # Create size listbox + set scrollbar [ttk::scrollbar $top_right_frame.scrollbar\ + -orient vertical \ + -command "$top_right_frame.list_box yview" \ + ] + set listBox [ListBox $top_right_frame.list_box \ + -bg white \ + -yscrollcommand "$scrollbar set" \ + -selectfill 1 \ + -selectbackground #8888FF \ + -width 7 \ + -height 15 \ + -highlightthickness 0 \ + -font [font create \ + -size -13 \ + -family {helvetica} \ + ] \ + ] + pack $scrollbar -side right -fill y + pack $listBox -side left -fill y + $listBox bindText <1> {::configDialogues::editor::select_font_size %W} + if {[winfo exists $listBox.c]} { + bind $listBox.c {%W yview scroll +5 units; break} + bind $listBox.c {%W yview scroll -5 units; break} + } + + # Create sample text entry + set sample_text [entry $bottom_frame.entry \ + -bg ${::COMMON_BG_COLOR} \ + -bd 0 \ + -width 30 \ + -font [font create \ + -family $sample_text_family \ + -size -$sample_text_size \ + ] \ + ] + pack $sample_text -pady 25 + $sample_text insert end [mc "The Quick Brown Fox Jumps Over The Lazy Dog"] + + # Pack frames + pack $top_left_frame -side left -padx 5 -fill x + pack $top_right_frame -side right -padx 5 + pack $top_frame -side top -pady 10 + pack $bottom_frame -side bottom -fill both -expand 1 + + # Fill up sizes listbox + for {set i 4} {$i < 22} {incr i} { + $listBox insert end $i -text "$i" + if {$i == $sample_text_size} { + $top_right_frame.list_box selection set $i + } + } + + pack [label $bottom_frame.progress \ + -text [mc "Searching for available fonts ..."] \ + ] + + # Fill up fonts listbox + after idle [subst { + if {[winfo exists $top_left_frame.list_box]} { + set i 0 + foreach font \[font families\] { + set font_ref \[font create -family \$font\] + if {!\[font metrics \$font_ref -fixed\]} { + font delete \$font_ref + continue + } + font delete \$font_ref + + $top_left_frame.list_box insert end \$i -text \$font + if {\$font == {$sample_text_family}} { + $top_left_frame.list_box selection set \$i + } + incr i + update + } + destroy $bottom_frame.progress + } + }] + } + {highlight} { ;# Tab "Syntax highlight" + set highlight_notebook [ModernNoteBook $highlight_tab.nb] + set highlight_tab_asm [$highlight_notebook insert end highlight_tab_asm \ + -createcmd {::configDialogues::editor::create_highlight_tab 0} \ + -text [mc "Assembler"] \ + ] + set highlight_tab_C [$highlight_notebook insert end highlight_tab_C \ + -createcmd {::configDialogues::editor::create_highlight_tab 1} \ + -text [mc "C language"] \ + ] + set highlight_tab_lst [$highlight_notebook insert end highlight_tab_lst \ + -createcmd {::configDialogues::editor::create_highlight_tab 2} \ + -text [mc "Code listing"] \ + ] + + $highlight_notebook raise highlight_tab_asm + pack [$highlight_notebook get_nb] -fill both -expand 1 + } + } + } + + ## Create tab synatx highlight in notebook "Syntax highlight" + # @parm Int language - Highlighting pattern + # 0 - Assembler + # 1 - C language + # 2 - Code listing + # @retuer void + proc create_highlight_tab {language} { + ## General + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + variable highlight_tab_asm ;# Widget: Tab "Syntax highlight"/"Assembler" + variable highlight_tab_C ;# Widget: Tab "Syntax highlight"/"C language" + variable highlight_tab_lst ;# Widget: Tab "Syntax highlight"/"Code listing" + + ## Assembler + variable highlight_tab_scr_text_asm ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + variable highlight_tab_checkbuttons_asm ;# List of checkbuttons affected by changing cursor + variable list_of_tags_asm ;# List: Highlighting tags + + # C language + variable highlight_tab_scr_text_C ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_C ;# ID of text widget for sample text + variable highlight_tab_checkbuttons_C ;# List of checkbuttons affected by changing cursor + variable list_of_tags_C ;# List: Highlighting tags + + # Code listing + variable highlight_tab_scr_text_lst ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_lst ;# ID of text widget for sample text + variable highlight_tab_checkbuttons_lst ;# List of checkbuttons affected by changing cursor + variable list_of_tags_lst ;# List: Highlighting tags + + # Determinate set of highlighting tags + switch -- $language { + 0 { + set tab_frame $highlight_tab_asm + set highlight_tags $highlight_tags_asm + } + 1 { + set tab_frame $highlight_tab_C + set highlight_tags $highlight_tags_C + } + 2 { + set tab_frame $highlight_tab_lst + set highlight_tags $highlight_tags_lst + } + } + + ## Create widgets + # Top frame - Contains: SCR frame (SRC header, list of tags), scrollbar + set highlight_tab_top_frame [frame $tab_frame.top_frame] + # SCR frame - Contains: SRC header, list of tags + set highlight_tab_scr_frm [frame $highlight_tab_top_frame.src_frm -bd 1 -relief sunken] + # Scrollbar (in Top frame) + set highlight_tab_scrollbar [ttk::scrollbar \ + $highlight_tab_top_frame.scrollbar \ + -orient vertical \ + -command "$highlight_tab_scr_frm.scr_text_c yview" \ + ] + # SRC header (in SCR frame) + set highlight_tab_scr_header [text $highlight_tab_scr_frm.scr_text_h \ + -bd 0 \ + -height 2 \ + -bg {#DFDFDF} \ + -height 1 \ + -width 0 \ + -cursor left_ptr \ + -font [font create \ + -family $::DEFAULT_FIXED_FONT \ + -size -16 \ + ] \ + ] + bind $highlight_tab_scr_header <> {false_selection %W} + bind $highlight_tab_scr_header {break} + bind $highlight_tab_scr_header {break} + # Padding above the list of tags (see below) + set padding_widget [text $highlight_tab_scr_frm.padding \ + -bd 0 \ + -bg {#FFFFFF} \ + -cursor left_ptr \ + -font [font create \ + -size -15 \ + -family $::DEFAULT_FIXED_FONT \ + ] \ + -height 1 \ + -width 1 \ + ] + # List of tags (in SCR frame) + set highlight_tab_scr_text [text $highlight_tab_scr_frm.scr_text_c \ + -bd 0 \ + -bg {#FFFFFF} \ + -cursor left_ptr \ + -font [font create \ + -size -12 \ + -family $::DEFAULT_FIXED_FONT \ + ] \ + -yscrollcommand "$highlight_tab_scrollbar set" \ + -width 1 \ + -tabstyle wordprocessor \ + ] + $highlight_tab_scr_text tag configure sel_user \ + -borderwidth 1 -background {#CCCCFF} -relief raised + switch -- $language { + 0 {set sh_ns ASMsyntaxHighlight} + 1 {set sh_ns CsyntaxHighlight} + 2 {set sh_ns LSTsyntaxHighlight} + } + ${sh_ns}::create_tags $highlight_tab_scr_text 12 $::DEFAULT_FIXED_FONT $highlight_tags 1 + bind $highlight_tab_scr_text <> {false_selection %W} + bind $highlight_tab_scr_text {break} + bind $highlight_tab_scr_text {break} + bind $highlight_tab_scr_text "$highlight_tab_scr_text yview scroll -1 units" + bind $highlight_tab_scr_text "$highlight_tab_scr_text yview scroll +1 units" + # Sample text + set highlight_tab_scr_sample_text [text $tab_frame.scr_text_sample \ + -bd 1 \ + -bg {#FFFFFF} \ + -width 0 \ + -height 3 \ + -maxundo 0 \ + -wrap none \ + -selectborderwidth 1 \ + -highlightcolor gray \ + -tabstyle wordprocessor \ + -font [font create -weight bold -size -12 -family $::DEFAULT_FIXED_FONT] \ + ] + ${sh_ns}::create_tags $highlight_tab_scr_sample_text 12 $::DEFAULT_FIXED_FONT $highlight_tags + bind $highlight_tab_scr_sample_text "::configDialogues::editor::parse %K $language" + bind $highlight_tab_scr_sample_text \ + "::configDialogues::editor::syntax_sample_text_click %x %y $language" + switch -- $language { + 0 { + $highlight_tab_scr_sample_text insert end [join [list \ + "FOX0 equ (100 % Xer)\n" \ + "main: inc FOX0 ; [mc {increment some register}]\n" \ + " sjmp main ; [mc {close main loop}]" \ + ] {}] + } + 1 { + $highlight_tab_scr_sample_text insert end [join [list \ + "/** @sa DOXYGEN **/ // [mc {Comment}]\n" \ + "unsigned int func() {\n" \ + "\treturn 0xFA+044-58+'d'\n" \ + "}\n" \ + "printf(\"[mc {String}] %f\", 7.2);\n" \ + "#define [mc {macro Some value}]\n" \ + "#include " \ + ] {}] + } + 2 { + $highlight_tab_scr_sample_text insert end [join { + { 0055 18 X data 55h} \ + { =1 32 sub_0:} \ + {0014 1122 =1 33 +1 inc A} \ + } "\n"] + } + } + + # Pack widgets + pack $highlight_tab_scr_header -in $highlight_tab_scr_frm -fill x -expand 1 -anchor n + pack $padding_widget -in $highlight_tab_scr_frm -fill x + pack $highlight_tab_scr_text -in $highlight_tab_scr_frm -fill both -expand 1 + pack $highlight_tab_scrollbar -side right -fill y + pack $highlight_tab_scr_frm -side left -expand 1 -fill both + pack $highlight_tab_scr_sample_text -side bottom -fill x -expand 0 + pack $highlight_tab_top_frame -side top -fill both -expand 1 + + # Create content of "SCR header" + $highlight_tab_scr_header tag configure tag_normal \ + -font [$highlight_tab_scr_text cget -font] + $highlight_tab_scr_header insert end " [mc {Content}] " + $highlight_tab_scr_header image create end -image ::ICONS::16::text_italic -pady 0 + $highlight_tab_scr_header insert end " " + $highlight_tab_scr_header image create end -image ::ICONS::16::text_strike -pady 0 + $highlight_tab_scr_header insert end " " + $highlight_tab_scr_header image create end -image ::ICONS::16::text_bold -pady 0 + $highlight_tab_scr_header insert end " [mc {Color}]" + $highlight_tab_scr_header configure -state disabled + $highlight_tab_scr_header tag add tag_normal 1.0 end + + # Create content of "list of tags" + set row 0 ;# Number of current row + set list_of_tags {} ;# List of highlighting tags + set highlight_tab_checkbuttons {} ;# List of check buttons + foreach key $highlight_tags { + incr row + + # Local variables + set tag [lindex $key 0] ;# ID of the text tag + set content { } ;# Name of the text tag + set color [lindex $key 1] ;# RGB: Foreground color + set overstrike [lindex $key 2] ;# Bool: Overstrike + set italic [lindex $key 3] ;# Bool: Italic + set bold [lindex $key 4] ;# Bool: Bold + + # Modify some variables + append content [mc [key2name $tag]] + set localButtons {} + lappend list_of_tags $tag + + # Determinate font weight + if {$bold} { + set weight bold + } else { + set weight normal + } + + # Determinate font slant + if {$italic} { + set slant italic + } else { + set slant roman + } + + # Initialize some NS variables + set ::configDialogues::editor::__${language}_${row}_italic $italic + set ::configDialogues::editor::__${language}_${row}_overstrike $overstrike + set ::configDialogues::editor::__${language}_${row}_bold $bold + + # Insert tag name and some '\t' + $highlight_tab_scr_text insert end $content + set len [string length $content] + $highlight_tab_scr_text tag add $tag \ + [$highlight_tab_scr_text index {insert linestart}] \ + [$highlight_tab_scr_text index insert] + $highlight_tab_scr_text insert end [string repeat { } [expr {24 - $len}]] + + # Insert checkbutton "Italic" + set button [checkbutton $highlight_tab_scr_frm.italic_${row} \ + -command "::configDialogues::editor::change_style italic $row $language"\ + -variable ::configDialogues::editor::__${language}_${row}_italic \ + -relief flat \ + -pady 0 \ + -highlightthickness 0 \ + -bg {#FFFFFF} \ + -activebackground {#FFFFFF} \ + -selectcolor {#FFFFFF} \ + ] + lappend localButtons $button + $highlight_tab_scr_text window create end -window $button + $highlight_tab_scr_text insert end " " + + # Insert checkbutton "Overstike" + set button [checkbutton $highlight_tab_scr_frm.overstrike_${row} \ + -command "::configDialogues::editor::change_style overstrike $row $language" \ + -variable ::configDialogues::editor::__${language}_${row}_overstrike \ + -relief flat \ + -pady 0 \ + -highlightthickness 0 \ + -bg {#FFFFFF} \ + -activebackground {#FFFFFF} \ + -selectcolor {#FFFFFF} \ + ] + lappend localButtons $button + $highlight_tab_scr_text window create end -window $button + $highlight_tab_scr_text insert end " " + + # Insert checkbutton "Bold" + set button [checkbutton $highlight_tab_scr_frm.bold_${row} \ + -command "::configDialogues::editor::change_style bold $row $language" \ + -variable ::configDialogues::editor::__${language}_${row}_bold \ + -relief flat \ + -pady 0 \ + -highlightthickness 0 \ + -bg {#FFFFFF} \ + -activebackground {#FFFFFF} \ + -selectcolor {#FFFFFF} \ + ] + lappend localButtons $button + $highlight_tab_scr_text window create end -window $button + $highlight_tab_scr_text insert end " " + + # Insert button "Color" + set button [button $highlight_tab_scr_frm.color_${row} \ + -bd 1 -relief raised -pady 0 -highlightthickness 0 \ + -bg $color -activebackground $color -width 3 \ + -command "::configDialogues::editor::select_bg_color $highlight_tab_scr_frm.color_${row} $row $language" \ + ] + $highlight_tab_scr_text window create end -window $button + + # Insert LF + $highlight_tab_scr_text insert end "\n" + + # Append local buttons to list of checkbuttons + lappend highlight_tab_checkbuttons $localButtons + } + + # Disable text widget "List of tags" and remove last line (empty line) + $highlight_tab_scr_text delete end-1l end + $highlight_tab_scr_text configure -state disabled + + # Set NS variables + switch -- $language { + 0 { + set highlight_tab_scr_text_asm $highlight_tab_scr_text + set highlight_tab_scr_sample_text_asm $highlight_tab_scr_sample_text + set highlight_tab_checkbuttons_asm $highlight_tab_checkbuttons + set list_of_tags_asm $list_of_tags + } + 1 { + set highlight_tab_scr_text_C $highlight_tab_scr_text + set highlight_tab_scr_sample_text_C $highlight_tab_scr_sample_text + set highlight_tab_checkbuttons_C $highlight_tab_checkbuttons + set list_of_tags_C $list_of_tags + } + 2 { + set highlight_tab_scr_text_lst $highlight_tab_scr_text + set highlight_tab_scr_sample_text_lst $highlight_tab_scr_sample_text + set highlight_tab_checkbuttons_lst $highlight_tab_checkbuttons + set list_of_tags_lst $list_of_tags + } + } + + # Initialize syntax highlight + if {$language != 1} { + for {set i 1} {$i < int([$highlight_tab_scr_sample_text index end])} {incr i} { + set lineEnd [$highlight_tab_scr_sample_text index "$i.0 lineend"] + set lineStart $i.0 + + ${sh_ns}::highlight $highlight_tab_scr_sample_text $i + } + } else { + parse {} 1 + } + } + + ## This function should be called always after change of $editor_to_use + # @return void + proc editor_to_use_changed {} { + variable nb ;# Widget: Notebook itself + variable editor_to_use ;# Int: Preferred editor + variable general_tab ;# Widget: Tab "General" + variable highlight_tab ;# Widget: Tab "Syntax highlight" + + settings_changed + + if {$editor_to_use} { + set state disabled + } else { + set state normal + } + foreach tab [list general_tab highlight_tab] { + $nb itemconfigure tab -state $state + } + } + + ## Create some text tag in the given text widget + # @parm Widget text_widget - target text widget + # @parm Int item - index of the tag (in variable highlight_tags) + # @parm Int language - Highlighting pattern + # 0 - Assembler + # 1 - C language + # 2 - Code listing + # @return void + proc create_tags {text_widget item language} { + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + + # Determinate set of highlighting tags + switch -- $language { + 0 { + set highlight_tags $highlight_tags_asm + } + 1 { + set highlight_tags $highlight_tags_C + } + 2 { + set highlight_tags $highlight_tags_lst + } + } + + # Gain tag definition + set item [lindex $highlight_tags $item] + # Create array of tag attributes + for {set i 0} {$i < 5} {incr i} { + set tag($i) [lindex $item $i] + } + + # Foreground color + if {$tag(1) == {}} { + set tag(1) black + } + # Font slant + if {$tag(3) == 1} { + set tag(3) italic + } else { + set tag(3) roman + } + + # Font weight + if {!$::MICROSOFT_WINDOWS} { + if {$tag(4) == 1} { + set tag(4) bold + } else { + set tag(4) normal + } + } else { + set tag(4) normal + } + + # Create the tag + $text_widget tag configure $tag(0) \ + -foreground $tag(1) \ + -font [ font create \ + -overstrike $tag(2) \ + -slant $tag(3) \ + -weight $tag(4) \ + -size -12 \ + -family $::DEFAULT_FIXED_FONT \ + ] + } + + ## Call procedure syntax_find + # @parm Int x - relative X coordinate + # @parm Int y - relative Y coordinate + # @parm Int language - Highlighting pattern + # 0 - Assembler + # 1 - C language + # 2 - Code listing + # @return void + proc syntax_sample_text_click {x y language} { + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + variable highlight_tab_scr_sample_text_C ;# ID of text widget for sample text + variable highlight_tab_scr_sample_text_lst ;# ID of text widget for sample text + + switch -- $language { + 0 {set text $highlight_tab_scr_sample_text_asm} + 1 {set text $highlight_tab_scr_sample_text_C} + 2 {set text $highlight_tab_scr_sample_text_lst} + } + syntax_find [$text index @$x,$y] $language + } + + ## Find tag used at the giuven index + # @parm TextIndex text_index - text index + # @parm Int language - Highlighting pattern + # 0 - Assembler + # 1 - C language + # 2 - Code listing + # @return void + proc syntax_find {text_index language} { + variable list_of_tags_asm ;# List: Highlighting tags + variable highlight_tab_checkbuttons_asm ;# List of checkbuttons affected by changing curosr + variable highlight_tab_scr_text_asm ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + + ## Assembler + variable highlight_tab_scr_text_asm ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + variable highlight_tab_checkbuttons_asm ;# List of checkbuttons affected by changing cursor + variable list_of_tags_asm ;# List: Highlighting tags + + # C language + variable highlight_tab_scr_text_C ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_C ;# ID of text widget for sample text + variable highlight_tab_checkbuttons_C ;# List of checkbuttons affected by changing cursor + variable list_of_tags_C ;# List: Highlighting tags + + # Code listing + variable highlight_tab_scr_text_lst ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_lst ;# ID of text widget for sample text + variable highlight_tab_checkbuttons_lst ;# List of checkbuttons affected by changing cursor + variable list_of_tags_lst ;# List: Highlighting tags + + + # Determinate set of highlighting tags + switch -- $language { + 0 { + set list_of_tags $list_of_tags_asm + set highlight_tab_checkbuttons $highlight_tab_checkbuttons_asm + set highlight_tab_scr_text $highlight_tab_scr_text_asm + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_asm + } + 1 { + set list_of_tags $list_of_tags_C + set highlight_tab_checkbuttons $highlight_tab_checkbuttons_C + set highlight_tab_scr_text $highlight_tab_scr_text_C + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_C + } + 2 { + set list_of_tags $list_of_tags_lst + set highlight_tab_checkbuttons $highlight_tab_checkbuttons_lst + set highlight_tab_scr_text $highlight_tab_scr_text_lst + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_lst + } + } + + # Remove previous selection + if {[$highlight_tab_scr_text tag ranges {sel_user}] != {}} { + set index [$highlight_tab_scr_text index sel_user.first] + set buttons [lindex $highlight_tab_checkbuttons [expr {int($index) - 1}]] + foreach button $buttons { + $button configure \ + -bg {#FFFFFF} \ + -selectcolor {#FFFFFF} \ + -activebackground {#FFFFFF} + } + $highlight_tab_scr_text tag remove sel_user 1.0 end + } + + # Determinate tag name + set index [$highlight_tab_scr_sample_text index $text_index] + set index [$highlight_tab_scr_sample_text tag names $index] + + # Remove tags subdued to other tags which are also contained in the tag list + if {[llength $index] > 1} { + set idx [lsearch -ascii -exact $index tag_c_dox_comment] + if {$idx != -1} { + set index [lreplace $index $idx $idx] + } + + set idx [lsearch -ascii -exact $index tag_normal] + if {$idx != -1} { + set index [lreplace $index $idx $idx] + } + } + + # If the tag could not be determinated -> abort + set index [lindex $index 0] + if {$index == {}} {return} + + # Determinate tag number + set index [lsearch $list_of_tags $index] + if {$index == -1} {return} + + # Change background color for checkbuttons related to the tag + set buttons [lindex $highlight_tab_checkbuttons $index] + foreach button $buttons { + $button configure \ + -bg {#CCCCFF} \ + -selectcolor {#CCCCFF} \ + -activebackground {#CCCCFF} + } + + # Select row related to the tag + incr index + $highlight_tab_scr_text tag add sel_user $index.0 [expr {$index + 1}].0 + $highlight_tab_scr_text see $index.0 + } + + ## Manages syntax highlighting in sample text + # @parm String key - ID of the released key + # @parm Int language - Highlighting pattern + # 0 - Assembler + # 1 - C language + # 2 - Code listing + # @return void + proc parse {key language} { + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + variable highlight_tab_scr_sample_text_C ;# ID of text widget for sample text + variable highlight_tab_scr_sample_text_lst ;# ID of text widget for sample text + + switch -- $language { + 0 { + set widget $highlight_tab_scr_sample_text_asm + } + 1 { + set widget $highlight_tab_scr_sample_text_C + } + 2 { + set widget $highlight_tab_scr_sample_text_lst + } + } + + set lineNumber [expr {int([$widget index insert])}] + + # Keep indentication level after line break + if {$key == "KP_Enter" || $key == "Return"} { + # Get content of previous line + set prev_line [$widget get \ + [$widget index {insert - 1 line linestart}] \ + [$widget index {insert - 1 line lineend}] \ + ] + + # Determinate indentication characters + set indent_chars {} + regexp {^\s+} $prev_line indent_chars + + # Insert indentication characters + if {$indent_chars != {}} { + $widget insert $lineNumber.0 $indent_chars + } + } + + # Syntax highlight for assembler or code listing + if {$language == 0 || $language == 2} { + # Highlight current line + if {[lsearch { + Left Right Down Up Insert Home Prior + End Next Shift_R Control_R Alt_L Alt_R + Control_L Shift_L Escape + } $key] == -1} then { + if {$language == 0} { + ::ASMsyntaxHighlight::highlight $widget $lineNumber + } else { + ::LSTsyntaxHighlight::highlight $widget $lineNumber + } + } + + # Syntax highlight for C language + } else { + # Highlight all lines + if {[lsearch { + Left Right Down Up Insert Home Prior + End Next Shift_R Control_R Alt_L Alt_R + Control_L Shift_L Escape + } $key] == -1} then { + set status 1 + set end_line [expr {int([$widget index end])}] + for {set line 0} {$line < $end_line} {incr line} { + set status [::CsyntaxHighlight::highlight \ + $widget $line $status \ + ] + } + } + } + + # Change selection in "Tag List" + syntax_find [$widget index insert] $language + } + + ## Change font family for sample text entry in tab "Fonts" + # @parm Widget widget - source listbox + # @parm String item - ID of current item in source listbox + # @return void + proc select_font_family {widget item} { + variable sample_text ;# ID of text widget for sample text + variable sample_text_size ;# Font size + variable sample_text_family ;# Font family + + # Select item in the lisbox + set sample_text_family [$widget itemcget $item -text] + $widget selection set $item + + # Change font in sample text + $sample_text configure -font [font create \ + -family $sample_text_family \ + -size -$sample_text_size] + + # Adjust status changed + settings_changed + } + + ## Change font size for sample text entry in tab "Fonts" + # @parm Widget widget - source listbox + # @parm String item - ID of current item in source listbox + # @return void + proc select_font_size {widget item} { + variable sample_text ;# ID of text widget for sample text + variable sample_text_size ;# Font size + variable sample_text_family ;# Font family + + # Select item in the lisbox + set sample_text_size $item + $widget selection set $item + + # Change font in sample text + $sample_text configure -font [font create \ + -family $sample_text_family \ + -size -$sample_text_size \ + ] + + # Adjust status changed + settings_changed + } + + ## Change font style in sample text and list of tags in tab "Syntax highlight" + # @parm String what - ID of style + # @parm Int row - number of row in "List of tags" + # @parm Int language - Highlighting pattern + # 0 - Assembler + # 1 - C language + # 2 - Code listing + # @return void + proc change_style {what row language} { + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + + variable highlight_tab_scr_text_C ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_C ;# ID of text widget for sample text + variable highlight_tab_scr_text_asm ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + variable highlight_tab_scr_text_lst ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_lst ;# ID of text widget for sample text + + + incr row -1 + + # Determinate set of highlighting tags and text widget + switch -- $language { + 0 { + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_asm + set highlight_tab_scr_text $highlight_tab_scr_text_asm + set highlight_tags highlight_tags_asm + } + 1 { + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_C + set highlight_tab_scr_text $highlight_tab_scr_text_C + set highlight_tags highlight_tags_C + } + 2 { + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_lst + set highlight_tab_scr_text $highlight_tab_scr_text_lst + set highlight_tags highlight_tags_lst + } + } + + # Decide what to change + switch -- $what { + overstrike { + lset $highlight_tags [list $row 2] \ + [subst -nocommands "\${::configDialogues::editor::__${language}_[expr {$row + 1}]_overstrike}"] + } + italic { + lset $highlight_tags [list $row 3] \ + [subst -nocommands "\${::configDialogues::editor::__${language}_[expr {$row + 1}]_italic}"] + } + bold { + lset $highlight_tags [list $row 4] \ + [subst -nocommands "\${::configDialogues::editor::__${language}_[expr {$row + 1}]_bold}"] + } + default {return} + } + + # Change tags + create_tags $highlight_tab_scr_sample_text $row $language + create_tags $highlight_tab_scr_text $row $language + + # Adjust status changed + settings_changed + } + + ## Validate content of nofs_spinbox + # @parm String content - content to validate + # @return Bool - success + proc nofs_spinbox_val {content} { + if {![string length $content]} { + return 1 + } + if {![string is digit $content]} { + return 0 + } + if {$content > 16 || $content < 1} { + return 0 + } + ::configDialogues::editor::settings_changed + return 1 + } + + ## Validate content of tabw_spinbox + # @parm String content - content to validate + # @return Bool - success + proc tabw_spinbox_val {content} { + if {![string length $content]} { + return 1 + } + if {![string is digit $content]} { + return 0 + } + if {$content > 40 || $content < 1} { + return 0 + } + ::configDialogues::editor::settings_changed + return 1 + } + + ## Change font color in sample text and list of tags in tab "Syntax highlight" + # @parm Widget button - ID of the button used to change the color + # @parm Int row - number of row in "List of tags" + # @parm Int language - Highlighting pattern + # 0 - Assembler + # 1 - C language + # 2 - Code listing + # @return void + proc select_bg_color {button row language} { + variable win ;# ID of dialog toplevel window + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + + variable highlight_tab_scr_text_asm ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_asm ;# ID of text widget for sample text + variable highlight_tab_scr_text_C ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_C ;# ID of text widget for sample text + variable highlight_tab_scr_text_lst ;# ID of text widget for configuring syntax + variable highlight_tab_scr_sample_text_lst ;# ID of text widget for sample text + + # Determinate set of highlighting tags + switch -- $language { + 0 { + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_asm + set highlight_tab_scr_text $highlight_tab_scr_text_asm + set highlight_tags_var highlight_tags_asm + set highlight_tags $highlight_tags_asm + } + 1 { + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_C + set highlight_tab_scr_text $highlight_tab_scr_text_C + set highlight_tags_var highlight_tags_C + set highlight_tags $highlight_tags_C + } + 2 { + set highlight_tab_scr_sample_text $highlight_tab_scr_sample_text_lst + set highlight_tab_scr_text $highlight_tab_scr_text_lst + set highlight_tags_var highlight_tags_lst + set highlight_tags $highlight_tags_lst + } + } + + incr row -1 + + # Destroy prevoisly opened color selection dialog + if {[winfo exists .select_color]} { + destroy .select_color + } + + # Invoke new color selection dialog + set color [lindex $highlight_tags [list $row 1]] + set color [SelectColor .select_color \ + -parent $win \ + -color $color \ + -title [mc "Select color - %s" ${::APPNAME}] \ + ] + + # Change button background color + if {$color != {}} { + lset $highlight_tags_var [list $row 1] $color + $button configure -bg $color -activebackground $color + } + + # Change tags + create_tags $highlight_tab_scr_sample_text $row $language + create_tags $highlight_tab_scr_text $row $language + + # Adjust status changed + settings_changed + } + + ## Translate Tk tag name to human readable string + # @parm String key - tag name + # @return String - result + proc key2name {key} { + switch -- $key { + tag_char {return {Char}} + tag_hex {return {Hexadecimal number}} + tag_oct {return {Octal number}} + tag_dec {return {Decimal number}} + tag_bin {return {Binary number}} + tag_constant {return {Constant}} + tag_unknown_base {return {Generic number}} + tag_string {return {String}} + tag_comment {return {Comment}} + tag_control {return {Control sequence}} + tag_symbol {return {Symbol}} + tag_oper_sep {return {Operand separator}} + tag_directive {return {Directive}} + tag_label {return {Label}} + tag_instruction {return {Instruction}} + tag_sfr {return {SFR register}} + tag_indirect {return {Indirect address}} + tag_imm_char {return {Immediate char}} + tag_imm_hex {return {Immediate hex}} + tag_imm_oct {return {Immediate oct}} + tag_imm_dec {return {Immediate dec}} + tag_imm_bin {return {Immediate bin}} + tag_imm_constant {return {Immediate const}} + tag_imm_unknown {return {Immediate generic}} + tag_macro {return {Macro instruction}} + + tag_c_keyword {return {Keyword}} + tag_c_data_type {return {Data type}} + tag_c_dec {return {Decimal}} + tag_c_hex {return {Hexadecimal}} + tag_c_bin {return {Binary number}} + tag_c_oct {return {Octal}} + tag_c_char {return {Char}} + tag_c_float {return {Float}} + tag_c_string {return {String}} + tag_c_string_char {return {String char}} + tag_c_comment {return {Comment}} + tag_c_symbol {return {Symbol}} + tag_c_bracket {return {Bracket}} + tag_c_preprocessor {return {Preprocessor}} + tag_c_directive {return {Directive}} + tag_c_prep_lib {return {Preprocessor lib.}} + tag_normal {return {Normal text}} + tag_c_dox_comment {return {Doxygen: Comment}} + tag_c_dox_tag {return {Doxygen: Tag}} + tag_c_dox_word {return {Doxygen: Word}} + tag_c_dox_name {return {Doxygen: Name}} + tag_c_dox_html {return {Doxygen: HTML}} + tag_c_dox_harg {return {Doxygen: HTML arg.}} + tag_c_dox_hargval {return {Doxygen: HTML val.}} + + tag_lst_number {return {Value}} + tag_lst_code {return {Processor code}} + tag_lst_address {return {Address}} + tag_lst_line {return {Line number}} + tag_lst_macro {return {Macro level}} + tag_lst_include {return {Inclusion level}} + tag_lst_error {return {Error / Warning}} + tag_lst_msg {return {Message}} + } + } + + + ## Create button for selecting some color (used in tab "Colors") + # @parm Widget parent - parent frame + # @parm Variable variable - variable containg button background color (RGB format) + # @parm String name - button name (used in GUI path) + # @parm String text - text showed beside the button + # @return void + proc mk_button_select_menu {parent variable name text} { + variable row ;# General purpose variable (some row somewhere) + variable win ;# ID of dialog toplevel window + variable button_index ;# Button index (for creating many buttons) + + # Get color from the given variable + set color [subst -nocommands "\${$variable}"] + + # Create button label + grid [label $parent.${name}${button_index} \ + -text $text \ + -anchor w -bd 0 -relief raised \ + -pady 0 -highlightthickness 0 \ + ] -column 1 -row $row -sticky we + # Create button + set button [button $parent.but_normal_text$button_index \ + -bd 1 -relief raised -pady 0 -highlightthickness 0 \ + -bg $color -width 10 -activebackground $color \ + -command "::configDialogues::editor::select_color $variable $parent.but_normal_text$button_index" + ] + + # Show button + grid $button -column 2 -row $row -sticky ns -padx 10 + + # Adjust button index and current row + incr button_index + incr row + } + + ## Select some color (command for buttons in tab "Colors") + # @parm Variable variable - variable containing current color (format RGB) + # @parm Widget button - ID of button which invoked this procedure + # @return void + proc select_color {variable button} { + variable win ;# ID of dialog toplevel window + + # Destroy previously opened color selection dialog + if {[winfo exists .select_color]} { + destroy .select_color + } + + # Invoke new color selection dialog + set color [subst -nocommands "\$$variable"] + set color [SelectColor .select_color \ + -parent $win \ + -color $color \ + -title [mc "Select color - %s" ${::APPNAME}] \ + ] + + # Set new content of the given variable and button background color + if {$color != {}} { + set $variable $color + $button configure -bg $color -activebackground $color + + # Adjust status changed + settings_changed + } + } + + ## Retrieve settings related to this dialog from the program + # @return void + proc getSettings {} { + variable editor_to_use ;# Int: Prefred editor + variable default_encoding ;# Default encoding for opening files + variable default_eol ;# Default EOL character + variable intentation_mode ;# Editor indentation mode + variable spaces_no_tabs ;# Bool: Use spaces instead of tabs + variable number_of_spaces ;# Number of spaces to use instead of tab + variable tab_width ;# Int: Tab width + variable autosave ;# Int: Autosave interval in minutes (0 == disabled) + variable auto_completion ;# Bool: Enable popup-base completion + variable cline_completion ;# Bool: Enable popup-based completion for command line + variable auto_brackets ;# Automaticaly insert oposite brackets, quotes, etc. + variable hg_trailing_sp ;# Bool: Highlight trailing space + + variable color_normal_text ;# RGB: Editor backgound color + variable color_selected_text ;# RGB: Backgound color for selected text + variable color_current_line ;# RGB: Backgound color for current line + variable color_bookmark ;# RGB: Backgound color for bookmarks + variable color_breakpoint ;# RGB: Backgound color for breakpoints + variable color_breakpoint_I ;# RGB: Backgound color for invalid breakpoints + variable color_simulator_line ;# RGB: Backgound color for simulator line + variable color_error_line ;# RGB: Backgound color for line containing an error + variable color_trailing_space ;# RGB: Backgound color for trailing space + + variable color_iconBorder_bg ;# RGB: Backgound color for icon border + variable color_lineNumbers_bg ;# RGB: Backgound color for line numbers + variable color_lineNumbers_fg ;# RGB: Foregound color for line numbers + + variable sample_text_size ;# Font size + variable sample_text_family ;# Font family + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + + + # Get highlighting tags + set highlight_tags_asm ${::ASMsyntaxHighlight::highlight_tags} + set highlight_tags_C ${::CsyntaxHighlight::highlight_tags} + set highlight_tags_lst ${::LSTsyntaxHighlight::highlight_tags} + + # Get data from editor NS + set intentation_mode [mc ${::Editor::intentation_mode}] + set spaces_no_tabs ${::Editor::spaces_no_tabs} + set number_of_spaces ${::Editor::number_of_spaces} + set tab_width ${::Editor::tab_width} + set auto_completion ${::Editor::auto_completion} + set cline_completion ${::Editor::cline_completion} + set autosave ${::Editor::autosave} + set auto_brackets ${::Editor::auto_brackets} + set hg_trailing_sp ${::Editor::hg_trailing_sp} + set sample_text_size ${::Editor::fontSize} + set sample_text_family ${::Editor::fontFamily} + set color_normal_text ${::Editor::normal_text_bg} + set color_iconBorder_bg ${::Editor::iconBorder_bg} + set color_lineNumbers_bg ${::Editor::lineNumbers_bg} + set color_lineNumbers_fg ${::Editor::lineNumbers_fg} + set editor_to_use [::settings getValue \ + "Editor config/editor_to_use" \ + ${::Editor::editor_to_use} \ + ] + + # Get data from filelist NS + set default_encoding ${::FileList::default_encoding} + set default_eol ${::FileList::default_eol} + + foreach record ${::Editor::line_markers} { + set key [lindex $record 0] + set val [lindex $record 1] + + switch -- $key { + {sel} { + set color_selected_text $val + } + {tag_current_line} { + set color_current_line $val + } + {tag_bookmark} { + set color_bookmark $val + } + {tag_breakpoint} { + set color_breakpoint $val + } + {tag_breakpoint_INVALID} { + set color_breakpoint_I $val + } + {tag_simulator_curr} { + set color_simulator_line $val + } + {tag_error_line} { + set color_error_line $val + } + {tag_trailing_space} { + set color_trailing_space $val + } + default { + error "Error: Inconsistency in configuration managment, ::Editor::line_markers" + } + } + } + } + + ## Change content of configuration variables in Editor NS, Filelist NS and SyntaxHighlight NS + # @return void + proc use_settings {} { + variable autocompletion_turned_on + + variable default_encoding ;# Default encoding for opening files + variable default_eol ;# Default EOL character + variable intentation_mode ;# Editor indentation mode + variable spaces_no_tabs ;# Bool: Use spaces instead of tabs + variable number_of_spaces ;# Number of spaces to use instead of tab + variable tab_width ;# Int: Tab width + variable autosave ;# Int: Autosave interval in minutes (0 == disabled) + variable auto_completion ;# Bool: Enable popup-base completion + variable cline_completion ;# Bool: Enable popup-based completion for command line + variable auto_brackets ;# Automaticaly insert oposite brackets, quotes, etc. + variable hg_trailing_sp ;# Bool: Highlight trailing space + + variable editor_to_use ;# Int: Prefred editor + variable color_normal_text ;# RGB: Editor backgound color + variable color_selected_text ;# RGB: Backgound color for selected text + variable color_current_line ;# RGB: Backgound color for current line + variable color_bookmark ;# RGB: Backgound color for bookmarks + variable color_breakpoint ;# RGB: Backgound color for breakpoints + variable color_breakpoint_I ;# RGB: Backgound color for invalid breakpoints + variable color_simulator_line ;# RGB: Backgound color for simulator line + variable color_error_line ;# RGB: Backgound color for line containing an error + variable color_trailing_space ;# RGB: Backgound color for trailing space + + variable color_iconBorder_bg ;# RGB: Backgound color for icon border + variable color_lineNumbers_bg ;# RGB: Backgound color for line numbers + variable color_lineNumbers_fg ;# RGB: Foregound color for line numbers + + variable sample_text_size ;# Font size + variable sample_text_family ;# Font family + variable highlight_tags_asm ;# List: Definition of colors and styles for assembler syntax highlighting + variable highlight_tags_C ;# List: Definition of colors and styles for C syntax highlighting + variable highlight_tags_lst ;# List: Definition of colors and styles for LST syntax highlighting + + if {!${::Editor::auto_completion} && $auto_completion} { + set autocompletion_turned_on 1 + } else { + set autocompletion_turned_on 0 + } + + ## Filelist + set FileList::default_encoding $default_encoding + set FileList::default_eol $default_eol + + ## Editor + set Editor::intentation_mode [mc $intentation_mode] + set Editor::spaces_no_tabs $spaces_no_tabs + set Editor::auto_brackets $auto_brackets + set Editor::hg_trailing_sp $hg_trailing_sp + set Editor::auto_completion $auto_completion + set Editor::cline_completion $cline_completion + set Editor::autosave $autosave + set Editor::normal_text_bg $color_normal_text + set Editor::iconBorder_bg $color_iconBorder_bg + set Editor::lineNumbers_bg $color_lineNumbers_bg + set Editor::lineNumbers_fg $color_lineNumbers_fg + set Editor::fontSize $sample_text_size + set Editor::fontFamily $sample_text_family + + if {$number_of_spaces != {}} { + set Editor::number_of_spaces $number_of_spaces + } else { + set Editor::number_of_spaces 8 + } + if {$tab_width != {}} { + set Editor::tab_width $tab_width + } else { + set Editor::tab_width 8 + } + + set Editor::line_markers [list \ + [list sel $color_selected_text ] \ + [list tag_current_line $color_current_line ] \ + [list tag_bookmark $color_bookmark ] \ + [list tag_breakpoint $color_breakpoint ] \ + [list tag_simulator_curr $color_simulator_line ] \ + [list tag_error_line $color_error_line ] \ + [list tag_trailing_space $color_trailing_space ] \ + [list tag_breakpoint_INVALID $color_breakpoint_I ] \ + ] + + set Editor::defaultFont [font create \ + -size -$sample_text_size \ + -family $sample_text_family \ + ] + set Editor::defaultFont_bold [font create \ + -size -$sample_text_size \ + -family $sample_text_family \ + -weight {bold} \ + ] + + ## Syntax highlight + set ::ASMsyntaxHighlight::highlight_tags $highlight_tags_asm + set ::CsyntaxHighlight::highlight_tags $highlight_tags_C + set ::LSTsyntaxHighlight::highlight_tags $highlight_tags_lst + } + + ## Adjust all editors to fit new settings + # @return Bool - result + proc apply_settings {} { + variable autocompletion_turned_on + + # Check if there is at least 1 opened editor + if {[llength ${::X::openedProjects}] == 0} { + return 0 + } + + # Iterate over projects + foreach project ${::X::openedProjects} { + + # Refresh font settings in right panel + $project rightPanel_refresh_font_settings 1 + $project rightPanel_clear_symbol_list + + # Adjust tab bar + $project show_hide_tab_bar + + # Refresh font settings in all editors + foreach editor [$project cget -editors] { + $editor change_colors + $editor refresh_font_settings + $editor define_line_markers + if {$autocompletion_turned_on} { + $editor autocompletion_turned_on + } + ASMsyntaxHighlight::create_tags \ + [$editor cget -editor] \ + ${::Editor::fontSize} \ + ${::Editor::fontFamily} + CsyntaxHighlight::create_tags \ + [$editor cget -editor] \ + ${::Editor::fontSize} \ + ${::Editor::fontFamily} + LSTsyntaxHighlight::create_tags \ + [$editor cget -editor] \ + ${::Editor::fontSize} \ + ${::Editor::fontFamily} + } + + $project rightPanel_refresh_symbols + } + + # done ... + return 1 + } + + ## Set status changed to True + # @return true + proc settings_changed {} { + variable apply_button ;# ID of button "Apply" + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + + if {$changed} {return} + + set changed 1 + set anything_modified 1 + + $apply_button configure -state normal + } + + ## Take back changes and destroy dialog window + # @return void + proc CANCEL {} { + variable win ;# ID of dialog toplevel window + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Restore previous configuration + if {$anything_modified} { + load_config + apply_settings + set anything_modified 0 + } + + # Get rid of dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Apply changes and destroy dialog window + # @return void + proc OK {} { + variable win ;# ID of dialog toplevel window + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Apply new settings + if {$anything_modified} { + use_settings ;# Adjust NS variables + apply_settings ;# Adjust GUI + save_config ;# Save new config + } + + # Get rid of dialog window + grab release $win + set dialog_opened 0 + destroy $win + } + + ## Apply changes in GUI + # @return Bool - result + proc APPLY {} { + variable apply_button ;# ID of button "Apply" + variable changed ;# Bool: Settings changed + + # Check if there is at least 1 opened editor + if {[llength ${::X::openedProjects}] == 0} { + return 0 + } + + # Reset status changed + set changed 0 + $apply_button configure -state disabled + + ${::X::actualProject} rightPanel_clear_symbol_list + + # Adjust NS variables + use_settings + + ## Apply settings in current editor + set actualEditor [${::X::actualProject} cget -actualEditor] + set actualEditor2 [${::X::actualProject} cget -actualEditor2] + ${::X::actualProject} show_hide_tab_bar + ${::X::actualProject} rightPanel_refresh_font_settings 0 + ${::X::actualProject} editor_procedure $actualEditor change_colors {} + ${::X::actualProject} editor_procedure $actualEditor refresh_font_settings {} + ${::X::actualProject} editor_procedure $actualEditor define_line_markers {} + if {$actualEditor2 >= 0} { + ${::X::actualProject} editor_procedure $actualEditor2 change_colors {} + ${::X::actualProject} editor_procedure $actualEditor2 refresh_font_settings {} + ${::X::actualProject} editor_procedure $actualEditor2 define_line_markers {} + } + set editors [${::X::actualProject} cget -editors] + ASMsyntaxHighlight::create_tags [[lindex $editors $actualEditor] cget -editor] \ + ${::Editor::fontSize} ${::Editor::fontFamily} + CsyntaxHighlight::create_tags [[lindex $editors $actualEditor] cget -editor] \ + ${::Editor::fontSize} ${::Editor::fontFamily} + LSTsyntaxHighlight::create_tags [[lindex $editors $actualEditor] cget -editor] \ + ${::Editor::fontSize} ${::Editor::fontFamily} + if {$actualEditor2 >= 0} { + ASMsyntaxHighlight::create_tags [[lindex $editors $actualEditor2] cget -editor] \ + ${::Editor::fontSize} ${::Editor::fontFamily} + CsyntaxHighlight::create_tags [[lindex $editors $actualEditor2] cget -editor] \ + ${::Editor::fontSize} ${::Editor::fontFamily} + LSTsyntaxHighlight::create_tags [[lindex $editors $actualEditor2] cget -editor] \ + ${::Editor::fontSize} ${::Editor::fontFamily} + } + ${::X::actualProject} rightPanel_refresh_symbols + + # done ... + return 1 + } + + ## Save configuration to config file + # @return void + proc save_config {} { + variable editor_to_use ;# Int: Prefred editor + + # Section "Syntax highlight" + foreach item [concat \ + ${::ASMsyntaxHighlight::highlight_tags} \ + ${::CsyntaxHighlight::highlight_tags} \ + ${::LSTsyntaxHighlight::highlight_tags} \ + ] { + set key [lindex $item 0] + set value [lrange $item 1 end] + ::settings setValue "Syntax highlight/$key" $value + } + + # Section "Editor colors" + foreach key { + normal_text_bg iconBorder_bg lineNumbers_bg lineNumbers_fg + fontSize fontFamily line_markers + } { + ::settings setValue "Editor colors/$key" [subst -nocommands "\$::Editor::$key"] + } + + # Section "Editor config" + foreach key { + intentation_mode spaces_no_tabs + number_of_spaces auto_brackets + auto_completion autosave + cline_completion hg_trailing_sp + tab_width + } { + ::settings setValue "Editor config/$key" [subst -nocommands "\$::Editor::$key"] + } + ::settings setValue "Editor config/default_encoding" ${::FileList::default_encoding} + ::settings setValue "Editor config/default_eol" ${::FileList::default_eol} + ::settings setValue "Editor config/editor_to_use" $editor_to_use + + # Commit + ::settings saveConfig + } + + ## Load configuration from config file + # @return void + proc load_config {} { + variable available_encodings ;# Encodings supported by editor + + ## Section "Syntax highlight" + # Assembler + set highlight_tags {} + foreach item ${::ASMsyntaxHighlight::highlight_tags} { + set key [lindex $item 0] + set value [lrange $item 1 end] + set value [::settings getValue "Syntax highlight/$key" $value] + lappend highlight_tags [concat $key $value] + } + set ::ASMsyntaxHighlight::highlight_tags $highlight_tags + # C language + set highlight_tags {} + foreach item ${::CsyntaxHighlight::highlight_tags} { + set key [lindex $item 0] + set value [lrange $item 1 end] + set value [::settings getValue "Syntax highlight/$key" $value] + lappend highlight_tags [concat $key $value] + } + set ::CsyntaxHighlight::highlight_tags $highlight_tags + unset highlight_tags + # Code listing + set highlight_tags {} + foreach item ${::LSTsyntaxHighlight::highlight_tags} { + set key [lindex $item 0] + set value [lrange $item 1 end] + set value [::settings getValue "Syntax highlight/$key" $value] + lappend highlight_tags [concat $key $value] + } + set ::LSTsyntaxHighlight::highlight_tags $highlight_tags + unset highlight_tags + + # Section "Editor config" + foreach key { + intentation_mode spaces_no_tabs + number_of_spaces auto_brackets + auto_completion autosave + cline_completion editor_to_use + hg_trailing_sp tab_width + } { + set value [subst -nocommands "\$::Editor::$key"] + set value [::settings getValue "Editor config/$key" $value] + set ::Editor::$key $value + } + if { + ![string is integer ${::Editor::editor_to_use}] + || + ${::Editor::editor_to_use} < 0 + || + ${::Editor::editor_to_use} > 5 + } then { + set ::Editor::editor_to_use 0 + puts stderr [mc "Invalid key: '%s'" {editor_to_use}] + } elseif {${::Editor::editor_to_use}} { + if {!${::PROGRAM_AVAILABLE(urxvt)}} { + puts stderr [mc "Unable to use external embedded editor because rxvt-unicode is not available"] + set ::Editor::editor_to_use 0 + } else { + switch -- ${::Editor::editor_to_use} { + 1 {set program {vim} } + 2 {set program {emacs} } + 3 {set program {nano} } + 4 {set program {dav} } + 5 {set program {le} } + } + if {!$::PROGRAM_AVAILABLE($program)} { + puts stderr [mc "Program %s is not available. Using native editor." $program] + set ::Editor::editor_to_use 0 + } + } + } + if {![string is boolean -strict ${::Editor::spaces_no_tabs}]} { + set FileList::spaces_no_tabs 0 + puts stderr [mc "Invalid key: '%s'" {spaces_no_tabs}] + } + if {![string is boolean -strict ${::Editor::auto_brackets}]} { + set FileList::auto_brackets 1 + puts stderr [mc "Invalid key: '%s'" {auto_brackets}] + } + if {![string is boolean -strict ${::Editor::hg_trailing_sp}]} { + set FileList::hg_trailing_sp 1 + puts stderr [mc "Invalid key: '%s'" {hg_trailing_sp}] + } + if {![string is digit -strict ${::Editor::autosave}]} { + set Editor::autosave 0 + puts stderr [mc "Invalid key: '%s'" {autosave}] + } else { + if {${::Editor::autosave} > 60 || ${::Editor::autosave} < 0} { + set Editor::autosave 0 + puts stderr [mc "Invalid key: '%s'" {autosave}] + } + } + if {![string is digit -strict ${::Editor::tab_width}]} { + set Editor::tab_width 8 + puts stderr [mc "Invalid key: '%s'" {tab_width}] + } else { + if {${::Editor::tab_width} > 40 || ${::Editor::tab_width} < 1} { + set Editor::tab_width 8 + puts stderr [mc "Invalid key: '%s'" {tab_width}] + } + } + if {![string is digit -strict ${::Editor::number_of_spaces}]} { + set FileList::number_of_spaces 8 + puts stderr [mc "Invalid key: '%s'" {number_of_spaces}] + } else { + if {${::Editor::number_of_spaces} > 16 || ${::Editor::number_of_spaces} < 1} { + set FileList::number_of_spaces 8 + puts stderr [mc "Invalid key: '%s'" {number_of_spaces}] + } + } + if {![string is boolean -strict ${::Editor::auto_completion}]} { + set FileList::auto_completion 1 + puts stderr [mc "Invalid key: '%s'" {auto_completion}] + } + if {![string is boolean -strict ${::Editor::cline_completion}]} { + set FileList::cline_completion 1 + puts stderr [mc "Invalid key: '%s'" {cline_completion}] + } + if { + ${::Editor::intentation_mode} != {none} + && + ${::Editor::intentation_mode} != {normal} + } then { + set FileList::intentation_mode {normal} + puts stderr [mc "Invalid key: '%s'" {intentation_mode}] + } + + set FileList::default_encoding [::settings getValue \ + "Editor config/default_encoding" {utf-8}] + if {[lsearch $available_encodings ${FileList::default_encoding}] == -1} { + set FileList::default_encoding {utf-8} + puts stderr [mc "Invalid key: '%s'" {default_encoding}] + } + + set FileList::default_eol [::settings getValue "Editor config/default_eol" {lf}] + if { + ${FileList::default_eol} != {lf} && + ${FileList::default_eol} != {cr} && + ${FileList::default_eol} != {crlf} + } then { + set FileList::default_eol {lf} + puts stderr [mc "Invalid key: '%s'" {default_eol}] + } + + # Section "Editor colors" and "Fonts" + foreach key { + normal_text_bg iconBorder_bg lineNumbers_bg lineNumbers_fg + fontSize fontFamily line_markers + } { + set value [subst -nocommands "\$::Editor::$key"] + set value [::settings getValue "Editor colors/$key" $value] + + set valid 1 + + # Validate line_markers + if {$key == {line_markers}} { + foreach def ${::Editor::line_markers} new $value { + if {![string equal [lindex $def 0] [lindex $new 0]]} { + puts stderr [mc "-- Invalid key: '%s'" [lindex $new 0]] + set valid 0 + break + } + } + } + + if {$valid} { + set ::Editor::$key $value + } + } + + # Set editor default font + set ::Editor::defaultFont [font create \ + -size -${::Editor::fontSize} \ + -family ${::Editor::fontFamily} \ + ] + set ::Editor::defaultFont_bold [font create \ + -size -${::Editor::fontSize} \ + -family ${::Editor::fontFamily} \ + -weight {bold} \ + ] + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/global_config.tcl b/lib/configdialogues/global_config.tcl new file mode 100644 index 0000000..66ca346 --- /dev/null +++ b/lib/configdialogues/global_config.tcl @@ -0,0 +1,535 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _GLOBAL_CONFIG_TCL ] } { +set _GLOBAL_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements global configuration dialog +# -------------------------------------------------------------------------- + + +## Global configuration dialog + # see Array OPTION in root NS +namespace eval global { + + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + variable win ;# ID of dialog toplevel window + + variable available_languages ;# List: Available languages (their codes) + variable language_names ;# List: Available languages (their names) + + ## Configuration variables + variable show_splash ;# Bool: Show splash creen on start-up + variable show_tips ;# Bool: Show tips on start-up + variable language ;# String: Language code + variable language_name ;# String: Language name + variable font_size ;# Float: Global font size factor + variable font_size_desc ;# String: Global font size factor in its "string" form (I mean description) + variable background ;# String: Human readable description of the common background color + variable wstyle ;# String: Preffered widget style + + ## Create the dialog + # @return void + proc mkDialog {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable available_languages ;# List: Available languages (their codes) + variable language_names ;# List: Available languages (their names) + + # Destroy the dialog if it's already opened + if {$dialog_opened} { + destroy .global_config_dialog + } + set dialog_opened 1 + + # Determinate available languages + get_languages + + # Get settings from main NS + getSettings + + # Create toplevel window + set win [toplevel .global_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -image ::ICONS::32::kcmmemory \ + -text [mc "MCU 8051 IDE configuration"] \ + -font [font create -size [expr {int(-20 * $::font_size_factor)}]] + + # Create horizontal separator + Separator $win.sep -orient horizontal + + ## Create middle frame + set middle_frame [frame $win.middle_frame] + # Checkbutton "Display splash screen" + grid [Label $middle_frame.lbl_splash \ + -text [mc "Display splash screen"] \ + -helptext [mc "Show splash screen on start-up"] \ + ] -row 0 -column 0 -sticky w + grid [checkbutton $middle_frame.chb_splash \ + -variable ::configDialogues::global::show_splash \ + ] -row 0 -column 1 -sticky w + DynamicHelp::add $middle_frame.chb_splash \ + -text [mc "Show splash screen on start-up"] + # Checkbutton "Show tips on start-up" + grid [Label $middle_frame.lbl_tips \ + -text [mc "Show tips on start-up"] \ + -helptext [mc "Invoke dialog with tip of the day on start-up"] \ + ] -row 1 -column 0 -sticky w + grid [checkbutton $middle_frame.chb_tips \ + -variable ::configDialogues::global::show_tips \ + ] -row 1 -column 1 -sticky w + DynamicHelp::add $middle_frame.chb_tips \ + -text [mc "Invoke dialog with tip of the day on start-up"] + # Combo "Language" + grid [Label $middle_frame.lbl_lang \ + -text [mc "Language"] \ + -helptext [mc "Your preferred language"] \ + ] -row 2 -column 0 -sticky w + grid [ttk::combobox $middle_frame.cb_lang \ + -values $language_names \ + -state readonly \ + -textvariable ::configDialogues::global::language_name \ + ] -row 2 -column 1 -sticky w + bind $middle_frame.cb_lang <> { + bind %W <> { + set ::configDialogues::global::language \ + [lindex ${::configDialogues::global::available_languages} [%W current]] + } + set ::configDialogues::global::language \ + [lindex ${::configDialogues::global::available_languages} [%W current]] + ::configDialogues::global::language_changed + } + DynamicHelp::add $middle_frame.cb_lang \ + -text [mc "Your preferred language"] + # SpinBox "Font Size Factor" + grid [Label $middle_frame.lbl_fontsize \ + -text [mc "Global font size factor"] \ + -helptext [mc "Allows you to adjust size of (almost) all fonts used in this IDE"] \ + ] -row 3 -column 0 -sticky w + grid [ttk::combobox $middle_frame.cb_fontsize \ + -values [list \ + [mc "Normal"] [mc "A little larger"] \ + [mc "Notably larger"] [mc "Much larger"] \ + [mc "Huge"] [mc "Too BIG"] \ + ] \ + -state readonly \ + -textvariable ::configDialogues::global::font_size_desc \ + ] -row 3 -column 1 -sticky w + bind $middle_frame.cb_fontsize <> " + bind $middle_frame.cb_fontsize <> {} + ::configDialogues::global::fontsize_changed + " + DynamicHelp::add $middle_frame.cb_fontsize \ + -text [mc "Allows you to adjust size of (almost) all fonts used in this IDE"] + + # Combo "Widget style" + grid [Label $middle_frame.lbl_style \ + -text [mc "Widget style"] \ + -helptext [mc "Your preferred widget style"] \ + ] -row 4 -column 0 -sticky w + grid [ttk::combobox $middle_frame.cb_style \ + -values [ttk::style theme names] \ + -state readonly \ + -textvariable ::configDialogues::global::wstyle \ + ] -row 4 -column 1 -sticky w + bind $middle_frame.cb_style <> " + bind $middle_frame.cb_style <> {} + ::configDialogues::global::restart_required + " + DynamicHelp::add $middle_frame.cb_style \ + -text [mc "Your preferred widget style"] + + # Combo "Background color" + if {!$::MICROSOFT_WINDOWS} { + grid [Label $middle_frame.lbl_background \ + -text [mc "Background color"] \ + -helptext [mc "Common background color for almost everything in the GUI"] \ + ] -row 5 -column 0 -sticky w + grid [ttk::combobox $middle_frame.cb_background \ + -values [list \ + {Default} {Windows} \ + {Tk} {Light} \ + {Dark} \ + ] \ + -state readonly \ + -textvariable ::configDialogues::global::background \ + ] -row 5 -column 1 -sticky w + bind $middle_frame.cb_background <> " + bind $middle_frame.cb_background <> {} + ::configDialogues::global::restart_required + " + DynamicHelp::add $middle_frame.cb_background \ + -text [mc "Common background color for almost everything in the GUI"] + } + + # Separator + grid [ttk::separator $middle_frame.sep -orient horizontal] \ + -columnspan 2 -sticky we -row 10 -column 0 -pady 5 + # Checkbutton "Do not ask whether ..." + grid [text $middle_frame.lbl_ask \ + -wrap word \ + -height 4 \ + -width 0 \ + -bg ${::COMMON_BG_COLOR} \ + -bd 0 \ + ] -row 11 -column 0 -sticky we + $middle_frame.lbl_ask insert end [mc "Do not always ask whether to add file to the project after the file is opened"] + $middle_frame.lbl_ask configure -state disabled + grid [checkbutton $middle_frame.cb_ask \ + -onvalue 0 -offvalue 1 \ + -variable ::FileList::ask__append_file_to_project \ + ] -row 11 -column 1 -sticky w + # Checkbutton "Do not show performnace warning ..." + grid [text $middle_frame.lbl_dont_per_warn \ + -wrap word \ + -height 4 \ + -width 0 \ + -bg ${::COMMON_BG_COLOR} \ + -bd 0 \ + ] -row 12 -column 0 -sticky we + $middle_frame.lbl_dont_per_warn insert end [mc "Do not show performance warning when enabling external HW simulation."] + $middle_frame.lbl_dont_per_warn configure -state disabled + grid [checkbutton $middle_frame.cb_dont_per_warn\ + -onvalue 0 -offvalue 1 \ + -variable ::Graph::show_sim_per_warn \ + ] -row 12 -column 1 -sticky w + + # Finalize + grid columnconfigure $middle_frame 0 -minsize 200 + + ## Button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Reset" + pack [ttk::button $but_frame.but_default \ + -text [mc "Reset to defaults"] \ + -command {::configDialogues::global::DEFAULTS} \ + ] -side left + DynamicHelp::add $but_frame.but_default \ + -text [mc "Reset all settings to defaults"] + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::global::OK} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_ok \ + -text [mc "Commit new settings"] + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::global::CANCEL} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_cancel \ + -text [mc "Take changes back and close dialog"] + + # Pack frames and notebook + pack $win.header_label -side top -pady 6 + pack $win.sep -side top -fill x -after $win.header_label + pack $middle_frame -side top -padx 10 -anchor nw -pady 10 + pack $but_frame -side bottom -fill x -expand 1 -anchor s -padx 5 -pady 5 + + # Set window attributes + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Configure MCU 8051 IDE"] + wm minsize $win 380 380 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::global::CANCEL + } + tkwait window $win + } + + ## Application language changed + # Takes any set of arguments and discards them + # @parm List - meaningless + # @return void + proc language_changed args { + tk_messageBox \ + -parent .global_config_dialog \ + -type ok -icon info \ + -title [mc "Application language changed"] \ + -message [mc "Language for this application has been changed. The change will take effect upon next start of application"] + } + + ## Display message "The change will take effect upon next start of application" + # Takes any set of arguments and discards them + # @parm List - meaningless + # @return void + proc restart_required args { + tk_messageBox \ + -parent .global_config_dialog \ + -type ok -icon info \ + -title [mc "Restart required"] \ + -message [mc "The change will take effect upon next start of application"] + } + + + ## Global font size factor changed + # Takes any set of arguments and discards them + # @parm List - meaningless + # @return void + proc fontsize_changed args { + tk_messageBox \ + -parent .global_config_dialog \ + -type ok -icon info \ + -title [mc "Global font size factor changed"] \ + -message [mc "The change will take effect upon next start of application"] + } + + ## Retrieve list of available translations + # @return void + proc get_languages {} { + variable available_languages ;# List: Available languages (their codes) + variable language_names ;# List: Available languages (their names) + + set available_languages {en} + set tmp [list] + catch { ;# For Microsoft Windows it has to be enclosed in catch block + set tmp [glob -nocomplain -types f -tails \ + -directory "${::INSTALLATION_DIR}/translations" *.msg \ + ] + } + + foreach translation $tmp { + lappend available_languages [file rootname $translation] + } + + set language_names [list] + foreach lang $available_languages { + set idx [lsearch -ascii -exact ${::LANGUAGE_CODES} $lang] + if {$idx == -1} { + lappend language_names $lang + } else { + incr idx + lappend language_names [lindex ${::LANGUAGE_CODES} $idx] + } + } + } + + ## Set configuration variable + # @parm String variable - variable to set + # @parm Mixed value - new value + proc set_variable {variable value} { + variable show_splash ;# Bool: Show splash creen on start-up + variable show_tips ;# Bool: Show tips on start-up + variable language ;# String: Language + variable font_size ;# Float: Global font size factor + variable background ;# String: Human readable description of the common background color + variable wstyle ;# String: Preffered widget style + + getSettings + + switch -- $variable { + {splash} { + set show_splash $value + } + {tips} { + set show_tips $value + } + {language} { + set language $value + } + {fontsize} { + set font_size $value + } + {background} { + set background $value + } + {wstyle} { + set wstyle $value + } + default { + puts stderr "::configDialogues::global::set_variable(): `$variable' was not recognized" + } + } + + use_settings + save_config + } + + ## Retrieve settings from main NS + # @return void + proc getSettings {} { + variable show_splash ;# Bool: Show splash creen on start-up + variable show_tips ;# Bool: Show tips on start-up + variable language ;# String: Language code + variable language_name ;# String: Language name + variable available_languages ;# List: Available languages (their codes) + variable language_names ;# List: Available languages (their names) + variable font_size ;# Float: Global font size factor + variable font_size_desc ;# String: Global font size factor in its "string" form (I mean description) + variable background ;# String: Human readable description of the common background color + variable wstyle ;# String: Preffered widget style + + set show_splash ${::GLOBAL_CONFIG(splash)} + set show_tips ${::GLOBAL_CONFIG(tips)} + set language ${::GLOBAL_CONFIG(language)} + set font_size $::font_size_factor + set background ${::GLOBAL_CONFIG(background)} + set wstyle ${::GLOBAL_CONFIG(wstyle)} + + switch -- $font_size { + 1.0 {set font_size_desc [mc "Normal"] } + 1.1 {set font_size_desc [mc "A little larger"] } + 1.2 {set font_size_desc [mc "Notably larger"] } + 1.3 {set font_size_desc [mc "Much larger"] } + 1.4 {set font_size_desc [mc "Huge"] } + 1.5 {set font_size_desc [mc "Too BIG"] } + default {set font_size_desc [mc "Normal"] } + } + + if {[catch { + set language_name [lindex $language_names [lsearch -ascii -exact $available_languages $language]] + }]} then { + set language_name {} + } + } + + ## Set application according to local settings + # @return void + proc use_settings {} { + variable show_splash ;# Bool: Show splash creen on start-up + variable show_tips ;# Bool: Show tips on start-up + variable language ;# String: Language code + variable font_size ;# Float: Global font size factor + variable font_size_desc ;# String: Global font size factor in its "string" form (I mean description) + variable background ;# String: Human readable description of the common background color + variable wstyle ;# String: Preffered widget style + + switch -- $font_size_desc [subst { + {[mc "Normal"]} {set font_size 1.0} + {[mc "A little larger"]} {set font_size 1.1} + {[mc "Notably larger"]} {set font_size 1.2} + {[mc "Much larger"]} {set font_size 1.3} + {[mc "Huge"]} {set font_size 1.4} + {[mc "Too BIG"]} {set font_size 1.5} + default {set font_size 1.0} + + }] + + if {${::GLOBAL_CONFIG(language)} != $language} { + set lang_changed 1 + } else { + set lang_changed 0 + } + + set ::GLOBAL_CONFIG(splash) $show_splash + set ::GLOBAL_CONFIG(tips) $show_tips + set ::GLOBAL_CONFIG(language) $language + set ::font_size_factor $font_size + set ::GLOBAL_CONFIG(background) $background + set ::GLOBAL_CONFIG(wstyle) $wstyle + + if {$lang_changed} { + ::X::switch_language + } + } + + ## Save settings to the config file + # @return void + proc save_config {} { + variable show_splash ;# Bool: Show splash creen on start-up + variable show_tips ;# Bool: Show tips on start-up + variable language ;# String: Language code + variable font_size ;# Float: Global font size factor + variable background ;# String: Human readable description of the common background color + variable wstyle ;# String: Preffered widget style + + if {[catch { + set conf_file [open "${::CONFIG_DIR}/base.conf" w] + puts -nonewline $conf_file \ + [list $show_splash $show_tips $language $font_size $background $wstyle] + close $conf_file + }]} then { + puts stderr [mc "Unable to write to base configuration file"] + } + } + + ## Destroy the dialog + # @return void + proc CANCEL {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Destroy dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Use settings and destroy the dialog + # @return void + proc OK {} { + variable win ;# ID of toplevel dialog window + + # Use and save settings + use_settings + save_config + + # Destroy dialog window + CANCEL + } + + ## Restrore defaults + # @return void + proc DEFAULTS {} { + variable show_splash ;# Bool: Show splash creen on start-up + variable show_tips ;# Bool: Show tips on start-up + variable language ;# String: Language code + variable language_name ;# String: Language name + variable available_languages ;# List: Available languages (their codes) + variable language_names ;# List: Available languages (their names) + variable font_size_desc ;# String: Global font size factor in its "string" form (I mean description) + variable background ;# String: Human readable description of the common background color + variable wstyle ;# String: Preffered widget style + + set show_splash 1 + set show_tips 1 + set language {en} + set font_size_desc {Normal} + set background {Default} + set wstyle {clam} + + if {[catch { + set language_name [lindex $language_names [lsearch -ascii -exact $available_languages $language]] + }]} then { + set language_name {} + } + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/rightpanel_config.tcl b/lib/configdialogues/rightpanel_config.tcl new file mode 100644 index 0000000..0cace4e --- /dev/null +++ b/lib/configdialogues/rightpanel_config.tcl @@ -0,0 +1,505 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _RIGHTPANEL_CONFIG_TCL ] } { +set _RIGHTPANEL_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements right panel configuration dialog +# -------------------------------------------------------------------------- + +namespace eval rightPanel { + + variable win ;# ID of toplevel dialog window + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + + variable apply_button ;# ID of button "Apply" + variable instruction_tags ;# Highlighting tags for instruction details + variable watch_text_tags ;# Highlighting tags for register watches + + ## Create the dialog + # @parm Int tab_number=0 - number of tab to raise + # @return void + proc mkDialog {{tab_number 0}} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable changed ;# Bool: Settings changed + variable apply_button ;# ID of button "Apply" + variable instruction_tags ;# Highlighting tags for instruction details + variable watch_text_tags ;# Highlighting tags for register watches + + # Destroy the dialog if it's already opened + if {$dialog_opened} { + destroy .rightPanel_config_dialog + } + set anything_modified 0 + set dialog_opened 1 + set changed 0 + + # Get settings from Compiler NS + getSettings + + # Create toplevel window + set win [toplevel .rightPanel_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -text [mc "Right panel configuration"] \ + -font [font create -size [expr {int(-20 * $::font_size_factor)}]] + + ## Create notebook + set nb [ModernNoteBook $win.nb] + # Tab "Register watches" + set watches_tab [$nb insert end watches_tab -text [mc "Register watches"]] + # Tab "Instruction details" + set instruction_tab [$nb insert end instruction_tab -text [mc "Instruction details"]] + + # + ## Tab "Register watches" + # + + # Create header + grid [label $watches_tab.lbl_header_1 -anchor w \ + -text [mc "Bold"] \ + ] -column 1 -row 0 + + + # Create buttons + set idx 0 ;# Current tag index + set row 1 ;# Row in the grid + foreach tag $watch_text_tags { + + # Local variables + set tag_name [lindex $tag 0] ;# Tag name + set color [lindex $tag 1] ;# Foreground color (RGB) + set boldItalic [lindex $tag 2] ;# Bool: 1 == Bold, 0 == Italic + + # Short tag decription + grid [label $watches_tab.lbl_${tag_name} \ + -text [tag2name $tag_name] -pady 0 \ + -highlightthickness 0 -bd 0 -anchor w \ + ] -column 0 -row $row -sticky we + + # Checkbutton "Bold" + set checkbutton [checkbutton $watches_tab.chbut_${tag_name} \ + -pady 0 -highlightthickness 0 \ + -command "::configDialogues::rightPanel::change_style $idx 1" \ + ] + if {$boldItalic == {1}} { + $checkbutton select + } + grid $checkbutton -column 1 -row $row -sticky we + + # Button for selecting foreground color + grid [button $watches_tab.but_${tag_name} \ + -bd 1 -relief raised -pady 0 -highlightthickness 0 \ + -bg $color -width 10 -activebackground $color \ + -command "::configDialogues::rightPanel::select_color $idx $watches_tab.but_${tag_name} 1" + ] -column 2 -row $row -sticky ns -padx 10 + + incr row ;# Row in the grid + incr idx ;# Current tag index + } + + # Adjust the grid + grid columnconfigure $watches_tab 0 -minsize 150 + + + # + ## Tab "Instruction details" + # + + # Create header + grid [label $instruction_tab.lbl_header_2 -anchor w \ + -text [mc "Bold"] \ + ] -column 2 -row 0 -sticky we + + # Create buttons + set row 1 ;# Row in the grid + set idx 0 ;# Current tag index + foreach tag $instruction_tags { + + # Skip highlight for numbers + if {[llength $tag] != 3} { + incr idx + continue + } + + # Local variables + set tag_name [lindex $tag 0] ;# Tag name + set color [lindex $tag 1] ;# Foreground color (RGB) + set boldItalic [lindex $tag 2] ;# Bool: 1 == Bold, 0 == Italic + + # Short tag decription + grid [label $instruction_tab.lbl_${tag_name} \ + -text [tag2name $tag_name] -pady 0 \ + -highlightthickness 0 -bd 0 -anchor w \ + ] -column 1 -row $row -sticky we + + # Checkbutton "Bold" + set checkbutton [checkbutton $instruction_tab.chbut_${tag_name} \ + -pady 0 -highlightthickness 0 \ + -command "::configDialogues::rightPanel::change_style $idx 0" \ + ] + if {$boldItalic} { + $checkbutton select + } + grid $checkbutton -column 2 -row $row -sticky we + + # Button for selecting foreground color + grid [button $instruction_tab.but_${tag_name} \ + -bd 1 -relief raised -pady 0 -highlightthickness 0 \ + -bg $color -width 10 -activebackground $color \ + -command "::configDialogues::rightPanel::select_color $idx $instruction_tab.but_${tag_name} 0" + ] -column 3 -row $row -sticky ns -padx 10 + + + incr row ;# Row in the grid + incr idx ;# Current tag index + } + + # Adjust the grid + grid columnconfigure $instruction_tab 1 -minsize 150 + + # Raise appropriate tab + if {$tab_number == {}} { + $nb raise watches_tab + } else { + $nb raise [lindex [$nb pages] $tab_number] + } + + # Create button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Apply" + set apply_button [ttk::button $but_frame.but_apply \ + -state disabled \ + -text [mc "Apply"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::rightPanel::APPLY} \ + ] + pack $apply_button -side left + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::rightPanel::OK} \ + ] -side right -padx 2 + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::rightPanel::CANCEL} \ + ] -side right -padx 2 + + # Pack frames and notebook + pack $but_frame -side bottom -fill x -expand 0 -anchor s -padx 10 -pady 5 + pack $win.header_label -side top -pady 6 + pack [$nb get_nb] -side top -fill both -expand 1 -padx 10 + + # Finalize creation of the dialog + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Configure right panel - %s" ${::APPNAME}] + wm geometry $win =340x380 + wm resizable $win 0 0 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::rightPanel::CANCEL + } + tkwait window $win + } + + ## Traslate tag name to human readable string + # @return String - result or {} + proc tag2name {tag} { + switch -- $tag { + {tag_code8} {return "code8"} + {tag_code11} {return "code11"} + {tag_code16} {return "code16"} + {tag_imm8} {return "imm8"} + {tag_imm16} {return "imm16"} + {tag_data} {return "data"} + {tag_bit} {return "bit"} + {tag_DPTR} {return "DPTR"} + {tag_A} {return "A"} + {tag_AB} {return "AB"} + {tag_SFR} {return "C, R0..R7"} + {tag_indr} {return "@R0, @R0[mc { etc.}]"} + {tag_Baddr} {return [mc "Bit"]} + {tag_Xaddr} {return "XDATA"} + {tag_Eaddr} {return "EDATA"} + {tag_addr} {return "IDATA"} + {tag_name} {return [mc "Name"]} + default {return {}} + } + } + + ## Toggle style flag for given text tag (Bold <-> Italic / Roman) + # @parm Int row - Index of the target text tag + # @parm Bool for - 0 == instruction_tags; 1 == watch_text_tags + # @return void + proc change_style {row for} { + variable instruction_tags ;# Highlighting tags for instruction details + variable watch_text_tags ;# Highlighting tags for register watches + + if {$for} { + if {[lindex $watch_text_tags [list $row 2]] != 1} { + lset watch_text_tags [list $row 2] 1 + } else { + lset watch_text_tags [list $row 2] {} + } + } else { + lset instruction_tags [list $row 2] [expr {!([lindex $instruction_tags [list $row 2]])}] + } + + # Adjust status changed + settings_changed + } + + ## Change color for given text tag and adjust given bg color of given button + # @parm Int row - Index of the target text tag + # @parm Widget button - ID of source button + # @parm Bool for - 0 == instruction_tags; 1 == watch_text_tags + # @return void + proc select_color {row button for} { + variable instruction_tags ;# Highlighting tags for instruction details + variable watch_text_tags ;# Highlighting tags for register watches + variable win ;# ID of toplevel dialog window + + # Destroy prevoisly opened color selection dialog + if {[winfo exists .select_color]} { + destroy .select_color + } + + # Invoke new color selection dialog + if {$for} { + set color [lindex $watch_text_tags [list $row 1]] + } else { + set color [lindex $instruction_tags [list $row 1]] + } + set color [SelectColor .select_color \ + -parent $win \ + -color $color \ + -title [mc "Select color - %s" ${::APPNAME}] \ + ] + + # Change button background color + if {$color != {}} { + if {$for} { + lset watch_text_tags [list $row 1] $color + } else { + lset instruction_tags [list $row 1] $color + } + $button configure -bg $color -activebackground $color + + # Adjust status changed + settings_changed + } + } + + ## Adjust all editors to fit new settings + # @return Bool - result + proc apply_settings {} { + # Check if there is at least 1 opened editor + if {[llength ${::X::openedProjects}] == 0} { + return 0 + } + + # Apply new settings in all projects + foreach project ${::X::openedProjects} { + $project rightPanel_refresh_instruction_highlighting + $project rightPanel_refresh_regwatches_highlighting + } + + # Done ... + return 1 + } + + ## Change content of configuration variables RightPanel NS + # @return void + proc use_settings {} { + variable watch_text_tags ;# Highlighting tags for register watches + variable instruction_tags ;# Highlighting tags for instruction details + + set ::InstructionDetails::instruction_tags $instruction_tags + set ::RegWatches::watch_text_tags $watch_text_tags + } + + ## Retrieve settings related to this dialog from the program + # @return void + proc getSettings {} { + variable instruction_tags ;# Highlighting tags for instruction details + variable watch_text_tags ;# Highlighting tags for register watches + + set instruction_tags ${::InstructionDetails::instruction_tags} + set watch_text_tags ${::RegWatches::watch_text_tags} + } + + ## Save configuration to config file + # @return void + proc save_config {} { + + # Save configuration of "Instruction details" + foreach item ${::InstructionDetails::instruction_tags} { + # Save config + set key [lindex $item 0] + set value [lrange $item 1 end] + ::settings setValue "Instruction details/$key" $value + } + + # Save configuration of "Register watches" + foreach item ${::RegWatches::watch_text_tags} { + # Save config + set key [lindex $item 0] + set value [lrange $item 1 end] + ::settings setValue "Register watches/$key" $value + } + + # Commit + ::settings saveConfig + } + + ## Load configuratin from config file + # @return void + proc load_config {} { + variable instruction_tags ;# Highlighting tags for instruction details + variable watch_text_tags ;# Highlighting tags for register watches + + set instruction_tags {} + set watch_text_tags {} + foreach item ${::InstructionDetails::instruction_tags} { + # Load config + set key [lindex $item 0] + set value [lrange $item 1 end] + set value [::settings getValue "Instruction details/$key" $value] + lappend instruction_tags [concat $key $value] + } + foreach item ${::RegWatches::watch_text_tags} { + # Load config + set key [lindex $item 0] + set value [lrange $item 1 end] + set value [::settings getValue "Register watches/$key" $value] + lappend watch_text_tags [concat $key $value] + } + set ::InstructionDetails::instruction_tags $instruction_tags + set ::RegWatches::watch_text_tags $watch_text_tags + unset instruction_tags + unset watch_text_tags + } + + ## Set status changed to True + # @return true + proc settings_changed {} { + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable apply_button ;# ID of button "Apply" + + if {$changed} {return} + + set changed 1 + set anything_modified 1 + $apply_button configure -state normal + } + + ## Take back changes and destroy dialog window + # @return void + proc CANCEL {} { + variable win ;# ID of dialog toplevel window + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Restore previous configuration + if {$anything_modified} { + load_config + apply_settings + set anything_modified 0 + } + + # Get rid of dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Apply changes and destroy dialog window + # @return void + proc OK {} { + variable win ;# ID of dialog toplevel window + variable changed ;# Bool: Settings changed + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Apply new settings + if {$changed} { + use_settings ;# Adjust NS variables + apply_settings ;# Adjust GUI + save_config ;# Save new config + } + + # Get rid of dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Apply changes in GUI + # @return Bool - result + proc APPLY {} { + variable apply_button ;# ID of button "Apply" + variable changed ;# Bool: Settings changed + + # Check if there is at least 1 opened editor + if {[llength ${::X::openedProjects}] == 0} { + return 0 + } + + # Reset status changed + set changed 0 + $apply_button configure -state disabled + + # Adjust NS variables + use_settings + # Adjust GUI in current project + ${::X::actualProject} rightPanel_refresh_instruction_highlighting + ${::X::actualProject} rightPanel_refresh_regwatches_highlighting + + # done ... + return 1 + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/shortcuts_config.tcl b/lib/configdialogues/shortcuts_config.tcl new file mode 100644 index 0000000..612dc6a --- /dev/null +++ b/lib/configdialogues/shortcuts_config.tcl @@ -0,0 +1,1035 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _SHORTCUTS_CONFIG_TCL ] } { +set _SHORTCUTS_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements shortcuts configuration dialog +# -------------------------------------------------------------------------- + +namespace eval shortcuts { + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + variable win ;# ID of dialog toplevel window + + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable local_DB ;# Array: Local database of shortcuts + variable root_hard_cd ;# List of hadrcoded shortcuts (main window only) + variable currentNode ;# ID of the currently selected tree node + variable search_in_P ;# Bool: search in progress + # Empty image + variable empty_image [image create bitmap] + # Font for entry "Current shortcut" + variable current_entry_font [font create \ + -family $::DEFAULT_FIXED_FONT \ + -weight [expr {$::MICROSOFT_WINDOWS ? "normal" : "bold"}] \ + -size [expr {int(-12 * $::font_size_factor)}] \ + ] + # Normal font for tree widget nodes + variable node_font [font create \ + -family $::DEFAULT_FIXED_FONT \ + -weight normal \ + -size [expr {int(-12 * $::font_size_factor)}] \ + ] + # Bold font for tree widget nodes + variable node_font_b [font create \ + -family {helvetica} \ + -weight bold \ + -size [expr {int(-14 * $::font_size_factor)}] \ + ] + + variable status_label ;# ID of status label + variable search_entry ;# ID of entry widget on search panel + variable search_clear ;# ID of button "Clear search entry" + variable treeWidget ;# ID of the tree widget + variable bottom_lf_label ;# ID of label for bottom label frame + variable discard_button ;# ID of button "Discard" + variable accept_button ;# ID of button "Accept" + variable default_entry ;# ID of label containging default key shortcut + variable default_button ;# ID of button "Restore default" (bottom label frame) + variable clear_button ;# ID of button "Clear" + variable current_entry ;# ID of entry "Current shortcut" + + ## Create the dialog + # @return void + proc mkDialog {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable local_DB ;# Array: Local database of shortcuts + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable search_entry ;# ID of entry widget on search panel + variable search_clear ;# ID of button "Clear search entry" + variable treeWidget ;# ID of the tree widget + variable search_in_P ;# Bool: search in progress + variable bottom_lf_label ;# ID of label for bottom label frame + variable discard_button ;# ID of button "Discard" + variable accept_button ;# ID of button "Accept" + variable default_entry ;# ID of label containging default key shortcut + variable default_button ;# ID of button "Restore default" (bottom label frame) + variable clear_button ;# ID of button "Clear" + variable current_entry ;# ID of entry "Current shortcut" + variable empty_image ;# Empty image + variable current_entry_font ;# Font for entry "Current shortcut" + variable currentNode ;# ID of the currently selected tree node + variable status_label ;# ID of status label + variable root_hard_cd ;# List of hadrcoded shortcuts (main window only) + variable node_font ;# Normal font for tree widget nodes + variable node_font_b ;# Bold font for tree widget nodes + + # Destroy dialog window if it is already opened + if {$dialog_opened} { + destroy .shortcuts_config_dialog + } + set anything_modified 0 + set dialog_opened 1 + set currentNode {} + set search_in_P 0 + set changed 0 + + # Configure ttk styles + ttk::style configure Shortcuts_Default.TLabel -relief sunken -borderwidth 1 -background {#F0F0F0} + + # Get settings from the program + getSettings + + # Create list of hard-coded shortcuts related to main window + set root_hard_cd {} + foreach key ${::HARDCODED_SHORTCUTS} { + lappend root_hard_cd [simplify_key_seq $key] + } + + # Create toplevel window + set win [toplevel .shortcuts_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -image ::ICONS::32::configure \ + -text [mc "Configure key shortcuts"] \ + -font [font create -size [expr {int(-20 * $::font_size_factor)}]] + + # Create header labels for label frames + set top_lf_label [label $win.top_lf_label \ + -text [mc "available items"] \ + -image ::ICONS::16::view_choose \ + -compound left \ + ] + set bottom_lf_label [label $win.bottom_lf_label \ + -text [mc ""] \ + -compound left -height 20 \ + -image $empty_image \ + ] + + # Create label frames + set top_labelframe [ttk::labelframe $win.top_labelframe \ + -labelwidget $top_lf_label -padding 7 \ + ] + set bottom_labelframe [ttk::labelframe $win.bottom_labelframe \ + -labelwidget $bottom_lf_label -padding 7 \ + ] + + # Create serach panel + set search_frame [frame $top_labelframe.search_frame] + pack [Label $search_frame.label \ + -text [mc "Search:"] \ + -helptext [mc "Enter your search string here"] \ + ] -side left + set search_entry [ttk::entry $search_frame.entry \ + -validate all \ + -validatecommand {::configDialogues::shortcuts::search %P} \ + ] + DynamicHelp::add $search_frame.entry \ + -text [mc "Enter your search string here"] + pack $search_entry -side left -fill x -expand 1 + set search_clear [ttk::button $search_frame.button \ + -image ::ICONS::16::clear_left \ + -style Flat.TButton \ + -command "$search_entry delete 0 end" \ + -state disabled \ + ] + DynamicHelp::add $search_frame.button \ + -text [mc "Clear"] + pack $search_clear -side right -after $search_entry + pack $search_frame -fill x -pady 5 + + # Create frame for the tree widget and its scrollbar + set tree_frame [frame $top_labelframe.tree_frame] + pack $tree_frame -fill both -expand 1 + + # Create tree widget showing available items + set treeWidget [Tree $tree_frame.tree \ + -selectfill 1 \ + -showlines 1 \ + -linesfill {#888888} \ + -bg {#FFFFFF} \ + -selectbackground {#CCCCFF} \ + -selectforeground {#0000FF} \ + -highlightthickness 0 \ + -padx 5 \ + -deltay 20 \ + -deltax 20 \ + -yscrollcommand "$tree_frame.scrollbar set" \ + -crossopenimage ::ICONS::16::1downarrow \ + -crosscloseimage ::ICONS::16::1rightarrow \ + -selectcommand {::configDialogues::shortcuts::item_selected} \ + ] + pack $treeWidget -fill both -expand 1 -side left + bind $treeWidget {%W yview scroll +5 units; break} + bind $treeWidget {%W yview scroll -5 units; break} + + # Create scrollbar for the tree widget + pack [ttk::scrollbar $tree_frame.scrollbar \ + -command "$treeWidget yview" \ + -orient vertical \ + ] -fill y -side left -after $treeWidget + + # Fill in the tree + foreach block ${::SHORTCUTS_LIST} { + # Determinate category + set cat_org [lindex $block 0] + set cat "__$cat_org" + + # Adjus list of harcoded shotcuts + set hardcoded {} + foreach key [lindex $block 2] { + lappend hardcoded [simplify_key_seq $key] + } + + # Create category node + $treeWidget insert end root $cat \ + -selectable 1 \ + -data $hardcoded \ + -text [mc [lindex $block 1]] \ + -fill {#0000FF} \ + -font $node_font_b + + ## Create item node + set block [lreplace $block 0 2] ;# Item definitions + set len [llength $block] ;# Length of data block + + # Iterate over item definitions + for {set i 0; set j 1} {$i < $len} {incr i 2; incr j 2} { + + # Local variables + set item [lindex $block $i] ;# Item ID + set image [lindex $block [list $j 2]] ;# Image ID or {} + set text [mc [lindex $block [list $j 3]]];# Item text + set txt_len [string length $text] ;# Item text length + + # Adjust text width + append text [string repeat "\t" [expr {4 - ($txt_len / 8)}]] + + # Determinate text to show in the node + set text_and_key $text + append text_and_key [simplify_key_seq $local_DB($cat_org:$item)] + + # Determinate image ID + if {$image != {}} { + set image "::ICONS::16::$image" + } else { + set image $empty_image + } + + # Adjust key combination + set key_seq [regsub {Key(Press|Release)?\-} $local_DB($cat_org:$item) {}] + + # Create node in the tree widget + $treeWidget insert end $cat $item \ + -selectable 1 \ + -font $node_font \ + -text $text_and_key \ + -data [list \ + $text \ + [lindex $block [list $j 0]] \ + $key_seq \ + ] \ + -image $image -padx 25 + } + } + + ## Create widgets of bottom label frame + # Label and entry "Current" + grid [label $bottom_labelframe.current_label \ + -text [mc "Current shortcut:"] \ + ] -row 0 -column 0 -sticky w + set current_entry [ttk::entry $bottom_labelframe.current_entry \ + -validatecommand {::configDialogues::shortcuts::cur_entry_val %P} \ + ] + grid $current_entry -row 0 -column 1 + bind $current_entry \ + {::configDialogues::shortcuts::current_entry_key %K; break} + bind $current_entry \ + {::configDialogues::shortcuts::current_entry_key Ctrl+%K; break} + bind $current_entry \ + {::configDialogues::shortcuts::current_entry_key Alt+%K; break} + bind $current_entry \ + {::configDialogues::shortcuts::current_entry_key Ctrl+Alt+%K; break} + set clear_button [ttk::button $bottom_labelframe.clear_button \ + -image ::ICONS::16::clear_left \ + -state disabled \ + -style Flat.TButton \ + -command {::configDialogues::shortcuts::clear_current} \ + ] + DynamicHelp::add $bottom_labelframe.clear_button -text [mc "Clear"] + grid $clear_button -row 0 -column 2 -sticky w + + # Label and entry "Default" + grid [label $bottom_labelframe.default_label \ + -text [mc "Default:"] \ + ] -row 1 -column 0 -sticky w + set default_entry [ttk::label $bottom_labelframe.default_entry \ + -style Shortcuts_Default.TLabel \ + ] + grid $default_entry -row 1 -column 1 -sticky we + set default_button [ttk::button $bottom_labelframe.default_button \ + -image ::ICONS::16::up0 \ + -state disabled \ + -command {::configDialogues::shortcuts::to_default} \ + -style Flat.TButton \ + ] + DynamicHelp::add $bottom_labelframe.default_button -text [mc "Restore default"] + grid $default_button -row 1 -column 2 -sticky w + + # Button "Accept" + set accept_button [ttk::button $bottom_labelframe.accept_button \ + -command {::configDialogues::shortcuts::accept_current} \ + -text [mc "Accept"] \ + -compound left \ + -image ::ICONS::16::ok \ + -state disabled \ + ] + DynamicHelp::add $bottom_labelframe.accept_button -text [mc "Accept new shortcut"] + grid $accept_button -row 0 -column 4 -rowspan 2 + # Button "Original" + set discard_button [ttk::button $bottom_labelframe.discard_button \ + -command {::configDialogues::shortcuts::discard_current} \ + -text [mc "Original"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -state disabled \ + ] + DynamicHelp::add $bottom_labelframe.discard_button -text [mc "Discard new shortcut"] + grid $discard_button -row 0 -column 5 -rowspan 2 + + # Create status label + set status_label [label $bottom_labelframe.status_label \ + -fg {#DD0000} -anchor w -text {} \ + ] + grid $status_label -row 2 -column 0 -columnspan 6 -sticky w + + # Create empty space on column 3 + grid columnconfigure $bottom_labelframe 3 -minsize 70 + + + ## Button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Reset" + pack [ttk::button $but_frame.but_default \ + -text [mc "Defaults"] \ + -command {::configDialogues::shortcuts::DEFAULTS} \ + ] -side left + DynamicHelp::add $but_frame.but_default -text [mc "Reset all settings to defaults"] + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::shortcuts::OK} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_ok -text [mc "Commit new settings"] + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::shortcuts::CANCEL} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_cancel -text [mc "Take changes back and close dialog"] + + # Pack frames + pack $win.header_label -side top -pady 6 + pack $top_labelframe -side top -fill both -expand 1 -padx 10 + pack $bottom_labelframe -side top -fill x -padx 10 -pady 10 -after $top_labelframe + pack $but_frame -side bottom -fill x -padx 10 -pady 5 + + # Set window attributes + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Configure shortcuts - %s" ${::APPNAME}] + wm minsize $win 600 520 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::shortcuts::CANCEL + } + tkwait window $win + } + + ## Argument of parameter '-selectcommand' for the tree widget + # @parm Widget widget - Source tree widget + # @parm List nodes - Selected nodes + # @return void + proc item_selected {widget nodes} { + variable current_entry_font ;# Font for entry "Current shortcut" + variable node_font ;# Normal font for tree widget nodes + variable search_entry ;# ID of entry widget on search panel + variable search_in_P ;# Bool: search in progress + variable discard_button ;# ID of button "Discard" + variable accept_button ;# ID of button "Accept" + variable default_entry ;# ID of label containging default key shortcut + variable bottom_lf_label ;# ID of label for bottom label frame + variable default_button ;# ID of button "Restore default" (bottom label frame) + variable clear_button ;# ID of button "Clear" + variable current_entry ;# ID of entry "Current shortcut" + variable empty_image ;# Empty image + variable status_label ;# ID of status label + variable changed ;# Bool: Settings changed + variable currentNode ;# ID of the currently selected tree node + + # Empty selection -> disable widgets on the bottom frame and return + if {$nodes == {}} { + # Save last changed item + if {$changed} { + current_item_changed + } + + # Clear and disable componets of the bottom frame + $current_entry delete 0 end + cur_entry_val {} + $default_entry configure -text {} + $status_label configure -text {} + $current_entry configure -state disabled + $default_button configure -state disabled + $accept_button configure -state disabled + $discard_button configure -state disabled + $bottom_lf_label configure -text [mc ""] -image $empty_image + return + } + + # Only one node can be selected + set node [lindex $nodes end] + if {[llength $nodes] > 1} { + foreach nd [lreplace $nodes end end] { + $widget selection remove $nd + } + return + } + + # Clear status label, search entry and ask for saving the last change + $status_label configure -text {} + if {!$search_in_P} { + $search_entry delete 0 end + if {$changed} { + current_item_changed + } + } + + # If the selected node is a toplevel one -> open its node + if {[regexp {^__} $node]} { + $widget toggle $node + $widget selection clear + return + } + + if {$currentNode != {}} { + $widget itemconfigure $currentNode -font $node_font + } + $widget itemconfigure $node -font $current_entry_font + + # Set the current node + set currentNode $node + + # Adjust bottom frame + set data [$widget itemcget $node -data] + $bottom_lf_label configure \ + -image [$widget itemcget $node -image] \ + -text [string trimright [lindex $data 0]] + $current_entry configure -state normal + $current_entry delete 0 end + $current_entry insert end [simplify_key_seq [lindex $data 2]] + cur_entry_val [simplify_key_seq [lindex $data 2]] + $default_entry configure -text [simplify_key_seq [lindex $data 1]] + $default_button configure -state normal + ena_dis__accept_discard 0 + } + + ## Binding for X-Key event for entry "Custom shortcut" (see proc. 'mkDialog') + # @parm String key_seq - human readable key combination string + # @return void + proc current_entry_key {key_seq} { + variable current_entry ;# ID of entry "Current shortcut" + variable status_label ;# ID of status label + variable changed ;# Bool: Settings changed + variable treeWidget ;# ID of the tree widget + variable currentNode ;# ID of the currently selected tree node + variable root_hard_cd ;# List of hadrcoded shortcuts (main window only) + + if {$currentNode == {}} { + return + } + + # Clear entry "Custom shortcut" + $current_entry delete 0 end + cur_entry_val {} + + # Adjust key combination + set lastchar [string index $key_seq end] + if {[string index $key_seq end-1] == {+}} { + if {[string is lower -strict $lastchar]} { + set key_seq [string replace $key_seq \ + end end [string toupper $lastchar]] + } else { + set key_seq [string replace $key_seq end end \ + "Shift+[string toupper $lastchar]"] + } + } + + # Check for validity of the given shortcut and set flag "changed" + set changed 0 + if {![regexp {^(Ctrl|Alt)\+} $key_seq] && ![regexp {^F\d\d?$} $key_seq]} { + $status_label configure -text [mc "Modifier required (Control or Alt)"] + } elseif {[lsearch $root_hard_cd $key_seq] != -1} { + $status_label configure -text \ + [mc "This combination is hard-coded in the main window, so it cannot be used"] + } elseif {[lsearch [$treeWidget itemcget [$treeWidget parent $currentNode] -data] $key_seq] != -1} { + $status_label configure -text \ + [mc "This combination is hard-coded, so it cannot be used"] + } else { + set changed 1 + } + if {!$changed} { + $current_entry insert end $key_seq + cur_entry_val $key_seq + ena_dis__accept_discard 0 + return + } + + # Change content of entry "Custom shortcut" + $current_entry insert end $key_seq + cur_entry_val $key_seq + + # Check if the given combination is not already assigned to something + set name [lindex [key_seq_to_name \ + [extend_key_seq $key_seq] \ + [$treeWidget parent $currentNode]] 1] + if {$name != {} && $name != [string trim [lindex [$treeWidget itemcget $currentNode -data] 0]]} { + $status_label configure -text \ + [mc "The '%s' key combination has already been assigned to \"%s\"." $key_seq $name] + } else { + $status_label configure -text {} + } + + # Enable buttons "Accept" and "Original" (but only if user is not trying to redefine a shortcut with the same key combination) + if {$name != [string trim [lindex [$treeWidget itemcget $currentNode -data] 0]]} { + ena_dis__accept_discard 1 + } + } + + ## Clear entry "Custom shortcut" + # @return void + proc clear_current {} { + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable current_entry ;# ID of entry "Current shortcut" + variable status_label ;# ID of status label + + # Adjust flag "Anything modified" + if {[$current_entry get] != {}} { + set anything_modified 1 + } + # Clear the entry widget and status label + $current_entry delete 0 end + cur_entry_val {} + $status_label configure -text {} + # Enable buttons "Accept" and "Original" + ena_dis__accept_discard 1 + # Set flag "Changed" + set changed 1 + } + + ## Validate content of entry "Current shortcut" + # @parm String content - content of entry "Current shortcut" + # @return Bool - always 1 + proc cur_entry_val {content} { + variable clear_button ;# ID of button "Clear" + + # Enable/Disable button "Clear" + if {$content == {}} { + $clear_button configure -state disabled + } else { + $clear_button configure -state normal + } + + return 1 + } + + ## Set current shortcut to default + # @return void + proc to_default {} { + variable treeWidget ;# ID of the tree widget + variable changed ;# Bool: Settings changed + variable currentNode ;# ID of the currently selected tree node + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable current_entry ;# ID of entry "Current shortcut" + variable default_entry ;# ID of label containging default key shortcut + variable status_label ;# ID of status label + + # Se flag "Anything modified" + if {[$current_entry get] != [$default_entry cget -text]} { + set anything_modified 1 + } + + # Adjust content of entry "Current shortcut" + set key [$default_entry cget -text] + $current_entry delete 0 end + $current_entry insert 0 $key + cur_entry_val $key + + # Check if the new setting is unique + set name [lindex [key_seq_to_name \ + [extend_key_seq $key ] \ + [$treeWidget parent $currentNode]] 1] + if {$name != {}} { + $status_label configure -text \ + [mc "The '%s' key combination has already been assigned to \"%s\"." $key $name] + } + + # Enable buttons "Accept" and "Original" + ena_dis__accept_discard 1 + set changed 1 + } + + ## Accept new key combination fot the currently selected action + # @return void + proc accept_current {} { + variable changed ;# Bool: Settings changed + variable treeWidget ;# ID of the tree widget + variable current_entry ;# ID of entry "Current shortcut" + variable currentNode ;# ID of the currently selected tree node + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable local_DB ;# Local database of shortcuts + variable status_label ;# ID of status label + + # Gain details about the current action + set data [$treeWidget itemcget $currentNode -data] + set parent [$treeWidget parent $currentNode] + set category [string replace $parent 0 1] + set text_org [lindex $data 0] + set default [lindex $data 1] + set current [extend_key_seq [$current_entry get]] + set text $text_org + append text [$current_entry get] + + ## Redefine shortcut for action which have the same shortcut as the current one + $treeWidget itemconfigure $currentNode -data {} + set defined [key_seq_to_name $current $parent] + # Redefine + if {$defined != {}} { + $status_label configure -text \ + [mc "Removing key combination for action \"%s\"" [lindex $defined 1]] + set defined [lindex $defined 0] + set cat [string replace [$treeWidget parent $defined] 0 1] + set local_DB($cat:$defined) {} + set dt [$treeWidget itemcget $defined -data] + set txt [lindex $dt 0] + set dt [lindex $dt 1] + $treeWidget itemconfigure $defined \ + -text $txt \ + -data [list $txt $dt {}] + # Keep + } else { + $status_label configure -text {} + } + + # Adjust local database and the tree widget + set local_DB($category:$currentNode) $current + $treeWidget itemconfigure $currentNode \ + -text $text \ + -data [list $text_org $default $current] + + # Adjust modifed flags and disable buttons "Accept" and "Original" + set changed 0 + set anything_modified 1 + ena_dis__accept_discard 0 + } + + ## Discard new key combination fot the currently selected action + # @return void + proc discard_current {} { + variable changed ;# Bool: Settings changed + variable treeWidget ;# ID of the tree widget + variable current_entry ;# ID of entry "Current shortcut" + variable status_label ;# ID of status label + variable currentNode ;# ID of the currently selected tree node + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + + # Restore previous content of entry "Current shortcut" + $current_entry delete 0 end + $current_entry insert end [simplify_key_seq \ + [lindex [$treeWidget itemcget $currentNode -data] 2]] + cur_entry_val [$current_entry get] + + # Clear status label + $status_label configure -text {} + + # Disable buttons "Accept" and "Original" + ena_dis__accept_discard 0 + set changed 0 + } + + ## Ask user about saving the last change and conditionly save it + # @return void + proc current_item_changed {} { + variable changed ;# Bool: Settings changed + variable currentNode ;# ID of the currently selected tree node + variable win ;# ID of toplevel dialog window + + set changed 0 + if {[tk_messageBox \ + -type yesno \ + -parent $win \ + -icon question \ + -title [mc "Item changed"] \ + -message [mc "The previous item was modified. Do you want to save it ?"] \ + ] != {yes} + } then { + return + } + + accept_current + } + + ## Translate key combination acceptable by Tk to "human readable" representation + # @parm String key_seq - Human readable representation of a key combination + # @return String - Key combination acceptable by Tk + proc extend_key_seq {key_seq} { + if {$key_seq == {}} { + return {} + } + + regsub -all {\+} $key_seq {-} key_seq + regsub {Ctrl\-} $key_seq {Control-} key_seq + set last_char [string index $key_seq end] + if {![string compare {Shift-} [string range $key_seq {end-6} {end-1}]]} { + set last_char [string toupper $last_char] + set key_seq [string range $key_seq 0 {end-7}] + append key_seq $last_char + } elseif {[string index $key_seq {end-1}] == {-}} { + set key_seq [string replace $key_seq end end [string tolower $last_char]] + } + + return $key_seq + } + + ## Find name of action specified by the given key combination + # @parm String key_seq - Key combination acceptable by Tk + # @parm String parent_node - Parent node (category) + # @return String - Action name or {} + proc key_seq_to_name {key_seq parent_node} { + variable treeWidget ;# ID of the tree widget + + if {$key_seq == {}} { + return {} + } + + # Search the tree widget + foreach node [$treeWidget nodes $parent_node] { + if {![string compare $key_seq \ + [lindex [$treeWidget itemcget $node -data] 2]]} \ + { + return [list $node \ + [string trimright \ + [lindex [$treeWidget itemcget $node -data] 0]]] + } + } + + return {} + } + + ## Enable/Disable buttons "Discard" and "Accept" + # @parm Bool ena_dis - Enable/Disable (1 == enable; 0 == disable) + # @return void + proc ena_dis__accept_discard {ena_dis} { + variable discard_button ;# ID of button "Discard" + variable accept_button ;# ID of button "Accept" + + if {$ena_dis} { + $discard_button configure -state normal + $accept_button configure -state normal + } else { + $discard_button configure -state disabled + $accept_button configure -state disabled + } + } + + ## Search the given string in the tree widget + # @parm String string - string to find + # @return Bool - always 1 + proc search {string} { + variable search_entry ;# ID of entry widget on search panel + variable search_clear ;# ID of button "Clear search entry" + variable treeWidget ;# ID of the tree widget + variable search_in_P ;# Bool: search in progress + variable changed ;# Bool: Settings changed + + # Empty input string + if {$string == {}} { + $search_clear configure -state disabled + $search_entry configure -style TEntry + return 1 + } + $search_clear configure -state normal + + # String to lowercase + set string [string tolower $string] + + # Search all nodes + foreach top [$treeWidget nodes root] { + foreach node [$treeWidget nodes $top] { + set text [$treeWidget itemcget $node -text] + set text [string tolower $text] + + # String found + if {[string first $string $text] != -1} { + # Select the node + set search_in_P 1 + $treeWidget opentree [$treeWidget parent $node] + $treeWidget selection set $node + $treeWidget see $node + + # Adjust entry widget and return + set search_in_P 0 + $search_entry configure -style StringFound.TEntry + return 1 + } + } + } + + # String not found + $search_entry configure -style StringNotFound.TEntry + return 1 + } + + ## Retrieve settings related to this dialog from the program + # @return void + proc getSettings {} { + variable local_DB ;# Local database of shortcuts + + foreach key [array names ::SHORTCUTS_DB] { + set local_DB($key) $::SHORTCUTS_DB($key) + } + } + + ## Change content of configuration variables + # @return void + proc use_settings {} { + variable local_DB ;# Local database of shortcuts + + foreach key [array names local_DB] { + set ::SHORTCUTS_DB($key) $local_DB($key) + } + } + + ## Adjust application to fit new settings + # @return Bool - result + proc apply_settings {} { + # Adjust main window + shortcuts_reevaluate + mainmenu_redraw + + # Adjust projects + foreach project ${::X::openedProjects} { + + # Adjust editors + foreach editor [$project cget -editors] { + $editor shortcuts_reevaluate + $editor makePopupMenu + } + + # Adjust right panel + $project rightPanel_makePopupMenu + $project rightPanel_watch_shortcuts_reevaluate + # Adjust to do list + $project TodoProc_makePopupMenu + $project TodoProc_shortcuts_reevaluate + # Adjust messages text + $project messages_text_makePopupMenu + $project messages_text_shortcuts_reevaluate + # Adjust filelist + $project filelist_makePopupMenu + $project filelist_fsb_makePopupMenu + } + + # Restore previous state of menu items (enabled / disabled) + ::X::disaena_menu_toolbar_for_current_project + } + + ## Save configuration to config file + # @return void + proc save_config {} { + variable local_DB ;# Local database of shortcuts + + foreach key [array names local_DB] { + ::settings setValue "Shortcuts/$key" $local_DB($key) + } + + # Commit + ::settings saveConfig + } + + ## Load configuratin from config file + # @return void + proc load_config {} { + array unset ::SHORTCUTS_DB + foreach block ${::SHORTCUTS_LIST} { + set category [lindex $block 0] ;# Shortcut category (eg. 'edit') + set block [lreplace $block 0 2] ;# Item definitions + set len [llength $block] ;# Length of data block + + # Iterate over data block and redefine local database + for {set i 0; set j 1} {$i < $len} {incr i 2; incr j 2} { + set key [lindex $block $i] ;# Item name + + set ::SHORTCUTS_DB($category:$key) \ + [::settings getValue "Shortcuts/$category:$key" \ + [lindex $block [list $j 0]]] + } + } + } + + ## Destroy the dialog + # @return void + proc CANCEL {} { + variable win ;# ID of toplevel dialog window + variable local_DB ;# Local database of shortcuts + variable dialog_opened ;# Bool: True if this dialog is already opened + variable root_hard_cd ;# List of hadrcoded shortcuts (main window only) + + # Discard local database of shortcuts + array unset local_DB + unset root_hard_cd + + # Destroy dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Use settings and destroy the dialog + # @return void + proc OK {} { + variable win ;# ID of toplevel dialog window + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + + # Save last changed item + if {$changed} { + current_item_changed + } + + # Use and save settings + if {$anything_modified} { + use_settings + apply_settings + save_config + } + + # Destroy the dialog window + CANCEL + } + + ## Restrore defaults + # @return void + proc DEFAULTS {} { + variable local_DB ;# Local database of shortcuts + variable treeWidget ;# ID of the tree widget + variable win ;# ID of toplevel dialog window + variable changed ;# Bool: Settings changed + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + + # Ask user + if {[tk_messageBox \ + -parent $win \ + -type yesno \ + -title [mc "Confirmation required"] \ + -icon question \ + -message [mc "This will discard all shortcut settings and replace them with defaults. Are you sure by that ?"]\ + ] != {yes} + } then { + return + } + + # Adjust flags + set changed 0 ;# Last item modified --> NO + set anything_modified 1 ;# Any item modified --> YES + + # Reset local database of shortcuts + array unset local_DB + foreach block ${::SHORTCUTS_LIST} { + set category [lindex $block 0] ;# Shortcut category (eg. 'edit') + set block [lreplace $block 0 2] ;# Item definitions + set len [llength $block] ;# Length of data block + + # Redefine local database + for {set i 0; set j 1} {$i < $len} {incr i 2; incr j 2} { + set key [lindex $block $i] + set local_DB($category:$key) [lindex $block [list $j 0]] + } + } + + ## Refresh content of the tree widget + $treeWidget selection clear + # Iterate over toplevel items + foreach top [$treeWidget nodes root] { + set cat [string replace $top 0 1] ;# Shortcut category (eg. 'edit') + + # Iterate over lowlevel items + foreach node [$treeWidget nodes $top] { + # Long key sequence (for Tk) + set key_seq [regsub {Key(Press|Release)?\-} $local_DB($cat:$node) {}] + + # Determinate new item data + set data [$treeWidget itemcget $node -data] + lset data 2 $key_seq + + # Determinate item text + set text_and_key [lindex $data 0] + append text_and_key [simplify_key_seq $key_seq] + + # Adjust item + $treeWidget itemconfigure $node \ + -data $data \ + -text $text_and_key + } + } + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/simulator_config.tcl b/lib/configdialogues/simulator_config.tcl new file mode 100644 index 0000000..bbfd2b0 --- /dev/null +++ b/lib/configdialogues/simulator_config.tcl @@ -0,0 +1,547 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _SIMULATOR_CONFIG_TCL ] } { +set _SIMULATOR_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements simulator configuration dialog +# -------------------------------------------------------------------------- + +namespace eval simulator { + + variable win ;# ID of toplevel dialog window + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + variable on_color_button ;# Widget: Button "ON color" in section "Colors" + variable off_color_button ;# Widget: Button "OFF color" in section "Colors" + + # List of default settings + variable defaults { + {reverse_run_steps 10} + {ignore_read_from_wr_only 0} + {ignore_invalid_reti 0} + {ignore_watchdog_reset 0} + {ignore_stack_overflow 0} + {ignore_stack_underflow 0} + {ignore_invalid_ins 0} + {ignore_invalid_IDATA 0} + {ignore_invalid_XDATA 0} + {ignore_invalid_BIT 0} + {ignore_invalid_CODE 0} + {ignore_EEPROM_WR_fail 0} + {ignore_EEPROM_WR_abort 0} + {ignore_invalid_USB 0} + {ignore_invalid_UMC 0} + {ignore_invalid_TMC 0} + {undefined_value 2} + {ignore_invalid_brkpoints 0} + {on_color #00CC00} + {off_color #DD0000} + } + + # Option variables + variable reverse_run_steps ;# Int: Number of steps which can be taken back + variable ignore_watchdog_reset ;# Bool: Ignore reset invoked by watchdog overflow + variable ignore_read_from_wr_only ;# Bool: Ignore reading from read only register + variable ignore_stack_overflow ;# Bool: Do not show "Stack overflow" dialog + variable ignore_stack_underflow ;# Bool: Do not show "Stack underflow" dialog + variable ignore_invalid_reti ;# Bool: Ignore invalid return fom interrupt + variable ignore_invalid_ins ;# Bool: Ignore invalid instructions + variable ignore_invalid_IDATA ;# Bool: Ignore access to unimplemented IDATA memory + variable ignore_invalid_XDATA ;# Bool: Ignore access to unimplemented XDATA memory + variable ignore_invalid_BIT ;# Bool: Ignore access to unimplemented bit + variable ignore_invalid_CODE ;# Bool: Ignore access to unimplemented CODE memory + variable ignore_EEPROM_WR_fail ;# Bool: Ignore EEPROM write failure + variable ignore_EEPROM_WR_abort ;# Bool: Ignore EEPROM write abort + variable ignore_invalid_USB ;# Bool: Ignore UART frame discart + variable ignore_invalid_UMC ;# Bool: Ignore invalid UART mode change + variable ignore_invalid_TMC ;# Bool: Ignore invalid Timer/Counter mode change + variable undefined_value ;# Int: How to handle undefined values (0 == 0; 1 == 255; 2 == random) + variable ignore_invalid_brkpoints ;# Bool: Do not warn user about invalid (unreachable) breakpoints + variable on_color ;# RGB: Color to display a bit name for a bit set to log. 1 + variable off_color ;# RGB: Color to display a bit name for a bit set to log. 0 + + ## Create the dialog + # @return void + proc mkDialog {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable on_color_button ;# Widget: Button "ON color" in section "Colors" + variable off_color_button ;# Widget: Button "OFF color" in section "Colors" + + # Destroy the dialog if it's already opened + if {$dialog_opened} { + destroy .simulator_config_dialog + } + set dialog_opened 1 + + # Get settings from Compiler NS + getSettings + + # Create toplevel window + set win [toplevel .simulator_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -image ::ICONS::32::kcmmemory \ + -text [mc "Simulator configuration"] \ + -font [font create \ + -size -20] + + ## Create notebook + set nb [ModernNoteBook $win.nb] + # Tab "Warning dialogues" + set warnings_tab [$nb insert end warnings_tab -text [mc "Warning dialogues"]] + + # Tab "Other" + set other_tab [$nb insert end other_tab -text [mc "Other"]] + + # + ## Tab "Warning dialogues" + # + set row 0 + foreach text { + {Ignore stack overflow} + {Ignore stack underflow} + {-} + {Ignore invalid instructions} + {Ignore watchdog overflow} + {Ignore invalid return from interrupt} + {Ignore reading from write only register} + {-} + {Ignore invalid access to IDATA/SFR} + {Ignore invalid access to EDATA} + {Ignore invalid access to XDATA} + {Ignore invalid access to bit} + {Ignore invalid access to CODE} + {-} + {Ignore EEPROM write failure} + {Ignore EEPROM write abort} + {-} + {Ignore UART frame discard} + {Ignore illegal UART mode change} + {Ignore illegal Timer/Counter mode change} + {-} + {Do not complain about invalid breakpoints} + } helptext { + {Check this to disable warning on stack overflow} + {Check this to disable warning on stack underflow} + {-} + {Check this to disable warning on\ninvalid instruction} + {Do not stop simulation on device reset\ninvoked by watchdog timer overflow} + {Do not show warning dialog when program trying to return from interrupt which has not been invoked} + {Do not display warning dialog when\nreading from write-only register} + {-} + {Do not display dialog "Undefined result" when simulated program\naccessing unimplemented Internal Data Memory (IDATA) or SFR area} + {Do not display dialog "Undefined result" when simulated program\naccessing unimplemented Expanded Data Memory (EDATA)} + {Do not display dialog "Undefined result" when simulated program\naccessing unimplemented External Data Memory (XDATA)} + {Do not display dialog "Undefined result" when simulated program\naccessing unimplemented bit in IDATA or SFR area} + {Do not display dialog "Undefined result" when simulated program\naccessing unimplemented Program Memory (CODE)} + {-} + {Check this to disable warning on\ndata eeprom write failure} + {Check this to disable warning on\ndata eeprom write abort} + {-} + {Check this to disable warning on UART frame discard} + {Check this to disable warning on illegal UART mode change} + {Check this to disable warning on illegal Timer/Counter mode change} + {-} + {Disable warning: "warning: Invalid breakpoint"} + } variable { + ignore_stack_overflow ignore_stack_underflow + - + ignore_invalid_ins ignore_watchdog_reset + ignore_invalid_reti ignore_read_from_wr_only + - + ignore_invalid_IDATA ignore_invalid_EDATA + ignore_invalid_XDATA ignore_invalid_BIT + ignore_invalid_CODE + - + ignore_EEPROM_WR_fail ignore_EEPROM_WR_abort + - + ignore_invalid_USB ignore_invalid_UMC + ignore_invalid_TMC + - + ignore_invalid_brkpoints + } { + incr row + + # Create separator + if {$text == {-}} { + grid [ttk::separator $warnings_tab.sep_$row \ + -orient horizontal \ + ] -column 0 -row $row -columnspan 2 -sticky we -pady 5 -padx 5 + continue + } + + # Create + grid [Label $warnings_tab.label__$row \ + -text [mc $text] \ + -helptext [subst [mc $helptext]] \ + ] -row $row -column 0 -sticky w -padx 5 + grid [checkbutton $warnings_tab.chbutton_$row \ + -variable ::configDialogues::simulator::$variable \ + ] -row $row -column 1 -sticky e -padx 5 + DynamicHelp::add $warnings_tab.chbutton_$row \ + -text [subst $helptext] + } + grid columnconfigure $warnings_tab 0 -minsize 250 + grid columnconfigure $warnings_tab 1 -weight 1 + + # + # Tab "Other" + # + + # LabelFrame: "Undefined values" + set undefined_labelframe [ttk::labelframe $other_tab.undefined_labelframe \ + -text [mc "Undefined values"] -padding 7 \ + ] + pack [radiobutton $undefined_labelframe.random \ + -value 2 -text [mc "Return random value"] \ + -variable ::configDialogues::simulator::undefined_value \ + ] -anchor w + pack [radiobutton $undefined_labelframe.zero \ + -value 0 -text [mc "Return zero value"] \ + -variable ::configDialogues::simulator::undefined_value \ + ] -anchor w + pack [radiobutton $undefined_labelframe.one \ + -value 1 -text [mc "Return highest possible value"] \ + -variable ::configDialogues::simulator::undefined_value \ + ] -anchor w + pack $undefined_labelframe -fill x -padx 5 -pady 5 + + # LabelFrame: "Reverse run" + set reverse_run_labelframe [ttk::labelframe $other_tab.reverse_run_labelframe \ + -text [mc "Reverse run"] -padding 7 \ + ] + grid [Label $reverse_run_labelframe.rrun_lbl \ + -text [mc "Stack capacity"] \ + -helptext [mc "Number of steps which can be taken back"] \ + ] -row 4 -column 0 -sticky w -padx 5 + grid [ttk::spinbox $reverse_run_labelframe.rrun_spinbox \ + -from 0 -to 1000 -validate all -width 4 \ + -validatecommand "::configDialogues::simulator::rrun_spinbox_val %P" \ + -textvariable ::configDialogues::simulator::reverse_run_steps \ + ] -row 4 -column 1 -sticky we -padx 5 + DynamicHelp::add $reverse_run_labelframe.rrun_spinbox \ + -text [mc "Number of steps which can be taken back"] + grid columnconfigure $reverse_run_labelframe 0 -minsize 250 + grid columnconfigure $reverse_run_labelframe 1 -weight 1 + pack $reverse_run_labelframe -fill x -padx 5 -pady 5 + + # LabelFrame: "Colors" + set colors_labelframe [ttk::labelframe $other_tab.colors_labelframe \ + -text [mc "Colors"] -padding 7 \ + ] + set row -1 + foreach text { + {ON color} + {OFF color} + } helptext { + {Color to display a bit name for a bit set to log. 1} + {Color to display a bit name for a bit set to log. 0} + } variable { + on_color + off_color + } buttonvar { + on_color_button + off_color_button + } { + incr row + + set text [mc $text] + set helptext [mc $helptext] + set variable "::configDialogues::simulator::$variable" + + # Get color from the given variable + set color [subst -nocommands "\${$variable}"] + + # Create label + grid [Label $colors_labelframe.lbl$row \ + -text $text \ + -helptext $helptext \ + ] -row $row -column 0 -sticky w -padx 5 + + # Create button + set button [button $colors_labelframe.button$row \ + -bd 1 -relief raised -pady 0 -highlightthickness 0 \ + -bg $color -width 10 -activebackground $color \ + -command "::configDialogues::simulator::select_color $variable $colors_labelframe.button$row" + ] + grid $button -row $row -column 1 -sticky we -padx 5 + set $buttonvar $button + DynamicHelp::add $colors_labelframe.button$row -text $helptext + } + grid columnconfigure $colors_labelframe 0 -minsize 250 + grid columnconfigure $colors_labelframe 1 -weight 1 + pack $colors_labelframe -fill x -padx 5 -pady 5 + + # Raise tab "Output" + $nb raise warnings_tab + + # Create button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Defaults" + pack [ttk::button $but_frame.but_default \ + -text [mc "Defaults"] \ + -command {::configDialogues::simulator::DEFAULTS} \ + ] -side left + DynamicHelp::add $but_frame.but_default -text [mc "Reset settings to defaults"] + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::simulator::OK} \ + ] -side right -padx 2 + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::simulator::CANCEL} \ + ] -side right -padx 2 + + # Pack frames and notebook + pack $win.header_label -side top -pady 6 + pack [$nb get_nb] -side top -fill both -expand 1 -padx 10 + pack $but_frame -side top -fill x -anchor s -padx 10 -pady 5 + + # Set window attributes + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Simulator configuration - %s" ${::APPNAME}] + wm minsize $win 380 520 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::simulator::CANCEL + } + tkwait window $win + } + + ## Select some color (command for buttons in labelbox "Colors") + # @parm Variable variable - variable containing current color (format RGB) + # @parm Widget button - ID of button which invoked this procedure + # @return void + proc select_color {variable button} { + variable win ;# ID of dialog toplevel window + + # Destroy previously opened color selection dialog + if {[winfo exists .select_color]} { + destroy .select_color + } + + # Invoke new color selection dialog + set color [subst -nocommands "\$$variable"] + set color [SelectColor .select_color \ + -parent $win \ + -color $color \ + -title [mc "Select color - %s" ${::APPNAME}] \ + ] + + # Set new content of the given variable and button background color + if {$color != {}} { + set $variable $color + $button configure -bg $color -activebackground $color + } + } + + ## Validate contents of spinbox in section "Reverse Run" + # @parm String content - String to validate + # @return Bool - validation result (0 == failed; 1 == successfull) + proc rrun_spinbox_val {content} { + if {![string is digit $content]} { + return 0 + } + if {$content > 1000} { + return 0 + } + return 1 + } + + ## Set configuration variable + # This function is unsafe -- you must be sure by the given arguments + # @parm String variable - variable to set + # @parm Mixed value - new value + proc set_variable {variable value} { + variable reverse_run_steps ;# Int: Number of steps which can be taken back + variable ignore_watchdog_reset ;# Bool: Ignore reset invoked by watchdog overflow + variable ignore_read_from_wr_only ;# Bool: Ignore reading from read only register + variable ignore_invalid_reti ;# Bool: Ignore invalid return fom interrupt + variable ignore_stack_overflow ;# Bool: Do not show "Stack overflow" dialog + variable ignore_stack_underflow ;# Bool: Do not show "Stack underflow" dialog + variable ignore_invalid_ins ;# Bool: Ignore invalid instructions + variable ignore_invalid_IDATA ;# Bool: Ignore access to unimplemented IDATA memory + variable ignore_invalid_EDATA ;# Bool: Ignore access to unimplemented EDATA memory + variable ignore_invalid_XDATA ;# Bool: Ignore access to unimplemented XDATA memory + variable ignore_invalid_BIT ;# Bool: Ignore access to unimplemented bit + variable ignore_invalid_CODE ;# Bool: Ignore access to unimplemented CODE memory + variable ignore_EEPROM_WR_fail ;# Bool: Ignore EEPROM write failure + variable ignore_EEPROM_WR_abort ;# Bool: Ignore EEPROM write abort + variable undefined_value ;# Int: How to handle undefined values (0 == 0; 1 == 255; 2 == random) + variable ignore_invalid_brkpoints ;# Bool: Do not warn user about invalid (unreachable) breakpoints + + getSettings + set $variable $value + use_settings + save_config + } + + ## Retrieve settings from simulator NS + # @return void + proc getSettings {} { + variable defaults ;# List of default settings + + # Set local option variables + foreach var $defaults { + set var [lindex $var 0] + if {$var == {on_color} || $var == {off_color}} { + set ::configDialogues::simulator::${var} [subst -nocommands "\$::Simulator_GUI::${var}"] + } else { + set ::configDialogues::simulator::${var} [subst -nocommands "\$::Simulator::${var}"] + } + } + } + + ## Set simulator according to local settings + # @return void + proc use_settings {} { + variable reverse_run_steps ;# Int: Number of steps which can be taken back + variable defaults ;# List of default settings + + # Adjust RR stack capacity + if {$reverse_run_steps == {}} { + set reverse_run_steps 0 + } + + # Set option variables + foreach var $defaults { + set var [lindex $var 0] + if {$var == {on_color} || $var == {off_color}} { + set ::Simulator_GUI::$var [subst -nocommands "\$::configDialogues::simulator::${var}"] + } else { + set ::Simulator::$var [subst -nocommands "\$::configDialogues::simulator::${var}"] + } + } + } + + ## Save settings to the config file + # @return void + proc save_config {} { + variable defaults ;# List of default settings + + # Save option variables + foreach var $defaults { + set var [lindex $var 0] + if {$var == {on_color} || $var == {off_color}} { + ::settings setValue "Simulator/$var" [subst -nocommands "\$::Simulator_GUI::${var}"] + } else { + ::settings setValue "Simulator/$var" [subst -nocommands "\$::Simulator::${var}"] + } + } + + # Synchronize + ::settings saveConfig + } + + ## Load settings from config file + # @return void + proc load_config {} { + variable defaults ;# List of default settings + + # Load normal options + foreach item $defaults { + set var [lindex $item 0] + set val [lindex $item 1] + if {$var == {on_color} || $var == {off_color}} { + set ::Simulator_GUI::${var} [::settings getValue "Simulator/$var" $val] + } else { + set ::Simulator::${var} [::settings getValue "Simulator/$var" $val] + } + } + } + + ## Destroy the dialog + # @return void + proc CANCEL {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Destroy dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Use settings and destroy the dialog + # @return void + proc OK {} { + # Use and save settings + use_settings + save_config + + # Destroy dialog window + CANCEL + } + + ## Restrore defaults + # @return void + proc DEFAULTS {} { + variable win ;# ID of toplevel dialog window + variable defaults ;# List of default settings + variable on_color_button ;# Widget: Button "ON color" in section "Colors" + variable off_color_button ;# Widget: Button "OFF color" in section "Colors" + + if {[tk_messageBox \ + -parent $win \ + -type yesno \ + -icon question \ + -title [mc "Are you sure ?"] \ + -message [mc "Are you sure you want to restore default settings"] \ + ] != {yes}} { + return + } + + # Restore normal options + foreach item $defaults { + set var [lindex $item 0] + set val [lindex $item 1] + set ::configDialogues::simulator::${var} $val + + # Update colors of color buttons + if {$var == {on_color}} { + $on_color_button configure -bg $val -activebackground $val + } elseif {$var == {off_color}} { + $off_color_button configure -bg $val -activebackground $val + } + } + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/terminal_config.tcl b/lib/configdialogues/terminal_config.tcl new file mode 100644 index 0000000..732b5cb --- /dev/null +++ b/lib/configdialogues/terminal_config.tcl @@ -0,0 +1,396 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _TERMINAL_CONFIG_TCL ] } { +set _TERMINAL_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements terminal configuration dialog +# -------------------------------------------------------------------------- + +namespace eval terminal { + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + variable win ;# ID of dialog toplevel window + variable changed 0 ;# Bool: Settings changed + variable example_text ;# Widget: Label widget containing example text + variable selected_font ;# Font: Current font + variable fg_clr_but ;# Widget: Button for selecting foreground color + variable bg_clr_but ;# Widget: Button for selecting background color + + ## Configuration variables + variable configuration ;# Array: Configuration array + + ## Create the dialog + # @return void + proc mkDialog {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + variable configuration ;# Array: Configuration array + variable changed ;# Bool: Settings changed + variable example_text ;# Widget: Label widget containing example text + variable selected_font ;# Font: Current font + variable fg_clr_but ;# Widget: Button for selecting foreground color + variable bg_clr_but ;# Widget: Button for selecting background color + + # Destroy the dialog if it's already opened + if {$dialog_opened} { + destroy .terminal_config_dialog + } + + set dialog_opened 1 + set changed 0 + + # Get settings from main NS + getSettings + + # Create toplevel window + set win [toplevel .terminal_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -text [mc "Terminal configuration"] \ + -font [font create -size [expr {int(-20 * $::font_size_factor)}]] + + # Create horizontal separator + Separator $win.sep -orient horizontal + + ## Create main frame + set main_frame [frame $win.main_frame] + set row 0 + # Foreground color + grid [label $main_frame.fg_lbl \ + -text [mc "Foreground color"] \ + ] -row $row -column 0 -sticky w + set fg_clr_but [button $main_frame.fg_but \ + -bd 1 -relief raised -pady 0 -width 10 \ + -bg $configuration(fg) \ + -activebackground $configuration(fg) \ + -command "::configDialogues::terminal::select_color {foreground} fg $main_frame.fg_but" \ + ] + grid $fg_clr_but -column 1 -row $row -sticky wens + incr row + # Background color + grid [label $main_frame.bg_lbl \ + -text [mc "Background color"] \ + ] -row $row -column 0 -sticky w + set bg_clr_but [button $main_frame.bg_but \ + -bd 1 -relief raised -pady 0 -width 10 \ + -bg $configuration(bg) \ + -activebackground $configuration(bg) \ + -command "::configDialogues::terminal::select_color {background} bg $main_frame.bg_but" \ + ] + grid $bg_clr_but -column 1 -row $row -sticky wens + incr row + # Font size + grid [label $main_frame.font_size_lbl \ + -text [mc "Font size"] \ + ] -row $row -column 0 -sticky w + grid [ttk::spinbox $main_frame.font_size_spb \ + -from 4 -to 22 -validate all -width 0 \ + -validatecommand {::configDialogues::terminal::font_size_valiade %P} \ + -textvariable ::configDialogues::terminal::configuration(font_size) \ + -command ::configDialogues::terminal::font_changed \ + ] -row $row -column 1 -sticky we + incr row + # Font family + grid [label $main_frame.font_family_lbl \ + -text [mc "Font family"] \ + ] -row $row -column 0 -sticky w + grid [ttk::combobox $main_frame.font_family_cbx \ + -state readonly \ + -values [lsort [font families]] \ + -width 20 \ + -textvariable ::configDialogues::terminal::configuration(font_family) \ + ] -row $row -column 1 -sticky we + bind $main_frame.font_family_cbx <> \ + {::configDialogues::terminal::font_changed} + incr row + # Example text + set selected_font [font create \ + -family $configuration(font_family) \ + -size -$configuration(font_size) \ + ] + set example_text [label $main_frame.example_text_lbl \ + -text "rxvt-unicode " \ + -font $selected_font \ + ] + grid $example_text -row $row -column 0 -sticky w -columnspan 2 + # Finalize + grid columnconfigure $main_frame 0 -weight 1 + + # Button "Restart terminal emulator" + set restart_but [ttk::button $win.restart_but \ + -text [mc "Use settings and restart terminal emulator"] \ + -compound left \ + -image ::ICONS::16::reload \ + -command {::configDialogues::terminal::RESTART} \ + ] + + ## Button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Reset" + pack [ttk::button $but_frame.but_default \ + -text [mc "Reset to defaults"] \ + -command {::configDialogues::terminal::DEFAULTS} \ + ] -side left + DynamicHelp::add $but_frame.but_default \ + -text [mc "Reset all settings to defaults"] + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::terminal::OK} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_ok \ + -text [mc "Commit new settings"] + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::terminal::CANCEL} \ + ] -side right -padx 2 + DynamicHelp::add $but_frame.but_cancel \ + -text [mc "Take changes back and close dialog"] + + # Pack frames and notebook + pack $win.header_label -side top -pady 6 + pack $win.sep -side top -fill x -after $win.header_label + pack $main_frame -side top -padx 10 -anchor nw -pady 10 -fill x + pack $but_frame -side bottom -fill x -anchor s -padx 10 -pady 5 + pack $restart_but -side bottom -fill x -expand 1 -anchor s -padx 10 + + # Set window attributes + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Configure terminal emulator"] + wm minsize $win 380 280 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + ::configDialogues::terminal::CANCEL + } + tkwait window $win + } + + ## Valiadte content of font size spinbox + # @pamr String content - String to valiadte + # @return void + proc font_size_valiade {content} { + if {$content == {}} { + return 1 + } + if {![string is digit $content]} { + return 0 + } + if {$content > 22} { + return 0 + } + after idle { + ::configDialogues::terminal::font_changed + } + return 1 + } + + ## Change font for example text + # @return void + proc font_changed {} { + variable configuration ;# Array: Configuration array + variable example_text ;# Widget: Label widget containing example text + variable selected_font ;# Font: Current font + variable changed ;# Bool: Settings changed + + if {$configuration(font_size) == {} || $configuration(font_size) < 4} { + return + } + + font delete $selected_font + set selected_font [font create \ + -family $configuration(font_family) \ + -size -$configuration(font_size) \ + ] + $example_text configure -font $selected_font + set changed 1 + } + + ## Select color + # @parm String what_clr - What color (foreground / background ...) + # @parm String var - Key in configuration array + # @parm Widget button - Source button + # @return void + proc select_color {what_clr var button} { + variable configuration ;# Array: Configuration array + variable win ;# ID of toplevel dialog window + variable changed ;# Bool: Settings changed + + switch -- $what_clr { + {foreground} { + set txt [mc "Select foreground color"] + } + {background} { + set txt [mc "Select background color"] + } + } + + set color [SelectColor .select_color \ + -parent $win \ + -color $configuration($var) \ + -title $txt \ + ] + + # Set new content of the given variable and button background color + if {$color != {}} { + set configuration($var) $color + $button configure -bg $color -activebackground $color + + # Adjust status changed + set changed 1 + } + } + + ## Retrieve settings from main NS + # @return void + proc getSettings {} { + variable configuration ;# Array: Configuration array + array set configuration [array get ::Terminal::configuration] + } + + ## Set application according to local settings + # @return void + proc use_settings {} { + variable configuration ;# Array: Configuration array + if {$configuration(font_size) == {} || $configuration(font_size) < 4} { + set configuration(font_size) 13 + } + array set ::Terminal::configuration [array get configuration] + } + + ## Save settings to the config file + # @return void + proc save_config {} { + variable configuration ;# Array: Configuration array + + foreach key [array names configuration] { + ::settings setValue "Terminal emulator/$key" $::Terminal::configuration($key) + } + + ::settings saveConfig + } + + ## Load configuration from config file + # @return void + proc load_config {} { + # Load configuration + array set default_conf ${::Terminal::configuration_def} + foreach key [array names ::Terminal::configuration] { + set ::Terminal::configuration($key) [::settings getValue \ + "Terminal emulator/$key" $default_conf($key) \ + ] + } + + # Validate configuration + if {![regexp {^#[0-9a-fA-F]{6,12}$} ${::Terminal::configuration(bg)}]} { + puts stderr [mc "Invalid value of key: '%s'" {bg}] + set ::Terminal::configuration(bg) {#FFFFFF} + } + if {![regexp {^#[0-9a-fA-F]{6,12}$} ${::Terminal::configuration(fg)}]} { + puts stderr [mc "Invalid value of key: '%s'" {fg}] + set ::Terminal::configuration(fg) {#000000} + } + if { + ![regexp {^\d+$} ${::Terminal::configuration(font_size)}] + || + ${::Terminal::configuration(font_size)} < 4 + || + ${::Terminal::configuration(font_size)} > 22 + } then { + puts stderr [mc "Invalid value of key: '%s'" {font_size}] + set ::Terminal::configuration(font_size) 13 + } + if {![string length [string trim ${::Terminal::configuration(font_family)}]]} { + puts stderr [mc "Invalid value of key: '%s'" {font_family}] + set ::Terminal::configuration(font_family) $::DEFAULT_FIXED_FONT + } + } + + ## Resart terminal emulators for all projects + # @return void + proc RESTART {} { + use_settings + foreach project ${::X::openedProjects} { + $project terminal_restart + } + } + + ## Destroy the dialog + # @return void + proc CANCEL {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Destroy dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Use settings and destroy the dialog + # @return void + proc OK {} { + variable win ;# ID of toplevel dialog window + variable changed ;# Bool: Settings changed + + # Use and save settings + if {$changed} { + use_settings + save_config + } + + # Destroy dialog window + CANCEL + } + + ## Restrore defaults + # @return void + proc DEFAULTS {} { + variable configuration ;# Array: Configuration array + variable fg_clr_but ;# Widget: Button for selecting foreground color + variable bg_clr_but ;# Widget: Button for selecting background color + + array set configuration ${::Terminal::configuration_def} + $fg_clr_but configure \ + -bg $configuration(fg) \ + -activebackground $configuration(fg) + $bg_clr_but configure \ + -bg $configuration(bg) \ + -activebackground $configuration(bg) + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard diff --git a/lib/configdialogues/toolbar_config.tcl b/lib/configdialogues/toolbar_config.tcl new file mode 100644 index 0000000..abddd01 --- /dev/null +++ b/lib/configdialogues/toolbar_config.tcl @@ -0,0 +1,734 @@ +#!/usr/bin/tclsh +# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) + +############################################################################ +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # +# martin.osmera@gmail.com # +# # +# This program is free software; you can redistribute it and#or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the # +# Free Software Foundation, Inc., # +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +############################################################################ + +# >>> File inclusion guard +if { ! [ info exists _TOOLBAR_CONFIG_TCL ] } { +set _TOOLBAR_CONFIG_TCL _ +# <<< File inclusion guard + +# -------------------------------------------------------------------------- +# DESCRIPTION +# Implements main toolbar configuration dialog +# -------------------------------------------------------------------------- + + +namespace eval toolbar { + variable win ;# ID of toplevel dialog window + variable dialog_opened 0 ;# Bool: True if this dialog is already opened + + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable changed ;# Bool: Settings changed + variable apply_button ;# ID of button "Apply" + + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + variable current_search_entry ;# ID of search EntryBox for $current_ListBox + variable options_search_entry ;# ID of search EntryBox for $options_ListBox + variable current_search_clear ;# ID of search EntryBox clear button for $current_ListBox + variable options_search_clear ;# ID of search EntryBox clear button for $options_ListBox + variable up_button ;# ID of button "Up" + variable left_button ;# ID of button "Left" + variable right_button ;# ID of button "Right" + variable down_button ;# ID of button "Down" + + ## Create the dialog + # @return void + proc mkDialog {} { + variable win ;# ID of toplevel dialog window + variable dialog_opened ;# Bool: True if this dialog is already opened + + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable changed ;# Bool: Settings changed + variable apply_button ;# ID of button "Apply" + + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + variable current_search_entry ;# ID of search EntryBox for $current_ListBox + variable options_search_entry ;# ID of search EntryBox for $options_ListBox + variable current_search_clear ;# ID of search EntryBox clear button for $current_ListBox + variable options_search_clear ;# ID of search EntryBox clear button for $options_ListBox + variable up_button ;# ID of button "Up" + variable left_button ;# ID of button "Left" + variable right_button ;# ID of button "Right" + variable down_button ;# ID of button "Down" + + # Destroy the dialog if it's already opened + if {$dialog_opened} { + destroy .toolbar_config_dialog + } + set anything_modified 0 + set dialog_opened 1 + set changed 0 + + # Create toplevel window + set win [toplevel .toolbar_config_dialog -class {Configuration dialog} -bg ${::COMMON_BG_COLOR}] + + # Create window header + label $win.header_label \ + -compound left \ + -image ::ICONS::32::configure \ + -text [mc "Toolbar configuration"] \ + -font [font create -size [expr {int(-20 * $::font_size_factor)}]] + + # Create main frame (ListBoxes and Arrows) + set main_frame [frame $win.main_frame] + + ## Create arrows frame and buttons + set arrows [frame $main_frame.arrows] + # Arrow "Up" + set up_button [ttk::button $arrows.up \ + -image ::ICONS::16::up \ + -state disabled \ + -style Flat.TButton \ + -command {::configDialogues::toolbar::up} \ + ] + # Arrow "Left" + set left_button [ttk::button $arrows.left \ + -image ::ICONS::16::left \ + -state disabled \ + -style Flat.TButton \ + -command {::configDialogues::toolbar::left} \ + ] + # Arrow "Right" + set right_button [ttk::button $arrows.right \ + -image ::ICONS::16::right \ + -state disabled \ + -style Flat.TButton \ + -command {::configDialogues::toolbar::right} \ + ] + # Arrow "Down" + set down_button [ttk::button $arrows.down \ + -image ::ICONS::16::down \ + -state disabled \ + -style Flat.TButton \ + -command {::configDialogues::toolbar::down} \ + ] + + # Place arrows to the grid + grid $up_button -column 1 -row 0 + grid $left_button -column 0 -row 1 + grid $right_button -column 2 -row 1 + grid $down_button -column 1 -row 2 + + # Create ListBox of available items and its scrollbar + set options_frame [frame $main_frame.options_frame] + set listbox_frame [frame $options_frame.listbox_frame] + set options_ListBox [ListBox $listbox_frame.options_ListBox \ + -background {#FFFFFF} -deltay 21 \ + -selectmode single \ + -highlightcolor {#FFFFFF} \ + -yscrollcommand "$listbox_frame.options_scrollbar set" \ + -highlightthickness 0 \ + ] + if {[winfo exists $options_ListBox.c]} { + bind $options_ListBox.c {%W yview scroll +5 units; break} + bind $options_ListBox.c {%W yview scroll -5 units; break} + } + pack $options_ListBox -fill both -expand 1 -side left + pack [ttk::scrollbar $listbox_frame.options_scrollbar \ + -takefocus 0 \ + -orient vertical \ + -command "$options_ListBox yview" \ + ] -side right -after $options_ListBox -fill y + + # Create search bar for ListBox of available items + set search_frame [frame $options_frame.search_frame] + set options_search_entry [ttk::entry $search_frame.entry \ + -validate all \ + -validatecommand {::configDialogues::toolbar::search O %P} \ + ] + DynamicHelp::add $search_frame.entry -text [mc "Search for a string in ListBox"] + pack $options_search_entry -side left -fill x -expand 1 + set options_search_clear [ttk::button $search_frame.button \ + -image ::ICONS::16::clear_left \ + -style Flat.TButton \ + -command "$options_search_entry delete 0 end" \ + -state disabled \ + ] + DynamicHelp::add $search_frame.button \ + -text [mc "Clear"] + pack $options_search_clear -side right -after $options_search_entry + + # Pack frames of the left part (available items) + pack $search_frame -fill x + pack [label $options_frame.label -text [mc "available items"]] -pady 5 + pack $listbox_frame -fill both -expand 1 + + + # Create ListBox of current items and its scrollbar + set current_frame [frame $main_frame.current_frame] + set listbox_frame [frame $current_frame.listbox_frame] + set current_ListBox [ListBox $listbox_frame.current_ListBox \ + -background {#FFFFFF} -deltay 21 \ + -selectmode single \ + -highlightcolor {#FFFFFF} \ + -yscrollcommand "$listbox_frame.current_scrollbar set" \ + -highlightthickness 0 \ + ] + if {[winfo exists $current_ListBox.c]} { + bind $current_ListBox.c {%W yview scroll +5 units; break} + bind $current_ListBox.c {%W yview scroll -5 units; break} + } + pack $current_ListBox -fill both -expand 1 -side left + pack [ttk::scrollbar $listbox_frame.current_scrollbar \ + -takefocus 0 \ + -orient vertical \ + -command "$current_ListBox yview" \ + ] -side right -after $current_ListBox -fill y + + # Create search bar for ListBox of current items + set search_frame [frame $current_frame.search_frame] + set current_search_entry [ttk::entry $search_frame.entry \ + -validate all \ + -validatecommand {::configDialogues::toolbar::search C %P} \ + ] + DynamicHelp::add $search_frame.entry -text [mc "Search for a string in ListBox"] + pack $current_search_entry -side left -fill x -expand 1 + set current_search_clear [ttk::button $search_frame.button \ + -image ::ICONS::16::clear_left \ + -style Flat.TButton \ + -command "$current_search_entry delete 0 end" \ + -state disabled \ + ] + DynamicHelp::add $search_frame.button \ + -text [mc "Clear"] + pack $current_search_clear -side right -after $current_search_entry + + # Pack frames of the left part (current items) + pack $search_frame -fill x + pack [label $current_frame.label -text [mc "Current toolbar items"]] -pady 5 + pack $listbox_frame -fill both -expand 1 + + + # Set event bindings for ListBoxes + bind $options_ListBox <> \ + "::configDialogues::toolbar::reevaluateArrows" + bind $current_ListBox <> \ + "::configDialogues::toolbar::reevaluateArrows" + + + # Pack left ListBox, arrows frame, right ListBox + pack $options_frame -side left -anchor n -fill both -expand 1 -padx 5 + pack $arrows -side left -anchor center + pack $current_frame -side left -anchor n -fill both -expand 1 -padx 5 + + # Fill up ListBoxes + fillListBox ${::ICONBAR_CURRENT} + + # Create button frame at the bottom + set but_frame [frame $win.button_frame] + # Button "Defaults" + pack [ttk::button $but_frame.but_default \ + -text [mc "Defaults"] \ + -command {::configDialogues::toolbar::DEFAULTS} \ + ] -side left + DynamicHelp::add $but_frame.but_default \ + -text [mc "Reset settings to defaults"] + # Button "Ok" + pack [ttk::button $but_frame.but_ok \ + -text [mc "Ok"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::toolbar::OK} \ + ] -side right -padx 2 + # Button "Apply" + set apply_button [ttk::button $but_frame.but_apply \ + -state disabled \ + -text [mc "Apply"] \ + -compound left \ + -image ::ICONS::16::ok \ + -command {::configDialogues::toolbar::APPLY} \ + ] + pack $apply_button -side right -padx 2 + # Button "Cancel" + pack [ttk::button $but_frame.but_cancel \ + -text [mc "Cancel"] \ + -compound left \ + -image ::ICONS::16::button_cancel \ + -command {::configDialogues::toolbar::CANCEL} \ + ] -side right -padx 2 + + # Pack frames and notebook + pack $but_frame -side bottom -fill x -expand 0 -anchor s -padx 10 -pady 5 + pack $win.header_label -side top -pady 6 + pack $main_frame -side top -fill both -expand 1 -padx 10 + + # Finalize creation of the dialog + wm iconphoto $win ::ICONS::16::configure + wm transient $win . + wm title $win [mc "Configure Main Toolbar - %s" ${::APPNAME}] + wm minsize $win 600 400 + raise $win + catch {grab $win} + wm protocol $win WM_DELETE_WINDOW { + if {${::configDialogues::toolbar::anything_modified}} { + set result [tk_messageBox \ + -parent .toolbar_config_dialog \ + -title [mc "Save changes?"] \ + -icon question \ + -type yesno \ + -message [mc "The settings have been changed. Do you want to save the changes?"] \ + ] + if {$result == {yes}} { + ::configDialogues::toolbar::OK + } else { + ::configDialogues::toolbar::CANCEL + } + } else { + ::configDialogues::toolbar::CANCEL + } + } + tkwait window $win + } + + ## Validator procedure for search EntryBoxes + # Search for the given string in the given ListBox and + #+ adjust EntryBox background color according to search result + # @parm Char where - + # "O" (O as Omega not 0 as zero) == Options ListBox (available items) + # "C" == ListBox containing current onfiguration + # @parm String what - String to search for + # @return Bool - Always true + proc search {where what} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + variable current_search_entry ;# ID of search EntryBox for $current_ListBox + variable options_search_entry ;# ID of search EntryBox for $options_ListBox + variable current_search_clear ;# ID of search EntryBox clear button for $current_ListBox + variable options_search_clear ;# ID of search EntryBox clear button for $options_ListBox + + if {$where == {C}} { + set listbox $current_ListBox + set entry $current_search_entry + set clearbut $current_search_clear + } else { + set listbox $options_ListBox + set entry $options_search_entry + set clearbut $options_search_clear + } + + # Empty string + if {$what == {}} { + $entry configure -style TEntry + $clearbut configure -state disabled + return 1 + } else { + $clearbut configure -state normal + } + + # Search for the given string + set what [string tolower $what] + foreach item [$listbox items] { + if { + [string first $what \ + [string tolower \ + [$listbox itemcget $item -text] \ + ] \ + ] != -1 + } then { + $listbox selection clear + $listbox selection set $item + $listbox see $item + $entry configure -style StringFound.TEntry + return 1 + } + } + + # String not found + $entry configure -style StringNotFound.TEntry + return 1 + } + + ## Fill ListBoxes acoring to the given toolbar definition + # Note: function depends on toplevel variable 'ICONBAR_ICONS' + # @parm List definition - Definition of current toolbar (eg. {new open | exit}) + # @return void + proc fillListBox {definition} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + + # Fill in left ListBox + $options_ListBox insert end sep -text [mc " -- SEPARATOR --"] + for {set i 0} {$i < [llength ${::ICONBAR_ICONS}]} {incr i} { + # Determinate item name + set item [lindex ${::ICONBAR_ICONS} $i] + incr i + # Skip invalid items + if {[lsearch $definition $item] != -1} {continue} + # Insert item + $options_ListBox insert end $item \ + -text [mc [lindex ${::ICONBAR_ICONS} [list $i 0]]] \ + -image ::ICONS::16::[lindex ${::ICONBAR_ICONS} [list $i 2]] + } + + # Fill in right ListBox + foreach key $definition { + # Insert separator + if {$key == {|}} { + $current_ListBox insert end #auto -text [mc " -- SEPARATOR --"] + } + # Deteminate item index + set i [lsearch ${::ICONBAR_ICONS} $key] + if {$i == -1} {continue} + incr i + # Insert regular item + $current_ListBox insert end $key \ + -text [mc [lindex ${::ICONBAR_ICONS} [list $i 0]]] \ + -image ::ICONS::16::[lindex ${::ICONBAR_ICONS} [list $i 2]] + } + } + + ## Enable/Disable arrow buttons according to selection in ListBoxes + # @return void + proc reevaluateArrows {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + variable left_button ;# ID of button "Left" + variable right_button ;# ID of button "Right" + + # Button "Left" + if {[$current_ListBox selection get] == {}} { + $left_button configure -state disabled + } else { + $left_button configure -state normal + } + + # Button "Right" + if {[$options_ListBox selection get] == {}} { + $right_button configure -state disabled + } else { + $right_button configure -state normal + } + + # Evaluate buttons "Up/Down" + reevaluateUpDown + + } + + ## Enable/Disable Up/Down arrow according to selection in the right ListBox + # @return void + proc reevaluateUpDown {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable down_button ;# ID of button "Down" + variable up_button ;# ID of button "Up" + + # Determinate ID of selected item + set sel [$current_ListBox selection get] + + # Valid selection + if {$sel != {}} { + # Button "Up" + set curIndex [$current_ListBox index $sel] + if {$curIndex == 0} { + $up_button configure -state disabled + } else { + $up_button configure -state normal + } + + # Button "Down" + set numberOfItems [llength [$current_ListBox items]] + if {$curIndex == ($numberOfItems - 1)} { + $down_button configure -state disabled + } else { + $down_button configure -state normal + } + # Empty selection + } else { + $up_button configure -state disabled + $down_button configure -state disabled + } + } + + ## Command for button "Up" + # Move selected item in the right listbox up + # @return void + proc up {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + + # Deteminate ID of selected item + set sel [$current_ListBox selection get] + # Determinate target index + set trgIdx [$current_ListBox index $sel] + incr trgIdx -1 + # Move item + $current_ListBox move $sel $trgIdx + $current_ListBox see $sel + + # Enable/Disabled buttons "Up/Down" + reevaluateUpDown + # Adjust status changed + settings_changed + } + + ## Command for button "Down" + # Move selected item in the right listbox down + # @return void + proc down {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + + # Deteminate ID of selected item + set sel [$current_ListBox selection get] + # Determinate target index + set trgIdx [$current_ListBox index $sel] + incr trgIdx + # Move item + $current_ListBox move $sel $trgIdx + $current_ListBox see $sel + + # Enable/Disabled buttons "Up/Down" + reevaluateUpDown + # Adjust status changed + settings_changed + } + + ## Command for button "Left" + # Move selected item from the right ListBox to the left one + # @return void + proc left {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + + # Local variables + set sel [$current_ListBox selection get] ;# ID of the selected item + set idx [$current_ListBox index $sel] ;# Index of the selected item + + # Remove selected item + $current_ListBox delete $sel + + # Regular item (no separator) + if {![regexp {^\d+$} $sel]} { + # Find index of the item (in available icons) + set i [lsearch ${::ICONBAR_ICONS} $sel] + if {$i == -1} {return} + incr i + + # Insert removed item into left ListBox + $options_ListBox insert 1 $sel \ + -text [lindex ${::ICONBAR_ICONS} [list $i 0]] \ + -image ::ICONS::16::[lindex ${::ICONBAR_ICONS} [list $i 2]] + } + + # Restore selection + if {[llength [$current_ListBox items]] == $idx} { + if {$idx} { + incr idx -1 + } + } + set idx [$current_ListBox item $idx] + $current_ListBox selection set $idx + $current_ListBox see $idx + $options_ListBox see $sel + + # Enable/Disable arrow buttons + reevaluateArrows + # Adjust status changed + settings_changed + } + + ## Command for button "Right" + # Move selected item from the left ListBox to the right one + # @return void + proc right {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + + # Determinate target index + set sel [$current_ListBox selection get] + if {$sel == {}} { + set trgIdx {end} + } else { + set trgIdx [$current_ListBox index $sel] + } + # Determinate source index and source item ID + set sel [$options_ListBox selection get] + set idx [$options_ListBox index $sel] + + # Separator + if {$sel == {sep}} { + $current_ListBox insert $trgIdx #auto -text [mc " -- SEPARATOR --"] + # Regular item + } else { + set i [lsearch ${::ICONBAR_ICONS} $sel] + if {$i == -1} {return} + incr i + $current_ListBox insert $trgIdx $sel \ + -text [lindex ${::ICONBAR_ICONS} [list $i 0]] \ + -image ::ICONS::16::[lindex ${::ICONBAR_ICONS} [list $i 2]] + + $options_ListBox delete $sel + } + + # Restore selection + if {[llength [$options_ListBox items]] == $idx} { + if {$idx} { + incr idx -1 + } + } + set idx [$options_ListBox item $idx] + $options_ListBox selection set $idx + $options_ListBox see $idx + $current_ListBox see [$current_ListBox item $trgIdx] + + # Enable/Disable arrow buttons + reevaluateArrows + # Adjust status changed + settings_changed + } + + ## Change content of configuration variables + # @return void + proc use_settings {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + + set ::ICONBAR_CURRENT { } + append ::ICONBAR_CURRENT [$current_ListBox items] + append ::ICONBAR_CURRENT { } + regsub -all {\s\d+\s} ${::ICONBAR_CURRENT} { | } ::ICONBAR_CURRENT + regsub -all {\s\d+\s} ${::ICONBAR_CURRENT} { | } ::ICONBAR_CURRENT + set ::ICONBAR_CURRENT [string trim ${::ICONBAR_CURRENT}] + } + + ## Save configuration to config file + # @return void + proc save_config {} { + ::settings setValue "Main toolbar" ${::ICONBAR_CURRENT} + + # Commit + ::settings saveConfig + } + + ## Load configuratin from config file + # @return void + proc load_config {} { + set ::ICONBAR_CURRENT [::settings getValue "Main toolbar" ${::ICONBAR_DEFAULT}] + } + + ## Set status changed to True + # @return true + proc settings_changed {} { + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable changed ;# Bool: Settings changed + variable apply_button ;# ID of button "Apply" + + if {$changed} {return} + + set changed 1 + set anything_modified 1 + $apply_button configure -state normal + } + + ## Take back changes and destroy dialog window + # @return void + proc CANCEL {} { + variable win ;# ID of dialog toplevel window + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + variable dialog_opened ;# Bool: True if this dialog is already opened + + # Restore previous configuration + if {$anything_modified} { + load_config + iconbar_redraw + set anything_modified 0 + ::X::disaena_menu_toolbar_for_current_project + set anything_modified 0 + } + + # Get rid of dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Apply changes and destroy dialog window + # @return void + proc OK {} { + variable win ;# ID of dialog toplevel window + variable changed ;# Bool: Settings changed + variable dialog_opened ;# Bool: True if this dialog is already opened + variable anything_modified ;# Bool: Settings changed (stay set to 1 even after APPLY) + + # Apply new settings + if {$anything_modified} { + use_settings ;# Adjust NS variables + iconbar_redraw ;# Adjust GUI + save_config ;# Save new config + # Restore previous state of menu items (enabled / disabled) + ::X::disaena_menu_toolbar_for_current_project + set anything_modified 0 + } + + # Get rid of dialog window + set dialog_opened 0 + grab release $win + destroy $win + } + + ## Apply changes in GUI + # @return Bool - result + proc APPLY {} { + variable apply_button ;# ID of button "Apply" + variable changed ;# Bool: Settings changed + + # Reset status changed + set changed 0 + $apply_button configure -state disabled + + # Adjust NS variables + use_settings + iconbar_redraw + # Restore previous state of menu items (enabled / disabled) + ::X::disaena_menu_toolbar_for_current_project + + # done ... + return 1 + } + + ## Restrore defaults + # @return void + proc DEFAULTS {} { + variable current_ListBox ;# ID of ListBox containing current toolbar setup + variable options_ListBox ;# ID of ListBox containing available icons + variable win ;# ID of dialog toplevel window + + # Ask user + if {[tk_messageBox \ + -parent $win -type yesno \ + -icon question -title [mc "Restore defaults"] \ + -message [mc "Are you sure that you want restore default settings ?"] + ] != {yes}} { + return + } + + # Clear ListBoxes + $current_ListBox delete [$current_ListBox items] + $options_ListBox delete [$options_ListBox items] + # Refill ListBoxes + fillListBox ${::ICONBAR_DEFAULT} + # Adjust status changed + settings_changed + } +} + +# >>> File inclusion guard +} +# <<< File inclusion guard -- cgit v1.2.3