summaryrefslogtreecommitdiff
path: root/lib/dialogues/tips.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialogues/tips.tcl')
-rw-r--r--lib/dialogues/tips.tcl402
1 files changed, 402 insertions, 0 deletions
diff --git a/lib/dialogues/tips.tcl b/lib/dialogues/tips.tcl
new file mode 100644
index 0000000..d2df211
--- /dev/null
+++ b/lib/dialogues/tips.tcl
@@ -0,0 +1,402 @@
+#!/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 _TIPS_TCL ] } {
+set _TIPS_TCL _
+# <<< File inclusion guard
+
+# --------------------------------------------------------------------------
+# DESCRIPTION
+# Provides facility to show tips on start-up
+# * Tips are readed from file deindef in NS variable "tips_file"
+# * Format of definition file is XML and it supports mutiple languages
+# * Usage is simple: execute procedure "::Tips::show_tip_of_the_day_win"
+# * It requires NS ConfigDialogues (see ${::GLOBAL_CONFIG(tips)})
+# --------------------------------------------------------------------------
+
+namespace eval Tips {
+ variable tip_of_the_day_win ;# ID of window "Tip of the day"
+ variable tip_of_the_day_text ;# ID of text widget in "Tip of the day"
+ variable tip_of_the_day_show_again ;# Bool: Show "Tip of the day"
+
+ variable tips_data ;# List containing tips data
+ variable number_of_tips ;# Number of tips available
+ variable current_tip ;# Number of the currently displayed tip
+ variable expected ;# Expeceted element
+ variable take_data ;# Bool: Append data section to $tips_data
+ # File containing tips data
+ variable tips_file "${::INSTALLATION_DIR}/data/tips.xml"
+
+ ## Invoke dialog "Tip on start-up"
+ # @return void
+ proc show_tip_of_the_day_win {} {
+ variable tip_of_the_day_win ;# ID of window "Tip of the day"
+ variable tip_of_the_day_text ;# ID of text widget in "Tip of the day"
+ variable tip_of_the_day_show_again ;# Bool: Show "Tip of the day"
+ variable number_of_tips ;# Number of tips available
+ variable tip_of_the_day_show_again ;# Bool: Show "Tip of the day"
+
+ # Set value of checkbox "Show again"
+ set tip_of_the_day_show_again ${::GLOBAL_CONFIG(tips)}
+ # Load tips definition file
+ load_tips_file
+
+ # Create toplevel window
+ set win [toplevel .tip_of_the_day -class {Tip of the day} -bg ${::COMMON_BG_COLOR}]
+ set tip_of_the_day_win $win
+
+ # Create window header
+ pack [label $win.header \
+ -text [mc "Did you know ... "] \
+ -font [font create \
+ -family {times} \
+ -size [expr {int(-25 * $::font_size_factor)}] \
+ -weight bold \
+ ] \
+ -compound right \
+ -image ::ICONS::32::help \
+ ] -pady 5
+
+ # Create middle frame (text windget and scrollbar)
+ set middle_frame [frame $win.middle_frame]
+ set text [text $middle_frame.text \
+ -width 0 -height 0 -bg white \
+ -wrap word \
+ -yscrollcommand "$middle_frame.scrollbar set" \
+ -font [font create \
+ -family {helvetica} \
+ -size [expr {int(-14 * $::font_size_factor)}] \
+ -weight normal \
+ ] \
+ ]
+ pack $text -side left -fill both -expand 1
+ pack [ttk::scrollbar $middle_frame.scrollbar \
+ -orient vertical \
+ -command [list $text yview] \
+ ] -side left -fill y -after $text
+ set tip_of_the_day_text $text
+
+ ## Create bottom frame
+ set bottom_frame [frame $win.bottom_frame]
+ # - CheckButton "Show tips on start-up"
+ pack [checkbutton $bottom_frame.chbutton \
+ -variable ::Tips::tip_of_the_day_show_again \
+ -command {::Tips::tip_otd_show_again} \
+ -text [mc "Show tips on start-up"] \
+ ] -side left -anchor e
+ # - Button "Close"
+ pack [ttk::button $bottom_frame.close_but \
+ -compound left \
+ -text [mc "Close"] \
+ -image ::ICONS::16::button_cancel \
+ -command {::Tips::tip_otd_CLOSE} \
+ -width 8 \
+ ] -side right -anchor w -padx 2
+ # - Button "Next"
+ pack [ttk::button $bottom_frame.next_but \
+ -compound left \
+ -text [mc "Next"] \
+ -image ::ICONS::16::right \
+ -command {::Tips::tip_otd_NEXT} \
+ -width 8 \
+ ] -side right -anchor w -padx 2
+ # - Button "Previous"
+ pack [ttk::button $bottom_frame.prev_but \
+ -compound left \
+ -text [mc "Previous"] \
+ -image ::ICONS::16::left \
+ -command {::Tips::tip_otd_PREV} \
+ -width 8 \
+ ] -side right -anchor w -padx 2
+
+ # Pack window frames
+ pack $middle_frame -side top -fill both -expand 1 -padx 10 -pady 5
+ pack $bottom_frame -side bottom -fill x -after $middle_frame -padx 10 -pady 5
+
+ # Configure text tags
+ $text tag configure tag_bold -font [font create \
+ -family {helvetica} \
+ -size [expr {int(-14 * $::font_size_factor)}] \
+ -weight bold \
+ ]
+ # Configure text tags
+ $text tag configure tag_code -font [font create \
+ -family $::DEFAULT_FIXED_FONT \
+ -size [expr {int(-14 * $::font_size_factor)}] \
+ -weight normal \
+ ] -foreground {#DD8800}
+
+ # Create tag for external hyperlinks
+ create_link_tag_in_text_widget $text
+
+ # Determinate random number of tip to show
+ expr {srand([clock seconds])}
+ display_tip [expr {int(rand() * $number_of_tips)}]
+
+ # Configure dialog window
+ wm iconphoto $win ::ICONS::16::info
+ wm title $win [mc "Tip of the day - MCU 8051 IDE"]
+ wm minsize $win 520 250
+ wm protocol $win WM_DELETE_WINDOW {
+ ::Tips::tip_otd_CLOSE
+ }
+ wm transient $win .
+ raise $win
+ catch {
+ grab $win
+ }
+ }
+
+ ## Load definition of tips
+ # @return void
+ proc load_tips_file {} {
+ variable tips_data ;# List containing tips data
+ variable number_of_tips ;# Number of tips available
+ variable tips_file ;# File containing tips data
+ variable expected ;# Expeceted element
+ variable take_data ;# Bool: Append data section to $tips_data
+
+ # Initialize NS variables
+ set take_data 0
+ set number_of_tips 0
+ set expected {tips}
+ set tips_data {}
+
+ # Open file
+ if {[catch {
+ set file [open $tips_file {r}]
+ }]} then {
+ tk_messageBox \
+ -parent . \
+ -type ok \
+ -icon warning \
+ -title "tips.xml" \
+ -message [mc "Unable to open file containing tips,\nplease check your installation"]
+ return
+ }
+
+ # Create XML parser
+ set parser [::xml::parser -final 1 -ignorewhitespace 1 \
+ -elementstartcommand ::Tips::xml_data_parser_element \
+ -characterdatacommand ::Tips::xml_data_parser_data \
+ ]
+
+ # Start XML parser
+ if {[catch {
+ $parser parse [read $file]
+ } result]} then {
+ set number_of_tips 0
+ set tips_data {}
+ tk_messageBox \
+ -parent . \
+ -type ok \
+ -icon warning \
+ -title [mc "Unable to parse tips.xml"] \
+ -message [mc "File tips.xml is corrupted,\nplease check your installation"]
+ puts stderr $result
+ return
+ }
+
+ # Close file and free parser
+ close $file
+ $parser free
+ }
+
+ ## Universal parser handler - handles XML tags and data
+ # @parm String arg1 - content of the element
+ # @return void
+ proc xml_data_parser_data {arg1} {
+ variable tips_data ;# List containing tips data
+ variable number_of_tips ;# Number of tips available
+ variable current_tip ;# Number of the currently displayed tip
+ variable expected ;# Expeceted element
+ variable take_data ;# Bool: Append data section to $tips_data
+
+ if {!$take_data} {
+ return
+ }
+
+ set take_data 0
+ incr number_of_tips
+
+ regsub -all {^\s+} $arg1 {} arg1
+ regsub -all {\s+$} $arg1 {} arg1
+ lappend tips_data [regsub -all -line {^\t+} $arg1 {}]
+ }
+
+ ## XML parser handler - handles XML tags
+ # @parm String arg1 - name of the element
+ # @parm List attrs - list of attributes '{attr0 val0 attr1 val1 ...}'
+ # @return void
+ proc xml_data_parser_element {arg1 attrs} {
+ variable tips_data ;# List containing tips data
+ variable number_of_tips ;# Number of tips available
+ variable current_tip ;# Number of the currently displayed tip
+ variable expected ;# Expeceted element
+ variable take_data ;# Bool: Append data section to $tips_data
+
+ if {$arg1 != $expected} {
+ error "Bad element `$arg1'"
+ }
+ if {$arg1 == {tips}} {
+ set expected {tip}
+ }
+
+ # Iterate over element attributes
+ for {set i 0} {$i < [llength $attrs]} {incr i} {
+ if {[lindex $attrs $i] != {lang}} {
+ incr i
+ continue
+ }
+ incr i
+
+ # Take data only if some translation has been loaded and it conforms with the text
+ if {[string tolower [lindex $attrs $i]] == [string tolower ${::GLOBAL_CONFIG(language)}]} {
+ set take_data 1
+ } else {
+ set take_data 0
+ }
+ }
+ }
+
+ ## Close dialog
+ # @return void
+ proc tip_otd_CLOSE {} {
+ variable tips_data ;# List containing tips data
+ variable number_of_tips ;# Number of tips available
+ variable current_tip ;# Number of the currently displayed tip
+ variable tip_of_the_day_win ;# ID of window "Tip of the day"
+
+ # Remove dialog
+ grab release $tip_of_the_day_win
+ destroy $tip_of_the_day_win
+
+ # Free dialog resources
+ set tips_data {}
+ set number_of_tips {}
+ set current_tip {}
+ }
+
+ ## Display tip with the given number in the window
+ # @parm Int tip_number - number of the tip to show (can overlap allowed range)
+ # @return void
+ proc display_tip {tip_number} {
+ variable tips_data ;# List containing tips data
+ variable number_of_tips ;# Number of tips available
+ variable current_tip ;# Number of the currently displayed tip
+ variable tip_of_the_day_text ;# ID of text widget in "Tip of the day"
+
+ set current_tip $tip_number
+
+ # Clear text widget
+ $tip_of_the_day_text configure -state normal
+ $tip_of_the_day_text delete 1.0 end
+
+ # Validate tip number
+ if {!$number_of_tips} {
+ $tip_of_the_day_text configure -state disabled
+ return
+ }
+ if {$tip_number >= $number_of_tips} {
+ set current_tip $number_of_tips
+ incr current_tip -1
+ }
+
+ # Create map of bold and code font tags
+ set bold_tag_map [list]
+ set code_tag_map [list]
+ set content [lindex $tips_data $current_tip]
+ foreach map {bold_tag_map code_tag_map} \
+ tag {b c} \
+ {
+ while {1} {
+ set tag_pair {}
+
+ set idx [string first "<$tag>" $content]
+ if {$idx == -1} {break}
+ regsub "<$tag>" $content {} content
+ lappend tag_pair $idx
+
+ set idx [string first "</$tag>" $content]
+ if {$idx == -1} {break}
+ regsub "</$tag>" $content {} content
+ lappend tag_pair $idx
+
+ lappend $map $tag_pair
+ }
+ }
+
+ # Fill text widget
+ set start [$tip_of_the_day_text index insert]
+ $tip_of_the_day_text insert end $content
+ foreach pair $bold_tag_map {
+ $tip_of_the_day_text tag add tag_bold $start+[lindex $pair 0]c $start+[lindex $pair 1]c
+ }
+ foreach pair $code_tag_map {
+ $tip_of_the_day_text tag add tag_code $start+[lindex $pair 0]c $start+[lindex $pair 1]c
+ }
+ $tip_of_the_day_text configure -state disabled
+
+ # Detect external hyperlinks and make the functional
+ convert_all_https_to_links $tip_of_the_day_text
+ }
+
+ ## Show next tip
+ # @return void
+ proc tip_otd_NEXT {} {
+ variable number_of_tips ;# Number of tips available
+ variable current_tip ;# Number of the currently displayed tip
+
+ incr current_tip
+ if {$current_tip >= $number_of_tips} {
+ set current_tip 0
+ }
+ display_tip $current_tip
+ }
+
+ ## Show previous tip
+ # @return void
+ proc tip_otd_PREV {} {
+ variable number_of_tips ;# Number of tips available
+ variable current_tip ;# Number of the currently displayed tip
+
+ incr current_tip -1
+ if {$current_tip < 0} {
+ set current_tip [expr {$number_of_tips - 1}]
+ }
+ display_tip $current_tip
+ }
+
+ ## Adjust base configuration file to variable "tip_of_the_day_show_again"
+ # @return void
+ proc tip_otd_show_again {} {
+ variable tip_of_the_day_show_again ;# Bool: Show "Tip of the day"
+
+ ::configDialogues::global::set_variable tips $tip_of_the_day_show_again
+ }
+}
+
+# >>> File inclusion guard
+}
+# <<< File inclusion guard