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