Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
recent.tcl
Go to the documentation of this file.
1 
2 ####################
3 # Recent files list:
4 
5 set recentFiles(limit) 10 ;# Maximum number of recent files to remember.
6 set recentFiles(menu) 9 ;# Maximum number of files to show in File menu.
7 set recentFiles(extra) 9 ;# Maximum number of files to show in extra menu.
8 set recentFiles(data) {} ;# List of recently used files.
9 
10 catch {source [scidConfigFile recentfiles]}
11 
12 namespace eval ::recentFiles {}
13 
14 # ::recentFiles::save
15 # Saves the recent-file-list file, reporting any error in a message box
16 # if reportError is true.
17 #
18 proc ::recentFiles::save {{reportError 0}} {
19  global recentFiles
20  set f {}
21  set filename [scidConfigFile recentfiles]
22  if {[catch {open $filename w} f]} {
23  if {$reportError} {
24  tk_messageBox -title "Scid" -type ok -icon warning \
25  -message "Unable to write file: $filename\n$f"
26  }
27  return
28  }
29  puts $f "# Scid $::scidVersion recent files list"
30  puts $f ""
31  foreach i {limit menu extra data} {
32  puts $f "set recentFiles($i) [list [set recentFiles($i)]]"
33  puts $f ""
34  }
35  if {[info exists ::recentSort]} {
36  puts $f "set ::recentSort [list $::recentSort]"
37  }
39  close $f
40 }
41 
42 # ::recentFiles::add
43 # Adds a file to the recent files list, or moves it to the front
44 # if that file is already in the list.
45 #
46 proc ::recentFiles::add {fname} {
47  global recentFiles
48 
49  if {$fname == "" } { return}
50 
51  set rlist $recentFiles(data)
52 
53  # Remove file to be added from its current place in the
54  # list, if it is there:
55  while {1} {
56  set idx [lsearch -exact $rlist $fname]
57  if {$idx < 0} { break}
58  set rlist [lreplace $rlist $idx $idx]
59  }
60 
61  # Insert the current file at the start of the list:
62  set rlist [linsert $rlist 0 $fname]
63 
64  # Trim the list if necessary:
65  if {[llength $rlist] < $recentFiles(limit)} {
66  set rlist [lrange $rlist 0 [expr {$recentFiles(limit) - 1}]]
67  }
68 
69  set recentFiles(data) $rlist
70  # ::recentFiles::save
71 }
72 
73 # ::recentFiles::load
74 # Loads the selected recent file, or switches to its database slot
75 # if it is already open.
76 #
77 proc ::recentFiles::load {fname} {
78  set rname $fname
79  if {[file extension $rname] == ".si4"} {
80  set rname [file rootname $rname]
81  }
82  ::file::Open $fname
83 }
84 
85 #################################################################################
86 proc ::recentFiles::treeshow {menu} {
87  global recentFiles
88  set rlist $recentFiles(data)
89  $menu delete 0 end
90  set nfiles [llength $rlist]
91  if {$nfiles > $recentFiles(limit)} { set nfiles $recentFiles(limit)}
92 
93  for {set i 0} {$i<$nfiles} {incr i} {
94  set name [lindex $rlist $i]
95  $menu add command -label "$name" -command [list ::file::openBaseAsTree $name]
96  }
97 }
98 
99 #################################################################################
100 # ::recentFiles::show
101 # Adds the recent files to the end of the specified menu.
102 # Returns the number of menu entries added.
103 #
104 proc ::recentFiles::show {menu idx} {
105  global recentFiles
106  set rlist $recentFiles(data)
107  set nfiles [llength $rlist]
108  set nExtraFiles [expr {$nfiles - $recentFiles(menu)}]
109  if {$nfiles > $recentFiles(menu)} { set nfiles $recentFiles(menu)}
110  if {$nExtraFiles > $recentFiles(extra)} {
111  set nExtraFiles $recentFiles(extra)
112  }
113  if {$nExtraFiles < 0} { set nExtraFiles 0}
114 
115  # Add menu commands for the most recent files:
116 
117  for {set i 0} {$i < $nfiles} {incr i} {
118  set fname [lindex $rlist $i]
119  set mname [::recentFiles::menuname $fname]
120  set text [file tail $fname]
121  set num [expr {$i + 1}]
122  set underline -1
123  if {$num <= 9} { set underline 0}
124  if {$num == 10} { set underline 1}
125  $menu insert $idx command -label "$num: $mname" -underline $underline \
126  -command [list ::recentFiles::load $fname]
127  set ::helpMessage($menu,$idx) " [file nativename $fname]"
128  incr idx
129  }
130 
131  # If no extra submenu of recent files is needed, return now:
132  if {$nExtraFiles <= 0} { return $nfiles}
133 
134  # Now add the extra submenu of files:
135  catch {destroy $menu.recentFiles}
136  menu $menu.recentFiles
137  $menu insert $idx cascade -label "..." -underline 0 -menu $menu.recentFiles
138  set i $nfiles
139  for {set extra 0} {$extra < $nExtraFiles} {incr extra} {
140  set fname [lindex $rlist $i]
141  incr i
142  set mname [::recentFiles::menuname $fname]
143  set text [file tail $fname]
144  set num [expr {$extra + 1}]
145  set underline -1
146  if {$num <= 9} { set underline 0}
147  if {$num == 10} { set underline 1}
148  $menu.recentFiles add command -label "$num: $mname" -underline $underline \
149  -command [list ::recentFiles::load $fname]
150  set ::helpMessage($menu.recentFiles,$extra) " $fname"
151  }
152  return [expr {$nfiles + 1}]
153 }
154 
155 # ::recentFiles::menuname
156 # Given a full-path filename, returns a possibly shortened
157 # version suitable for displaying in a menu, such as
158 # "..../my/files/abc.pgn" instead of "/long/path/to/my/files/abc.pgn"
159 #
160 proc ::recentFiles::menuname {fname} {
161  set mname $fname
162  set mname [file nativename $mname]
163  if {[file extension $mname] == [sc_info suffix index]} {
164  set mname [file rootname $mname]
165  }
166  if {[string length $mname] < 25} { return $mname}
167 
168  # Generate a menu name " ..../path/filename" for the file:
169  set dir [file dirname $fname]
170  while {1} {
171  set tail [file join [file tail $dir] $mname]
172  set dir [file dirname $dir]
173  if {[string length $tail] > 20} { break}
174  set mname $tail
175  }
176  set mname [file join .... $mname]
177  set mname [file nativename $mname]
178  return $mname
179 }
180 
181 # ::recentFiles::configure
182 # Produces a dialog box for configuring the number of recent files
183 # to display in the File menu and in a submenu.
184 #
185 proc ::recentFiles::configure {} {
186  global recentFiles
187  set recentFiles(temp_menu) $recentFiles(menu)
188  set recentFiles(temp_extra) $recentFiles(extra)
189  set w .recentFilesDlg
191  wm title $w "Scid: [tr OptionsRecent]"
192  ttk::frame $w.m
193  ttk::frame $w.e
194  ttk::label $w.lmenu -text $::tr(RecentFilesMenu)
195  set tmpcombo {}
196  for {set x 1} {$x <= 10} {incr x} {
197  lappend tmpcombo $x
198  }
199  ttk::combobox $w.menu -textvariable recentFiles(temp_menu) -width 3 -values $tmpcombo -justify right -state readonly
200  ttk::label $w.lextra -text $::tr(RecentFilesExtra)
201  ttk::combobox $w.extra -textvariable recentFiles(temp_extra) -width 3 -values $tmpcombo -justify right -state readonly
202  pack $w.m $w.e -side top -anchor e
203  pack $w.lmenu $w.menu -side left -padx "0 5" -pady "0 5" -in $w.m -anchor e
204  pack $w.lextra $w.extra -side left -padx "0 5" -in $w.e -anchor e
205  pack [ttk::frame $w.b] -side bottom -fill x
206  ttk::button $w.b.ok -text "OK" -command {
207  set recentFiles(menu) $recentFiles(temp_menu)
208  set recentFiles(extra) $recentFiles(temp_extra)
209  catch {grab release .recentFilesDlg}
210  destroy .recentFilesDlg
211  ::recentFiles::save
212  }
213  ttk::button $w.b.cancel -text $::tr(Cancel) \
214  -command "catch {grab release $w}; destroy $w"
215  packdlgbuttons $w.b.cancel $w.b.ok
216  catch {grab $w}
217 }
218