File: header.tcl

package info (click to toggle)
scid 1%3A4.3.0.cvs20120311-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 24,232 kB
  • sloc: tcl: 135,238; cpp: 47,810; ansic: 5,339; sh: 2,882; python: 278; makefile: 105; perl: 86
file content (832 lines) | stat: -rw-r--r-- 34,872 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
###
### search/header.tcl: Header Search routines for Scid.
###

namespace eval ::search::header {}

set sWhite "";  set sBlack "";  set sEvent ""; set sSite "";  set sRound ""; set sAnnotator ""; set sAnnotated 0;
set sWhiteEloMin 0; set sWhiteEloMax [sc_info limit elo]
set sBlackEloMin 0; set sBlackEloMax [sc_info limit elo]
set sEloDiffMin "-[sc_info limit elo]"; set sEloDiffMax "+[sc_info limit elo]"
set sTitleList [list gm im fm none wgm wim wfm w]
foreach i $sTitleList {
  set sTitles(w:$i) 1
  set sTitles(b:$i) 1
}
set sGlMin 0; set sGlMax 999
set sEcoMin "A00";  set sEcoMax "E99"; set sEco Yes
set sDateMin "0000.00.00"; set sDateMax "[sc_info limit year].12.31"
set sResWin 1; set sResLoss 1; set sResDraw 1; set sResOther 1
set sGnumMin 1; set sGnumMax -1
set sIgnoreCol No
set sSideToMove wb
set sHeaderFlagList {StdStart Promotions Comments Variations Annotations \
      DeleteFlag WhiteOpFlag BlackOpFlag MiddlegameFlag EndgameFlag \
      NoveltyFlag PawnFlag TacticsFlag KsideFlag QsideFlag \
      BrilliancyFlag BlunderFlag UserFlag }

set sHeaderCustomFlagList {  CustomFlag1 CustomFlag2 CustomFlag3 CustomFlag4 CustomFlag5 CustomFlag6 }

foreach i [ concat $sHeaderFlagList $sHeaderCustomFlagList ] {
  set sHeaderFlags($i) both
}
set sPgntext(1) ""
set sPgntext(2) ""
set sPgntext(3) ""

trace variable sDateMin w ::utils::validate::Date
trace variable sDateMax w ::utils::validate::Date

foreach i {sWhiteEloMin sWhiteEloMax sBlackEloMin sBlackEloMax} {
  trace variable $i w [list ::utils::validate::Integer [sc_info limit elo] 0]
}
trace variable sEloDiffMin w [list ::utils::validate::Integer "-[sc_info limit elo]" 0]
trace variable sEloDiffMax w [list ::utils::validate::Integer "-[sc_info limit elo]" 0]

trace variable sGlMin w {::utils::validate::Integer 9999 0}
trace variable sGlMax w {::utils::validate::Integer 9999 0}

trace variable sGnumMin w {::utils::validate::Integer -9999999 0}
trace variable sGnumMax w {::utils::validate::Integer -9999999 0}

# Forcing ECO entry to be valid ECO codes:
foreach i {sEcoMin sEcoMax} {
  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]$}}
}

# checkDates:
#    Checks minimum/maximum search dates in header search window and
#    extends them if necessary.
proc checkDates {} {
  global sDateMin sDateMax
  if {[string length $sDateMin] == 0} { set sDateMin "0000" }
  if {[string length $sDateMax] == 0} { set sDateMax [sc_info limit year]}
  if {[string length $sDateMin] == 4} { append sDateMin ".??.??" }
  if {[string length $sDateMax] == 4} { append sDateMax ".12.31" }
  if {[string length $sDateMin] == 7} { append sDateMin ".??" }
  if {[string length $sDateMax] == 7} { append sDateMax ".31" }
}

proc ::search::header::defaults {} {
  global sWhite sBlack sEvent sSite sRound sAnnotator sAnnotated sDateMin sDateMax sIgnoreCol sSideToMove
  global sWhiteEloMin sWhiteEloMax sBlackEloMin sBlackEloMax
  global sEloDiffMin sEloDiffMax
  global sEco sEcoMin sEcoMax sHeaderFlags sGlMin sGlMax
  global sGnumMin sGnumMax
  global sResWin sResLoss sResDraw sResOther glstart
  global sPgntext sTitles
  
  set sWhite "";  set sBlack ""
  set sEvent ""; set sSite "";  set sRound ""; set sAnnotator ""; set sAnnotated 0
  set sWhiteEloMin 0; set sWhiteEloMax [sc_info limit elo]
  set sBlackEloMin 0; set sBlackEloMax [sc_info limit elo]
  set sEloDiffMin "-[sc_info limit elo]"
  set sEloDiffMax "+[sc_info limit elo]"
  set sGlMin 0; set sGlMax 999
  set sEcoMin "A00";  set sEcoMax "E99"; set sEco Yes
  set sGnumMin 1; set sGnumMax -1
  set sDateMin "0000.00.00"; set sDateMax "[sc_info limit year].12.31"
  set sResWin 1; set sResLoss 1; set sResDraw 1; set sResOther 1
  set sIgnoreCol No
  set sSideToMove wb
  foreach flag  [ concat $::sHeaderFlagList $::sHeaderCustomFlagList ] { set sHeaderFlags($flag) both }
  foreach i [array names sPgntext] { set sPgntext($i) "" }
  foreach i $::sTitleList {
    set sTitles(w:$i) 1
    set sTitles(b:$i) 1
  }
}

::search::header::defaults

set sHeaderFlagFrame 0

