1 /***************************************************************************
2 Aldo
3 --------------------
4 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Giuseppe "denever" Martino
5 begin : Sun May 6 2001
6 email : denever@users.sourceforge.net
7 ***************************************************************************/
8 /***************************************************************************
9 * *
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. *
14 * *
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. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the Free Software *
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
23 * MA 02110-1301 USA *
24 * *
25 ***************************************************************************/
26
27 #include "resources.hh"
28
29 #include "menu.hh"
30 #include "dialog.hh"
31 #include "datafile.hh"
32 #include "skill.hh"
33
34 #include <string>
35 #include <cstdlib>
36
37 #define CONFIG_FILE ".aldorc"
38
39 using namespace std;
40 using namespace libmenu;
41 using namespace libdatafile;
42
43 /*
44 * This function returns the data structure containing
45 * the current configuration.
46 */
get_configuration()47 Datafile get_configuration()
48 {
49 string fileconf_name(getenv("HOME"));
50 fileconf_name += "/";
51 fileconf_name += CONFIG_FILE;
52 Datafile fileconf(fileconf_name, Update);
53 return fileconf;
54 }
55
56 /*
57 * This function offers the user te possibility to change a
58 * configuration option interactively.
59 * The option's old value is displayed in the prompt.
60 * Pressing Enter keeps the option's old value.
61 * This function automatically distinguishes between integer and string
62 * input values and sets the proper one.
63 */
update_option(opt_it option,const string & label)64 void update_option(opt_it option, const string& label)
65 {
66 string tmpstr;
67 unsigned int tmpint = option->get();
68
69 if(tmpint == 9999)
70 {
71 tmpstr = option->getstr();
72
73 do
74 {
75 cout << endl;
76 cout << label << " [";
77 cout << tmpstr;
78 cout << "]: ";
79
80 cin.clear();
81 }
82 while( ! getline(cin, tmpstr) );
83
84 // if input is empty, keep current value unchanged
85 if(tmpstr[0] == '\0')
86 return;
87
88 option->set(tmpstr);
89 }
90 else
91 {
92 do
93 {
94 cout << endl;
95 cout << label << " [";
96 cout << tmpint;
97 cout << "]: ";
98
99 cin.clear();
100 }
101 while( ! getline(cin, tmpstr) );
102
103 // if input is empty, keep current value unchanged
104 if(tmpstr[0] == '\0')
105 return;
106
107 tmpint = (unsigned int)atoi(tmpstr.c_str());
108
109 option->set(tmpint);
110 }
111 }
112
OnKeyerConf()113 void OnKeyerConf()
114 {
115 Datafile cfg = get_configuration();
116 sec_it this_sec = cfg.section("Keyer");
117
118 cin.ignore();
119
120 update_option(this_sec->option("BeginPause"), insert_beginpause);
121 update_option(this_sec->option("CharPause"), insert_charpause);
122 update_option(this_sec->option("StringPause"), insert_strpause);
123 update_option(this_sec->option("Speed"), insert_wpm);
124 update_option(this_sec->option("DotLength"), insert_dotlen);
125 update_option(this_sec->option("LineLength"), insert_linelen);
126 update_option(this_sec->option("Tone"), insert_tone);
127 update_option(this_sec->option("Device"), insert_device);
128 }
129
OnBlocksConf()130 void OnBlocksConf()
131 {
132 Datafile cfg = get_configuration();
133 sec_it this_sec = cfg.section("Blocks");
134
135 cin.ignore();
136
137 update_option(this_sec->option("StringsNumber"), insert_strnum);
138
139 update_option(this_sec->option("StringLength"), insert_strlen);
140
141 Dialog<unsigned int> ask_skill(dlg_skill_title, main_menu_prompt);
142 ask_skill.add_default_choice(dlg_skill_choice1,libexercises::skill1);
143 ask_skill.add_choice(dlg_skill_choice2,libexercises::skill2);
144 ask_skill.add_choice(dlg_skill_choice3,libexercises::skill3);
145 ask_skill.add_choice(dlg_skill_choice4,libexercises::skill4);
146 ask_skill.add_choice(dlg_skill_choice5,libexercises::skill5);
147 ask_skill.add_choice(dlg_skill_choice6,libexercises::skill6);
148 ask_skill.add_choice(dlg_skill_choice7,0);
149
150 unsigned int skill = ask_skill.show();
151
152 if(skill == 0)
153 while(true)
154 {
155 Dialog<unsigned int> ask_skill2(dlg_skill2_title, main_menu_prompt);
156
157 ask_skill2.add_default_choice(dlg_skill2_choice1,libexercises::chars1);
158 ask_skill2.add_choice(dlg_skill2_choice2,libexercises::chars2);
159 ask_skill2.add_choice(dlg_skill2_choice3,libexercises::chars3);
160 ask_skill2.add_choice(dlg_skill2_choice4,libexercises::chars4);
161 ask_skill2.add_choice(dlg_skill2_choice5,libexercises::chars5);
162 ask_skill2.add_choice(dlg_skill2_choice6,libexercises::numbrs);
163 ask_skill2.add_choice(dlg_skill2_choice7,0x1000);
164 ask_skill2.add_choice(dlg_skill2_choice8,libexercises::submixed);
165 ask_skill2.add_choice(dlg_skill2_choice9,libexercises::mixed);
166 ask_skill2.add_choice(dlg_skill2_choice10,0);
167
168 unsigned int skill2 = ask_skill2.show();
169
170 if(skill2 != 0 && skill2 != 0x1000)
171 skill |= skill2;
172
173 if(skill2 == 0)
174 break;
175 }
176
177 this_sec->option("Skill")->set(skill);
178 }
179
OnKochConf()180 void OnKochConf()
181 {
182 Datafile cfg = get_configuration();
183 sec_it this_sec = cfg.section("Koch");
184
185 cin.ignore();
186
187 update_option(this_sec->option("Chars"), insert_chars);
188
189 update_option(this_sec->option("StringsNumber"), insert_strnum);
190
191 update_option(this_sec->option("StringLength"), insert_strlen);
192
193 update_option(this_sec->option("StartSpeed"), insert_wpm);
194
195 update_option(this_sec->option("Skill"), insert_pos);
196
197 update_option(this_sec->option("Difficulty"), insert_pos);
198 }
199
OnQrzConf()200 void OnQrzConf()
201 {
202 Datafile cfg = get_configuration();
203 sec_it this_sec = cfg.section("Qrz");
204
205 cin.ignore();
206
207 update_option(this_sec->option("CallFormat"), insert_callformat);
208 update_option(this_sec->option("StringsNumber"), insert_strnum);
209 }
210
OnResetDefault()211 void OnResetDefault()
212 {
213 string fileconf_name(getenv("HOME"));
214 fileconf_name += "/";
215 fileconf_name += CONFIG_FILE;
216
217 Datafile fileconf(fileconf_name, Create);
218
219 fileconf.add_section("Keyer");
220 sec_it keyer_sec = fileconf.section("Keyer");
221
222 keyer_sec->add_option("BeginPause");
223 keyer_sec->option("BeginPause")->set(2);
224
225 keyer_sec->add_option("Speed");
226 keyer_sec->option("Speed")->set(10);
227
228 keyer_sec->add_option("CharPause");
229 keyer_sec->option("CharPause") ->set(3);
230
231 keyer_sec->add_option("StringPause");
232 keyer_sec->option("StringPause")->set(7);
233
234 keyer_sec->add_option("DotLength");
235 keyer_sec->option("DotLength")->set(1);
236
237 keyer_sec->add_option("LineLength");
238 keyer_sec->option("LineLength")->set(3);
239
240 keyer_sec->add_option("Tone");
241 keyer_sec->option("Tone")->set(900);
242
243 keyer_sec->add_option("Device");
244 keyer_sec->option("Device")->set("default");
245
246 fileconf.add_section("Blocks");
247 sec_it blocks_sec = fileconf.section("Blocks");
248
249 blocks_sec->add_option("StringsNumber");
250 blocks_sec->option("StringsNumber")->set(3);
251
252 blocks_sec->add_option("StringLength");
253 blocks_sec->option("StringLength")->set(5);
254
255 blocks_sec->add_option("Skill");
256 blocks_sec->option("Skill")->set(libexercises::skill1);
257
258 fileconf.add_section("Koch");
259 sec_it koch_sec = fileconf.section("Koch");
260
261 koch_sec->add_option("Chars");
262 // Suggested sequence from http://www.qsl.net/kb5wck/super.html
263 koch_sec->option("Chars")->set("kmrsuaptlowi.njef0y,vg5/q9zh38b?427c1d6x");
264
265 koch_sec->add_option("StringsNumber");
266 koch_sec->option("StringsNumber")->set(15);
267
268 koch_sec->add_option("StringLength");
269 koch_sec->option("StringLength")->set(2);
270
271 koch_sec->add_option("StartSpeed");
272 koch_sec->option("StartSpeed")->set(20);
273
274 koch_sec->add_option("Skill");
275 koch_sec->option("Skill")->set(2);
276
277 koch_sec->add_option("Difficulty");
278 koch_sec->option("Difficulty")->set(0);
279
280 fileconf.add_section("Qrz");
281 sec_it qrz_sec = fileconf.section("Qrz");
282
283 qrz_sec->add_option("CallFormat");
284 qrz_sec->option("CallFormat")->set("@@@@@");
285
286 qrz_sec->add_option("StringsNumber");
287 qrz_sec->option("StringsNumber")->set(3);
288 }
289
OnExitSetup(Menu & main)290 void OnExitSetup(Menu& main)
291 {
292 main.close();
293 }
294
OnSetup()295 void OnSetup()
296 {
297 Menu setup_menu(conf_menu_title, main_menu_prompt);
298
299 const id_type keyconf_id = 1;
300 const id_type clasconf_id = 2;
301 const id_type kochconf_id = 3;
302 const id_type qrzconf_id = 4;
303 const id_type rstdfl_id = 5;
304 const id_type exit_id = 6;
305
306 setup_menu.add_item(keyconf_id, conf_menu_item1, OnKeyerConf);
307 setup_menu.add_item(clasconf_id, conf_menu_item2, OnBlocksConf);
308 setup_menu.add_item(kochconf_id, conf_menu_item3, OnKochConf);
309 setup_menu.add_item(qrzconf_id, conf_menu_item4, OnQrzConf);
310 setup_menu.add_item(rstdfl_id, conf_menu_item5, OnResetDefault);
311 setup_menu.add_item(exit_id, conf_menu_item6, OnExitSetup);
312
313 while( setup_menu.running() )
314 {
315 try
316 {
317 setup_menu.show();
318 }
319 catch(Not_datafile_format e)
320 {
321 cerr<<errmsg_noformat<<endl;
322 cerr<<errmsg_conf<<endl;
323 return;
324 }
325 catch(Over_write_file e)
326 {
327 cerr<<errmsg_overwrite<<endl;
328 cerr<<errmsg_conf<<endl;
329 return;
330 }
331 catch(Option_not_found e)
332 {
333 cerr<<errmsg_nooption<<endl;
334 cerr<<errmsg_conf<<endl;
335 return;
336 }
337 catch(Section_not_found e)
338 {
339 cerr<<errmsg_nosection<<endl;
340 cerr<<errmsg_conf<<endl;
341 return;
342 }
343 catch(File_not_opened e)
344 {
345 cerr<<errmsg_noopenfile<<endl;
346 cerr<<errmsg_conf<<endl;
347 return;
348 }
349 catch(File_not_exist e)
350 {
351 cerr<<errmsg_nofile<<endl;
352 cerr<<errmsg_conf<<endl;
353 return;
354 }
355 }
356 }
357