make sure closing the application aborts the remaining HttpGet objects. Should fix...
[Rockbox.git] / apps / menus / settings_menu.c
bloba85024e3d2062a95d48b1240fea01772d0c04316
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Jonathan Gordon
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <limits.h>
23 #include <string.h>
24 #include "config.h"
25 #include "lang.h"
26 #include "action.h"
27 #include "settings.h"
28 #include "menu.h"
29 #include "sound_menu.h"
30 #include "exported_menus.h"
31 #include "tree.h"
32 #include "tagtree.h"
33 #include "usb.h"
34 #include "splash.h"
35 #include "talk.h"
36 #include "sprintf.h"
37 #include "powermgmt.h"
38 #ifdef HAVE_RTC_ALARM
39 #include "alarm_menu.h"
40 #endif
41 #if CONFIG_TUNER
42 #include "radio.h"
43 #endif
45 #ifdef HAVE_USBSTACK
46 #include "list.h"
47 #include "usbstack.h"
48 #include "statusbar.h"
49 #include "misc.h"
50 #endif
52 /***********************************/
53 /* TAGCACHE MENU */
54 #ifdef HAVE_TAGCACHE
56 static void tagcache_rebuild_with_splash(void)
58 tagcache_rebuild();
59 gui_syncsplash(HZ*2, ID2P(LANG_TAGCACHE_FORCE_UPDATE_SPLASH));
62 static void tagcache_update_with_splash(void)
64 tagcache_update();
65 gui_syncsplash(HZ*2, ID2P(LANG_TAGCACHE_FORCE_UPDATE_SPLASH));
68 #ifdef HAVE_TC_RAMCACHE
69 MENUITEM_SETTING(tagcache_ram, &global_settings.tagcache_ram, NULL);
70 #endif
71 MENUITEM_SETTING(tagcache_autoupdate, &global_settings.tagcache_autoupdate, NULL);
72 MENUITEM_FUNCTION(tc_init, 0, ID2P(LANG_TAGCACHE_FORCE_UPDATE),
73 (int(*)(void))tagcache_rebuild_with_splash,
74 NULL, NULL, Icon_NOICON);
75 MENUITEM_FUNCTION(tc_update, 0, ID2P(LANG_TAGCACHE_UPDATE),
76 (int(*)(void))tagcache_update_with_splash,
77 NULL, NULL, Icon_NOICON);
78 MENUITEM_SETTING(runtimedb, &global_settings.runtimedb, NULL);
79 MENUITEM_FUNCTION(tc_export, 0, ID2P(LANG_TAGCACHE_EXPORT),
80 (int(*)(void))tagtree_export, NULL,
81 NULL, Icon_NOICON);
82 MENUITEM_FUNCTION(tc_import, 0, ID2P(LANG_TAGCACHE_IMPORT),
83 (int(*)(void))tagtree_import, NULL,
84 NULL, Icon_NOICON);
85 MAKE_MENU(tagcache_menu, ID2P(LANG_TAGCACHE), 0, Icon_NOICON,
86 #ifdef HAVE_TC_RAMCACHE
87 &tagcache_ram,
88 #endif
89 &tagcache_autoupdate, &tc_init, &tc_update, &runtimedb,
90 &tc_export, &tc_import);
91 #endif /* HAVE_TAGCACHE */
92 /* TAGCACHE MENU */
93 /***********************************/
95 /***********************************/
96 /* FILE VIEW MENU */
97 static int fileview_callback(int action,const struct menu_item_ex *this_item);
98 MENUITEM_SETTING(sort_case, &global_settings.sort_case, NULL);
99 MENUITEM_SETTING(sort_dir, &global_settings.sort_dir, fileview_callback);
100 MENUITEM_SETTING(sort_file, &global_settings.sort_file, fileview_callback);
101 MENUITEM_SETTING(dirfilter, &global_settings.dirfilter, NULL);
102 MENUITEM_SETTING(show_filename_ext, &global_settings.show_filename_ext, NULL);
103 MENUITEM_SETTING(browse_current, &global_settings.browse_current, NULL);
104 MENUITEM_SETTING(show_path_in_browser, &global_settings.show_path_in_browser, NULL);
105 static int fileview_callback(int action,const struct menu_item_ex *this_item)
107 static int oldval;
108 int *variable = this_item->variable;
109 switch (action)
111 case ACTION_ENTER_MENUITEM: /* on entering an item */
112 oldval = *variable;
113 break;
114 case ACTION_EXIT_MENUITEM: /* on exit */
115 if (*variable != oldval)
116 reload_directory(); /* force reload if this has changed */
117 break;
119 return action;
122 MAKE_MENU(file_menu, ID2P(LANG_FILE), 0, Icon_file_view_menu,
123 &sort_case, &sort_dir, &sort_file,
124 &dirfilter, &show_filename_ext, &browse_current,
125 &show_path_in_browser);
126 /* FILE VIEW MENU */
127 /***********************************/
130 /***********************************/
131 /* SYSTEM MENU */
133 /* Battery */
134 #if BATTERY_CAPACITY_INC > 0
135 MENUITEM_SETTING(battery_capacity, &global_settings.battery_capacity, NULL);
136 #endif
137 #if BATTERY_TYPES_COUNT > 1
138 MENUITEM_SETTING(battery_type, &global_settings.battery_type, NULL);
139 #endif
140 #ifdef HAVE_USB_POWER
141 #if CONFIG_CHARGING
142 static int usbcharging_callback(int action,const struct menu_item_ex *this_item)
144 (void)this_item;
145 switch (action)
147 case ACTION_EXIT_MENUITEM: /* on exit */
148 usb_charging_enable(global_settings.usb_charging);
149 break;
151 return action;
153 MENUITEM_SETTING(usb_charging, &global_settings.usb_charging, usbcharging_callback);
154 #endif
155 #endif
156 MAKE_MENU(battery_menu, ID2P(LANG_BATTERY_MENU), 0, Icon_NOICON,
157 #if BATTERY_CAPACITY_INC > 0
158 &battery_capacity,
159 #endif
160 #if BATTERY_TYPES_COUNT > 1
161 &battery_type,
162 #endif
163 #ifdef HAVE_USB_POWER
164 #if CONFIG_CHARGING
165 &usb_charging,
166 #endif
167 #endif
169 /* Disk */
170 #ifndef HAVE_FLASH_STORAGE
171 MENUITEM_SETTING(disk_spindown, &global_settings.disk_spindown, NULL);
172 #endif
173 #ifdef HAVE_DIRCACHE
174 static int dircache_callback(int action,const struct menu_item_ex *this_item)
176 (void)this_item;
177 switch (action)
179 case ACTION_EXIT_MENUITEM: /* on exit */
180 switch (global_settings.dircache)
182 case true:
183 if (!dircache_is_enabled())
184 gui_syncsplash(HZ*2, ID2P(LANG_PLEASE_REBOOT));
185 break;
186 case false:
187 if (dircache_is_enabled())
188 dircache_disable();
189 break;
191 break;
193 return action;
195 MENUITEM_SETTING(dircache, &global_settings.dircache, dircache_callback);
196 #endif
197 #if defined(HAVE_DIRCACHE) || !defined(HAVE_FLASH_STORAGE)
198 MAKE_MENU(disk_menu, ID2P(LANG_DISK_MENU), 0, Icon_NOICON,
199 #ifndef HAVE_FLASH_STORAGE
200 &disk_spindown,
201 #endif
202 #ifdef HAVE_DIRCACHE
203 &dircache,
204 #endif
206 #endif
208 /* Time & Date */
209 #if CONFIG_RTC
210 static int timedate_set(void)
212 struct tm tm;
213 int result;
215 /* Make a local copy of the time struct */
216 memcpy(&tm, get_time(), sizeof(struct tm));
218 /* do some range checks */
219 /* This prevents problems with time/date setting after a power loss */
220 if (!valid_time(&tm))
222 /* Macros to convert a 2-digit string to a decimal constant.
223 (YEAR), MONTH and DAY are set by the date command, which outputs
224 DAY as 00..31 and MONTH as 01..12. The leading zero would lead to
225 misinterpretation as an octal constant. */
226 #define S100(x) 1 ## x
227 #define C2DIG2DEC(x) (S100(x)-100)
229 tm.tm_hour = 0;
230 tm.tm_min = 0;
231 tm.tm_sec = 0;
232 tm.tm_mday = C2DIG2DEC(DAY);
233 tm.tm_mon = C2DIG2DEC(MONTH)-1;
234 tm.tm_wday = 1;
235 tm.tm_year = YEAR-1900;
238 result = (int)set_time_screen(str(LANG_SET_TIME), &tm);
240 if(tm.tm_year != -1) {
241 set_time(&tm);
243 return result;
246 MENUITEM_FUNCTION(time_set, 0, ID2P(LANG_SET_TIME),
247 timedate_set, NULL, NULL, Icon_NOICON);
248 MENUITEM_SETTING(timeformat, &global_settings.timeformat, NULL);
249 MAKE_MENU(time_menu, ID2P(LANG_TIME_MENU), 0, Icon_NOICON, &time_set, &timeformat);
250 #endif
252 /* System menu */
253 MENUITEM_SETTING(poweroff, &global_settings.poweroff, NULL);
255 #ifdef HAVE_RTC_ALARM
256 MENUITEM_FUNCTION(alarm_screen_call, 0, ID2P(LANG_ALARM_MOD_ALARM_MENU),
257 (menu_function)alarm_screen, NULL, NULL, Icon_NOICON);
258 #if CONFIG_TUNER || defined(HAVE_RECORDING)
260 #if CONFIG_TUNER && !defined(HAVE_RECORDING)
261 /* This need only be shown if we dont have recording, because if we do
262 then always show the setting item, because there will always be at least
263 2 items */
264 static int alarm_callback(int action,const struct menu_item_ex *this_item)
266 (void)this_item;
267 switch (action)
269 case ACTION_REQUEST_MENUITEM:
270 if (radio_hardware_present() == 0)
271 return ACTION_EXIT_MENUITEM;
272 break;
274 return action;
276 #else
277 #define alarm_callback NULL
278 #endif /* CONFIG_TUNER && !HAVE_RECORDING */
279 /* have to do this manually because the setting screen
280 doesnt handle variable item count */
281 static int alarm_setting(void)
283 struct opt_items items[ALARM_START_COUNT];
284 int i = 0;
285 items[i].string = str(LANG_RESUME_PLAYBACK);
286 items[i].voice_id = LANG_RESUME_PLAYBACK;
287 i++;
288 #if CONFIG_TUNER
289 if (radio_hardware_present())
291 items[i].string = str(LANG_FM_RADIO);
292 items[i].voice_id = LANG_FM_RADIO;
293 i++;
295 #endif
296 #ifdef HAVE_RECORDING
297 items[i].string = str(LANG_RECORDING);
298 items[i].voice_id = LANG_RECORDING;
299 i++;
300 #endif
301 return set_option(str(LANG_ALARM_WAKEUP_SCREEN),
302 &global_settings.alarm_wake_up_screen,
303 INT, items, i, NULL);
306 MENUITEM_FUNCTION(alarm_wake_up_screen, 0, ID2P(LANG_ALARM_WAKEUP_SCREEN),
307 alarm_setting, NULL, alarm_callback, Icon_Menu_setting);
308 #endif /* CONFIG_TUNER || defined(HAVE_RECORDING) */
309 #endif /* HAVE_RTC_ALARM */
311 /* Limits menu */
312 MENUITEM_SETTING(max_files_in_dir, &global_settings.max_files_in_dir, NULL);
313 MENUITEM_SETTING(max_files_in_playlist, &global_settings.max_files_in_playlist, NULL);
314 MAKE_MENU(limits_menu, ID2P(LANG_LIMITS_MENU), 0, Icon_NOICON,
315 &max_files_in_dir, &max_files_in_playlist);
317 #if CONFIG_CODEC == MAS3507D
318 void dac_line_in(bool enable);
319 static int linein_callback(int action,const struct menu_item_ex *this_item)
321 (void)this_item;
322 switch (action)
324 case ACTION_EXIT_MENUITEM: /* on exit */
325 #ifndef SIMULATOR
326 dac_line_in(global_settings.line_in);
327 #endif
328 break;
330 return action;
332 MENUITEM_SETTING(line_in, &global_settings.line_in, linein_callback);
333 #endif
334 #if CONFIG_CHARGING
335 MENUITEM_SETTING(car_adapter_mode, &global_settings.car_adapter_mode, NULL);
336 #endif
337 MENUITEM_SETTING(start_screen, &global_settings.start_in_screen, NULL);
339 #ifdef HAVE_BUTTON_LIGHT
340 MENUITEM_SETTING(button_light_timeout, &global_settings.button_light_timeout, NULL);
341 #endif
343 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
344 MENUITEM_SETTING(buttonlight_brightness, &global_settings.buttonlight_brightness, NULL);
345 #endif
347 MAKE_MENU(system_menu, ID2P(LANG_SYSTEM),
348 0, Icon_System_menu,
349 &start_screen,
350 #if (BATTERY_CAPACITY_INC > 0) || (BATTERY_TYPES_COUNT > 1)
351 &battery_menu,
352 #endif
353 #if defined(HAVE_DIRCACHE) || !defined(HAVE_FLASH_STORAGE)
354 &disk_menu,
355 #endif
356 #if CONFIG_RTC
357 &time_menu,
358 #endif
359 &poweroff,
360 #ifdef HAVE_RTC_ALARM
361 &alarm_screen_call,
362 #if defined(HAVE_RECORDING) || CONFIG_TUNER
363 &alarm_wake_up_screen,
364 #endif
365 #endif
366 &limits_menu,
367 #if CONFIG_CODEC == MAS3507D
368 &line_in,
369 #endif
370 #if CONFIG_CHARGING
371 &car_adapter_mode,
372 #endif
373 #ifdef HAVE_BUTTON_LIGHT
374 &button_light_timeout,
375 #endif
376 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
377 &buttonlight_brightness
378 #endif
381 /* SYSTEM MENU */
382 /***********************************/
385 /***********************************/
386 /* BOOKMARK MENU */
387 static int bmark_callback(int action,const struct menu_item_ex *this_item)
389 (void)this_item;
390 switch (action)
392 case ACTION_EXIT_MENUITEM: /* on exit */
393 if(global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_YES ||
394 global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_ASK)
396 if(global_settings.usemrb == BOOKMARK_NO)
397 global_settings.usemrb = BOOKMARK_YES;
400 break;
402 return action;
404 MENUITEM_SETTING(autocreatebookmark,
405 &global_settings.autocreatebookmark, bmark_callback);
406 MENUITEM_SETTING(autoloadbookmark, &global_settings.autoloadbookmark, NULL);
407 MENUITEM_SETTING(usemrb, &global_settings.usemrb, NULL);
408 MAKE_MENU(bookmark_settings_menu, ID2P(LANG_BOOKMARK_SETTINGS), 0,
409 Icon_Bookmark,
410 &autocreatebookmark, &autoloadbookmark, &usemrb);
411 /* BOOKMARK MENU */
412 /***********************************/
414 /***********************************/
415 /* VOICE MENU */
416 static int talk_callback(int action,const struct menu_item_ex *this_item);
417 MENUITEM_SETTING(talk_menu_item, &global_settings.talk_menu, NULL);
418 MENUITEM_SETTING(talk_dir_item, &global_settings.talk_dir, NULL);
419 MENUITEM_SETTING(talk_dir_clip_item, &global_settings.talk_dir_clip, talk_callback);
420 MENUITEM_SETTING(talk_file_item, &global_settings.talk_file, NULL);
421 MENUITEM_SETTING(talk_file_clip_item, &global_settings.talk_file_clip, talk_callback);
422 static int talk_callback(int action,const struct menu_item_ex *this_item)
424 static int oldval = 0;
425 switch (action)
427 case ACTION_ENTER_MENUITEM:
428 oldval = global_settings.talk_file_clip;
429 break;
430 case ACTION_EXIT_MENUITEM:
431 #if CONFIG_CODEC == SWCODEC
432 audio_set_crossfade(global_settings.crossfade);
433 #endif
434 if (this_item == &talk_dir_clip_item)
435 break;
436 if (!oldval && global_settings.talk_file_clip)
438 /* force reload if newly talking thumbnails,
439 because the clip presence is cached only if enabled */
440 reload_directory();
442 break;
444 return action;
446 MAKE_MENU(voice_settings_menu, ID2P(LANG_VOICE), 0, Icon_Voice,
447 &talk_menu_item, &talk_dir_item, &talk_dir_clip_item,
448 &talk_file_item, &talk_file_clip_item);
449 /* VOICE MENU */
450 /***********************************/
452 #ifdef HAVE_USBSTACK
453 /***********************************/
454 /* USB STACK MENU */
455 char drivers[16][32];
456 static char* usb_menu_getname(int item, void * data, char *buffer)
458 (void)data; (void)buffer;
459 return drivers[item];
461 int usbdriver_menuitem(void)
463 struct gui_synclist lists;
464 int action, count = 0;
465 char *s = device_driver_names, *e;
466 do {
467 e = strchr(s, ',');
468 if (e)
470 strncpy(drivers[count++], s, e-s);
471 s = e+1;
473 } while (e && count < 16);
474 if (count < 16)
475 strcpy(drivers[count++], s);
476 for (action=0; action<count; action++)
478 if (!strcmp(drivers[action],
479 global_settings.usb_stack_device_driver))
480 break;
483 gui_synclist_init(&lists, usb_menu_getname, drivers, false, 1);
484 gui_synclist_set_title(&lists, str(LANG_USBSTACK_DEVICE_DRIVER), NOICON);
485 gui_synclist_set_icon_callback(&lists, NULL);
486 gui_synclist_set_nb_items(&lists, count);
487 gui_synclist_select_item(&lists, action==count?0:action);
488 gui_synclist_draw(&lists);
490 while(1)
492 gui_syncstatusbar_draw(&statusbars, true);
493 action = get_action(CONTEXT_STD, HZ/5);
494 if (gui_synclist_do_button(&lists, action, LIST_WRAP_UNLESS_HELD))
495 continue;
496 if (action == ACTION_STD_CANCEL)
498 /* setting was canceled */
499 break;
501 else if (action == ACTION_STD_OK)
503 /* setting was accepted... save */
504 strcpy(global_settings.usb_stack_device_driver,
505 drivers[gui_synclist_get_sel_pos(&lists)]);
507 /* switch device driver */
508 usb_device_driver_bind(drivers[gui_synclist_get_sel_pos(&lists)]);
509 break;
511 else if (action == ACTION_REDRAW)
512 gui_synclist_draw(&lists);
513 else if(default_event_handler(action) == SYS_USB_CONNECTED)
514 return true;
516 return false;
519 MENUITEM_SETTING(usbstack_mode, &global_settings.usb_stack_mode, NULL);
520 MENUITEM_FUNCTION(usbdriver, 0, ID2P(LANG_USBSTACK_DEVICE_DRIVER),
521 usbdriver_menuitem, 0, NULL, Icon_NOICON);
523 MAKE_MENU(usbstack_menu, ID2P(LANG_USBSTACK), 0, Icon_NOICON,
524 &usbstack_mode, &usbdriver);
525 /* USB STACK MENU */
526 /***********************************/
527 #endif
529 /***********************************/
531 /***********************************/
532 /* SETTINGS MENU */
533 static int language_browse(void)
535 return (int)rockbox_browse(LANG_DIR, SHOW_LNG);
537 MENUITEM_FUNCTION(browse_langs, 0, ID2P(LANG_LANGUAGE), language_browse,
538 NULL, NULL, Icon_Language);
540 MAKE_MENU(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS), 0,
541 Icon_General_settings_menu,
542 &playback_menu_item, &playlist_settings, &file_menu,
543 #ifdef HAVE_TAGCACHE
544 &tagcache_menu,
545 #endif
546 &display_menu, &system_menu,
547 &bookmark_settings_menu, &browse_langs, &voice_settings_menu
548 #ifdef HAVE_USBSTACK
549 , &usbstack_menu
550 #endif
552 /* SETTINGS MENU */
553 /***********************************/