# ::search::header
#
#   Opens the window for searching by header information.
#
proc search::header {} {
  global sWhite sBlack sEvent sSite sRound sAnnotator sAnnotated sDateMin sDateMax sIgnoreCol
  global sWhiteEloMin sWhiteEloMax sBlackEloMin sBlackEloMax
  global sEloDiffMin sEloDiffMax sSideToMove
  global sEco sEcoMin sEcoMax sHeaderFlags sGlMin sGlMax sTitleList sTitles
  global sResWin sResLoss sResDraw sResOther glstart sPgntext
    
  set w .sh
  if {[winfo exists $w]} {
    wm deiconify $w
    raiseWin $w
    return
  }
  
  toplevel $w
  wm title $w "Scid: $::tr(HeaderSearch)"
  foreach frame {cWhite cBlack ignore tw tb eventsite dateround res ano gl ends eco} {
    ttk::frame $w.$frame
  }
  
  raise $w
  
  bind $w <F1> { helpWindow Searches Header }
  bind $w <Escape> "$w.b.cancel invoke"
  bind $w <Return> "$w.b.search invoke"
  
  set regular font_Small
  set bold font_SmallBold
  
  foreach color {White Black} {
    pack $w.c$color -side top -fill x
    ttk::label $w.c$color.lab -textvar ::tr($color:) -font $bold -width 9 -anchor w
    ttk::combobox $w.c$color.e -textvariable "s$color" -width 40
    ::utils::history::SetCombobox HeaderSearch$color $w.c$color.e
    bind $w.c$color.e <Return> { .sh.b.search invoke; break }
    
    ttk::label $w.c$color.space
    ttk::label $w.c$color.elo1 -textvar ::tr(Rating:) -font $bold
    ttk::entry $w.c$color.elomin -textvar s${color}EloMin -width 6 -justify right \
        -font $regular
    ttk::label $w.c$color.elo2 -text "-" -font $regular
    ttk::entry $w.c$color.elomax -textvar s${color}EloMax -width 6 -justify right \
        -font $regular
    bindFocusColors $w.c$color.e
    bindFocusColors $w.c$color.elomin
    bindFocusColors $w.c$color.elomax
    pack $w.c$color.lab $w.c$color.e $w.c$color.space -side left
    pack $w.c$color.elomax $w.c$color.elo2 $w.c$color.elomin $w.c$color.elo1 \
        -side right
  }
  
  pack $w.ignore -side top -fill x
  ttk::label $w.ignore.l -textvar ::tr(IgnoreColors:) -font $bold
  ttk::radiobutton $w.ignore.yes -variable sIgnoreCol -value Yes -textvar ::tr(Yes) -style Small.TRadiobutton
  ttk::radiobutton $w.ignore.no  -variable sIgnoreCol -value No -textvar ::tr(No) -style Small.TRadiobutton
  pack $w.ignore.l $w.ignore.yes $w.ignore.no -side left
  ttk::label $w.ignore.rdiff -textvar ::tr(RatingDiff:) -font $bold
  ttk::entry $w.ignore.rdmin -width 6 -textvar sEloDiffMin -justify right -font $regular
  ttk::label $w.ignore.rdto -text "-" -font $regular
  ttk::entry $w.ignore.rdmax -width 6 -textvar sEloDiffMax -justify right -font $regular
  bindFocusColors $w.ignore.rdmin
  bindFocusColors $w.ignore.rdmax
  pack $w.ignore.rdmax $w.ignore.rdto $w.ignore.rdmin $w.ignore.rdiff \
      -side right
  
  set spellstate normal
  if {[lindex [sc_name read] 0] == 0} { set spellstate disabled }
  foreach c {w b} name {White Black} {
    pack $w.t$c -side top -fill x
    ttk::label $w.t$c.label -text "$::tr($name) FIDE:" -font $bold -width 14 -anchor w
    pack $w.t$c.label -side left
    foreach i $sTitleList {
      set name [string toupper $i]
      if {$i == "none"} { set name "-" }
      ttk::checkbutton $w.t$c.b$i -text $name -width 5 -variable sTitles($c:$i) -offvalue 0 -onvalue 1 -state $spellstate
      pack $w.t$c.b$i -side left -padx 1
    }
  }
  
  addHorizontalRule $w
  
  set f $w.eventsite
  pack $f -side top -fill x
  foreach i {Event Site} {
    ttk::label $f.l$i -textvar ::tr(${i}:) -font $bold
    ttk::combobox $f.e$i -textvariable s$i -width 30
    bind $f.e$i <Return> { .sh.b.search invoke ; break }
    ::utils::history::SetCombobox HeaderSearch$i $f.e$i
    bindFocusColors $f.e$i
  }
  pack $f.lEvent $f.eEvent -side left
  pack $f.eSite $f.lSite -side right
  
  set f $w.dateround
  pack $f -side top -fill x
  ttk::label $f.l1 -textvar ::tr(Date:) -font $bold
  ttk::label $f.l2 -text "-" -font $regular
  ttk::label $f.l3 -text " " -font $regular
  ttk::entry $f.emin -textvariable sDateMin -width 10 -font $regular
  button $f.eminCal -image ::utils::date::calendar -padx 0 -pady 0 -command {
    regsub -all {[.]} $sDateMin "-" newdate
    set ndate [::utils::date::chooser $newdate]
    if {[llength $ndate] == 3} {
      set sDateMin "[lindex $ndate 0].[lindex $ndate 1].[lindex $ndate 2]"
    }
  }
  ttk::entry $f.emax -textvariable sDateMax -width 10 -font $regular
  button $f.emaxCal -image ::utils::date::calendar -padx 0 -pady 0 -command {
    regsub -all {[.]} $sDateMax "-" newdate
    set ndate [::utils::date::chooser $newdate]
    if {[llength $ndate] == 3} {
      set sDateMax "[lindex $ndate 0].[lindex $ndate 1].[lindex $ndate 2]"
    }
  }
  bindFocusColors $f.emin
  bindFocusColors $f.emax
  bind $f.emin <FocusOut> +checkDates
  bind $f.emax <FocusOut> +checkDates
  ttk::button $f.lyear -textvar ::tr(YearToToday) -style Pad0.Small.TButton -command {
    set sDateMin "[expr [::utils::date::today year]-1].[::utils::date::today month].[::utils::date::today day]"
    set sDateMax [::utils::date::today]
  }
  
  pack $f.l1 $f.emin $f.eminCal $f.l2 $f.emax $f.emaxCal $f.l3 $f.lyear -side left
  
  ttk::label $f.lRound -textvar ::tr(Round:) -font $bold
  ttk::entry $f.eRound -textvariable sRound -width 10 -font $regular
  bindFocusColors $f.eRound
  pack $f.eRound $f.lRound -side right
  
  addHorizontalRule $w
  
  pack .sh.res -side top -fill x
  ttk::label $w.res.l1 -textvar ::tr(Result:) -font $bold
  pack $w.res.l1 -side left
  foreach i {win draw loss other} \
      v {sResWin sResDraw sResLoss sResOther} \
      text {"1-0 "  "1/2-1/2 "  "0-1 "  "* "} {
        ttk::checkbutton $w.res.e$i -text $text -variable $v -offvalue 0 -onvalue 1
        pack $w.res.e$i -side left
      }
  
  ttk::label $w.gl.l1 -textvar ::tr(GameLength:) -font $bold
  ttk::label $w.gl.l2 -text "-" -font $regular
  ttk::label $w.gl.l3 -textvar ::tr(HalfMoves) -font $regular
  ttk::entry $w.gl.emin -textvariable sGlMin -justify right -width 4 -font $regular
  ttk::entry $w.gl.emax -textvariable sGlMax -justify right -width 4 -font $regular
  bindFocusColors $w.gl.emin
  bindFocusColors $w.gl.emax
  pack $w.gl -in $w.res -side right -fill x
  pack $w.gl.l1 $w.gl.emin $w.gl.l2 $w.gl.emax $w.gl.l3 -side left
  
  ttk::label $w.ends.label -textvar ::tr(EndSideToMove:) -font $bold
  ttk::frame $w.ends.sep1 -width 5
  ttk::frame $w.ends.sep2 -width 5
  ttk::radiobutton $w.ends.white -textvar ::tr(White) -variable sSideToMove -value w
  ttk::radiobutton $w.ends.black -textvar ::tr(Black) -variable sSideToMove -value b
  ttk::radiobutton $w.ends.both -textvar ::tr(Both) -variable sSideToMove -value wb
  pack $w.ends.label $w.ends.white $w.ends.sep1 $w.ends.black $w.ends.sep2 $w.ends.both -side left
  pack $w.ends -side top -fill x
  
  addHorizontalRule $w
  
  pack .sh.ano -side top -fill x
  ttk::label $w.ano.a1 -textvar ::tr(Annotations:) -font $bold
  ttk::label $w.ano.a2 -textvar ::tr(Annotator:) -font $bold
  ttk::checkbutton $w.ano.an -textvar ::tr(Cmnts:) -variable sAnnotated -offvalue 0 -onvalue 1
  ttk::entry $w.ano.aname -textvariable sAnnotator -width 20 -font $regular
  pack $w.ano.a1 $w.ano.an -side left
  pack $w.ano.aname $w.ano.a2 -side right

  addHorizontalRule $w
  
  ttk::label $w.eco.l1 -textvar ::tr(ECOCode:) -font $bold
  ttk::label $w.eco.l2 -text "-" -font $regular
  ttk::label $w.eco.l3 -text " " -font $regular
  ttk::label $w.eco.l4 -textvar ::tr(GamesWithNoECO:) -font $bold
  ttk::entry $w.eco.emin -textvariable sEcoMin -width 5 -font $regular
  ttk::entry $w.eco.emax -textvariable sEcoMax -width 5 -font $regular
  bindFocusColors $w.eco.emin
  bindFocusColors $w.eco.emax
  ttk::button $w.eco.range -text "..." -style  Pad0.Small.TButton -width 0 -command {
    set tempResult [chooseEcoRange]
    if {[scan $tempResult "%\[A-E0-9a-z\]-%\[A-E0-9a-z\]" sEcoMin_tmp sEcoMax_tmp] == 2} {
      set sEcoMin $sEcoMin_tmp
      set sEcoMax $sEcoMax_tmp
    }
    unset tempResult
  }
  ttk::radiobutton $w.eco.yes -variable sEco -value Yes -textvar ::tr(Yes) -style Small.TRadiobutton
  ttk::radiobutton $w.eco.no -variable sEco -value No -textvar ::tr(No) -style Small.TRadiobutton
  pack $w.eco -side top -fill x
  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
  
  set f [ttk::frame $w.gnum]
  pack $f -side top -fill x
  ttk::label $f.l1 -textvar ::tr(GlistGameNumber:) -font $bold
  ttk::entry $f.emin -textvariable sGnumMin -width 8 -justify right -font $regular
  ttk::label $f.l2 -text "-" -font $regular
  ttk::entry $f.emax -textvariable sGnumMax -width 8 -justify right -font $regular
  pack $f.l1 $f.emin $f.l2 $f.emax -side left
  bindFocusColors $f.emin
  bindFocusColors $f.emax
  ttk::label $f.l3 -text " " -font $regular
  ttk::button $f.all -text [::utils::string::Capital $::tr(all)] -style Pad0.Small.TButton -command {set sGnumMin 1; set sGnumMax -1}
  ttk::menubutton $f.first -style pad0.TMenubutton -textvar ::tr(First...) -menu $f.first.m
  ttk::menubutton $f.last -style pad0.TMenubutton -textvar ::tr(Last...) -menu $f.last.m
  menu $f.first.m -font $regular
  menu $f.last.m -font $regular
  foreach x {10 50 100 500 1000 5000 10000} {
    $f.first.m add command -label $x \
        -command "set sGnumMin 1; set sGnumMax $x"
    $f.last.m add command -label $x \
        -command "set sGnumMin -$x; set sGnumMax -1"
  }
  pack $f.l3 $f.all $f.first $f.last -side left -padx 2
  
  set f [ttk::frame $w.pgntext]
  pack $f -side top -fill x
  ttk::label $f.l1 -textvar ::tr(PgnContains:) -font $bold
  ttk::entry $f.e1 -textvariable sPgntext(1) -width 15 -font $regular
  ttk::label $f.l2 -text "+" -font $regular
  ttk::entry $f.e2 -textvariable sPgntext(2) -width 15 -font $regular
  ttk::label $f.l3 -text "+" -font $regular
  ttk::entry $f.e3 -textvariable sPgntext(3) -width 15 -font $regular
  bindFocusColors $f.e1
  bindFocusColors $f.e2
  bindFocusColors $f.e3
  pack $f.l1 $f.e1 $f.l2 $f.e2 $f.l3 $f.e3 -side left
  
  addHorizontalRule $w
  
  ttk::button $w.flagslabel -textvar ::tr(FindGamesWith:) -style Pad0.Small.TButton -image bluetriangle -compound left -command {
    if {$sHeaderFlagFrame} {
      set sHeaderFlagFrame 0
      pack forget .sh.flags
    } else {
      set sHeaderFlagFrame 1
      pack .sh.flags -side top -after .sh.flagslabel
    }
  }
  pack $w.flagslabel -side top -fill x
  
  ttk::frame $w.flags
  if {$::sHeaderFlagFrame} {
    pack $w.flags -side top
  }
  
  set count 0
  set row 0
  set col 0
  foreach var $::sHeaderFlagList {   
    set lab [ttk::label $w.flags.l$var -text  [ ::tr $var ] -font font_Small]
    grid $lab -row $row -column $col -sticky e
    incr col
    grid [ttk::radiobutton $w.flags.yes$var -variable sHeaderFlags($var) -value yes -text $::tr(Yes)] -row $row -column $col
    incr col
    grid [ttk::radiobutton $w.flags.no$var -variable sHeaderFlags($var) -value no -text $::tr(No)] -row $row -column $col
    incr col
    grid [ttk::radiobutton $w.flags.both$var -variable sHeaderFlags($var) -value both -text $::tr(Both)] -row $row -column $col
    incr count
    incr col -3
    incr row
    if {$count == 6} { set col 5; set row 0 }
    if {$count == 12} { set col 10; set row 0 }
  }
  
  set count 1
  set col 0
  set row 7
  foreach var $::sHeaderCustomFlagList {
    
    set lb [sc_game flag $count description]
    if { $lb == ""  } {  set lb $var  }
    
    set lab [ttk::label $w.flags.l$var -text $lb -font font_Small]
    grid $lab -row $row -column $col -sticky e
    incr col
    grid [ttk::radiobutton $w.flags.yes$var -variable sHeaderFlags($var) -value yes -text $::tr(Yes)] -row $row -column $col
    incr col
    grid [ttk::radiobutton $w.flags.no$var -variable sHeaderFlags($var) -value no -text $::tr(No)] -row $row -column $col
    incr col
    grid [ttk::radiobutton $w.flags.both$var -variable sHeaderFlags($var) -value both -text $::tr(Both)] -row $row -column $col
    incr col 2
    incr count
    if {$count == 4} { set col 0; set row 8 }
  }
  
  grid [ttk::label $w.flags.space -text "" -font $regular] -row 0 -column 4
  grid [ttk::label $w.flags.space2 -text "" -font $regular] -row 0 -column 9
  
  addHorizontalRule $w
  ::search::addFilterOpFrame $w 1
  addHorizontalRule $w
  
  ### Header search: search/cancel buttons
  
  ttk::frame $w.b
  pack $w.b -side top -fill both
  ttk::button $w.b.defaults -textvar ::tr(Defaults) -command ::search::header::defaults ;# -padx 20
  ttk::button $w.b.save -textvar ::tr(Save...) -command ::search::header::save ;# -padx 20
  ttk::button $w.b.stop -textvar ::tr(Stop) -command sc_progressBar
  ttk::button $w.b.search -textvar ::tr(Search) -command {
    ::utils::history::AddEntry HeaderSearchWhite $sWhite
    ::utils::history::AddEntry HeaderSearchBlack $sBlack
    ::utils::history::AddEntry HeaderSearchEvent $sEvent
    ::utils::history::AddEntry HeaderSearchSite $sSite
    
    set sPgnlist {}
    foreach i {1 2 3} {
      set temp [string trim $sPgntext($i)]
      if {$temp != ""} { lappend sPgnlist $temp }
    }
    busyCursor .
    pack .sh.b.stop -side right -padx 5
    grab .sh.b.stop
    sc_progressBar .sh.fprogress.progress bar 301 21 time
    set wtitles {}
    set btitles {}
    foreach i $sTitleList {
      if $sTitles(w:$i) { lappend wtitles $i }
      if $sTitles(b:$i) { lappend btitles $i }
    }
    
    if {($sWhite == "!me") || ($sBlack == "!me")} {
      set i 0
      foreach name $::myPlayerNames {
        
        set filter 0
        
        if {$i == 0} {
          set filter 2
        } else {
          set filter 1
        }
        set i [expr {$i+1}]
        set wname $sWhite
        set bname $sBlack
        
        if {$sWhite == "!me"} {
          set wname $name
        }
        if {$sBlack == "!me"} {
          set bname $name
        }
        set str [sc_search header  \
            -white $wname           \
            -black $bname           \
            -toMove $sSideToMove \
            -results [list $sResWin $sResDraw $sResLoss $sResOther] \
            -event $sEvent -site $sSite -round $sRound \
            -date [list $sDateMin $sDateMax] \
            -welo [list $sWhiteEloMin $sWhiteEloMax] \
            -belo [list $sBlackEloMin $sBlackEloMax] \
            -delo [list $sEloDiffMin $sEloDiffMax] \
            -eco [list $sEcoMin $sEcoMax $sEco] \
            -length [list $sGlMin $sGlMax] \
            -gameNumber [list $sGnumMin $sGnumMax] \
            -flip $sIgnoreCol -filter $filter \
            -annotated $sAnnotated \
            -annotator $sAnnotator \
            -fStdStart $sHeaderFlags(StdStart) \
            -fPromotions $sHeaderFlags(Promotions) \
            -fComments $sHeaderFlags(Comments) \
            -fVariations $sHeaderFlags(Variations) \
            -fAnnotations $sHeaderFlags(Annotations) \
            -fDelete $sHeaderFlags(DeleteFlag) \
            -fWhiteOp $sHeaderFlags(WhiteOpFlag) \
            -fBlackOp $sHeaderFlags(BlackOpFlag) \
            -fMiddlegame $sHeaderFlags(MiddlegameFlag) \
            -fEndgame $sHeaderFlags(EndgameFlag) \
            -fNovelty $sHeaderFlags(NoveltyFlag) \
            -fPawnStruct $sHeaderFlags(PawnFlag) \
            -fTactics $sHeaderFlags(TacticsFlag) \
            -fKingside $sHeaderFlags(KsideFlag) \
            -fQueenside $sHeaderFlags(QsideFlag) \
            -fBrilliancy $sHeaderFlags(BrilliancyFlag) \
            -fBlunder $sHeaderFlags(BlunderFlag) \
            -fUser $sHeaderFlags(UserFlag) \
            -fCustom1 $sHeaderFlags(CustomFlag1) \
            -fCustom2 $sHeaderFlags(CustomFlag2) \
            -fCustom3 $sHeaderFlags(CustomFlag3) \
            -fCustom4 $sHeaderFlags(CustomFlag4) \
            -fCustom5 $sHeaderFlags(CustomFlag5) \
            -fCustom6 $sHeaderFlags(CustomFlag6) \
            -pgn $sPgnlist -wtitles $wtitles -btitles $btitles \
            ]
      }
    } elseif {($sWhite == "!mymove") || ($sBlack == "!mymove")} {
      set i 0
      foreach name $::myPlayerNames {
        
        set filter 0
        
        if {$i == 0} {
          set filter 2
        } else {
          set filter 1
        }
        
        set str [sc_search header  \
            -white $name            \
            -toMove w               \
            -results [list 0 0 0 1] \
            -event $sEvent -site $sSite -round $sRound \
            -date [list $sDateMin $sDateMax] \
            -welo [list $sWhiteEloMin $sWhiteEloMax] \
            -belo [list $sBlackEloMin $sBlackEloMax] \
            -delo [list $sEloDiffMin $sEloDiffMax] \
            -eco [list $sEcoMin $sEcoMax $sEco] \
            -length [list $sGlMin $sGlMax] \
            -gameNumber [list $sGnumMin $sGnumMax] \
            -flip $sIgnoreCol -filter $filter \
            -annotated $sAnnotated \
            -annotator $sAnnotator \
            -fStdStart $sHeaderFlags(StdStart) \
            -fPromotions $sHeaderFlags(Promotions) \
            -fComments $sHeaderFlags(Comments) \
            -fVariations $sHeaderFlags(Variations) \
            -fAnnotations $sHeaderFlags(Annotations) \
            -fDelete $sHeaderFlags(DeleteFlag) \
            -fWhiteOp $sHeaderFlags(WhiteOpFlag) \
            -fBlackOp $sHeaderFlags(BlackOpFlag) \
            -fMiddlegame $sHeaderFlags(MiddlegameFlag) \
            -fEndgame $sHeaderFlags(EndgameFlag) \
            -fNovelty $sHeaderFlags(NoveltyFlag) \
            -fPawnStruct $sHeaderFlags(PawnFlag) \
            -fTactics $sHeaderFlags(TacticsFlag) \
            -fKingside $sHeaderFlags(KsideFlag) \
            -fQueenside $sHeaderFlags(QsideFlag) \
            -fBrilliancy $sHeaderFlags(BrilliancyFlag) \
            -fBlunder $sHeaderFlags(BlunderFlag) \
            -fUser $sHeaderFlags(UserFlag) \
            -fCustom1 $sHeaderFlags(CustomFlag1) \
            -fCustom2 $sHeaderFlags(CustomFlag2) \
            -fCustom3 $sHeaderFlags(CustomFlag3) \
            -fCustom4 $sHeaderFlags(CustomFlag4) \
            -fCustom5 $sHeaderFlags(CustomFlag5) \
            -fCustom6 $sHeaderFlags(CustomFlag6) \
            -pgn $sPgnlist -wtitles $wtitles -btitles $btitles \
            ]
        
        set str [sc_search header  \
            -black $name            \
            -toMove b               \
            -results [list 0 0 0 1] \
            -event $sEvent -site $sSite -round $sRound \
            -date [list $sDateMin $sDateMax] \
            -welo [list $sWhiteEloMin $sWhiteEloMax] \
            -belo [list $sBlackEloMin $sBlackEloMax] \
            -delo [list $sEloDiffMin $sEloDiffMax] \
            -eco [list $sEcoMin $sEcoMax $sEco] \
            -length [list $sGlMin $sGlMax] \
            -gameNumber [list $sGnumMin $sGnumMax] \
            -flip $sIgnoreCol -filter $filter \
            -annotated $sAnnotated \
            -annotator $sAnnotator \
            -fStdStart $sHeaderFlags(StdStart) \
            -fPromotions $sHeaderFlags(Promotions) \
            -fComments $sHeaderFlags(Comments) \
            -fVariations $sHeaderFlags(Variations) \
            -fAnnotations $sHeaderFlags(Annotations) \
            -fDelete $sHeaderFlags(DeleteFlag) \
            -fWhiteOp $sHeaderFlags(WhiteOpFlag) \
            -fBlackOp $sHeaderFlags(BlackOpFlag) \
            -fMiddlegame $sHeaderFlags(MiddlegameFlag) \
            -fEndgame $sHeaderFlags(EndgameFlag) \
            -fNovelty $sHeaderFlags(NoveltyFlag) \
            -fPawnStruct $sHeaderFlags(PawnFlag) \
            -fTactics $sHeaderFlags(TacticsFlag) \
            -fKingside $sHeaderFlags(KsideFlag) \
            -fQueenside $sHeaderFlags(QsideFlag) \
            -fBrilliancy $sHeaderFlags(BrilliancyFlag) \
            -fBlunder $sHeaderFlags(BlunderFlag) \
            -fUser $sHeaderFlags(UserFlag) \
            -fCustom1 $sHeaderFlags(CustomFlag1) \
            -fCustom2 $sHeaderFlags(CustomFlag2) \
            -fCustom3 $sHeaderFlags(CustomFlag3) \
            -fCustom4 $sHeaderFlags(CustomFlag4) \
            -fCustom5 $sHeaderFlags(CustomFlag5) \
            -fCustom6 $sHeaderFlags(CustomFlag6) \
            -pgn $sPgnlist -wtitles $wtitles -btitles $btitles \
            ]
        
        set i [expr {$i+1}]
      }
    } else {
      set str [sc_search header -white $sWhite -black $sBlack \
          -event $sEvent -site $sSite -round $sRound \
          -date [list $sDateMin $sDateMax] \
          -results [list $sResWin $sResDraw $sResLoss $sResOther] \
          -welo [list $sWhiteEloMin $sWhiteEloMax] \
          -belo [list $sBlackEloMin $sBlackEloMax] \
          -delo [list $sEloDiffMin $sEloDiffMax] \
          -eco [list $sEcoMin $sEcoMax $sEco] \
          -length [list $sGlMin $sGlMax] \
          -toMove $sSideToMove \
          -gameNumber [list $sGnumMin $sGnumMax] \
          -flip $sIgnoreCol -filter $::search::filter::operation \
          -annotated $sAnnotated \
          -annotator $sAnnotator \
          -fStdStart $sHeaderFlags(StdStart) \
          -fPromotions $sHeaderFlags(Promotions) \
          -fComments $sHeaderFlags(Comments) \
          -fVariations $sHeaderFlags(Variations) \
          -fAnnotations $sHeaderFlags(Annotations) \
          -fDelete $sHeaderFlags(DeleteFlag) \
          -fWhiteOp $sHeaderFlags(WhiteOpFlag) \
          -fBlackOp $sHeaderFlags(BlackOpFlag) \
          -fMiddlegame $sHeaderFlags(MiddlegameFlag) \
          -fEndgame $sHeaderFlags(EndgameFlag) \
          -fNovelty $sHeaderFlags(NoveltyFlag) \
          -fPawnStruct $sHeaderFlags(PawnFlag) \
          -fTactics $sHeaderFlags(TacticsFlag) \
          -fKingside $sHeaderFlags(KsideFlag) \
          -fQueenside $sHeaderFlags(QsideFlag) \
          -fBrilliancy $sHeaderFlags(BrilliancyFlag) \
          -fBlunder $sHeaderFlags(BlunderFlag) \
          -fUser $sHeaderFlags(UserFlag) \
          -fCustom1 $sHeaderFlags(CustomFlag1) \
          -fCustom2 $sHeaderFlags(CustomFlag2) \
          -fCustom3 $sHeaderFlags(CustomFlag3) \
          -fCustom4 $sHeaderFlags(CustomFlag4) \
          -fCustom5 $sHeaderFlags(CustomFlag5) \
          -fCustom6 $sHeaderFlags(CustomFlag6) \
          -pgn $sPgnlist -wtitles $wtitles -btitles $btitles \
          ]
    }
    
    grab release .sh.b.stop
    pack forget .sh.b.stop
    unbusyCursor .
    
    .sh.status configure -text $str
    set glstart 1
    ::windows::gamelist::Refresh
    ::search::loadFirstGame
    
	 # refresh the tree window, this includes Best Games
	 ::tree::refresh
    ::windows::stats::Refresh
  }
  
  ttk::button $w.b.cancel -textvar ::tr(Close) -command {focus .; destroy .sh} ;# -padx 20
  
  foreach i {defaults save cancel search stop} {
    $w.b.$i configure -style Small.TButton
    
    pack $w.b.defaults $w.b.save -side left -padx 5
    pack $w.b.cancel $w.b.search -side right -padx 5
  }
  
  pack [ ttk::frame $w.fprogress ] -fill both
  canvas $w.fprogress.progress -height 20 -width 300 -bg white -relief solid -border 1
  $w.fprogress.progress create rectangle 0 0 0 0 -fill blue -outline blue -tags bar
  $w.fprogress.progress create text 295 10 -anchor e -font font_Regular -tags time \
      -fill black -text "0:00 / 0:00"
  pack $w.fprogress.progress -side top -pady 2
  ttk::label $w.status -text "" -width 1 -font font_Small -relief sunken -anchor w
  pack $w.status -side bottom -fill x
  # update
  wm resizable $w 0 0
  # standardShortcuts $w
  ::search::Config
  focus $w.cWhite.e
}

