Scid  4.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
board.tcl
Go to the documentation of this file.
1 # Copyright (C) 2018-2019 Fulvio Benini
2 #
3 # This file is part of Scid (Shane's Chess Information Database).
4 #
5 # Scid is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation.
8 #
9 # Scid is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with Scid. If not, see <http://www.gnu.org/licenses/>.
16 
17 namespace eval ::search {}
18 
19 # Create a search window using a common framework.
20 # It manages the database, the filter and the and/or/reset combination of the
21 # results with the previous filter's values.
22 # @param create_subwnd: a function that creates all the specific widgets of a
23 # search window. Should return a valid command that when
24 # evaluated returns a list of the search's options.
25 proc ::search::Open {ref_base ref_filter title create_subwnd} {
26  set w ".wnd_$title"
27  if {[winfo exists $w]} { destroy $w}
29  ::setTitle $w [::tr $title]
30 
31  grid [ttk::frame $w.refdb] -sticky news
32  CreateSelectDBWidget "$w.refdb" "::search::dbase_($w)" "$ref_base"
33  trace add variable ::search::dbase_($w) write ::search::use_dbfilter_
34  set ::search::filter_($w) $ref_filter
35 
36  grid [ttk::frame $w.options] -sticky news
37  set options_cmd [$create_subwnd $w.options]
38 
39  grid [ttk::labelframe $w.filterOp] -sticky news -pady 8
40  if {![info exists ::search::filterOp_($w)]} {
41  set ::search::filterOp_($w) reset
42  }
43  ttk::radiobutton $w.filterOp.and -text [::tr FilterAnd] -variable ::search::filterOp_($w) -value and
44  ttk::radiobutton $w.filterOp.or -text [::tr FilterOr] -variable ::search::filterOp_($w) -value or
45  ttk::radiobutton $w.filterOp.reset -text [::tr FilterIgnore] -variable ::search::filterOp_($w) -value reset
46  grid $w.filterOp.and $w.filterOp.or $w.filterOp.reset -ipadx 8
47 
48  grid [ttk::frame $w.buttons] -sticky news
49  ttk::button $w.buttons.save -text [::tr Save] -state disabled \
50  -command "::search::save_ $options_cmd"
51  ttk::button $w.buttons.reset_values -text [::tr Defaults] \
52  -command "set ::search::filterOp_($w) reset; $options_cmd reset"
53  ttk::button $w.buttons.search_new -text "[tr Search] ([tr GlistNewSort] [tr Filter])" \
54  -command "::search::start_ 1 $w $options_cmd"
55  ttk::button $w.buttons.search -text [::tr Search] \
56  -command "::search::start_ 0 $w $options_cmd"
57  grid $w.buttons.save $w.buttons.reset_values x $w.buttons.search_new $w.buttons.search -sticky w -padx "0 5"
58  grid columnconfigure $w.buttons 2 -weight 1
59 
60  ttk::button $w.buttons.stop -text [::tr Stop] -command progressBarCancel
61  canvas $w.progressbar -width 300 -height 20 -bg white -relief solid -border 1 -highlightthickness 0
62  $w.progressbar create rectangle 0 0 0 0 -fill blue -outline blue -tags bar
63  $w.progressbar create text 295 10 -anchor e -font font_Regular -tags time
64  grid $w.buttons.stop -row 0 -column 0
65  grid $w.progressbar -in $w.buttons -row 0 -column 1 -columnspan 4
66  progressbar_ $w hide
67 
68  bind $w <Return> "$w.buttons.search invoke"
69  bind $w.buttons.search <Destroy> "unset ::search::dbase_($w)"
70 
72 }
73 
74 proc ::search::CloseAll {} {
75  foreach {w} [array names ::search::dbase_] {
76  destroy $w
77  }
78 }
79 
80 proc ::search::DatabaseModified {{dbase} {filter -1}} {
81  foreach {w w_base} [array get ::search::dbase_] {
82  if {$dbase == $w_base} {
83  if {$filter == -1 || $filter eq $::search::filter_($w)} {
85  }
86  }
87  }
88 }
89 
90 proc ::search::refresh_ {w} {
91  if {[catch {
92  lassign [sc_filter sizes $::search::dbase_($w) $::search::filter_($w)] filterSz gameSz
93  }]} {
94  destroy $w
95  return
96  }
97  set n_games [::windows::gamelist::formatFilterText $filterSz $gameSz]
98  $w.filterOp configure -text "[::tr FilterOperation] ($n_games)"
99 }
100 
101 proc ::search::use_dbfilter_ { unused1 w {unused2 ""} } {
102  set ::search::filter_($w) dbfilter
103 }
104 
105 proc ::search::progressbar_ {w show_hide} {
106  if {$show_hide eq "show"} {
107  grid remove $w.buttons.save
108  grid remove $w.buttons.reset_values
109  grid remove $w.buttons.search_new
110  grid remove $w.buttons.search
111  grid $w.progressbar
112  progressBarSet $w.progressbar 301 21
113  grid $w.buttons.stop
114  grab $w.buttons.stop
115  } else {
116  grab release $w.buttons.stop
117  grid remove $w.buttons.stop
118  grid remove $w.progressbar
119  grid $w.buttons.save
120  grid $w.buttons.reset_values
121  grid $w.buttons.search_new
122  grid $w.buttons.search
123  }
124 }
125 
126 proc ::search::save_ {options_cmd} {
127  # TODO:
128 }
129 
130 proc ::search::start_ {new_filter w options_cmd} {
131  set dbase $::search::dbase_($w)
132  set src_filter $::search::filter_($w)
133  set src_op $::search::filterOp_($w)
134 
135  if {$new_filter} {
136  set dest_filter [sc_filter new $dbase]
137  } else {
138  set dest_filter [sc_filter compose $dbase $src_filter ""]
139  }
140  if {$dest_filter ne $src_filter && $src_op ne "reset"} {
141  sc_filter copy $dbase $dest_filter $src_filter
142  }
143 
144  lassign [$options_cmd] options ignore_color_hack
145  if {$ignore_color_hack ne ""} {
146  set filter_hack [sc_filter new $dbase]
147  sc_filter copy $dbase $filter_hack $dest_filter
148  }
149 
150  ::search::progressbar_ $w show
151  set err [catch {::search::do_search_ $dbase $dest_filter $src_op $options}]
152  ::search::progressbar_ $w hide
153  if {$err} {
154  if {$::errorCode != $::ERROR::UserCancel} { ERROR::MessageBox}
155  }
156 
157  if {!$err && $ignore_color_hack ne ""} {
158  ::search::progressbar_ $w show
159  set err [catch {::search::do_search_ $dbase $filter_hack $src_op $ignore_color_hack}]
160  ::search::progressbar_ $w hide
161  if {$err} {
162  if {$::errorCode != $::ERROR::UserCancel} { ERROR::MessageBox}
163  } else {
164  sc_filter or $dbase $dest_filter $filter_hack
165  }
166  }
167  if {$ignore_color_hack ne ""} {
168  sc_filter release $dbase $filter_hack
169  }
170 
171  set ::search::filter_($w) $dest_filter
172  ::notify::DatabaseModified $dbase $dest_filter
173 
174  if {$new_filter} {
175  ::windows::gamelist::Open $dbase $dest_filter
176  }
177 }
178 
179 proc ::search::do_search_ {dbase filter filter_op options} {
180  switch $filter_op {
181  reset {
182  sc_filter reset $dbase $filter full
183  }
184  and {
185  }
186  or {
187  set or_filter [sc_filter new $dbase]
188  sc_filter copy $dbase $or_filter $filter
189  sc_filter negate $dbase $filter
190  }
191  }
192 
193  sc_filter search $dbase $filter {*}$options -filter AND
194 
195  if {[info exists or_filter]} {
196  sc_filter or $dbase $filter $or_filter
197  sc_filter release $dbase $or_filter
198  }
199 }
200 
201 
202 # ::search::board
203 # Opens the search window for the current board position.
204 #
205 proc ::search::board {{ref_base ""} {ref_filter "dbfilter"}} {
206  ::search::Open $ref_base $ref_filter BoardSearch ::search::boardCreateFrame
207 }
208 
209 proc ::search::boardCreateFrame {w} {
210  if {![info exists ::search::boardOptType_]} {
212  }
213 
214  ttk::labelframe $w.pos -text [::tr SearchType]
215  grid $w.pos -sticky news -pady 6
216  grid columnconfigure $w 0 -weight 1
217 
218  ttk::radiobutton $w.pos.exact -textvar ::tr(SearchBoardExact) -variable ::search::boardOptType_ -value Exact
219  ttk::radiobutton $w.pos.pawns -textvar ::tr(SearchBoardPawns) -variable ::search::boardOptType_ -value Pawns
220  ttk::radiobutton $w.pos.files -textvar ::tr(SearchBoardFiles) -variable ::search::boardOptType_ -value Fyles
221  ttk::radiobutton $w.pos.material -textvar ::tr(SearchBoardAny) -variable ::search::boardOptType_ -value Material
222  grid $w.pos.exact -sticky w
223  grid $w.pos.pawns -sticky w
224  grid $w.pos.files -sticky w
225  grid $w.pos.material -sticky w
226 
227  ttk::checkbutton $w.vars -text [::tr LookInVars] -variable ::search::boardOptInVars_ -onvalue 1 -offvalue 0
228  grid $w.vars -sticky w
229 
230  ttk::checkbutton $w.flip -text [::tr IgnoreColors] -variable ::search::boardOptIgnoreCol_ -onvalue 1 -offvalue 0
231  grid $w.flip -sticky w
232 
233  return "::search::boardOptions"
234 }
235 
236 proc ::search::boardOptions {{cmd ""}} {
237  if {$cmd eq "reset"} {
238  set ::search::boardOptType_ Exact
239  set ::search::boardOptInVars_ 0
240  set ::search::boardOptIgnoreCol_ 0
241  return
242  }
243 
244  set options {board}
245  lappend options $::search::boardOptType_
246  lappend options $::search::boardOptInVars_
247  lappend options $::search::boardOptIgnoreCol_
248  return [list $options]
249 }