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