proc ::search::header::save {} {
  global sWhite sBlack sEvent sSite sRound sAnnotator sAnnotated sDateMin sDateMax sIgnoreCol
  global sWhiteEloMin sWhiteEloMax sBlackEloMin sBlackEloMax
  global sEloDiffMin sEloDiffMax sGlMin sGlMax
  global sEco sEcoMin sEcoMax sHeaderFlags sSideToMove
  global sResWin sResLoss sResDraw sResOther glstart sPgntext
  
  set ftype { { "Scid SearchOptions files" {".sso"} } }
  set fName [tk_getSaveFile -initialdir [pwd] -filetypes $ftype -title "Create a SearchOptions file"]
  if {$fName == ""} { return }
  
  if {[string compare [file extension $fName] ".sso"] != 0} {
    append fName ".sso"
  }
  
  if {[catch {set searchF [open [file nativename $fName] w]} ]} {
    tk_messageBox -title "Error: Unable to open file" -type ok -icon error \
        -message "Unable to create SearchOptions file: $fName"
    return
  }
  puts $searchF "\# SearchOptions File created by Scid [sc_info version]"
  puts $searchF "set searchType Header"
  
  # First write the regular variables:
  foreach i {sWhite sBlack sEvent sSite sRound sAnnotator sAnnotated sDateMin sDateMax sResWin
    sResLoss sResDraw sResOther sWhiteEloMin sWhiteEloMax sBlackEloMin
    sBlackEloMax sEcoMin sEcoMax sEloDiffMin sEloDiffMax
    sIgnoreCol sSideToMove sGlMin sGlMax ::search::filter::operation} {
    puts $searchF "set $i [list [set $i]]"
  }
  # Now write the array values:
  foreach i [array names sHeaderFlags] {
    puts $searchF "set sHeaderFlags($i) [list $sHeaderFlags($i)]"
  }
  foreach i [array names sPgntext] {
    puts $searchF "set sPgntext($i) [list $sPgntext($i)]"
  }
  
  tk_messageBox -type ok -icon info -title "Search Options saved" \
      -message "Header search options saved to: $fName"
  close $searchF
}

