Scid  4.6.5
end.tcl
Go to the documentation of this file.
1 # end.tcl: part of Scid.
2 # Copyright (C) 2000-2003 Shane Hudson.
3 
4 if { ! [file isdirectory $::scidBooksDir]} {
5  tk_messageBox -title "Scid" -type ok -icon warning -message "Books directory not found"
6 }
7 
8 
9 # findNovelty:
10 # Searches the for first position in the current game not
11 # found in the selected database.
12 
13 set noveltyOlder 0
14 
15 proc findNovelty {} {
16  global noveltyBase noveltyOlder
17  set noveltyBase [sc_base current]
18  set w .noveltyWin
19  if {[winfo exists $w]} {
21  return
22  }
23  toplevel $w
24  wm title $w "Scid: $::tr(FindNovelty)"
25 
26  pack [frame $w.help] -side top -fill x
27  text $w.help.text -width 1 -height 5 -wrap word \
28  -relief ridge -cursor top_left_arrow -yscrollcommand "$w.help.ybar set"
29  scrollbar $w.help.ybar -orient vertical -command "$w.help.text yview" \
30  -takefocus 0 -width 10
31  pack $w.help.ybar -side right -fill y
32  pack $w.help.text -side left -fill x -expand yes
33  $w.help.text insert end [string trim $::tr(NoveltyHelp)]
34  $w.help.text configure -state disabled
35 
36  label $w.title -text $::tr(Database:) -font font_Bold
37  pack $w.title -side top
38 
39  pack [frame $w.bases] -side top -fill x
40  pack [frame $w.bases.del]
42 
43  label $w.which -text $::tr(TwinsWhich:) -font font_Bold
44  pack $w.which -side top
45  radiobutton $w.all -text $::tr(SelectAllGames) \
46  -variable noveltyOlder -value 0
47  radiobutton $w.older -text $::tr(SelectOlderGames) \
48  -variable noveltyOlder -value 1
49  pack $w.all $w.older -side top -anchor w -padx 10
50 
52 
53  label $w.status -text "" -width 1 -font font_Small -relief sunken -anchor w
54  pack $w.status -side bottom -fill x
55  pack [frame $w.b] -side top -fill x
56  dialogbutton $w.b.go -text $::tr(FindNovelty) -command {
57  destroy .noveltyWin
58  progressWindow "Scid" "$::tr(FindNovelty)" $::tr(Cancel)
59  if {$noveltyOlder} {
60  set err [catch {sc_game novelty -older $noveltyBase} result]
61  } else {
62  set err [catch {sc_game novelty $noveltyBase} result]
63  }
64  closeProgressWindow
65  if {$err} {
66  ERROR::MessageBox
67  } else {
68  if {$result < 0} {
69  tk_messageBox -message "[tr NoveltyNone]"
70  }
71  }
72  updateBoard -pgn
73  }
74  dialogbutton $w.b.close -textvar ::tr(Close) -command {
75  catch {destroy .noveltyWin}
76  }
77  packbuttons right $w.b.close $w.b.go
78  wm resizable $w 0 0
79  focus $w.b.go
80  bind $w <KeyPress-1> "$w.b1 invoke"
81  bind $w <KeyPress-2> "$w.b2 invoke"
82  bind $w <KeyPress-3> "$w.b3 invoke"
83  bind $w <KeyPress-4> "$w.b4 invoke"
85 }
86 
87 proc updateNoveltyWin {} {
88  set w .noveltyWin
89  if {! [winfo exists $w]} { return}
90  $w.older configure -text "$::tr(SelectOlderGames) (< [sc_game info date])"
91  catch { destroy $w.bases.del}
92  pack [frame $w.bases.del]
93  foreach i [sc_base list] {
94  set name [file tail [sc_base filename $i]]
95  set ng [::utils::thousands [sc_base numGames $i]]
96  set txt "Base $i: $name ($ng $::tr(games))"
97  radiobutton $w.bases.del.b$i -text "$txt" -variable noveltyBase -value $i -underline 5
98  if {$ng == 0} { $w.bases.del.b$i configure -state disabled}
99  pack $w.bases.del.b$i -side top -anchor w -padx 10
100  }
101 }
102 
103 set merge(ply) 40
104 
105 # mergeGame:
106 # Produces a dialog for the user to merge a selected game into
107 # the current game.
108 #
109 proc mergeGame {base gnum} {
110  global merge
111 
112  sc_game push copy
113  set err [catch {sc_game merge $base $gnum} result]
114  sc_game pop
115  if {$err} {
116  tk_messageBox -title "Scid" -type ok -icon info \
117  -message "Unable to merge the selected game:\n$result"
118  return
119  }
120  set merge(base) $base
121  set merge(gnum) $gnum
122  set w .mergeDialog
123  toplevel $w
124  wm title $w "Scid: $::tr(MergeGame)"
125  bind $w <Escape> "$w.b.cancel invoke"
126  bind $w <F1> {helpWindow GameList Browsing}
127  label $w.title -text $::tr(Preview:) -font font_Bold
128  pack $w.title -side top
129  pack [frame $w.b] -side bottom -fill x
130  frame $w.f
131  text $w.f.text -background white -wrap word -width 60 -height 20 \
132  -font font_Small -yscrollcommand "$w.f.ybar set"
133  scrollbar $w.f.ybar -takefocus 0 -command "$w.f.text yview"
134  event generate $w.f.text <ButtonRelease-1>
135  pack $w.f.ybar -side right -fill y
136  pack $w.f.text -side left -fill both -expand yes
137  pack $w.f -fill both -expand yes
138  set small font_Small
139  label $w.b.label -text "Up to move:" -font $small
140  pack $w.b.label -side left
141  foreach i {5 10 15 20 25 30 35 40} {
142  radiobutton $w.b.m$i -text $i -variable merge(ply) -value [expr {$i * 2}] \
143  -indicatoron 0 -padx 2 -pady 1 -font $small -command updateMergeGame
144  pack $w.b.m$i -side left
145  }
146  radiobutton $w.b.all -text [::utils::string::Capital $::tr(all)] \
147  -variable merge(ply) -value 1000 -indicatoron 0 -padx 2 -pady 1 \
148  -font $small -command updateMergeGame
149  pack $w.b.all -side left
150  dialogbutton $w.b.ok -text "OK" -command {
151  undoFeature save
152  sc_game merge $merge(base) $merge(gnum) $merge(ply)
153  catch {grab release .mergeDialog}
154  destroy .mergeDialog
155  updateBoard -pgn
156  }
157  dialogbutton $w.b.cancel -text $::tr(Cancel) \
158  -command "catch {grab release $w}; destroy $w"
159  packbuttons right $w.b.cancel $w.b.ok
160  grab $w
162 }
163 
164 proc updateMergeGame {args} {
165  global merge
166  set w .mergeDialog
167  if {! [winfo exists $w]} { return}
168  sc_game push copy
169  sc_game merge $merge(base) $merge(gnum) $merge(ply)
170  set pgn [sc_game pgn -indentV 1 -short 1 -width 60]
171  sc_game pop
172  $w.f.text configure -state normal
173  $w.f.text tag configure red -foreground darkRed
174  $w.f.text tag configure blue -foreground darkBlue
175  $w.f.text delete 1.0 end
176  foreach line [split $pgn "\n"] {
177  if {[string index $line 0] == " "} {
178  $w.f.text insert end $line blue
179  } else {
180  $w.f.text insert end $line
181  }
182  $w.f.text insert end "\n"
183  }
184  $w.f.text tag add red 1.0 4.0
185  #$w.f.text insert end $pgn
186  $w.f.text configure -state disabled
187 }
188 
189 # setExportText:
190 # Allows the user to modify the text printed at the start and end of a
191 # file for a particular export format
192 #
193 proc setExportText {exportType} {
194  global exportStartFile exportEndFile
195 
196  switch -- $exportType {
197  "PGN" {
198  set title "Set PGN file export text"
199  }
200  "HTML" {
201  set title "Set HTML file export text"
202  }
203  "LaTeX" {
204  set title "Set LaTeX file export text"
205  }
206  default {
207  return
208  }
209  }
210 
211  set w .setExportText$exportType
212  if {[winfo exists $w]} { return}
213  toplevel $w
214  wm title $w "Scid: $title"
215 
216  frame $w.buttons
217  pack $w.buttons -side bottom -fill x -anchor e
218 
219  set pane [::utils::pane::Create $w.pane start end 500 400]
220  ::utils::pane::SetRange $w.pane 0.3 0.7
221  pack $pane -side top -expand true -fill both
222  foreach f [list $pane.start $pane.end] type {start end} {
223  label $f.title -font font_Bold -text "Text at $type of $exportType file:"
224  text $f.text -wrap none -background white \
225  -yscroll "$f.ybar set" -xscroll "$f.xbar set"
226  scrollbar $f.ybar -orient vertical -command "$f.text yview"
227  scrollbar $f.xbar -orient horizontal -command "$f.text xview"
228  bind $f.text <FocusIn> {%W configure -background lightYellow}
229  bind $f.text <FocusOut> {%W configure -background white}
230  grid $f.title -row 0 -column 0 -sticky w
231  grid $f.text -row 1 -column 0 -sticky nesw
232  grid $f.ybar -row 1 -column 1 -sticky nesw
233  grid $f.xbar -row 2 -column 0 -sticky nesw
234  grid rowconfig $f 1 -weight 1 -minsize 0
235  grid columnconfig $f 0 -weight 1 -minsize 0
236  }
237 
238  $pane.start.text insert end $exportStartFile($exportType)
239  $pane.end.text insert end $exportEndFile($exportType)
240 
241  button $w.buttons.default -text "Reset to Default" -command "
242  $pane.start.text delete 1.0 end
243  $pane.start.text insert end \$default_exportStartFile($exportType)
244  $pane.end.text delete 1.0 end
245  $pane.end.text insert end \$default_exportEndFile($exportType)
246  "
247  dialogbutton $w.buttons.ok -text "OK" -command "
248  set exportStartFile($exportType) \[$pane.start.text get 1.0 end-1c\]
249  set exportEndFile($exportType) \[$pane.end.text get 1.0 end-1c\]
250  focus .
251  destroy $w
252  "
253  dialogbutton $w.buttons.cancel -text $::tr(Cancel) -command "focus .; destroy $w"
254  pack $w.buttons.default -side left -padx 5 -pady 2
255  pack $w.buttons.cancel $w.buttons.ok -side right -padx 5 -pady 2
256  focus $pane.start.text
257 }
258 
259 image create photo htmldiag0 -data {
260  R0lGODdhbgBkAIAAAAAAAP///ywAAAAAbgBkAAAC/oyPqcvtD6OctNqLs968+w+G4kiW5omm
261  6moAgQu/ckzPdo3fes7vfv5wsYQtBFF2OCqNzCPrs4xEi0mQEyWcApxbqhfpvYa2ZCNZeQ4y
262  k122YgqGNs7oMtu+aH9f6XT1vydm5ddCyIenlkB3KAgnePFIJzm5yECkRVmpuPbokflpaLl2
263  eKeHCNcRCQo6F3e52qY3Gve04QhbJkvrGYQb+jbrB8sHaJPi25mnGItLvDmRnLwnCpH1luUb
264  WGwpLdUsIdaFHLtdHe09bM45Lkw9p4uRXfHKbseFntibnk9fT/4XDR6kb+BKsfrkrFuhc+b2
265  OYhh0J+1Z+8U6ltVMGIm/kaTpnnL95DgQzPpMC6RJtCCPArMOmqsNDFjq4YYq5lZGKokxZEc
266  Vtok5pIkwl2p0NXsZZDUsmH3fmpIuWxeUKEHy828yo0dT6p5sk3sZrGrP6dWx3kMCRKYykhE
267  xcpD1fWpxK1tOX4LK9OtVneuliKjAnEEIqkMA9UrgjctTokCY+4a29fvL6OM2ZabW3co1peH
268  rwVb3DmM5lpSRlV2DHryrGPFEidqShrS59azz2Zw/TTyF0e168aG1ps3bRG4bz8pvqmH8h/M
269  lztvDj0wVuG7g/sW3Bv48Orbr7Purky3eOpgkMsenxcuX/XHs3NzzzG8NsJQ38EnG2Uq+rWa
270  /s7bVrvfRtwBxhIlLHWnEHUCklegfumtpgx5AloHjYHAMTjdahbeB46D+EG4Hoj68YaXh3Sx
271  B9IVrADo3TUTHmjVTHA5pFuCR70G4oeSaYZiRTemyGJcw72lIWWj2TckjKLRKN5FKypZHj/B
272  iBQZWFS6g2GIVI3Wo15HApljFTMSlKWLP4oyo45L8himkxuq2eJ+nKV0UoUvgvlfhmb2x2FI
273  JsL505hPDmjjoDx1qeWWEyK655d6tunMNGbt5N2kaF0Wlop7DejnX9qRJGWj++TnJpMUhVPf
274  bJhBOqehWqompmmQgbejT8Bgkup4s8aZ2pU71VGYK4xVp8qqLAJriREXw1LqpaV0xXeoqJ4C
275  Uuyuz2g62KvL5tnqmb8uhhS128Imra03iZvtsz2xikU8CFLInXkqvVsavZwyekKZTcArZ5Pt
276  6vutvf3GBjC7VrRX1HMKR8fwwg4bo26+/Eq4729FCUyxHEPcO7FpFtvSscC8DJExx9vI+3G/
277  JfNK1ncqh4zybyuvLEEBADs=
278 }
279 
280 image create photo htmldiag1 -data {
281  R0lGODdhbgBkAIQAAAAAAAsLCxYWFiAgICsrKzY2NkBAQEtLS1VVVWBgYGtra3V1dYCAgIuL
282  i5WVlaCgoKqqqrW1tcDAwMrKytXV1eDg4Orq6vX19f//////////////////////////////
283  /ywAAAAAbgBkAAAF/iAmjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEgsGo/IJBGAYTqb0Kc0
284  Sp1aq9irNst9vphLkYWAEFEEkFGEIkIQLJhxGUMhsDGQ9wis7MnNaCducH90diJ5cBgVQ3xC
285  AIVnaSMLiHqRh3h6GAgNUCsRBgd3NRIAp3ymqKcMe6gSKQdzkiIScAYKJJh3iW1zLBWoAzGO
286  GKqnI8eorSKrsCcAk7QiDG8GAA4kjIa8mwi/xSbKN8oS5g6rpwnm5SvTcAwAA6gFtrrbvZy/
287  LgWnk18llKUbSPCZCSbTIBjAEIGgvAQPSEjwNscCrHAmCJzaN0Ogw48GTSQUwMaCgFMH/lAJ
288  YJBAwEpFI76JIRChBYJVAmAU8/ixIAoABiZBIDlCAQACFfrJY2Qh3oAJMSsSmIRxBIR0w2zc
289  7PmRYwlFQ0lNOLXQwqoEjCaczEZn5j8VFU7i1CnoFLu7eM1tVAEmLIl5AARYMJuu1RkAv8a8
290  rYpBabocKV0AONDCL0MMD7juPTwpKCJmKMYSpHsiHoPTqFOnBgD6p2UEEa8JANyVzklSeIhW
291  dfwYRzzNy1gguDOoCS+uZdARsEo0BYWPpE38Bs56BZ/iwQrcudazZr+IEZp/KjF9YI7ymlur
292  KN6YrEa5HwUHG1bhzrYT3EcDLE2dlXVOmzTUX3AJAEAKAq1g/pSfeb4NqN4JCmwS14DCMARA
293  JQDCZMKCvUmGAnpcPVjChYqMgdxHbMijiSIYgYjKeQ7CoJEBGhGUy0etXFPBYKBAt590MfIV
294  h0XVmVVAjQQcABVPZGFQYE1xXIQCfAMsEIE5MPYn4ldvPCdBeNk4RUID8WFgWhwEeJLCAqew
295  NUNV8Ui25R6yiEDAAC6J0A9UI/Bm3pl1jldCMMtFkAB3OJgo2SYp/HMYA3VEQ4KAKJpC2X0q
296  sEkbAyGxEI6JQBkg6qikjnoKoweJsOMiFBAKJSBc6bUQCYzFQ+YpA8xaQ0oUouROJiiEp5le
297  GFIQkQrTCWDAadGJQRuFA2hIax28/qg5ggV+gmSKYQLUxBiZNOUAaq+nShtTN4owVSNwFpDZ
298  ylQsmGJLA4fq2oIjLlIoIh/5DIeBUf2ZCUBNrzLR1IIDaPQsYyzkGyQK/ZYRzIBOGmiCSQH/
299  KDC5q+y7oi8i3KrlPFYlyKZmVc7ZMMcdQ0zRCBOUKvPMuCDSHIcEudlsECSCHOUNzU2mLAMN
300  5IVlHzLIhOZbM2CKKQ8M7wCG0orZTNwlZAAilHiCIu3117R2IfYWZI9tdtlo0xBJILldTUjW
301  3FhirhFrb42bh3VbLYICB7w9Syb5MBK1DgbDPdIducCQd9snUKAmtXK3YW0Ri1smw2SzsG05
302  HUTfB/nH/vo088IDpzUwN1+BHk7C3SxIo3lzjGzlDwYXAP6y4usGxvoKrtutKieDh22b75xU
303  IJpKcOBzu+grp1MAaaoXL5oM0SPwPIgGRSxGpyrgHHwJ1V+PzBfV63E8KttEcPsY3rYAYlaS
304  lQ/H9DB4xjgGCyygyAPwAWUu1fByQVMG4pUV2M8y+dvfSXQCFq7F4QG5UwlEKCGVfzCsAg3o
305  3yqqxCfrNPBuFoDgi2RgmQTAQVhceYouAtg8zRTgaY1qjgkZokG6vKYVlAIOn6qGhwShAGDU
306  EYyQbmghBr3gNXpYWArtRLwTTGxACeBdc4qjxO81w18ZMkavTqi3rlGjV8tJ/gFi3KZF/SRt
307  ExSQWTqUVar7bO4EDyhVBOVRKsrYBI1qtOInisOjg6zCXiWwjOBa4BGVpSqLfRyRHtuANfuQ
308  Ih2AZA5xDCmRgVDSBHzMRH1coZMI+c0MmcjhKdRFvOIED4j06CTW/nYHAcVAf2hi5QjmWIkH
309  lBJVK3hiOjrYAljuYpbj81AsQUmK5wwkJ5JkJEwGl68oCvOXZhgh7mRJCYdACYmE4B4KqhiY
310  GEBTBCfTIyQMB7iaeK864SHjGDwRNV0OBIY/gSYEzClNF6TOdnD4yEIeoE64xasn2kTBPdHV
311  hHp6Shr4tJNDMKTMYTLPOT3ZHTQQSlAMrGsGn8tH/hHXeKBVxkB26QgjDDLKKErRhaTSoqU2
312  PkmHiAzOna8ACEpLUKMYzDQOETgNQQZwGoOs7VUoqEBOC0SQBHAKniJJKE51Gsx7YbEXFiAq
313  cFYiArZMAyMUyFZPCsDLgzz1ElJdBQ2gOkfN/GIaKDhMr4DaKKw5hDT5EBmFoIJWL/KqV8iE
314  RuQwINcOHZFR50wPBg4glC2xDAAB3SsGAquTfKSBdKqJrGQ5RQK/hGOymFUNUqOxicdi9pWK
315  QEDicPBGIsCSE6PFwXUqwoALiCACbmrAJJrCJwq0tote/MFqxXBbhugsaRXsYiYz10QlALCU
316  OwPCImmwXLqk7blniy50waebXN1qTbgeHd5elfZQsN1Afg5NyPpOJ7UiGOh1/STudqWSIu/i
317  AL0Nrdz6WMgz815zitkVb2iD21331gCb4dXcfJlW3zAAWL77dYsZBunf/+KXpfr1GQ/rgNTy
318  LuHBARbKgInZ3wbDYBvDvS7ojsvhMJg4xNodMX8/12EPvwDFEQ7d0kqMgMQSzrwwFnCCZxy3
319  LDbXxfnVsYQD+Dn2PMK8M1GvihXcYyP/2MUIHjJF40veGy8hyjKecCYyKSUYhAAAOw==
320 }
321 
322 # exportOptions:
323 # Prompts the user to select exporting options.
324 #
325 proc exportOptions {exportType} {
326  global exportFlags
327 
328  set w .exportFlagsWin
329  set exportFlags(ok) -1
330  toplevel $w
331  wm title $w "Scid: [tr OptionsExport]"
332  # wm transient $w .
333  wm protocol $w WM_DELETE_WINDOW { }
334  bind $w <Escape> "$w.b.cancel invoke"
335  bind $w <Return> "$w.b.ok invoke"
336  bind $w <F1> {helpWindow Export}
337 
338  pack [frame $w.o] -side top -fill x -pady 5 -padx 5
339  label $w.o.append -text $::tr(AddToExistingFile)
340  radiobutton $w.o.appendYes -text $::tr(Yes) \
341  -variable exportFlags(append) -value 1
342  radiobutton $w.o.appendNo -text $::tr(No) \
343  -variable exportFlags(append) -value 0
344  label $w.o.comments -text $::tr(ExportComments)
345  radiobutton $w.o.commentsOn -text $::tr(Yes) \
346  -variable exportFlags(comments) -value 1
347  radiobutton $w.o.commentsOff -text $::tr(No) \
348  -variable exportFlags(comments) -value 0
349  label $w.o.stripMarks -text $::tr(ExportStripMarks)
350  radiobutton $w.o.stripMarksOn -text $::tr(Yes) \
351  -variable exportFlags(stripMarks) -value 1
352  radiobutton $w.o.stripMarksOff -text $::tr(No) \
353  -variable exportFlags(stripMarks) -value 0
354  label $w.o.indentc -text $::tr(IndentComments)
355  radiobutton $w.o.indentcOn -text $::tr(Yes) \
356  -variable exportFlags(indentc) -value 1
357  radiobutton $w.o.indentcOff -text $::tr(No) \
358  -variable exportFlags(indentc) -value 0
359  label $w.o.vars -text $::tr(ExportVariations)
360  radiobutton $w.o.varsOn -text $::tr(Yes) -variable exportFlags(vars) -value 1
361  radiobutton $w.o.varsOff -text $::tr(No) -variable exportFlags(vars) -value 0
362  label $w.o.indentv -text $::tr(IndentVariations)
363  radiobutton $w.o.indentvOn -text $::tr(Yes) \
364  -variable exportFlags(indentv) -value 1
365  radiobutton $w.o.indentvOff -text $::tr(No) \
366  -variable exportFlags(indentv) -value 0
367  label $w.o.column -text $::tr(ExportColumnStyle)
368  radiobutton $w.o.columnOn -text $::tr(Yes) \
369  -variable exportFlags(column) -value 1
370  radiobutton $w.o.columnOff -text $::tr(No) \
371  -variable exportFlags(column) -value 0
372  label $w.o.symbols -text $::tr(ExportSymbolStyle)
373  radiobutton $w.o.symbolsOn -text "! +=" \
374  -variable exportFlags(symbols) -value 1
375  radiobutton $w.o.symbolsOff -text {$2 $14} \
376  -variable exportFlags(symbols) -value 0
377  grid $w.o.append -row 0 -column 0 -sticky w
378  grid $w.o.appendYes -row 0 -column 1 -sticky w
379  grid $w.o.appendNo -row 0 -column 2 -sticky w
380  grid $w.o.comments -row 1 -column 0 -sticky w
381  grid $w.o.commentsOn -row 1 -column 1 -sticky w
382  grid $w.o.commentsOff -row 1 -column 2 -sticky w
383  grid $w.o.stripMarks -row 2 -column 0 -sticky w
384  grid $w.o.stripMarksOn -row 2 -column 1 -sticky w
385  grid $w.o.stripMarksOff -row 2 -column 2 -sticky w
386  grid $w.o.indentc -row 3 -column 0 -sticky w
387  grid $w.o.indentcOn -row 3 -column 1 -sticky w
388  grid $w.o.indentcOff -row 3 -column 2 -sticky w
389  grid $w.o.vars -row 4 -column 0 -sticky w
390  grid $w.o.varsOn -row 4 -column 1 -sticky w
391  grid $w.o.varsOff -row 4 -column 2 -sticky w
392  grid $w.o.indentv -row 5 -column 0 -sticky w
393  grid $w.o.indentvOn -row 5 -column 1 -sticky w
394  grid $w.o.indentvOff -row 5 -column 2 -sticky w
395  grid $w.o.column -row 6 -column 0 -sticky w
396  grid $w.o.columnOn -row 6 -column 1 -sticky w
397  grid $w.o.columnOff -row 6 -column 2 -sticky w
398  grid $w.o.symbols -row 7 -column 0 -sticky w
399  grid $w.o.symbolsOn -row 7 -column 1 -sticky w
400  grid $w.o.symbolsOff -row 7 -column 2 -sticky w
401 
402  # Extra option for PGN format: handling of null moves
403  if {$exportType == "PGN"} {
404  label $w.o.space -text ""
405  grid $w.o.space -row 8 -column 0 -sticky w
406  label $w.o.nullMoves -text "Convert null moves to comments"
407  radiobutton $w.o.convertNullMoves -text $::tr(Yes) \
408  -variable exportFlags(convertNullMoves) -value 1
409  radiobutton $w.o.keepNullMoves -text $::tr(No) \
410  -variable exportFlags(convertNullMoves) -value 0
411  grid $w.o.nullMoves -row 9 -column 0 -sticky w
412  grid $w.o.convertNullMoves -row 9 -column 1 -sticky w
413  grid $w.o.keepNullMoves -row 9 -column 2 -sticky w
414  }
415 
416  # Extra option for HTML format: diagram image set
417  if {$exportType == "HTML"} {
418  label $w.o.space -text ""
419  label $w.o.hdiag -text "Diagram"
420  radiobutton $w.o.hb0 -text "bitmaps" \
421  -variable exportFlags(htmldiag) -value 0
422  radiobutton $w.o.hb1 -text "bitmaps2" \
423  -variable exportFlags(htmldiag) -value 1
424  label $w.o.hl0 -image htmldiag0
425  label $w.o.hl1 -image htmldiag1
426  grid $w.o.space -row 8 -column 0
427  grid $w.o.hdiag -row 9 -column 0 -sticky w
428  grid $w.o.hb0 -row 9 -column 1 -sticky w
429  grid $w.o.hb1 -row 9 -column 2 -sticky w
430  grid $w.o.hl0 -row 10 -column 1
431  grid $w.o.hl1 -row 10 -column 2
432  }
433 
435  pack [frame $w.b] -side top
436  dialogbutton $w.b.ok -text "OK" -command {
437  set exportFlags(ok) 1
438  }
439  dialogbutton $w.b.cancel -text $::tr(Cancel) -command {
440  set exportFlags(ok) 0
441  }
442  pack $w.b.ok $w.b.cancel -side left -padx 5 -pady 5
443 
444  wm withdraw $w
445  update idletasks
446  set x [expr {[winfo screenwidth $w]/2 - [winfo reqwidth $w]/2 \
447  - [winfo vrootx [winfo parent $w]]}]
448  set y [expr {[winfo screenheight $w]/2 - [winfo reqheight $w]/2 \
449  - [winfo vrooty [winfo parent $w]]}]
450  wm geom $w +$x+$y
451  wm deiconify $w
452 
453  grab $w
454  tkwait variable exportFlags(ok)
455  grab release $w
456  destroy $w
457  return $exportFlags(ok)
458 }
459 
460 # exportGames:
461 # exports current game or all filtered games to a new PGN, LaTeX or Html file.
462 #
463 proc exportGames {selection exportType} {
464  global ::pgn::moveNumberSpaces exportStartFile exportEndFile exportFlags
465  if {$selection == "filter" && [sc_filter count] == 0} {
466  tk_messageBox -title "Scid: Filter empty" -type ok -icon info \
467  -message "The filter contains no games."
468  return
469  }
470 
471  if {[exportOptions $exportType] == 0} { return}
472  sc_info html $exportFlags(htmldiag)
473 
474  switch -- $exportType {
475  "PGN" {
476  set ftype {
477  { "PGN files" {".pgn"} }
478  { "All files" {"*"} }
479  }
480  set title "a PGN file"
481  set idir $::initialDir(base)
482  set default ".pgn"
483  }
484  "HTML" {
485  set ftype {
486  { "HTML files" {".html" ".htm"} }
487  { "All files" {"*"} }
488  }
489  set title "an HTML file"
490  set idir $::initialDir(html)
491  set default ".html"
492  }
493  "LaTeX" {
494  set ftype {
495  { "LaTeX files" {".tex" ".ltx"} }
496  { "All files" {"*"} }
497  }
498  set title "a LaTeX file"
499  set idir $::initialDir(tex)
500  set default ".tex"
501  }
502  default { return}
503  }
504 
505  if {$exportFlags(append)} {
506  set getfile tk_getOpenFile
507  set title "Add games to $title"
508  } else {
509  set getfile tk_getSaveFile
510  set title "Create $title"
511  }
512  set fName [$getfile -initialdir $idir -filetypes $ftype -defaultextension $default -title $title]
513  if {$fName == ""} { return}
514 
515  progressWindow "Scid" "Exporting games..." $::tr(Cancel)
516  sc_base export $selection $exportType $fName -append $exportFlags(append) \
517  -starttext $exportStartFile($exportType) \
518  -endtext $exportEndFile($exportType) \
519  -comments $exportFlags(comments) -variations $exportFlags(vars) \
520  -space $::pgn::moveNumberSpaces -symbols $exportFlags(symbols) \
521  -indentC $exportFlags(indentc) -indentV $exportFlags(indentv) \
522  -column $exportFlags(column) -noMarkCodes $exportFlags(stripMarks) \
523  -convertNullMoves $exportFlags(convertNullMoves)
525 }
526 
527 ###########################################################################
528 ### Global variables used in gameSave:
529 set date 0; set year 0; set month 0; set day 0; set white 0; set black 0
530 set resultVal 0; set event 0; set site 0; set round 0
531 set whiteElo 0; set blackElo 0; set eco 0; set extraTags ""
532 set whiteRType "Elo"; set blackRType "Elo"
533 set edate 0; set eyear 0; set emonth 0; set eday 0
534 
535 # Traces on game-save dialog variables to ensure sane values:
536 
537 trace variable resultVal w ::utils::validate::Result
538 trace variable whiteElo w {::utils::validate::Integer [sc_info limit elo] 0}
539 trace variable blackElo w {::utils::validate::Integer [sc_info limit elo] 0}
540 trace variable year w {::utils::validate::Integer [sc_info limit year] 1}
541 trace variable month w {::utils::validate::Integer 12 1}
542 trace variable day w {::utils::validate::Integer 31 1}
543 trace variable eyear w {::utils::validate::Integer [sc_info limit year] 1}
544 trace variable emonth w {::utils::validate::Integer 12 1}
545 trace variable eday w {::utils::validate::Integer 31 1}
546 
547 set gsaveNum 0
548 set i 0; set j 0
549 set temp 0
550 
551 array set nameMatches {}
552 set nameMatchCount 0
553 
554 # updateMatchList:
555 # Called from gameSave to update the matching name list as the user
556 # types a player/site/event/round name.
557 #
558 proc updateMatchList { tw nametype maxMatches name el op } {
559  global nameMatches nameMatchCount
560  global $name editNameType
561  if {![winfo exists $tw]} return
562 
563  if {$nametype == ""} { set nametype $editNameType}
564  if {$nametype == "rating"} { set nametype "player"}
565  set val [set $name]
566  $tw configure -state normal
567  $tw delete 0.0 end
568  set matches {}
569  catch {set matches [sc_name match $nametype $val $maxMatches]}
570  set count [llength $matches]
571  set nameMatchCount [expr {$count / 2}]
572  for {set i 0} { $i < $count } {incr i 2} {
573  set nameMatchCount [expr {($i / 2) + 1}]
574  set nameMatches($nameMatchCount) [lindex $matches [expr {$i + 1}]]
575  set str "$nameMatchCount:\t[lindex $matches $i]\t$nameMatches($nameMatchCount)\n"
576  $tw insert end $str
577  }
578  $tw configure -state disabled
579 }
580 
581 proc clearMatchList { tw } {
582  global nameMatches nameMatchCount
583  set nameMatchCount 0
584  $tw configure -state normal
585  $tw delete 0.0 end
586  $tw configure -state disabled
587 }
588 
589 # Traces to update the match list as names are typed in:
590 
591 trace variable event w { updateMatchList .save.g.list e 9 }
592 trace variable site w { updateMatchList .save.g.list s 9 }
593 trace variable white w { updateMatchList .save.g.list p 9 }
594 trace variable black w { updateMatchList .save.g.list p 9 }
595 trace variable round w { updateMatchList .save.g.list r 9 }
596 
597 set editName ""
598 set editNameNew ""
599 set editNameType "player"
600 set editNameSelect "all"
601 set editNameRating ""
602 set editNameRType "Elo"
603 set editDate ""
604 set editDateNew ""
605 
606 trace variable editNameRating w {::utils::validate::Integer [sc_info limit elo] 0}
607 trace variable editName w { updateMatchList .nedit.g.list "" 9 }
608 trace variable editDate w ::utils::validate::Date
609 trace variable editDateNew w ::utils::validate::Date
610 
611 proc editNameNewProc { tw nametype maxMatches name el op } {
612  global editNameNew
613  if {! [winfo exists .nedit]} { return}
614  if {[string compare $editNameNew ""]} {
615  .nedit.buttons.replace configure -state normal
616  } else {
617  .nedit.buttons.replace configure -state disabled
618  }
619  catch {updateMatchList $tw $nametype $maxMatches $name $el $op}
620 }
621 
622 trace variable editNameNew w { editNameNewProc .nedit.g.list "" 9 }
623 
624 
625 set nameEditorWin 0
626 
627 proc makeNameEditor {} {
628  if {! [winfo exists .nedit]} { nameEditor}
629 }
630 
631 proc setNameEditorType {type} {
632  if {! [winfo exists .nedit]} { return}
633  catch {.nedit.typeButtons.$type invoke}
634 }
635 
636 proc nameEditor {} {
637  global editName editNameType editNameNew nameEditorWin editNameSelect
638  global editNameRating editDate editDateNew
639 
640  set w .nedit
641  if {[winfo exists $w]} {
642  destroy $w
643  return
644  }
645  toplevel $w
646  wm title $w "Scid: [tr FileMaintNameEditor]"
647  set nameEditorWin 1
648  setWinLocation $w
649  bind $w <Configure> "recordWinSize $w"
650 
651  label $w.typeLabel -textvar ::tr(NameEditType:) -font font_Bold
652  frame $w.typeButtons
653  pack $w.typeLabel $w.typeButtons -side top -pady 5
654  foreach i { "Player" "Event" "Site" "Round"} {
655  set j [string tolower $i]
656  radiobutton $w.typeButtons.$j -textvar ::tr($i) -variable editNameType \
657  -value $j -indicatoron false -pady 5 -padx 5 -command {
658  grid remove .nedit.g.ratingE
659  grid remove .nedit.g.rtype
660  grid remove .nedit.g.fromD
661  grid remove .nedit.g.toD
662  grid .nedit.g.toL -row 1 -column 1 -sticky e
663  grid .nedit.g.fromE -row 0 -column 2 -sticky w
664  grid .nedit.g.toE -row 1 -column 2 -sticky w
665  }
666  pack $w.typeButtons.$j -side left -padx 5
667  }
668  radiobutton $w.typeButtons.rating -textvar ::tr(Rating) -variable editNameType \
669  -value rating -indicatoron false -pady 5 -padx 5 -command {
670  grid remove .nedit.g.toE
671  grid remove .nedit.g.toL
672  grid remove .nedit.g.fromD
673  grid remove .nedit.g.toD
674  grid .nedit.g.fromE -row 0 -column 2 -sticky w
675  grid .nedit.g.rtype -row 1 -column 0 -columnspan 2 -sticky e
676  grid .nedit.g.ratingE -row 1 -column 2 -sticky w
677  }
678  radiobutton $w.typeButtons.date -textvar ::tr(Date) -variable editNameType \
679  -value date -indicatoron false -pady 5 -padx 5 -command {
680  grid remove .nedit.g.toE
681  grid remove .nedit.g.fromE
682  grid remove .nedit.g.ratingE
683  grid remove .nedit.g.rtype
684  grid .nedit.g.fromD -row 0 -column 2 -sticky w
685  grid .nedit.g.toL -row 1 -column 1 -sticky e
686  grid .nedit.g.toD -row 1 -column 2 -sticky w
687  }
688  radiobutton $w.typeButtons.edate -textvar ::tr(EventDate) \
689  -variable editNameType -value edate -indicatoron false -pady 5 -padx 5 \
690  -command {
691  grid remove .nedit.g.toE
692  grid remove .nedit.g.fromE
693  grid remove .nedit.g.ratingE
694  grid remove .nedit.g.rtype
695  grid .nedit.g.fromD -row 0 -column 2 -sticky w
696  grid .nedit.g.toL -row 1 -column 1 -sticky e
697  grid .nedit.g.toD -row 1 -column 2 -sticky w
698  }
699  pack $w.typeButtons.rating $w.typeButtons.date $w.typeButtons.edate \
700  -side left -padx 5
701 
702  addHorizontalRule .nedit
703 
704  label $w.selectLabel -textvar ::tr(NameEditSelect) -font font_Bold
705  frame $w.selectButtons
706  pack $w.selectLabel $w.selectButtons -side top -pady 5
707  foreach i {all filter crosstable} row {0 1 2} text {
708  SelectAllGames
709  SelectFilterGames
710  SelectTournamentGames
711  } {
712  radiobutton $w.selectButtons.$i -textvar ::tr($text) \
713  -variable editNameSelect -value $i
714  grid $w.selectButtons.$i -row $row -column 0 -sticky w
715  }
716 
718 
719  pack [frame $w.g] -side top
720  label $w.g.space -text " "
721  grid $w.g.space $w.g.space -row 0 -column 0
722  label $w.g.fromL -textvar ::tr(NameEditReplace:) -font font_Bold -anchor e
723  entry $w.g.fromE -width 40 -background white -relief sunken \
724  -textvariable editName
725  entry $w.g.fromD -width 15 -background white -relief sunken \
726  -textvariable editDate
727  grid $w.g.fromL -row 0 -column 1 -sticky e
728  grid $w.g.fromE -row 0 -column 2 -sticky we
729 
730  label $w.g.toL -textvar ::tr(NameEditWith:) -font font_Bold -anchor e
731  entry $w.g.toE -width 40 -background white -relief sunken \
732  -textvariable editNameNew
733  entry $w.g.toD -width 15 -background white -relief sunken \
734  -textvariable editDateNew
735  grid $w.g.toL -row 1 -column 1 -sticky e
736  grid $w.g.toE -row 1 -column 2 -sticky we
737 
738  entry $w.g.ratingE -width 5 -background white -relief sunken \
739  -textvariable editNameRating -justify right
740  eval tk_optionMenu $w.g.rtype editNameRType [sc_info ratings]
741  $w.g.rtype configure -pady 2
742 
743  label $w.g.title -textvar ::tr(NameEditMatches) \
744  -font font_Bold
745  text $w.g.list -height 9 -width 40 -relief sunken \
746  -background grey90 -tabs {2c right 2.5c left} -wrap none
747 
748  label $w.g.padding -text ""
749  grid $w.g.padding -row 2 -column 0
750 
751  grid $w.g.title -row 3 -column 1 -columnspan 2 -sticky n
752  grid $w.g.list -row 4 -column 1 -rowspan 9 -columnspan 2 -sticky n
753 
754  updateMatchList $w.g.list "" 9 editName "" w
755 
756  foreach i {fromE toE ratingE fromD toD} {
757  bind $w.g.$i <FocusIn> { %W configure -background lightYellow }
758  bind $w.g.$i <FocusOut> { %W configure -background white }
759  }
760  foreach {i j} {.nedit.g.fromE "editName" .nedit.g.toE "editNameNew" } {
761  for {set z 1} {$z <= 9} {incr z} {
762  bind $i [format "<Control-Key-%d>" $z] \
763  [format "eval {if {\$nameMatchCount >= %d} { \
764  set %s \$nameMatches(%d)}}; break" $z $j $z]
765  }
766  }
767 
769 
770  frame $w.buttons
771  button $w.buttons.replace -textvar ::tr(NameEditReplace) -command {
772  if {$editNameType == "rating"} {
773  set err [catch {sc_name edit $editNameType $editNameSelect $editName $editNameRating $editNameRType} result]
774  } elseif {$editNameType == "date" || $editNameType == "edate"} {
775  set err [catch {sc_name edit $editNameType $editNameSelect $editDate $editDateNew} result]
776  } else {
777  set err [catch {sc_name edit $editNameType $editNameSelect $editName $editNameNew} result]
778  }
779  if {$err} {
780  ERROR::MessageBox
781  } else {
782  .nedit.status configure -text $result
783  }
784  sc_game tags reload
785  updateBoard -pgn
786  ::windows::gamelist::Refresh
787  }
788 
789  dialogbutton $w.buttons.cancel -textvar ::tr(Close) -command {focus .; destroy .nedit}
790  pack $w.buttons -side top -pady 5
791  pack $w.buttons.replace $w.buttons.cancel -side left -padx 10
792 
793  label $w.status -text "" -width 1 -font font_Small -relief sunken -anchor w
794  pack $w.status -side bottom -fill x
795 
796  wm resizable $w 0 0
797  bind $w <Escape> { focus .; destroy .nedit }
798  bind $w <Return> {.nedit.buttons.replace invoke}
799  bind $w <Destroy> {set nameEditorWin 0}
800  bind $w <F1> {helpWindow Maintenance Editing}
801  focus $w
802  $w.typeButtons.$editNameType invoke
803 }
804 
805 
806 # addGameSaveEntry:
807 # used in gameSave for setting up the simpler labels and entry boxes.
808 #
809 proc addGameSaveEntry { name row textname } {
810  ttk::label .save.g.label$name -textvar $textname
811  ttk::entry .save.g.entry$name -width 30 -textvariable $name
812  grid .save.g.label$name -row $row -column 0 -sticky w
813  grid .save.g.entry$name -row $row -column 1 -columnspan 7 -sticky w
814 }
815 
816 # gameSave:
817 # The game save dialog. Used for adding and replacing games. If the
818 # value gnum is zero, it is to add a new game; otherwise it is to
819 # replace game number gnum.
820 #
821 proc gameSave { gnum } {
822  global date year month day white black resultVal event site round
823  global whiteElo blackElo whiteRType blackRType eco extraTags gsaveNum
824  global edate eyear emonth eday
825 
826  # Make a new toplevel that contains the game save dialog:
827  set w .save
828  if {[winfo exists $w]} { return}
829  toplevel $w
830  if {$gnum == 0} {
831  wm title $w "Scid: [tr GameAdd]"
832  pack [ttk::frame $w.refdb] -side top -fill x
833  CreateSelectDBWidget "$w.refdb" "gameSave_toBase" [sc_base current] 0
835  } else {
836  wm title $w "Scid: [tr GameReplace]"
837  }
838  set gsaveNum $gnum
839  catch {grab $w}
840 
841  set f [ttk::frame $w.g]
842  pack $f -side top
843 
844  ttk::label $f.title -textvar ::tr(NameEditMatches)
845  text $f.list -height 9 -width 40 -relief sunken -background grey90 \
846  -tabs {2c right 2.5c left} -wrap none
847 
848  # Get current values of tags:
849  set year [sc_game tag get Year]; set eyear [sc_game tag get EYear]
850  set month [sc_game tag get Month]; set emonth [sc_game tag get EMonth]
851  set day [sc_game tag get Day]; set eday [sc_game tag get EDay]
852  set white [sc_game tag get White]; set black [sc_game tag get Black]
853  set event [sc_game tag get Event]; set site [sc_game tag get Site]
854  set resultVal [sc_game tag get Result]; set round [sc_game tag get Round]
855  set whiteElo [sc_game tag get WhiteElo]
856  set blackElo [sc_game tag get BlackElo]
857  set whiteRType [sc_game tag get WhiteRType]
858  set blackRType [sc_game tag get BlackRType]
859  set eco [sc_game tag get ECO]
860  set extraTags [sc_game tag get Extra]
861  if {[::board::isFlipped .main.board]} {
862  regsub -all {FlipB "[01]"\n} $extraTags {} extraTags
863  append extraTags "FlipB \"1\"\n"
864  } else {
865  regexp {FlipB "([01])"\n} $extraTags -> flipB
866  if {[info exists flipB] && $flipB} {
867  regsub -all {FlipB "[01]"\n} $extraTags {} extraTags
868  }
869  }
870  clearMatchList $f.list
871 
872  # Use question marks instead of zero values in date:
873  if {$year == 0} { set year "????"}
874  if {$month == 0} { set month "??"}
875  if {$day == 0} { set day "??"}
876  if {$eyear == 0} { set eyear "????"}
877  if {$emonth == 0} { set emonth "??"}
878  if {$eday == 0} { set eday "??"}
879 
880  addGameSaveEntry event 0 ::tr(Event:)
881  addGameSaveEntry site 1 ::tr(Site:)
882 
883  ttk::frame $f.dateframe
884  ttk::label $f.datelabel -textvar ::tr(Date:)
885  ttk::entry $f.dateyear -width 6 -textvariable year -justify right ;# -background white -relief sunken
886  ttk::label $f.datedot1 -text "."
887  ttk::entry $f.datemonth -width 3 -textvariable month -justify right
888  ttk::label $f.datedot2 -text "."
889  ttk::entry $f.dateday -width 3 -textvariable day -justify right
890  grid $f.datelabel -row 2 -column 0 -sticky w
891  grid $f.dateframe -row 2 -column 1 -columnspan 5 -sticky w
892  ttk::button $f.datechoose -image tb_calendar -style Pad0.Small.TButton -command {
893  set newdate [::utils::date::chooser "$year-$month-$day"]
894  if {[llength $newdate] == 3} {
895  set year [lindex $newdate 0]
896  set month [lindex $newdate 1]
897  set day [lindex $newdate 2]
898  }
899  }
900  ttk::button $f.today -textvar ::tr(Today) -command {
901  set year [::utils::date::today year]
902  set month [::utils::date::today month]
903  set day [::utils::date::today day]
904  }
905  pack $f.dateyear $f.datedot1 $f.datemonth $f.datedot2 $f.dateday \
906  -in $f.dateframe -side left
907  if {$::tcl_version >= 8.3} {
908  pack $f.datechoose -in $f.dateframe -side left
909  }
910  pack $f.today -in $f.dateframe -side left
911 
912  ttk::frame $f.edateframe
913  ttk::label $f.edatelabel -textvar ::tr(EventDate:)
914  ttk::entry $f.edateyear -width 6 -textvariable eyear -justify right
915  ttk::label $f.edatedot1 -text "."
916  ttk::entry $f.edatemonth -width 3 -textvariable emonth -justify right
917  ttk::label $f.edatedot2 -text "."
918  ttk::entry $f.edateday -width 3 -textvariable eday -justify right
919  grid $f.edatelabel -row 3 -column 0 -sticky w
920  grid $f.edateframe -row 3 -column 1 -columnspan 5 -sticky w
921  ttk::button $f.edatechoose -image tb_calendar -style Pad0.Small.TButton -command {
922  set newdate [::utils::date::chooser "$eyear-$emonth-$eday"]
923  if {[llength $newdate] == 3} {
924  set eyear [lindex $newdate 0]
925  set emonth [lindex $newdate 1]
926  set eday [lindex $newdate 2]
927  }
928  }
929  ttk::button $f.esame -text "=$::tr(Date)" -command {
930  set eyear $year
931  set emonth $month
932  set eday $day
933  }
934  pack $f.edateyear $f.edatedot1 $f.edatemonth $f.edatedot2 $f.edateday \
935  -in $f.edateframe -side left
936  if {$::tcl_version >= 8.3} {
937  pack $f.edatechoose -in $f.edateframe -side left
938  }
939  pack $f.esame -in $f.edateframe -side left
940 
941  addGameSaveEntry round 4 ::tr(Round:)
942  addGameSaveEntry white 5 ::tr(White:)
943  addGameSaveEntry black 6 ::tr(Black:)
944 
945  ttk::label $f.reslabel -textvar ::tr(Result:)
946  ttk::entry $f.resentry -width 2 -textvariable resultVal
947  ttk::label $f.rescomment -text "(1, =, 0, *)"
948  grid $f.reslabel -row 7 -column 0 -sticky w
949  grid $f.resentry -row 7 -column 1 -sticky w
950  grid $f.rescomment -row 7 -column 2 -columnspan 4 -sticky w
951 
952  ttk::label $f.welolabel -text "$::tr(White) "
953 
954  ttk::combobox $f.wrtype -values [sc_info ratings] -width 7 -textvariable whiteRType
955 
956  ttk::entry $f.weloentry -width 5 -textvariable whiteElo -justify right
957 
958  ttk::label $f.belolabel -text "$::tr(Black) "
959 
960  ttk::combobox $f.brtype -values [sc_info ratings] -width 7 -textvariable blackRType
961 
962  ttk::entry $f.beloentry -width 5 -textvariable blackElo -justify right
963 
964  grid $f.welolabel -row 8 -column 0 -sticky w
965  grid $f.wrtype -row 8 -column 1 -sticky w
966  grid $f.weloentry -row 8 -column 2 -sticky w
967  grid $f.belolabel -row 9 -column 0 -sticky w
968  grid $f.brtype -row 9 -column 1 -sticky w
969  grid $f.beloentry -row 9 -column 2 -sticky w
970 
971  ttk::label $f.ecolabel -text "ECO Code:"
972  ttk::entry $f.ecoentry -width 6 -textvariable eco
973  grid $f.ecolabel -row 10 -column 0 -sticky w
974  grid $f.ecoentry -row 10 -column 1 -sticky w
975 
976  ttk::button $f.ecob -textvar ::tr(ClassifyGame) -command {set eco [sc_eco game]}
977  grid $f.ecob -row 10 -column 2 -sticky w
978 
979  grid $f.title -row 0 -column 8 -sticky n -padx 10
980  grid $f.list -row 1 -column 8 -rowspan 9 -sticky nw -padx 10
981 
982  addHorizontalRule .save
983 
984  ttk::label .save.extralabel -text "Extra Tags: (example format: Annotator \"Anand, V\") "
985  pack .save.extralabel -side top -fill x
986  ttk::frame .save.extra
987  text .save.extra.text -height 4 -width 40 -bg white -wrap none \
988  -yscrollcommand ".save.extra.scroll set"
989  # Override tab-binding for this text widget:
990  bind .save.extra.text <Key-Tab> "[bind all <Key-Tab>]; break"
991  ttk::scrollbar .save.extra.scroll -command ".save.extra.text yview" -takefocus 0
992  ttk::button .save.extra.last -text "Use\nlast\ngame's\ntags" -command {
993  set extraTags [sc_game tag get -last Extra]
994  .save.extra.text delete 1.0 end
995  .save.extra.text insert 1.0 $extraTags
996  }
997  pack .save.extra -side top -fill both -expand 1 -ipady 10
998  pack .save.extra.text -side left -fill both -expand 1
999  if {$gnum == 0} {
1000  pack .save.extra.last -side right -padx 10
1001  }
1002  pack .save.extra.scroll -side right -fill y
1003  .save.extra.text insert 1.0 $extraTags
1004 
1005  foreach i {entryevent entrysite dateyear datemonth dateday \
1006  entryround entrywhite entryblack resentry \
1007  weloentry beloentry ecoentry edateyear edatemonth edateday} {
1008  bind $f.$i <Return> {.save.buttons.save invoke}
1009  # bind $f.$i <FocusIn> {%W configure -background lightYellow }
1010  # bind $f.$i <FocusOut> {%W configure -background white }
1011  }
1012  bind .save.extra.text <FocusIn> {%W configure -background lightYellow }
1013  bind .save.extra.text <FocusOut> {%W configure -background white }
1014 
1015  # Bindings so Ctrl-1 to Ctrl-9 select a matching name in the player,
1016  # site, event and round entryboxes:
1017 
1018  set j 0
1019  foreach {i j} {entryevent "event" entrysite "site"
1020  entrywhite "white" entryblack "black"
1021  entryround "round" } {
1022  for {set z 1} {$z <= 9} {incr z} {
1023  bind $f.$i [format "<Control-Key-%d>" $z] \
1024  [format "eval {if {\$nameMatchCount >= %d} \
1025  {set %s \$nameMatches(%d)}}" $z $j $z]
1026  }
1027  }
1028 
1029  addHorizontalRule .save
1030 
1031  ttk::frame .save.buttons
1032  if {$gnum == 0} {
1033  ttk::button .save.buttons.prev -text "As last game" -command {
1034  }
1035  }
1036  dialogbutton .save.buttons.save -textvar ::tr(Save) -underline 0 -command {
1037  set extraTags [.save.extra.text get 1.0 end-1c]
1038  if { [gsave $gsaveNum] } {
1039  destroy .save
1040  } else {
1041  ERROR::MessageBox
1042  }
1043  }
1044  # bind .save <Alt-s> { .save.buttons.save invoke; break }
1045 
1046  dialogbutton .save.buttons.cancel -textvar ::tr(Cancel) -command {destroy .save}
1047  pack .save.buttons -side bottom -ipady 10 -fill both -expand 1
1048  if {$gnum == 0} {
1049  #pack .save.buttons.prev -side left -padx 10
1050  }
1051  packbuttons right .save.buttons.cancel .save.buttons.save
1052 
1053  bind .save <Escape> { focus .; destroy .save; }
1054  ::utils::win::Centre .save
1055  focus .save.g.entryevent
1056  .save.g.entryevent selection range 0 end
1057  if {$gnum > 0} { focus .save.buttons.save}
1058 }
1059 
1060 # gsave:
1061 # Called by gameSave when the user presses the "Save" button
1062 # to save the game. Attempts to save and reports the result.
1063 #
1064 proc gsave { gnum } {
1065  global date year month day white black resultVal event site round
1066  global whiteElo blackElo whiteRType blackRType eco extraTags
1067  global edate eyear emonth eday
1068 
1069  set date [format "%s.%s.%s" $year $month $day]
1070  set edate [format "%s.%s.%s" $eyear $emonth $eday]
1071  set extraTagsList [split $extraTags "\n"]
1072  sc_game tags set -event $event -site $site -date $date -round $round \
1073  -white $white -black $black -result $resultVal \
1074  -whiteElo $whiteElo -whiteRatingType $whiteRType \
1075  -blackElo $blackElo -blackRatingType $blackRType \
1076  -eco $eco -eventdate $edate -extra $extraTagsList
1077  if {$gnum != 0} {
1078  if { [catch {sc_game save $gnum}] } { return 0}
1081  } else {
1082  set ply [sc_pos location]
1083  if { [catch {sc_game save $gnum $::gameSave_toBase}] } { return 0}
1084  ::notify::DatabaseModified $::gameSave_toBase
1085  ::file::SwitchToBase $::gameSave_toBase 0
1086  ::game::Load [sc_base numGames $::gameSave_toBase] $ply
1087  }
1088  return 1
1089 }
1090 
1091 # gameAdd:
1092 # Calls gameSave with a game number of zero.
1093 #
1094 proc gameAdd {} { gameSave 0}
1095 
1096 proc gameAddToClipbase {} {
1097  if {[catch {sc_game save 0 $::clipbase_db}]} {
1099  }
1100  ::notify::DatabaseModified $::clipbase_db
1101 }
1102 
1103 # gameReplace:
1104 # Calls gameSave with the current game number, which should be nonzero.
1105 #
1106 proc gameReplace {} { gameSave [sc_game number]}
1107 
1108 
1109 # helpAbout:
1110 # Displays information about Scid.
1111 #
1112 proc helpAbout {} {
1113  ::utils::sound::PlaySound sound_move
1114  set str {}
1115  append str "Scid: Shane's chess information database\n\n"
1116  append str "Version $::scidVersion, $::scidVersionDate\n"
1117  append str "Copyright (C) 1999-2004 Shane Hudson\n"
1118  append str "Copyright (C) 2006-2009 Pascal Georges\n"
1119  append str "Copyright (C) 2008-2011 Alexander Wagner\n"
1120  append str "Copyright (C) 2011 Gerd Lorscheid\n"
1121  append str "Copyright (C) 2009-2016 Fulvio Benini\n"
1122  append str "\nScid is licenced under the\n"
1123  append str "GNU General Public License.\n"
1124 
1125  append str "\n\nUsing Tcl/Tk version: [info patchlevel]\n"
1126  append str "Loaded packages:\n"
1127  foreach {pkg} [lsort [package names]] {
1128  set ver [package provide $pkg]
1129  if {$ver != ""} { append str "$pkg\($ver), "}
1130  }
1131  regsub ", $" $str "." str
1132 
1133  tk_messageBox -title "About Scid" -message $str -type ok
1134 }
1135 
1136 
1137 proc MouseWheelRedirector {W X Y D} {
1138  # Generate an MWheel virtual event to the window that has the mouse pointer
1139  set w [winfo containing -displayof $W $X $Y]
1140  # Check for active "grab"
1141  set grabW [grab current $w]
1142  if {$grabW != ""} { set w $grabW}
1143  # For virtual events we can't use the attribute "-delta" and we get away
1144  # without a global variable by using instead "-data" which maps to %d
1145  event generate $w <<MWheel>> -data $D -rootx $X -rooty $Y
1146 }
1147 
1148 proc ShiftMouseWheelRedirector {W X Y D} {
1149  set w [winfo containing -displayof $W $X $Y]
1150  set grabW [grab current $w]
1151  if {$grabW != ""} { set w $grabW}
1152  event generate $w <<Shift-MWheel>> -data $D -rootx $X -rooty $Y
1153 }
1154 
1155 # On Windows, redirect mouse wheel events to those windows that have the
1156 # mouse pointer:
1157 # - Disable completely MouseWheel handling for all used classes. No class or
1158 # window should listen to MouseWheel to avoid double firing
1159 # - Any window that receives a MouseWheel redirects these events as MWheel
1160 # to the window with the mouse pointer
1161 # - Rebind all classes and windows that handle mouse wheel to MWheel events.
1162 # Bind code is from TCL 8.5
1163 # On Linux and Macs this redirection is not necessary
1164 
1165 if { [tk windowingsystem] == "win32" } {
1166  # Disable MouseWheel handling
1167  set mw_classes [list Text Listbox Treeview]
1168  foreach class $mw_classes { bind $class <MouseWheel> {}}
1169 
1170  # Transform MouseWheel events into MWheel
1171  bind all <MouseWheel> { MouseWheelRedirector %W %X %Y %D }
1172  bind all <Shift-MouseWheel> { ShiftMouseWheelRedirector %W %X %Y %D }
1173 
1174  # Bind classes to MWheel
1175  bind Listbox <<MWheel>> { %W yview scroll [expr {-(%d/120) * 4}] units}
1176  bind Treeview <<MWheel>> { %W yview scroll [expr {-(%d/120)}] units }
1177  bind Text <<MWheel>> {
1178  if {%d >= 0} { %W yview scroll [expr {-%d/3}] pixels
1179  } else { %W yview scroll [expr {(2-%d)/3}] pixels }
1180  }
1181 }
1182 
1183 
1184 #################
1185 # Open files and databases:
1186 
1187 # Check for arguments starting with "-" (or "/" on Windows):
1188 
1189 set loadAtStart(spell) 1
1190 set loadAtStart(eco) 1
1191 set loadAtStart(tb) 1
1192 
1193 proc getCommandLineOptions {} {
1194  global argc argv windowsOS loadAtStart
1195 
1196  if { $::macOS && ([string first "-psn" [lindex $argv 0]] == 0)} {
1197  # Remove Process Serial Number from argument list:
1198  set argv [lrange $argv 1 end]
1199  incr argc -1
1200  }
1201 
1202  while {$argc > 0} {
1203  set arg [lindex $argv 0]
1204  set firstChar [string index $arg 0]
1205  if {$firstChar == "-" || ($windowsOS && $firstChar == "/")} {
1206  # Seen option argument:
1207  incr argc -1
1208  set argv [lrange $argv 1 end]
1209 
1210  # Special argument "--" means no more options:
1211  if {$arg == "--"} { return}
1212 
1213  # Check for known option names:
1214  # -f (/f), -fast (/fast): Fast start with no tablebases, etc.
1215  # -xeco, -xe: Do not load ECO file.
1216  # -xspell, -xs: Do not load spellcheck file.
1217  # -xtb, -xt: Do not check tablebase directory.
1218 
1219  set argName [string range $arg 1 end]
1220  switch $argName {
1221  "f" -
1222  "fast" {
1223  ::splash::add "Fast start: no tablebases, ECO or spelling file loaded."
1224  set loadAtStart(spell) 0
1225  set loadAtStart(eco) 0
1226  set loadAtStart(tb) 0
1227  }
1228  "xt" -
1229  "xtb" {
1230  set loadAtStart(tb) 0
1231  }
1232  "xe" -
1233  "xeco" {
1234  set loadAtStart(eco) 0
1235  }
1236  "xs" -
1237  "xspell" {
1238  set loadAtStart(spell) 0
1239  }
1240  default {
1241  ::splash::add "Warning: unknown option: \"$arg\""
1242  }
1243  }
1244  } else {
1245  # Seen first non-option argument:
1246  return
1247  }
1248  }
1249 }
1250 
1252 
1253 # Try to find tablebases:
1254 if {$loadAtStart(tb)} {
1255  if {[sc_info tb]} {
1256  ::splash::add "Checking for endgame tablebase files..."
1257  set tbDirs {}
1258  foreach i {1 2 3 4} {
1259  if {$initialDir(tablebase$i) != ""} {
1260  if {$tbDirs != ""} { append tbDirs ";"}
1261  append tbDirs [file nativename $initialDir(tablebase$i)]
1262  }
1263  }
1264  set result 0
1265  if {$tbDirs != ""} {
1266  set result [sc_info tb $tbDirs]
1267  }
1268  if {$result == 0} {
1269  ::splash::add " No tablebases were found."
1270  } else {
1271  ::splash::add " Tablebases with up to $result pieces were found."
1272  }
1273  }
1274 }
1275 
1276 # Try to open the ECO classification file:
1277 set result 0
1278 set ecoFile_fullname [file nativename $ecoFile]
1279 
1280 if {$loadAtStart(eco)} {
1281  ::splash::add "Trying to load the ECO openings file..."
1282  if {[catch { sc_eco read $ecoFile_fullname} result]} {
1283  # Could not load, so try "scid.eco" in the current directory:
1284  if {[catch {sc_eco read "scid.eco"} result]} {
1285  # Neither attempt worked, so do not use ECO classification
1286  ::splash::add " Unable to open the ECO file: $ecoFile"
1287  } else {
1288  ::splash::add " ECO file \"./scid.eco\" loaded: $result positions."
1289  }
1290  } else {
1291  ::splash::add " ECO file \"[file tail $ecoFile_fullname]\" loaded: $result positions."
1292  }
1293 }
1294 
1295 ################################################################################
1296 # returns a list of all toplevel windows, except some that are utilities
1297 ################################################################################
1298 proc getTopLevel {} {
1299 
1300  set topl {}
1301  set exclude { ".glistExtra" ".menu" "." ".pgnPopup" }
1302  foreach c [winfo children .] {
1303  if { $c != [winfo toplevel $c] } { continue}
1304  # Tk report .__tk_filedialog as toplevel window even if the window has been closed
1305  if { [ lsearch $topl $c] == -1 && [ lsearch $exclude $c] == -1 && ![string match "\.__tk*" $c] } {
1306  lappend topl $c
1307  }
1308  }
1309  return $topl
1310 }
1311 ################################################################################
1312 #
1313 ################################################################################
1314 # showHideAllWindows:
1315 # Arranges for all major Scid windows to be shown/hidden
1316 # Should be called type = "iconify" or "deiconify"
1317 #
1318 proc showHideAllWindows {type} {
1319 
1320  # Don't do this if user option is off:
1321  if {! $::autoIconify} { return}
1322 
1323  # Some window managers like KDE generate Unmap events for other
1324  # situations like switching to another desktop, etc.
1325  # So if the main window is still mapped, do not iconify others:
1326  if {($type == "iconify") && ([winfo ismapped .main] == 1)} { return}
1327 
1328  # Now iconify/deiconify all the major Scid windows that exist:
1329  foreach w [getTopLevel] {
1330  # .baseWin .glistWin .pgnWin .tourney .maintWin \
1331  # .ecograph .crosstabWin .treeWin .analysisWin1 .anslysisWin2 \
1332  # .playerInfoWin .commentWin .repWin .statsWin .tbWin \
1333  # .sb .sh .sm .noveltyWin .emailWin .oprepWin .plist \
1334  # .rgraph .sgraph .importWin .helpWin .tipsWin
1335  if {[winfo exists $w]} { catch {wm $type $w}}
1336  }
1337 
1338 }
1339 
1340 proc raiseAllWindows {} {
1341  # Don't do this if auto-raise option is turned off:
1342  if {! $::autoRaise} { return}
1343 
1344  showHideAllWindows deiconify
1345 
1346  foreach w [getTopLevel] {
1347  # .baseWin .glistWin .pgnWin .tourney .maintWin \
1348  # .ecograph .crosstabWin .treeWin .analysisWin1 .anslysisWin2 \
1349  # .playerInfoWin .commentWin .repWin .statsWin .tbWin \
1350  # .sb .sh .sm .noveltyWin .emailWin .oprepWin .plist \
1351  # .rgraph .sgraph .importWin .helpWin .tipsWin
1352  if {[winfo exists $w]} { catch { raise $w}}
1353  }
1354 }
1355 
1356 proc CreateMainWin { mainWin } {
1357  createToplevel .main
1358  wm minsize $mainWin 0 0
1359  wm iconname $mainWin "Scid"
1360  wm protocol $mainWin WM_DELETE_WINDOW { ::file::Exit }
1361  $mainWin configure -menu .menu
1362  setWinLocation $mainWin
1363  bind $mainWin <Configure> "recordWinSize $mainWin"
1365  CreateMainBoard .main
1366 }
1367 
1368 if { $::docking::USE_DOCKING } {
1369  CreateMainWin .
1372 } else {
1373  CreateMainWin .main
1374  if {$startup(switcher)} { ::windows::switcher::Open}
1375  if {$startup(pgn)} { ::pgn::OpenClose}
1376  if {$startup(gamelist)} { ::windows::gamelist::Open}
1377  if {$startup(tree)} { ::tree::make}
1378  if {$startup(crosstable)} { crosstabWin}
1379  if {$startup(book)} { ::book::open}
1380 }
1383 
1384 update
1385 update idletasks
1386 
1387 if {$startup(stats)} { ::windows::stats::Open}
1388 if {$startup(finder)} { ::file::finder::Open}
1389 if {$startup(tip)} { ::tip::show}
1390 
1391 # Try to load the spellcheck file:
1392 if {$loadAtStart(spell)} {
1393  progressWindow "Scid - [tr Spellcheking]" "Loading $spellCheckFile ..."
1394  set err [catch {sc_name read $spellCheckFile} result]
1396 }
1397 
1398 
1399 after 1 {
1400  ::file::autoLoadBases.load
1401 
1402  # fullname:
1403  # Given a file name, returns its absolute name.
1404  #
1405  proc fullname {fname} {
1406  if {[file pathtype $fname] == "absolute"} { return $fname }
1407  set old [pwd]
1408  if {[catch {cd [file dirname $fname]}]} { return $fname }
1409  set fname [file join [pwd] [file tail $fname]]
1410  catch {cd $old}
1411  return $fname
1412  }
1413  # Loading a database if specified on the command line:
1414  foreach cmdbase $::argv {
1415  ::file::Open "[fullname $cmdbase]"
1416  }
1417 }
1418 
1419 
1420 ### End of file: end.tcl