4 Website: http://www.vultaire.net/software/jben/
5 License: GNU General Public License (GPL) version 2
6 (http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt)
8 File: frame_ksearch_helpers.cpp
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>
24 #include "frame_ksearch_helpers.h"
26 #include <gtkmm/buttonbox.h>
27 #include <gtkmm/button.h>
28 #include <glibmm/i18n.h>
29 #include <boost/foreach.hpp>
30 #define foreach BOOST_FOREACH
33 typedef std::pair
<wchar_t, KInfo
> kdict_pair
;
34 typedef std::pair
<std::string
, SkipCode
> SkipMiscode
;
36 KSearchBox::KSearchBox(const Glib::ustring
& label
)
37 : Frame(label
), layout(false, 5) {
38 set_shadow_type(Gtk::SHADOW_ETCHED_IN
);
42 void KSearchBox::pack_start(Gtk::Widget
& child
,
43 Gtk::PackOptions options
, guint padding
) {
44 layout
.pack_start(child
, options
, padding
);
47 void KSearchBox::pack_end(Gtk::Widget
& child
,
48 Gtk::PackOptions options
, guint padding
) {
49 layout
.pack_end(child
, options
, padding
);
54 KSearchHW::KSearchHW()
55 : KSearchBox(_("Handwriting")), leftLayout(false, 5), btnClear(_("Clear")) {
56 khwp
.set_size_request(-1, 75);
57 btnClear
.signal_clicked()
58 .connect(sigc::mem_fun(*this, &KSearchHW::OnClear
));
60 buttons
.pack_start(btnClear
, Gtk::PACK_SHRINK
);
61 leftLayout
.pack_start(khwp
, Gtk::PACK_EXPAND_WIDGET
);
62 leftLayout
.pack_start(buttons
, Gtk::PACK_SHRINK
);
64 layout
.pack_start(leftLayout
, Gtk::PACK_EXPAND_WIDGET
);
67 std::list
<wchar_t> KSearchHW::Filter(std::list
<wchar_t> srcList
) {
68 std::list
<wchar_t> results
;
69 std::vector
<wchar_t> vwc
= khwp
.GetResults();
71 /* Append only the results which are also present in the source list. */
72 foreach(wchar_t& wc
, vwc
) {
73 if(find(srcList
.begin(), srcList
.end(), wc
) != srcList
.end())
74 results
.push_back(wc
);
79 void KSearchHW::OnClear() {
83 KSearchStroke::KSearchStroke()
84 : KSearchBox(_("Stroke Count")), leftLayout(false, 5),
85 strokeControls(false, 5),
86 allowCommonMiscounts(_("Include common stroke miscounts")),
87 miscountControls(false, 5),
88 allowMiscounts(_("Include stroke miscounts")), plusMinus(_("+/-")) {
89 strokeCount
.set_range(0, 40);
90 strokeCount
.set_digits(0);
91 strokeCount
.set_increments(1, 10);
92 strokeCount
.set_width_chars(2);
93 strokeCount
.set_text("0");
94 strokeCount
.set_activates_default(false);
95 miscountAdjust
.set_range(0,40);
96 miscountAdjust
.set_digits(0);
97 miscountAdjust
.set_increments(1, 1);
98 miscountAdjust
.set_width_chars(2);
99 miscountAdjust
.set_text("0");
100 miscountAdjust
.set_sensitive(false);
102 allowMiscounts
.signal_toggled()
103 .connect(sigc::mem_fun(*this, &KSearchStroke::OnMiscountToggled
));
105 strokeControls
.pack_start(strokeCount
, Gtk::PACK_SHRINK
);
106 miscountControls
.pack_start(allowMiscounts
, Gtk::PACK_SHRINK
);
107 miscountControls
.pack_start(plusMinus
, Gtk::PACK_SHRINK
);
108 miscountControls
.pack_start(miscountAdjust
, Gtk::PACK_SHRINK
);
109 leftLayout
.pack_start(strokeControls
, Gtk::PACK_SHRINK
);
110 leftLayout
.pack_start(allowCommonMiscounts
, Gtk::PACK_SHRINK
);
111 leftLayout
.pack_start(miscountControls
, Gtk::PACK_SHRINK
);
112 layout
.pack_start(leftLayout
, Gtk::PACK_EXPAND_WIDGET
);
115 std::list
<wchar_t> KSearchStroke::Filter(std::list
<wchar_t> srcList
) {
116 std::list
<wchar_t> results
;
119 if(allowMiscounts
.get_active())
120 mcAdj
= miscountAdjust
.get_value_as_int();
121 bool commonMistrokes
= allowCommonMiscounts
.get_active();
122 const KDict
* kd
= KDict::Get();
124 int sc
= strokeCount
.get_value_as_int();
126 /* Append only the results which are also present in the source list. */
127 foreach(wchar_t& wc
, srcList
) {
128 ki
= kd
->GetEntry(wc
);
129 if(ki
->strokeCount
>= sc
- mcAdj
&& ki
->strokeCount
<= sc
+ mcAdj
)
130 results
.push_back(wc
);
131 else if(commonMistrokes
) {
132 /* I'm -not- going to apply the miscount adjust when searching
133 lists of common mistrokes - kind of defeats the purpose, I
135 foreach(const int& miscount
, ki
->misstrokes
) {
137 results
.push_back(wc
);
146 void KSearchStroke::OnMiscountToggled() {
147 miscountAdjust
.set_sensitive(allowMiscounts
.get_active());
150 KSearchSKIP::KSearchSKIP()
151 : KSearchBox(_("SKIP search")), leftLayout(false, 5),
152 skipControls(false, 5), sep1(_("-")), sep2(_("-")),
153 allowMiscodes(_("Include SKIP miscodes")), miscountControls(false, 5),
154 allowMiscounts(_("Include stroke miscounts")), plusMinus(_("+/-")) {
156 /* Based on KANJIDIC2, the max values for these fields are as follows:
157 index1: 4 (by SKIP definition; should never change)
161 HOWEVER, let's not hard-code them. Set upper bounds to 30 on
162 index2/index3, and if we really need a specific upper bound, have it
163 determined on dictionary load time later. */
165 index1
.set_range(0, 4);
166 index1
.set_digits(0);
167 index1
.set_increments(1, 1);
168 index1
.set_width_chars(1);
169 index1
.set_text("0");
170 index1
.set_activates_default(false);
171 index2
.set_range(0, 30);
172 index2
.set_digits(0);
173 index2
.set_increments(1, 10);
174 index2
.set_width_chars(2);
175 index2
.set_text("0");
176 index2
.set_activates_default(false);
177 index3
.set_range(0, 30);
178 index3
.set_digits(0);
179 index3
.set_increments(1, 10);
180 index3
.set_width_chars(2);
181 index3
.set_text("0");
182 index3
.set_activates_default(false);
183 miscountAdjust
.set_range(0,30);
184 miscountAdjust
.set_digits(0);
185 miscountAdjust
.set_increments(1, 1);
186 miscountAdjust
.set_width_chars(2);
187 miscountAdjust
.set_text("0");
188 miscountAdjust
.set_sensitive(false);
189 allowMiscounts
.signal_toggled()
190 .connect(sigc::mem_fun(*this, &KSearchSKIP::OnMiscountToggled
));
192 skipControls
.pack_start(index1
, Gtk::PACK_SHRINK
);
193 skipControls
.pack_start(sep1
, Gtk::PACK_SHRINK
);
194 skipControls
.pack_start(index2
, Gtk::PACK_SHRINK
);
195 skipControls
.pack_start(sep2
, Gtk::PACK_SHRINK
);
196 skipControls
.pack_start(index3
, Gtk::PACK_SHRINK
);
197 miscountControls
.pack_start(allowMiscounts
, Gtk::PACK_SHRINK
);
198 miscountControls
.pack_start(plusMinus
, Gtk::PACK_SHRINK
);
199 miscountControls
.pack_start(miscountAdjust
, Gtk::PACK_SHRINK
);
200 leftLayout
.pack_start(skipControls
, Gtk::PACK_SHRINK
);
201 leftLayout
.pack_start(allowMiscodes
, Gtk::PACK_SHRINK
);
202 leftLayout
.pack_start(miscountControls
, Gtk::PACK_SHRINK
);
203 layout
.pack_start(leftLayout
, Gtk::PACK_EXPAND_WIDGET
);
206 std::list
<wchar_t> KSearchSKIP::Filter(std::list
<wchar_t> srcList
) {
207 std::list
<wchar_t> results
;
210 if(allowMiscounts
.get_active())
211 mcAdj
= miscountAdjust
.get_value_as_int();
212 bool miscodes
= allowMiscodes
.get_active();
213 const KDict
* kd
= KDict::Get();
215 int i1
= index1
.get_value_as_int();
216 int i2
= index2
.get_value_as_int();
217 int i3
= index3
.get_value_as_int();
219 /* Append only the results which are also present in the source list. */
220 foreach(wchar_t& wc
, srcList
) {
221 ki
= kd
->GetEntry(wc
);
222 if((i1
== 0 || ki
->qc_skip
.i1
== i1
) &&
224 (ki
->qc_skip
.i2
>= i2
- mcAdj
&& ki
->qc_skip
.i2
<= i2
+ mcAdj
)) &&
226 (ki
->qc_skip
.i3
>= i3
- mcAdj
&& ki
->qc_skip
.i3
<= i3
+ mcAdj
)))
227 results
.push_back(wc
);
229 foreach(const SkipMiscode
& code
, ki
->skipMisclass
) {
230 if((i1
== 0 || code
.second
.i1
== i1
) &&
232 (code
.second
.i2
>= i2
- mcAdj
&&
233 code
.second
.i2
<= i2
+ mcAdj
)) &&
235 (code
.second
.i3
>= i3
- mcAdj
&&
236 code
.second
.i3
<= i3
+ mcAdj
))) {
237 results
.push_back(wc
);
246 void KSearchSKIP::OnMiscountToggled() {
247 miscountAdjust
.set_sensitive(allowMiscounts
.get_active());