##############################
### Selecting common ECO ranges

set scid_ecoRangeChosen ""
set ecoCommonRanges {}
proc chooseEcoRange {} {
  global ecoCommonRanges scid_ecoRangeChosen
  set ecoCommonRanges [ list \
      "A04-A09  [tr Reti]: [trans 1.Nf3]" \
      "A10-A39  [tr English]: 1.c4" \
      "A40-A49  1.d4, [tr d4Nf6Miscellaneous]" \
      "A45l-A45z  [tr Trompowsky]: [trans [list 1.d4 Nf6 2.Bg5]]" \
      "A51-A52  [tr Budapest]: [trans [list 1.d4 Nf6 2.c4 e5]]" \
      "A53-A55  [tr OldIndian]: [trans [list 1.d4 Nf6 2.c4 d6]]" \
      "A57-A59  [tr BenkoGambit]: [trans [list 1.d4 Nf6 2.c4 c5 3.d5 b5]]" \
      "A60-A79  [tr ModernBenoni]: [trans [list 1.d4 Nf6 2.c4 c5 3.d5 e6]]" \
      "A80-A99  [tr DutchDefence]: 1.d4 f5" \
      "____________________________________________________________" \
      "B00-C99  1.e4" \
      "B01-B01     [tr Scandinavian]: 1.e4 d5" \
      "B02-B05     [tr AlekhineDefence]: [trans [list 1.e4 Nf6]]" \
      "B07-B09     [tr Pirc]: 1.e4 d6" \
      "B10-B19     [tr CaroKann]: 1.e4 c6" \
      "B12i-B12z      [tr CaroKannAdvance]: 1.e4 c6 2.d4 d5 3.e5" \
      "B20-B99  [tr Sicilian]: 1.e4 c5" \
      "B22-B22     [tr SicilianAlapin]: 1.e4 c5 2.c3" \
      "B23-B26     [tr SicilianClosed]: [trans [list 1.e4 c5 2.Nc3]]" \
      "B30-B39     [tr Sicilian]: [trans [list 1.e4 c5 2.Nf3 Nc6]]" \
      "B40-B49     [tr Sicilian]: [trans [list 1.e4 c5 2.Nf3 e6]]" \
      "B50-B59     [tr SicilianRauzer]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 Nc6]]" \
      "B70-B79     [tr SicilianDragon]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 g6]]" \
      "B80-B89     [tr SicilianScheveningen]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 e6]]" \
      "B90-B99     [tr SicilianNajdorf]: [trans [list 1.e4 c5 2.Nf3 d6 ... 5.Nc3 a6]]" \
      "____________________________________________________________" \
      "C00-C19  [tr FrenchDefence]: 1.e4 e6" \
      "C02-C02     [tr FrenchAdvance]: 1.e4 e6 2.d4 d5 3.e5" \
      "C03-C09     [tr FrenchTarrasch]: [trans [list 1.e4 e6 2.d4 d5 3.Nd2]]" \
      "C15-C19     [tr FrenchWinawer]: [trans [list 1.e4 e6 2.d4 d5 3.Nc3 Bb4]]" \
      "C20-C99  [tr OpenGame]: 1.e4 e5" \
      "C25-C29     [tr Vienna]: [trans [list 1.e4 e5 2.Nc3]]" \
      "C30-C39     [tr KingsGambit]: 1.e4 e5 2.f4" \
      "C42-C43     [tr RussianGame]: [trans [list 1.e4 e5 2.Nf3 Nf6]]" \
      "C44-C49     [tr OpenGame]: [trans [list 1.e4 e5 2.Nf3 Nc6]]" \
      "C50-C59     [tr ItalianTwoKnights]: 1.e4 e5 2.Nf3 Nc6 3.Bc4]]" \
      "C60-C99  [tr Spanish]: [trans [list 1.e4 e5 2.Nf3 Nc6 3.Bb5]]" \
      "C68-C69      [tr SpanishExchange]: [trans [list 3.Bb5 a6 4.Bxc6]]" \
      "C80-C83      [tr SpanishOpen]: [trans [list 3.Bb5 a6 4.Ba4 Nf6 5.O-O Nxe4]]" \
      "C84-C99      [tr SpanishClosed]: [trans [list 3.Bb5 a6 4.Ba4 Nf6 5.O-O Be7]]" \
      "____________________________________________________________" \
      "D00-D99  [tr Queen's Pawn]: 1.d4 d5" \
      "D10-D19  [tr Slav]: 1.d4 d5 2.c4 c6" \
      "D20-D29  [tr QGA]: 1.d4 d5 2.c4 dxc4" \
      "D30-D69  [tr QGD]: 1.d4 d5 2.c4 e6" \
      "D35-D36     [tr QGDExchange]: 1.d4 d5 2.c4 e6 3.cxd5 exd5" \
      "D43-D49     [tr SemiSlav]: [trans [list 3.Nc3 Nf6 4.Nf3 c6]]" \
      "D50-D69     [tr QGDwithBg5]: [trans [list 1.d4 d5 2.c4 e6 3.Nc3 Nf6 4.Bg5]]" \
      "D60-D69     [tr QGDOrthodox]: [trans [list 4.Bg5 Be7 5.e3 O-O 6.Nf3 Nbd7]]" \
      "D70-D99  [tr Grunfeld]: [trans [list 1.d4 Nf6 2.c4 g6 with 3...d5]]" \
      "D85-D89     [tr GrunfeldExchange]: [trans [list 3.Nc3 d5 4.e4 Nxc3 5.bxc3]]" \
      "D96-D99     [tr GrunfeldRussian]: [trans [list 3.Nc3 d5 4.Nf3 Bg7 5.Qb3]]" \
      "____________________________________________________________" \
      "E00-E09  [tr Catalan]: [trans [list 1.d4 Nf6 2.c4 e6 3.g3/...]]" \
      "E02-E05     [tr CatalanOpen]: [trans [list 3.g3 d5 4.Bg2 dxc4]]" \
      "E06-E09     [tr CatalanClosed]: [trans [list 3.g3 d5 4.Bg2 Be7]]" \
      "E12-E19  [tr QueensIndian]: [trans [list 1.d4 Nf6 2.c4 e6 3.Nf3 b6]]" \
      "E20-E59  [tr NimzoIndian]: [trans [list 1.d4 Nf6 2.c4 e6 3.Nc3 Bb4]]" \
      "E32-E39     [tr NimzoIndianClassical]: [trans [list 4.Qc2]]" \
      "E40-E59     [tr NimzoIndianRubinstein]: 4.e3" \
      "E60-E99  [tr KingsIndian]: [trans [list 1.d4 Nf6 2.c4 g6]]" \
      "E80-E89     [tr KingsIndianSamisch]: 4.e4 d6 5.f3" \
      "E90-E99     [tr KingsIndianMainLine]: [trans [list 4.e4 d6 5.Nf3]]" \
      ]
  
  if {[winfo exists .ecoRangeWin]} { return }
  set w .ecoRangeWin
  toplevel $w
  wm title $w "Scid: Choose ECO Range"
  wm minsize $w 30 5
  
  listbox $w.list -yscrollcommand "$w.ybar set" -height 20 -width 60 -background white -setgrid 1
  foreach i $ecoCommonRanges { $w.list insert end $i }
  ttk::scrollbar $w.ybar -command "$w.list yview" -takefocus 0
  pack [ttk::frame $w.b] -side bottom -fill x
  pack $w.ybar -side right -fill y
  pack $w.list -side left -fill both -expand yes
  
  ttk::button $w.b.ok -text "OK" -command {
    set sel [.ecoRangeWin.list curselection]
    if {[llength $sel] > 0} {
      set scid_ecoRangeChosen [lindex $ecoCommonRanges [lindex $sel 0]]
      set ::sEco No
    }
    focus .sh
    destroy .ecoRangeWin
  }
  ttk::button $w.b.cancel -text $::tr(Cancel) -command "focus .sh; destroy $w"
  pack $w.b.cancel $w.b.ok -side right -padx 5 -pady 2
  bind $w <Escape> "
  set scid_ecoRangeChosen {}
  grab release $w
  focus .
  destroy $w
  break"
  bind $w <Return> "$w.b.ok invoke; break"
  bind $w.list <Double-ButtonRelease-1> "$w.b.ok invoke; break"
  focus $w.list
  grab $w
  tkwait window $w
  return $scid_ecoRangeChosen
}


###
### End of file: search.tcl