Scid  4.6.5
header.tcl
Go to the documentation of this file.
1 ###
2 ### search/header.tcl: Header Search routines for Scid.
3 ###
4 
5 namespace eval ::search::header {}
6 
7 set sTitleList [list gm im fm none wgm wim wfm w]
8 foreach i $sTitleList {
9  set sTitles(w:$i) 1
10  set sTitles(b:$i) 1
11 }
12 set sHeaderFlagList {StdStart Promotions Comments Variations Annotations \
13  DeleteFlag WhiteOpFlag BlackOpFlag MiddlegameFlag EndgameFlag \
14  NoveltyFlag PawnFlag TacticsFlag KsideFlag QsideFlag \
15  BrilliancyFlag BlunderFlag UserFlag }
16 
17 set sHeaderCustomFlagList { CustomFlag1 CustomFlag2 CustomFlag3 CustomFlag4 CustomFlag5 CustomFlag6 }
18 
19 set sHeaderFlagChars {S X _ _ _ D W B M E N P T K Q ! ? U 1 2 3 4 5 6}
20 
21 set sPgntext(1) ""
22 set sPgntext(2) ""
23 set sPgntext(3) ""
24 
25 # checkDates:
26 # Checks minimum/maximum search dates in header search window and
27 # extends them if necessary.
28 proc checkDates {} {
29  global sDateMin sDateMax
30  if {[string length $sDateMin] == 0} { set sDateMin "0000"}
31  if {[string length $sDateMax] == 0} { set sDateMax [sc_info limit year]}
32  if {[string length $sDateMin] == 4} { append sDateMin ".??.??"}
33  if {[string length $sDateMax] == 4} { append sDateMax ".12.31"}
34  if {[string length $sDateMin] == 7} { append sDateMin ".??"}
35  if {[string length $sDateMax] == 7} { append sDateMax ".31"}
36 }
37 
38 proc ::search::header::defaults {} {
39  set ::sWhite ""; set ::sBlack ""
40  set ::sEvent ""; set ::sSite ""; set ::sRound ""; set ::sAnnotator ""; set ::sAnnotated 0
41  set ::sWhiteEloMin 0; set ::sWhiteEloMax [sc_info limit elo]
42  set ::sBlackEloMin 0; set ::sBlackEloMax [sc_info limit elo]
43  set ::sEloDiffMin "-[sc_info limit elo]"
44  set ::sEloDiffMax "+[sc_info limit elo]"
45  set ::sGlMin 0; set ::sGlMax 999
46  set ::sEcoMin "A00"; set ::sEcoMax "E99"; set ::sEco Yes
47  set ::sGnumMin 1; set ::sGnumMax -1
48  set ::sDateMin "0000.00.00"; set ::sDateMax "[sc_info limit year].12.31"
49  set ::sResWin ""; set ::sResLoss ""; set ::sResDraw ""; set ::sResOther ""
50  set ::sIgnoreCol No
51  set ::sSideToMove wb
52  foreach flag [ concat $::sHeaderFlagList $::sHeaderCustomFlagList] { set ::sHeaderFlags($flag) both}
53  foreach i [array names ::sPgntext] { set ::sPgntext($i) ""}
54  foreach i $::sTitleList {
55  set ::sTitles(w:$i) 1
56  set ::sTitles(b:$i) 1
57  }
58 }
59 
61 
62 trace variable sDateMin w ::utils::validate::Date
63 trace variable sDateMax w ::utils::validate::Date
64 
65 foreach i {sWhiteEloMin sWhiteEloMax sBlackEloMin sBlackEloMax} {
66  trace variable $i w [list ::utils::validate::Integer [sc_info limit elo] 0]
67 }
68 trace variable sEloDiffMin w [list ::utils::validate::Integer "-[sc_info limit elo]" 0]
69 trace variable sEloDiffMax w [list ::utils::validate::Integer "-[sc_info limit elo]" 0]
70 
71 trace variable sGlMin w {::utils::validate::Integer 9999 0}
72 trace variable sGlMax w {::utils::validate::Integer 9999 0}
73 
74 trace variable sGnumMin w {::utils::validate::Integer -9999999 0}
75 trace variable sGnumMax w {::utils::validate::Integer -9999999 0}
76 
77 # Forcing ECO entry to be valid ECO codes:
78 foreach i {sEcoMin sEcoMax} {
79  trace variable $i w {::utils::validate::Regexp {^$|^[A-Ea-e]$|^[A-Ea-e][0-9]$|^[A-Ea-e][0-9][0-9]$|^[A-Ea-e][0-9][0-9][a-z]$|^[A-Ea-e][0-9][0-9][a-z][1-4]$}}
80 }
81 
82 set sHeaderFlagFrame 0
83 
84 # ::search::header
85 #
86 # Opens the window for searching by header information.
87 #
88 proc search::header {{ref_base ""} {ref_filter ""}} {
89  global sWhite sBlack sEvent sSite sRound sAnnotator sAnnotated sDateMin sDateMax sIgnoreCol
90  global sWhiteEloMin sWhiteEloMax sBlackEloMin sBlackEloMax
91  global sEloDiffMin sEloDiffMax sSideToMove
92  global sEco sEcoMin sEcoMax sHeaderFlags sGlMin sGlMax sTitleList sTitles
93  global sResWin sResLoss sResDraw sResOther sPgntext
94 
95  set w .sh
96  if {[winfo exists $w]} {
97  wm deiconify $w
98  raiseWin $w
99  return
100  }
101 
102  toplevel $w
103  wm title $w "Scid: $::tr(HeaderSearch)"
104  foreach frame {cWhite cBlack ignore tw tb eventsite dateround res ano gl ends eco} {
105  ttk::frame $w.$frame
106  }
107 
108  raise $w
109 
110  bind $w <F1> { helpWindow Searches Header }
111  bind $w <Escape> "$w.b.cancel invoke"
112  bind $w <Return> "$w.b.search invoke"
113 
114  if {$ref_base != ""} {
115  set ::refDatabaseH $ref_base
116  set ::refFilterH $ref_filter
117  } else {
118  pack [ttk::frame $w.refdb] -side top -fill x
119  CreateSelectDBWidget "$w.refdb" "refDatabaseH" "$ref_base"
121  set ::refFilterH ""
122  }
123 
124  set regular font_Small
125  set bold font_SmallBold
126 
127  foreach color {White Black} {
128  pack $w.c$color -side top -fill x
129  ttk::label $w.c$color.lab -textvar ::tr($color:) -font $bold -width 9 -anchor w
130  ttk::combobox $w.c$color.e -textvariable "s$color" -width 40
131  ::utils::history::SetCombobox HeaderSearch$color $w.c$color.e
132  bind $w.c$color.e <Return> { .sh.b.search invoke; break }
133 
134  ttk::label $w.c$color.space
135  ttk::label $w.c$color.elo1 -textvar ::tr(Rating:) -font $bold
136  ttk::entry $w.c$color.elomin -textvar s${color}EloMin -width 6 -justify right \
137  -font $regular
138  ttk::label $w.c$color.elo2 -text "-" -font $regular
139  ttk::entry $w.c$color.elomax -textvar s${color}EloMax -width 6 -justify right \
140  -font $regular
141  bindFocusColors $w.c$color.e
142  bindFocusColors $w.c$color.elomin
143  bindFocusColors $w.c$color.elomax
144  pack $w.c$color.lab $w.c$color.e $w.c$color.space -side left
145  pack $w.c$color.elomax $w.c$color.elo2 $w.c$color.elomin $w.c$color.elo1 \
146  -side right
147  }
148 
149  pack $w.ignore -side top -fill x
150  ttk::label $w.ignore.l -textvar ::tr(IgnoreColors:) -font $bold
151  ttk::radiobutton $w.ignore.yes -variable sIgnoreCol -value Yes -textvar ::tr(Yes) -style Small.TRadiobutton
152  ttk::radiobutton $w.ignore.no -variable sIgnoreCol -value No -textvar ::tr(No) -style Small.TRadiobutton
153  pack $w.ignore.l $w.ignore.yes $w.ignore.no -side left
154  ttk::label $w.ignore.rdiff -textvar ::tr(RatingDiff:) -font $bold
155  ttk::entry $w.ignore.rdmin -width 6 -textvar sEloDiffMin -justify right -font $regular
156  ttk::label $w.ignore.rdto -text "-" -font $regular
157  ttk::entry $w.ignore.rdmax -width 6 -textvar sEloDiffMax -justify right -font $regular
158  bindFocusColors $w.ignore.rdmin
159  bindFocusColors $w.ignore.rdmax
160  pack $w.ignore.rdmax $w.ignore.rdto $w.ignore.rdmin $w.ignore.rdiff \
161  -side right
162 
163  set spellstate normal
164  if {[lindex [sc_name read] 0] == 0} { set spellstate disabled}
165  foreach c {w b} name {White Black} {
166  pack $w.t$c -side top -fill x
167  ttk::label $w.t$c.label -text "$::tr($name) FIDE:" -font $bold -width 14 -anchor w
168  pack $w.t$c.label -side left
169  foreach i $sTitleList {
170  set name [string toupper $i]
171  if {$i == "none"} { set name "-"}
172  ttk::checkbutton $w.t$c.b$i -text $name -width 5 -variable sTitles($c:$i) -offvalue 0 -onvalue 1 -state $spellstate
173  pack $w.t$c.b$i -side left -padx 1
174  }
175  }
176 
178 
179  set f $w.eventsite
180  pack $f -side top -fill x
181  foreach i {Event Site} {
182  ttk::label $f.l$i -textvar ::tr(${i}:) -font $bold
183  ttk::combobox $f.e$i -textvariable s$i -width 30
184  bind $f.e$i <Return> { .sh.b.search invoke ; break }
185  ::utils::history::SetCombobox HeaderSearch$i $f.e$i
186  bindFocusColors $f.e$i
187  }
188  pack $f.lEvent $f.eEvent -side left
189  pack $f.eSite $f.lSite -side right
190 
191  set f $w.dateround
192  pack $f -side top -fill x
193  ttk::label $f.l1 -textvar ::tr(Date:) -font $bold
194  ttk::label $f.l2 -text "-" -font $regular
195  ttk::label $f.l3 -text " " -font $regular
196  ttk::entry $f.emin -textvariable sDateMin -width 10 -font $regular
197  button $f.eminCal -image tb_calendar -padx 0 -pady 0 -command {
198  regsub -all {[.]} $sDateMin "-" newdate
199  set ndate [::utils::date::chooser $newdate]
200  if {[llength $ndate] == 3} {
201  set sDateMin "[lindex $ndate 0].[lindex $ndate 1].[lindex $ndate 2]"
202  }
203  }
204  ttk::entry $f.emax -textvariable sDateMax -width 10 -font $regular
205  button $f.emaxCal -image tb_calendar -padx 0 -pady 0 -command {
206  regsub -all {[.]} $sDateMax "-" newdate
207  set ndate [::utils::date::chooser $newdate]
208  if {[llength $ndate] == 3} {
209  set sDateMax "[lindex $ndate 0].[lindex $ndate 1].[lindex $ndate 2]"
210  }
211  }
212  bindFocusColors $f.emin
213  bindFocusColors $f.emax
214  bind $f.emin <FocusOut> +checkDates
215  bind $f.emax <FocusOut> +checkDates
216  ttk::button $f.lyear -textvar ::tr(YearToToday) -style Pad0.Small.TButton -command {
217  set sDateMin "[expr [::utils::date::today year]-1].[::utils::date::today month].[::utils::date::today day]"
218  set sDateMax [::utils::date::today]
219  }
220 
221  pack $f.l1 $f.emin $f.eminCal $f.l2 $f.emax $f.emaxCal $f.l3 $f.lyear -side left
222 
223  ttk::label $f.lRound -textvar ::tr(Round:) -font $bold
224  ttk::entry $f.eRound -textvariable sRound -width 10 -font $regular
225  bindFocusColors $f.eRound
226  pack $f.eRound $f.lRound -side right
227 
229 
230  pack .sh.res -side top -fill x
231  ttk::label $w.res.l1 -textvar ::tr(Result:) -font $bold
232  pack $w.res.l1 -side left
233  ttk::checkbutton $w.res.ewin -text "1-0 " -variable sResWin -offvalue "1" -onvalue ""
234  ttk::checkbutton $w.res.edraw -text "1/2-1/2 " -variable sResDraw -offvalue "=" -onvalue ""
235  ttk::checkbutton $w.res.eloss -text "0-1 " -variable sResLoss -offvalue "0" -onvalue ""
236  ttk::checkbutton $w.res.eother -text "* " -variable sResOther -offvalue "*" -onvalue ""
237  pack $w.res.ewin $w.res.edraw $w.res.eloss $w.res.eother -side left
238 
239  ttk::label $w.gl.l1 -textvar ::tr(GameLength:) -font $bold
240  ttk::label $w.gl.l2 -text "-" -font $regular
241  ttk::label $w.gl.l3 -textvar ::tr(HalfMoves) -font $regular
242  ttk::entry $w.gl.emin -textvariable sGlMin -justify right -width 4 -font $regular
243  ttk::entry $w.gl.emax -textvariable sGlMax -justify right -width 4 -font $regular
244  bindFocusColors $w.gl.emin
245  bindFocusColors $w.gl.emax
246  pack $w.gl -in $w.res -side right -fill x
247  pack $w.gl.l1 $w.gl.emin $w.gl.l2 $w.gl.emax $w.gl.l3 -side left
248 
249  ttk::label $w.ends.label -textvar ::tr(EndSideToMove:) -font $bold
250  ttk::frame $w.ends.sep1 -width 5
251  ttk::frame $w.ends.sep2 -width 5
252  ttk::radiobutton $w.ends.white -textvar ::tr(White) -variable sSideToMove -value w
253  ttk::radiobutton $w.ends.black -textvar ::tr(Black) -variable sSideToMove -value b
254  ttk::radiobutton $w.ends.both -textvar ::tr(Both) -variable sSideToMove -value wb
255  pack $w.ends.label $w.ends.white $w.ends.sep1 $w.ends.black $w.ends.sep2 $w.ends.both -side left
256  pack $w.ends -side top -fill x
257 
259 
260  pack .sh.ano -side top -fill x
261  ttk::label $w.ano.a1 -textvar ::tr(Annotations:) -font $bold
262  ttk::label $w.ano.a2 -textvar ::tr(Annotator:) -font $bold
263  ttk::checkbutton $w.ano.an -textvar ::tr(Cmnts:) -variable sAnnotated -offvalue 0 -onvalue 1
264  ttk::entry $w.ano.aname -textvariable sAnnotator -width 20 -font $regular
265  pack $w.ano.a1 $w.ano.an -side left
266  pack $w.ano.aname $w.ano.a2 -side right
267 
269 
270  ttk::label $w.eco.l1 -textvar ::tr(ECOCode:) -font $bold
271  ttk::label $w.eco.l2 -text "-" -font $regular
272  ttk::label $w.eco.l3 -text " " -font $regular
273  ttk::label $w.eco.l4 -textvar ::tr(GamesWithNoECO:) -font $bold
274  ttk::entry $w.eco.emin -textvariable sEcoMin -width 5 -font $regular
275  ttk::entry $w.eco.emax -textvariable sEcoMax -width 5 -font $regular
276  bindFocusColors $w.eco.emin
277  bindFocusColors $w.eco.emax
278  ttk::button $w.eco.range -text "..." -style Pad0.Small.TButton -width 0 -command {
279  set tempResult [chooseEcoRange]
280  if {[scan $tempResult "%\[A-E0-9a-z\]-%\[A-E0-9a-z\]" sEcoMin_tmp sEcoMax_tmp] == 2} {
281  set sEcoMin $sEcoMin_tmp
282  set sEcoMax $sEcoMax_tmp
283  }
284  unset tempResult
285  }
286  ttk::radiobutton $w.eco.yes -variable sEco -value Yes -textvar ::tr(Yes) -style Small.TRadiobutton
287  ttk::radiobutton $w.eco.no -variable sEco -value No -textvar ::tr(No) -style Small.TRadiobutton
288  pack $w.eco -side top -fill x
289  pack $w.eco.l1 $w.eco.emin $w.eco.l2 $w.eco.emax $w.eco.range $w.eco.l3 $w.eco.l4 $w.eco.yes $w.eco.no -side left
290 
291  set f [ttk::frame $w.gnum]
292  pack $f -side top -fill x
293  ttk::label $f.l1 -textvar ::tr(GlistGameNumber:) -font $bold
294  ttk::entry $f.emin -textvariable sGnumMin -width 8 -justify right -font $regular
295  ttk::label $f.l2 -text "-" -font $regular
296  ttk::entry $f.emax -textvariable sGnumMax -width 8 -justify right -font $regular
297  pack $f.l1 $f.emin $f.l2 $f.emax -side left
298  bindFocusColors $f.emin
299  bindFocusColors $f.emax
300  ttk::label $f.l3 -text " " -font $regular
301  ttk::button $f.all -text [::utils::string::Capital $::tr(all)] -style Pad0.Small.TButton -command {set sGnumMin 1; set sGnumMax -1}
302  ttk::menubutton $f.first -style pad0.TMenubutton -textvar ::tr(First...) -menu $f.first.m
303  ttk::menubutton $f.last -style pad0.TMenubutton -textvar ::tr(Last...) -menu $f.last.m
304  menu $f.first.m -font $regular
305  menu $f.last.m -font $regular
306  foreach x {10 50 100 500 1000 5000 10000} {
307  $f.first.m add command -label $x \
308  -command "set sGnumMin 1; set sGnumMax $x"
309  $f.last.m add command -label $x \
310  -command "set sGnumMin -$x; set sGnumMax -1"
311  }
312  pack $f.l3 $f.all $f.first $f.last -side left -padx 2
313 
314  set f [ttk::frame $w.pgntext]
315  pack $f -side top -fill x
316  ttk::label $f.l1 -textvar ::tr(PgnContains:) -font $bold
317  ttk::entry $f.e1 -textvariable sPgntext(1) -width 15 -font $regular
318  ttk::label $f.l2 -text "+" -font $regular
319  ttk::entry $f.e2 -textvariable sPgntext(2) -width 15 -font $regular
320  ttk::label $f.l3 -text "+" -font $regular
321  ttk::entry $f.e3 -textvariable sPgntext(3) -width 15 -font $regular
322  bindFocusColors $f.e1
323  bindFocusColors $f.e2
324  bindFocusColors $f.e3
325  pack $f.l1 $f.e1 $f.l2 $f.e2 $f.l3 $f.e3 -side left
326 
328 
329  ttk::button $w.flagslabel -textvar ::tr(FindGamesWith:) -style Pad0.Small.TButton -image tb_menu -compound left -command {
330  if {$sHeaderFlagFrame} {
331  set sHeaderFlagFrame 0
332  pack forget .sh.flags
333  } else {
334  set sHeaderFlagFrame 1
335  pack .sh.flags -side top -after .sh.flagslabel
336  }
337  }
338  pack $w.flagslabel -side top -fill x
339 
340  ttk::frame $w.flags
341  if {$::sHeaderFlagFrame} {
342  pack $w.flags -side top
343  }
344 
345  set count 0
346  set row 0
347  set col 0
348  foreach var $::sHeaderFlagList {
349  set lab [ttk::label $w.flags.l$var -text [ ::tr $var] -font font_Small]
350  grid $lab -row $row -column $col -sticky e
351  incr col
352  grid [ttk::radiobutton $w.flags.yes$var -variable sHeaderFlags($var) -value yes -text $::tr(Yes)] -row $row -column $col
353  incr col
354  grid [ttk::radiobutton $w.flags.no$var -variable sHeaderFlags($var) -value no -text $::tr(No)] -row $row -column $col
355  incr col
356  grid [ttk::radiobutton $w.flags.both$var -variable sHeaderFlags($var) -value both -text $::tr(Both)] -row $row -column $col
357  incr count
358  incr col -3
359  incr row
360  if {$count == 6} { set col 5; set row 0}
361  if {$count == 12} { set col 10; set row 0}
362  }
363 
364  set ::curr_db [sc_base current]
365  set count 1
366  set col 0
367  set row 7
368  foreach var $::sHeaderCustomFlagList {
369 
370  set lb [sc_base extra $::curr_db flag$count]
371  if { $lb == "" } { set lb $var}
372 
373  set lab [ttk::label $w.flags.l$var -text $lb -font font_Small]
374  grid $lab -row $row -column $col -sticky e
375  incr col
376  grid [ttk::radiobutton $w.flags.yes$var -variable sHeaderFlags($var) -value yes -text $::tr(Yes)] -row $row -column $col
377  incr col
378  grid [ttk::radiobutton $w.flags.no$var -variable sHeaderFlags($var) -value no -text $::tr(No)] -row $row -column $col
379  incr col
380  grid [ttk::radiobutton $w.flags.both$var -variable sHeaderFlags($var) -value both -text $::tr(Both)] -row $row -column $col
381  incr col 2
382  incr count
383  if {$count == 4} { set col 0; set row 8}
384  }
385 
386  grid [ttk::label $w.flags.space -text "" -font $regular] -row 0 -column 4
387  grid [ttk::label $w.flags.space2 -text "" -font $regular] -row 0 -column 9
388 
392 
393  ### Header search: search/cancel buttons
394 
395  ttk::frame $w.b
396  pack $w.b -side top -fill both
397  ttk::button $w.b.defaults -textvar ::tr(Defaults) -command ::search::header::defaults ;# -padx 20
398  ttk::button $w.b.save -textvar ::tr(Save...) -command ::search::header::save ;# -padx 20
399  ttk::button $w.b.stop -textvar ::tr(Stop) -command progressBarCancel
400  ttk::button $w.b.search -textvar ::tr(Search) -command {
401  ::utils::history::AddEntry HeaderSearchWhite $sWhite
402  ::utils::history::AddEntry HeaderSearchBlack $sBlack
403  ::utils::history::AddEntry HeaderSearchEvent $sEvent
404  ::utils::history::AddEntry HeaderSearchSite $sSite
405 
406  set sPgnlist {}
407  foreach i {1 2 3} {
408  set temp [string trim $sPgntext($i)]
409  if {$temp != ""} { lappend sPgnlist $temp }
410  }
411  pack .sh.b.stop -side right -padx 5
412  grab .sh.b.stop
413  set wtitles {}
414  set btitles {}
415  foreach i $sTitleList {
416  if $sTitles(w:$i) { lappend wtitles $i }
417  if $sTitles(b:$i) { lappend btitles $i }
418  }
419 
420  set dbase [string index $::refDatabaseH 0]
421  if {$::refFilterH == ""} {
422  set filter "dbfilter"
423  } else {
424  set filter [sc_filter compose $dbase $::refFilterH ""]
425  }
426 
427  if {$sEco == "Yes"} {
428  set noEco "-eco|"
429  } else {
430  set noEco "-eco!"
431  }
432 
433  if {$::search::filter::operation != "2" } {
434  set fOrig [sc_filter new $dbase]
435  sc_filter copy $dbase $fOrig $filter
436  }
437 
438  set flagsYes ""
439  set flagsNo ""
440  set idx -1
441  foreach i [ concat $::sHeaderFlagList $::sHeaderCustomFlagList ] {
442  incr idx
443  if {$i == "Comments"} { continue }
444  if {$i == "Variations"} { continue }
445  if {$i == "Annotations"} { continue }
446 
447  if { $sHeaderFlags($i) == "yes" } {
448  append flagsYes [lindex $::sHeaderFlagChars $idx]
449  } elseif { $sHeaderFlags($i) == "no" } {
450  append flagsNo [lindex $::sHeaderFlagChars $idx]
451  }
452  }
453 
454  set fCounts(Variations) "-n_variations"
455  set fCountsV(Variations) ""
456  set fCounts(Comments) "-n_comments"
457  set fCountsV(Comments) ""
458  set fCounts(Annotations) "-n_nags"
459  set fCountsV(Annotations) ""
460  foreach i {"Variations" "Comments" "Annotations"} {
461  if { $sHeaderFlags($i) == "yes" } {
462  append fCounts($i) "!"
463  set fCountsV($i) "0"
464  } elseif { $sHeaderFlags($i) == "no" } {
465  set fCountsV($i) "0"
466  }
467  }
468 
469  set results ""
470  append results $sResWin
471  append results $sResDraw
472  append results $sResLoss
473  append results $sResOther
474 
475  progressBarSet .sh.fprogress.progress 301 21
476  set err [catch { sc_filter search $dbase $filter header \
477  -filter RESET \
478  -white $sWhite -black $sBlack \
479  -event $sEvent -site $sSite -round $sRound \
480  -date [list $sDateMin $sDateMax] \
481  -result! $results \
482  -welo [list $sWhiteEloMin $sWhiteEloMax] \
483  -belo [list $sBlackEloMin $sBlackEloMax] \
484  -delo [list $sEloDiffMin $sEloDiffMax] \
485  -eco [list $sEcoMin $sEcoMax] $noEco [list 0 0] \
486  -length [list $sGlMin $sGlMax] \
487  -toMove $sSideToMove \
488  -gnum [list $sGnumMin $sGnumMax] \
489  -annotated $sAnnotated \
490  -annotator $sAnnotator \
491  -flag $flagsYes -flag! $flagsNo \
492  $fCounts(Variations) $fCountsV(Variations) \
493  $fCounts(Comments) $fCountsV(Comments) \
494  $fCounts(Annotations) $fCountsV(Annotations) \
495  -pgn $sPgnlist -wtitles $wtitles -btitles $btitles \
496  }]
497 
498  if {!$err && $sIgnoreCol == "Yes"} {
499  set fIgnore [sc_filter new $dbase]
500  set deloMin [ expr { $sEloDiffMax * -1 }]
501  set deloMax [ expr { $sEloDiffMin * -1 }]
502  progressBarSet .sh.fprogress.progress 301 21
503  catch { sc_filter search $dbase $fIgnore header \
504  -filter RESET \
505  -white $sBlack -black $sWhite \
506  -event $sEvent -site $sSite -round $sRound \
507  -date [list $sDateMin $sDateMax] \
508  -result! $results \
509  -welo [list $sBlackEloMin $sBlackEloMax] \
510  -belo [list $sWhiteEloMin $sWhiteEloMax] \
511  -delo [list $deloMin $deloMax] \
512  -eco [list $sEcoMin $sEcoMax] $noEco [list 0 0] \
513  -length [list $sGlMin $sGlMax] \
514  -toMove $sSideToMove \
515  -gnum [list $sGnumMin $sGnumMax] \
516  -annotated $sAnnotated \
517  -annotator $sAnnotator \
518  -flag $flagsYes -flag! $flagsNo \
519  $fCounts(Variations) $fCountsV(Variations) \
520  $fCounts(Comments) $fCountsV(Comments) \
521  $fCounts(Annotations) $fCountsV(Annotations) \
522  -pgn $sPgnlist -wtitles $wtitles -btitles $btitles \
523  }
524 
525  sc_filter or $dbase $filter $fIgnore
526  sc_filter release $dbase $fIgnore
527  }
528 
529  if {[info exists fOrig]} {
530  if {$::search::filter::operation == "0" } {
531  sc_filter and $dbase $filter $fOrig
532  } else {
533  sc_filter or $dbase $filter $fOrig
534  }
535  sc_filter release $dbase $fOrig
536  unset fOrig
537  }
538 
539  foreach {filterSz gameSz mainSz} [sc_filter sizes $dbase $filter] {}
540  set str "[::utils::thousands $mainSz] / [::utils::thousands $gameSz]"
541  .sh.status configure -text $str
542 
543  grab release .sh.b.stop
544  pack forget .sh.b.stop
545 
546  ::notify::DatabaseModified $dbase $filter
547  }
548 
549  ttk::button $w.b.cancel -textvar ::tr(Close) -command {focus .; destroy .sh} ;# -padx 20
550 
551  foreach i {defaults save cancel search stop} {
552  $w.b.$i configure -style Small.TButton
553 
554  pack $w.b.defaults $w.b.save -side left -padx 5
555  pack $w.b.cancel $w.b.search -side right -padx 5
556  }
557 
558  pack [ ttk::frame $w.fprogress] -fill both
559  canvas $w.fprogress.progress -height 20 -width 300 -bg white -relief solid -border 1
560  $w.fprogress.progress create rectangle 0 0 0 0 -fill blue -outline blue -tags bar
561  $w.fprogress.progress create text 295 10 -anchor e -font font_Regular -tags time \
562  -fill black -text "0:00 / 0:00"
563  pack $w.fprogress.progress -side top -pady 2
564  ttk::label $w.status -text "" -width 1 -font font_Small -relief sunken -anchor w
565  pack $w.status -side bottom -fill x
566  # update
567  wm resizable $w 0 0
569  focus $w.cWhite.e
570 }
571 
572 proc ::search::header::save {} {
573  global sWhite sBlack sEvent sSite sRound sAnnotator sAnnotated sDateMin sDateMax sIgnoreCol
574  global sWhiteEloMin sWhiteEloMax sBlackEloMin sBlackEloMax
575  global sEloDiffMin sEloDiffMax sGlMin sGlMax
576  global sEco sEcoMin sEcoMax sHeaderFlags sSideToMove
577  global sResWin sResLoss sResDraw sResOther sPgntext
578 
579  set ftype { { "Scid SearchOptions files" {".sso"} } }
580  set fName [tk_getSaveFile -initialdir [pwd] -filetypes $ftype -title "Create a SearchOptions file"]
581  if {$fName == ""} { return}
582 
583  if {[string compare [file extension $fName] ".sso"] != 0} {
584  append fName ".sso"
585  }
586 
587  if {[catch {set searchF [open [file nativename $fName] w]}]} {
588  tk_messageBox -title "Error: Unable to open file" -type ok -icon error \
589  -message "Unable to create SearchOptions file: $fName"
590  return
591  }
592  puts $searchF "\# SearchOptions File created by Scid $::scidVersion"
593  puts $searchF "set searchType Header"
594 
595  # First write the regular variables:
596  foreach i {sWhite sBlack sEvent sSite sRound sAnnotator sAnnotated sDateMin sDateMax sResWin
597  sResLoss sResDraw sResOther sWhiteEloMin sWhiteEloMax sBlackEloMin
598  sBlackEloMax sEcoMin sEcoMax sEloDiffMin sEloDiffMax
599  sIgnoreCol sSideToMove sGlMin sGlMax ::search::filter::operation} {
600  puts $searchF "set $i [list [set $i]]"
601  }
602  # Now write the array values:
603  foreach i [array names sHeaderFlags] {
604  puts $searchF "set sHeaderFlags($i) [list $sHeaderFlags($i)]"
605  }
606  foreach i [array names sPgntext] {
607  puts $searchF "set sPgntext($i) [list $sPgntext($i)]"
608  }
609 
610  tk_messageBox -type ok -icon info -title "Search Options saved" \
611  -message "Header search options saved to: $fName"
612  close $searchF
613 }
614 
615 ##############################
616 ### Selecting common ECO ranges
617 
618 set scid_ecoRangeChosen ""
619 set ecoCommonRanges {}
620 proc chooseEcoRange {} {
621  global ecoCommonRanges scid_ecoRangeChosen
622  set ecoCommonRanges [ list \
623  "A04-A09 [tr Reti]: [trans 1.Nf3]" \
624  "A10-A39 [tr English]: 1.c4" \
625  "A40-A49 1.d4, [tr d4Nf6Miscellaneous]" \
626  "A45l-A45z [tr Trompowsky]: [trans [list 1.d4 Nf6 2.Bg5]]" \
627  "A51-A52 [tr Budapest]: [trans [list 1.d4 Nf6 2.c4 e5]]" \
628  "A53-A55 [tr OldIndian]: [trans [list 1.d4 Nf6 2.c4 d6]]" \
629  "A57-A59 [tr BenkoGambit]: [trans [list 1.d4 Nf6 2.c4 c5 3.d5 b5]]" \
630  "A60-A79 [tr ModernBenoni]: [trans [list 1.d4 Nf6 2.c4 c5 3.d5 e6]]" \
631  "A80-A99 [tr DutchDefence]: 1.d4 f5" \
632  "____________________________________________________________" \
633  "B00-C99 1.e4" \
634  "B01-B01 [tr Scandinavian]: 1.e4 d5" \
635  "B02-B05 [tr AlekhineDefence]: [trans [list 1.e4 Nf6]]" \
636  "B07-B09 [tr Pirc]: 1.e4 d6" \
637  "B10-B19 [tr CaroKann]: 1.e4 c6" \
638  "B12i-B12z [tr CaroKannAdvance]: 1.e4 c6 2.d4 d5 3.e5" \
639  "B20-B99 [tr Sicilian]: 1.e4 c5" \
640  "B22-B22 [tr SicilianAlapin]: 1.e4 c5 2.c3" \
641  "B23-B26 [tr SicilianClosed]: [trans [list 1.e4 c5 2.Nc3]]" \
642  "B30-B39 [tr Sicilian]: [trans [list 1.e4 c5 2.Nf3 Nc6]]" \
643  "B40-B49 [tr Sicilian]: [trans [list 1.e4 c5 2.Nf3 e6]]" \
644  "B50-B59 [tr SicilianRauzer]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 Nc6]]" \
645  "B70-B79 [tr SicilianDragon]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 g6]]" \
646  "B80-B89 [tr SicilianScheveningen]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 e6]]" \
647  "B90-B99 [tr SicilianNajdorf]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 a6]]" \
648  "____________________________________________________________" \
649  "C00-C19 [tr FrenchDefence]: 1.e4 e6" \
650  "C02-C02 [tr FrenchAdvance]: 1.e4 e6 2.d4 d5 3.e5" \
651  "C03-C09 [tr FrenchTarrasch]: [trans [list 1.e4 e6 2.d4 d5 3.Nd2]]" \
652  "C15-C19 [tr FrenchWinawer]: [trans [list 1.e4 e6 2.d4 d5 3.Nc3 Bb4]]" \
653  "C20-C99 [tr OpenGame]: 1.e4 e5" \
654  "C25-C29 [tr Vienna]: [trans [list 1.e4 e5 2.Nc3]]" \
655  "C30-C39 [tr KingsGambit]: 1.e4 e5 2.f4" \
656  "C42-C43 [tr RussianGame]: [trans [list 1.e4 e5 2.Nf3 Nf6]]" \
657  "C44-C49 [tr OpenGame]: [trans [list 1.e4 e5 2.Nf3 Nc6]]" \
658  "C50-C59 [tr ItalianTwoKnights]: 1.e4 e5 2.Nf3 Nc6 3.Bc4]]" \
659  "C60-C99 [tr Spanish]: [trans [list 1.e4 e5 2.Nf3 Nc6 3.Bb5]]" \
660  "C68-C69 [tr SpanishExchange]: [trans [list 3.Bb5 a6 4.Bxc6]]" \
661  "C80-C83 [tr SpanishOpen]: [trans [list 3.Bb5 a6 4.Ba4 Nf6 5.O-O Nxe4]]" \
662  "C84-C99 [tr SpanishClosed]: [trans [list 3.Bb5 a6 4.Ba4 Nf6 5.O-O Be7]]" \
663  "____________________________________________________________" \
664  "D00-D99 [tr Queen's Pawn]: 1.d4 d5" \
665  "D10-D19 [tr Slav]: 1.d4 d5 2.c4 c6" \
666  "D20-D29 [tr QGA]: 1.d4 d5 2.c4 dxc4" \
667  "D30-D69 [tr QGD]: 1.d4 d5 2.c4 e6" \
668  "D35-D36 [tr QGDExchange]: 1.d4 d5 2.c4 e6 3.cxd5 exd5" \
669  "D43-D49 [tr SemiSlav]: [trans [list 3.Nc3 Nf6 4.Nf3 c6]]" \
670  "D50-D69 [tr QGDwithBg5]: [trans [list 1.d4 d5 2.c4 e6 3.Nc3 Nf6 4.Bg5]]" \
671  "D60-D69 [tr QGDOrthodox]: [trans [list 4.Bg5 Be7 5.e3 O-O 6.Nf3 Nbd7]]" \
672  "D70-D99 [tr Grunfeld]: [trans [list 1.d4 Nf6 2.c4 g6 with 3...d5]]" \
673  "D85-D89 [tr GrunfeldExchange]: [trans [list 3.Nc3 d5 4.e4 Nxc3 5.bxc3]]" \
674  "D96-D99 [tr GrunfeldRussian]: [trans [list 3.Nc3 d5 4.Nf3 Bg7 5.Qb3]]" \
675  "____________________________________________________________" \
676  "E00-E09 [tr Catalan]: [trans [list 1.d4 Nf6 2.c4 e6 3.g3/...]]" \
677  "E02-E05 [tr CatalanOpen]: [trans [list 3.g3 d5 4.Bg2 dxc4]]" \
678  "E06-E09 [tr CatalanClosed]: [trans [list 3.g3 d5 4.Bg2 Be7]]" \
679  "E12-E19 [tr QueensIndian]: [trans [list 1.d4 Nf6 2.c4 e6 3.Nf3 b6]]" \
680  "E20-E59 [tr NimzoIndian]: [trans [list 1.d4 Nf6 2.c4 e6 3.Nc3 Bb4]]" \
681  "E32-E39 [tr NimzoIndianClassical]: [trans [list 4.Qc2]]" \
682  "E40-E59 [tr NimzoIndianRubinstein]: 4.e3" \
683  "E60-E99 [tr KingsIndian]: [trans [list 1.d4 Nf6 2.c4 g6]]" \
684  "E80-E89 [tr KingsIndianSamisch]: 4.e4 d6 5.f3" \
685  "E90-E99 [tr KingsIndianMainLine]: [trans [list 4.e4 d6 5.Nf3]]"]
686 
687  if {[winfo exists .ecoRangeWin]} { return}
688  set w .ecoRangeWin
689  toplevel $w
690  wm title $w "Scid: Choose ECO Range"
691  wm minsize $w 30 5
692 
693  listbox $w.list -yscrollcommand "$w.ybar set" -height 20 -width 60 -background white -setgrid 1
694  foreach i $ecoCommonRanges { $w.list insert end $i}
695  ttk::scrollbar $w.ybar -command "$w.list yview" -takefocus 0
696  pack [ttk::frame $w.b] -side bottom -fill x
697  pack $w.ybar -side right -fill y
698  pack $w.list -side left -fill both -expand yes
699 
700  ttk::button $w.b.ok -text "OK" -command {
701  set sel [.ecoRangeWin.list curselection]
702  if {[llength $sel] > 0} {
703  set scid_ecoRangeChosen [lindex $ecoCommonRanges [lindex $sel 0]]
704  set ::sEco No
705  }
706  focus .sh
707  destroy .ecoRangeWin
708  }
709  ttk::button $w.b.cancel -text $::tr(Cancel) -command "focus .sh; destroy $w"
710  pack $w.b.cancel $w.b.ok -side right -padx 5 -pady 2
711  bind $w <Escape> "
712  set scid_ecoRangeChosen {}
713  grab release $w
714  focus .
715  destroy $w
716  break"
717  bind $w <Return> "$w.b.ok invoke; break"
718  bind $w.list <Double-ButtonRelease-1> "$w.b.ok invoke; break"
719  focus $w.list
720  grab $w
721  tkwait window $w
722  return $scid_ecoRangeChosen
723 }
724 
725 
726 ###
727 ### End of file: search.tcl
728