Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: apps/lang/english.lang
- ===================================================================
- --- apps/lang/english.lang (Revision 23417)
- +++ apps/lang/english.lang (Arbeitskopie)
- @@ -11016,6 +11016,20 @@
- </voice>
- </phrase>
- <phrase>
- + id: LANG_DICTIONARIES
- + desc: in the main menu
- + user: core
- + <source>
- + *: "Dictionaries"
- + </source>
- + <dest>
- + *: "Dictionaries"
- + </dest>
- + <voice>
- + *: "Dictionaries"
- + </voice>
- +</phrase>
- +<phrase>
- id: VOICE_OF
- desc: spoken only, as in 3/8 => 3 of 8
- user: core
- Index: apps/plugins/dict2.c
- ===================================================================
- --- apps/plugins/dict2.c (Revision 0)
- +++ apps/plugins/dict2.c (Revision 0)
- @@ -0,0 +1,966 @@
- +/***************************************************************************
- + * __________ __ ___.
- + * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- + * \/ \/ \/ \/ \/
- + * $Id: dict.c 14250 2007-08-08 23:32:35Z peter $
- + *
- + * Copyright (C) 2005 Tomas Salfischberger, 2006 Timo Horstschäfer
- + *
- + * All files in this archive are subject to the GNU General Public License.
- + * See the file COPYING in the source tree root for full license agreement.
- + *
- + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- + * KIND, either express or implied.
- + *
- + ****************************************************************************/
- +
- +#include "plugin.h"
- +#include "lib/pluginlib_actions.h"
- +#include "lib/configfile.h"
- +#include "lib/playback_control.h"
- +#include "lib/viewer.h"
- +
- +#include <ctype.h>
- +
- +PLUGIN_HEADER
- +
- +
- +#define CONFIG_VERSION 3
- +#define CACHE_VERSION 2
- +
- +//! Global dict variables
- +static struct dict_s {
- + char path[255]; /**< Path of current dictionary */
- + char name[255]; /**< Basename of current dictionary */
- +
- + int DataLen;
- +
- + int fCache;
- + int fIndex;
- + int fDict;
- + //! Current description file (there may be more than one)
- + int fDict_n;
- +
- + //! Alphabet offset table
- + int32_t charoft[26];
- +} Dict;
- +
- +#define DESC_BUFFER_ADD 512
- +
- +#define OFT_DIR ROCKBOX_DIR
- +
- +#define CONFIG_FILENAME "dict2.cfg"
- +#define CONFIG_ITEMS ( sizeof(Conf_data) / sizeof (struct configdata) )
- +struct conf_s {
- + int max_list; /**< Max number of articles listed */
- + int viewer_scroll; /**< Number of lines to scroll */
- + int viewer_backlight;
- + int viewer_shortcut;
- +} Conf;
- +
- +struct configdata Conf_data[] = {
- + { TYPE_INT, 1, 50, { .int_p = &Conf.max_list }, "max_list", NULL },
- + { TYPE_INT, 0, 4, { .int_p = &Conf.viewer_scroll }, "scroll", NULL },
- + { TYPE_INT, 0, 2, { .int_p = &Conf.viewer_backlight }, "backlight", NULL },
- + { TYPE_INT, 0, 2, { .int_p = &Conf.viewer_shortcut }, "shortcut", NULL },
- +};
- +
- +#define MAX_LIST_DEFAULT 50
- +
- +//! Malloc variables
- +static struct malloc_s {
- + void *buf;
- + size_t bufsize;
- + size_t bufpos;
- +} Malloc;
- +
- +struct cache_h {
- + char magic[9];
- + uint16_t version;
- + int32_t charoft[26];
- +};
- +
- +static struct cache_h Cache_h = {
- + "DICT_OFT",
- + CACHE_VERSION,
- + { 0 },
- +};
- +
- +//! Length of word_str in stardict's DICT format
- +#define WORDLEN 256
- +
- +//! Rockbox filesize limit
- +#define MAX_FILESIZE 2147483647
- +
- +enum dict_action
- +{
- + DICT_USB_CONNECTED = -4,
- + DICT_NOT_FOUND = -2,
- + DICT_QUIT = -3,
- + DICT_ERROR = -1,
- + DICT_OK,
- +};
- +
- +#define VIEWER_NEW (VIEWER_CUSTOM)
- +
- +/** \brief Data structure in .idx files
- + *
- + * Structure of .idx files:
- + * \code
- + * char[] name; // variable length, zero-terminated, UTF-8
- + * uint32_t offset; // beginning of the article in the .dict file, Big Endian
- + * uint32_t size; // article size, Big Endian
- + * \endcode
- + */
- +struct WordData_s
- +{
- + uint32_t offset;
- + uint32_t size;
- +};
- +
- +struct WordData
- +{
- + uint64_t offset;
- + uint32_t size;
- +};
- +
- +//! Internal structure for the result
- +struct DictEntry
- +{
- + char name[WORDLEN];
- + int32_t index;
- + struct WordData data;
- +};
- +
- +#ifndef betoh64
- +
- +#ifdef ROCKBOX_LITTLE_ENDIAN
- +static inline uint64_t swap64(uint64_t value)
- +{
- + uint64_t hi = swap32(value >> 32);
- + uint64_t lo = swap32(value & 0xffffffff);
- + return (lo << 32) | hi;
- +}
- +#define betoh64(x) swap64(x)
- +#else
- +#define betoh64(x) (x)
- +#endif
- +
- +#endif
- +
- +void str_toupper(const char *src, char *dst)
- +{
- + while (*src)
- + *dst++ = toupper(*src++);
- + *dst = '\0';
- +}
- +
- +//! Display an error message
- +#define dict_error(...) \
- + DEBUGF(__VA_ARGS__); DEBUGF("\n"); \
- + LOGF(__VA_ARGS__); \
- + rb->splashf(HZ, __VA_ARGS__);
- +
- +
- +//! Initialize the plugin buffer
- +void dict_buf_init(void)
- +{
- + Malloc.buf = rb->plugin_get_buffer((size_t *)&Malloc.bufsize);
- + Malloc.bufpos = 0;
- +}
- +
- +/** \brief Stack-like malloc
- + *
- + * This malloc implementation only keeps track of how much memory is allocated
- + */
- +void *dict_malloc(size_t size)
- +{
- + void *p;
- + if (Malloc.bufpos+size <= Malloc.bufsize)
- + {
- + p = Malloc.buf + Malloc.bufpos;
- + if ((int)p%4) { DEBUGF("\n%d %% 4 = %d\n", (int)p, (int)p%4); }
- + Malloc.bufpos += size;
- + return (void *)Malloc.buf + Malloc.bufpos - size;
- + }
- + else
- + {
- + dict_error("Out of Memory");
- + return NULL;
- + }
- +}
- +
- +size_t dict_malloc_align(void)
- +{
- + size_t align = 4 - (((size_t)Malloc.buf + Malloc.bufpos) % 4);
- + Malloc.bufpos += align;
- + return align;
- +}
- +
- +/** \brief Stack-like free
- + *
- + * @param size Nnumber of bytes to free, 0 will free the whole buffer
- + */
- +void dict_free(size_t size)
- +{
- + if (size == 0 || size > Malloc.bufpos)
- + Malloc.bufpos = 0;
- + else
- + Malloc.bufpos -= size;
- +}
- +
- +//! Extract the path and name of the given filename
- +void dict_get_name(const char *name)
- +{
- + char *slash, *dot;
- + size_t n;
- +
- + slash = rb->strrchr(name, '/');
- + dot = rb->strrchr(slash+1, '.');
- +
- + /* get path */
- + n = slash+1-name;
- + rb->strlcpy(Dict.path, name, n);
- + Dict.path[n] = '\0';
- +
- + /* get filename without extension */
- + n = dot-slash;
- + rb->strlcpy(Dict.name, slash+1, n);
- + Dict.name[n] = '\0';
- +
- + /* get index type */
- + if (rb->strcmp(dot, ".lidx") == 0)
- + Dict.DataLen = sizeof(struct WordData);
- + else
- + Dict.DataLen = sizeof(struct WordData_s);
- +}
- +
- +//! Generates the cache file to the current dictionary
- +enum dict_action dict_create_cache(void)
- +{
- + uint32_t offset;
- + int len;
- + char word[WORDLEN];
- + enum dict_action ret = DICT_OK;
- + int32_t count;
- + char a_c, a_cur = 'a'-1;
- +
- + int button;
- + const struct button_mapping *plugin_contexts[] = {
- + generic_actions,
- + };
- +
- + rb->splash(0, "Creating offset table... may take some minutes");
- +
- + rb->memset(Cache_h.charoft, 0, sizeof(Cache_h.charoft));
- + /* write dummy header */
- + rb->write(Dict.fCache, &Cache_h, sizeof(struct cache_h));
- +
- + offset = count = 0;
- + while (ret == DICT_OK)
- + {
- + /* get name length */
- + len = 0;
- + while (rb->read(Dict.fIndex, &word[len], 1) == 1)
- + {
- + if (word[len++] == '\0' || len >= WORDLEN)
- + break;
- + }
- + if (!len)
- + break;
- +
- + /* character offset table */
- + a_c = tolower(word[0]);
- + if (a_c > a_cur && a_c >= 'a' && a_c <= 'z')
- + {
- + LOGF("'%s' (%ld)", word, count);
- + do
- + Cache_h.charoft[++a_cur-'a'] = count;
- + while (a_cur < a_c);
- + }
- +
- + /* write current position to file */
- + rb->write(Dict.fCache, &offset, sizeof(uint32_t));
- +
- + rb->lseek(Dict.fIndex, Dict.DataLen, SEEK_CUR);
- + offset += Dict.DataLen + len;
- + count++;
- +
- + /* don't take over all control */
- + button = pluginlib_getaction(TIMEOUT_NOBLOCK, plugin_contexts, 1);
- + switch (button)
- + {
- + case PLA_QUIT:
- + ret = DICT_ERROR;
- + break;
- + default:
- + if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
- + ret = DICT_USB_CONNECTED;
- + break;
- + }
- + rb->yield();
- + }
- +
- + /* Finish table */
- + if (a_cur < 'z')
- + {
- + do
- + Cache_h.charoft[++a_cur-'a'] = count;
- + while (a_cur < 'z');
- + }
- +
- + /* write real header */
- + rb->lseek(Dict.fCache, 0, SEEK_SET);
- + rb->write(Dict.fCache, &Cache_h, sizeof(struct cache_h));
- +
- + return ret;
- +}
- +
- +//! Closes all file descriptors
- +void dict_close(void)
- +{
- + rb->close(Dict.fCache);
- + rb->close(Dict.fIndex);
- + rb->close(Dict.fDict);
- +
- + Conf.viewer_scroll = viewer_get_scroll();
- + Conf.viewer_backlight = viewer_get_backlight();
- + Conf.viewer_shortcut = viewer_get_shortcut();
- + configfile_save(CONFIG_FILENAME, Conf_data,
- + CONFIG_ITEMS, CONFIG_VERSION);
- +}
- +
- +enum dict_action dict_open(void)
- +{
- + char fn[FAT_FILENAME_BYTES];
- +
- + /* index file */
- + if (Dict.DataLen == sizeof(struct WordData))
- + rb->snprintf(fn, sizeof(fn), "%s/%s.lidx", Dict.path, Dict.name); // slash added
- + else
- + rb->snprintf(fn, sizeof(fn), "%s/%s.idx", Dict.path, Dict.name); // slash added
- + Dict.fIndex = rb->open(fn, O_RDONLY);
- + if (Dict.fIndex < 0)
- + {
- + dict_error("Failed to open index file: %s", fn);
- + dict_close();
- + return DICT_ERROR;
- + }
- +
- + /* cache file */
- + rb->snprintf(fn, sizeof(fn), "%s/%s.oft", OFT_DIR, Dict.name); // slash added
- + Dict.fCache = rb->open(fn, O_RDONLY);
- + if (Dict.fCache >= 0)
- + {
- + /* check the cache file */
- + struct cache_h header;
- +
- + rb->read(Dict.fCache, &header, sizeof(struct cache_h));
- + if (rb->strcmp(header.magic, Cache_h.magic) == 0 &&
- + header.version == Cache_h.version)
- + {
- + rb->memcpy(Dict.charoft, header.charoft, sizeof(Dict.charoft));
- + return PLUGIN_OK;
- + }
- +
- + dict_error("Cache file outdated");
- +
- + rb->close(Dict.fCache);
- + rb->remove(fn);
- + }
- +
- + /* incorrect cache file, create a new one */
- + Dict.fCache = rb->creat(fn);
- + if (Dict.fCache >= 0)
- + {
- + if (dict_create_cache() == DICT_OK)
- + {
- + rb->memcpy(Dict.charoft, Cache_h.charoft, sizeof(Dict.charoft));
- +
- + /* reopen read-only */
- + rb->close(Dict.fCache);
- + Dict.fCache = rb->open(fn, O_RDONLY);
- + return DICT_OK;
- + }
- + else
- + {
- + rb->close(Dict.fCache);
- + rb->remove(fn);
- + }
- + }
- +
- + dict_error("Failed to open cache file: %s", fn);
- + return DICT_ERROR;
- +}
- +
- +/** \brief Initializes everything related to dict.
- + *
- + * @param filename Filename of the .idx file for the dictionary
- + */
- +enum dict_action dict_init(const char *file)
- +{
- + /* malloc */
- + dict_buf_init();
- +
- + /* variables */
- + Conf.viewer_scroll = viewer_get_scroll();
- + Conf.viewer_backlight = viewer_get_backlight();
- + Conf.viewer_shortcut = viewer_get_shortcut();
- + Conf.max_list = MAX_LIST_DEFAULT;
- + Dict.fDict = Dict.fDict_n = -1;
- +
- + /* configuration data */
- + configfile_load(CONFIG_FILENAME, Conf_data,
- + CONFIG_ITEMS, CONFIG_VERSION);
- +
- + /* dict name */
- + dict_get_name(file);
- +
- + /* files */
- + return dict_open();
- +}
- +
- +/** \brief Returns offset for an entry in the idx file
- + *
- + * This function allows random access to the idx file
- + */
- +uint32_t dict_cache_offset(int32_t index)
- +{
- + uint32_t offset;
- +
- + /* read offset */
- + rb->lseek(Dict.fCache, sizeof(uint32_t)*index + sizeof(struct cache_h),
- + SEEK_SET);
- + rb->read(Dict.fCache, &offset, sizeof(uint32_t));
- +
- + return offset;
- +}
- +
- +//! Compare function, that represents the order in the .idx file
- +int dict_index_strcmp(const char *str1, const char *str2)
- +{
- + int a;
- +
- + a = rb->strcasecmp(str1, str2);
- + if (!a)
- + {
- + return rb->strcmp(str1, str2);
- + }
- +
- + return a;
- +}
- +
- +/** \brief Reads up to n bytes from current fIndex position until a zero occurs
- + *
- + * \return Number of bytes read.
- + */
- +int dict_index_gets(char *buf, int n)
- +{
- + int i;
- + for (i=0; i<n; i++)
- + {
- + if (!rb->read(Dict.fIndex, buf, 1))
- + break;
- + if (! *buf++)
- + {
- + i++;
- + break;
- + }
- + }
- + return i;
- +}
- +
- +/** \brief Reads up to n bytes from an entry in the idx file until a zero occurs
- + *
- + * @param index The index in idx t read from.
- + * \return Number of bytes read.
- + */
- +int dict_index_gets_from(int32_t index, char *buf, int n)
- +{
- + rb->lseek(Dict.fIndex, dict_cache_offset(index), SEEK_SET);
- + return dict_index_gets(buf, n);
- +}
- +
- +/** \brief Extracts all data about an entry in idx
- + *
- + * \return length of the article name
- + */
- +int dict_index_entry(int32_t index, struct DictEntry *out)
- +{
- + int size;
- + char buf[sizeof(struct WordData)];
- +
- + out->index = index;
- +
- + size = dict_index_gets_from(index, out->name, WORDLEN);
- +
- + rb->read(Dict.fIndex, buf, Dict.DataLen);
- +
- + /* convert to host endianess */
- + if (Dict.DataLen == sizeof(struct WordData))
- + {
- + out->data.offset = betoh64( ((struct WordData *)buf)->offset );
- + out->data.size = betoh32( ((struct WordData *)buf)->size );
- + }
- + else
- + {
- + out->data.offset = betoh32( ((struct WordData_s *)buf)->offset );
- + out->data.size = betoh32( ((struct WordData_s *)buf)->size );
- + }
- +
- + return size;
- +}
- +
- +/** \brief Binary search function
- + *
- + * @return If nothing was found, the last probe is returned negative.
- + */
- +int32_t dict_index_binary_search(const char *search,
- + int(*cmpf)(const char *, const char *))
- +{
- + char word[WORDLEN];
- + int32_t high, low, probe = 0;
- + int cmp;
- +
- + int count = 0;
- +
- + int i = tolower(search[0]) - 'a';
- + if (i < 0)
- + {
- + low = -1;
- + high = Dict.charoft[0];
- + }
- + else if (i >= 25)
- + {
- + low = Dict.charoft[25];
- + high = (rb->filesize(Dict.fCache) - sizeof (struct cache_h)) /
- + sizeof(uint32_t);
- + }
- + else
- + {
- + low = Dict.charoft[i] - 1;
- + high = Dict.charoft[i+1] + 1;
- + }
- +
- + while (high - low > 1)
- + {
- + count++;
- + probe = (high + low) / 2;
- +
- + dict_index_gets_from(probe, word, WORDLEN);
- + LOGF("%ld: '%s'", probe, word);
- +
- + /* jump according to the found word. */
- + cmp = cmpf(search, word);
- + if (cmp < 0)
- + high = probe;
- + else if (cmp > 0)
- + low = probe;
- + else
- + {
- + probe = -probe;
- + break;
- + }
- + }
- +
- + LOGF("probes: %d", count);
- + return -probe;
- +}
- +
- +/** \brief Shows a selection menu for all articles starting with the given word
- + *
- + * The selections screen is only displayed, if there's more than one result.
- + */
- +int32_t dict_index_find_startingWith(const char *search)
- +{
- + int32_t index;
- + char buf[WORDLEN];
- + int len, new_len, cmp, needmem;
- + int buffer_size;
- + int n = 0, sel = 0;
- +
- + char **items;
- + buffer_size = dict_malloc_align() + Conf.max_list * sizeof(char *);
- + items = (char **) dict_malloc(buffer_size);
- +
- + /* make uppercase to find lowest value */
- + str_toupper(search, buf);
- + index = dict_index_binary_search(buf, dict_index_strcmp);
- + if (index < 0)
- + index = -index;
- +
- + rb->lseek(Dict.fIndex, dict_cache_offset(index), SEEK_SET);
- +
- + /* find all words that start with the word */
- + len = rb->strlen(search);
- + while (n<Conf.max_list)
- + {
- + needmem = new_len = dict_index_gets(buf, WORDLEN);
- + if (!new_len)
- + break;
- + if (needmem%4 > 0)
- + needmem += 4 - needmem%4;
- +
- + /* seek to next article name */
- + rb->lseek(Dict.fIndex, Dict.DataLen, SEEK_CUR);
- +
- + cmp = rb->strncasecmp(search, buf, len);
- + if (cmp > 0)
- + {
- + index++;
- + continue;
- + }
- + else if (cmp < 0)
- + break;
- +
- + items[n] = (char *)dict_malloc(needmem);
- + if (items[n] == NULL)
- + break;
- + buffer_size += needmem;
- +
- + rb->strlcpy(items[n], buf, new_len);
- + DEBUGF("%s\n", buf);
- +
- + n++;
- + }
- +
- + /* show the selection list */
- + if (n > 1)
- + {
- + struct menu_callback_with_desc menu_ = {NULL,"Search Results", Icon_NOICON};
- + struct menu_item_ex menu = {
- + MT_RETURN_ID|MENU_HAS_DESC|MENU_ITEM_COUNT(n),
- + {.strings = (const char **)items},
- + {.callback_and_desc = &menu_}
- + };
- +
- + sel = rb->do_menu(&menu, &sel, NULL, true);
- + }
- +
- + dict_free(buffer_size);
- +
- + if (n == 0)
- + return DICT_NOT_FOUND;
- +
- + switch (sel)
- + {
- + case MENU_ATTACHED_USB:
- + return DICT_USB_CONNECTED;
- + case MENU_SELECTED_EXIT: case GO_TO_PREVIOUS: case GO_TO_ROOT:
- + return DICT_QUIT;
- + default:
- + return index + sel;
- + }
- +}
- +
- +//! Wrapper to open the correct .desc file depending on the description offset
- +enum dict_action dict_desc_open(int n)
- +{
- + char fn[FAT_FILENAME_BYTES];
- +
- + if (n == Dict.fDict_n)
- + return DICT_OK;
- +
- + if (Dict.fDict > 0)
- + rb->close(Dict.fDict);
- +
- + if (n < 1)
- + rb->snprintf(fn, sizeof(fn), "%s/%s.dict", Dict.path, Dict.name); // slash added
- + else
- + rb->snprintf(fn, sizeof(fn), "%s/%s.dict.%d", Dict.path, Dict.name, n); // slash added
- +
- + Dict.fDict = rb->open(fn, O_RDONLY);
- + if (Dict.fDict < 0)
- + {
- + dict_error("Failed to open description file: %s", fn);
- + return DICT_ERROR;
- + }
- +
- + Dict.fDict_n = n;
- +
- + return DICT_OK;
- +}
- +
- +/** \brief Reads the article description
- + *
- + * @param article The article to be read.
- + */
- +char *dict_desc_read(struct WordData *artl, char *buf)
- +{
- + uint64_t offset = artl->offset;
- + int len, n = offset/MAX_FILESIZE;
- +
- + if (dict_desc_open(n) != DICT_OK)
- + return NULL;
- +
- + offset %= MAX_FILESIZE;
- +
- + rb->lseek(Dict.fDict, offset, SEEK_SET);
- + len = rb->read(Dict.fDict, buf, artl->size);
- +
- + /* check if article is splitted between two files */
- + if (offset > MAX_FILESIZE - artl->size)
- + {
- + rb->close(Dict.fDict);
- + if (dict_desc_open(++n) != DICT_OK)
- + return NULL;
- +
- + rb->read(Dict.fDict, buf+len, artl->size-len);
- + }
- + buf[artl->size] = '\0';
- +
- + /* And print it to debug. */
- + DEBUGF("Description: %s\n", buf);
- +
- + return buf;
- +}
- +
- +void dict_menu(void)
- +{
- + bool quit = false;
- + int selection = 0;
- +
- + MENUITEM_STRINGLIST(menu, "DICT Menu", NULL,
- + "Viewer control",
- + "Playback control",
- + "Max listed articles");
- +
- + rb->button_clear_queue();
- + rb->sleep(HZ/5);
- + while (!quit) {
- + selection = rb->do_menu(&menu, &selection, NULL, false);
- + switch (selection)
- + {
- + case 0:
- + quit = viewer_menu();
- + break;
- + case 1:
- + quit = playback_control(NULL);
- + break;
- + case 2:
- + quit = rb->set_int("Max listed articles", "", UNIT_INT,
- + &Conf.max_list, NULL, 10, 10, 50, NULL);
- + break;
- + default:
- + quit = true;
- + break;
- + }
- + }
- +}
- +
- +void dict_viewer_callback(int button)
- +{
- + switch (button)
- + {
- + case PLA_UP: case PLA_UP_REPEAT:
- + viewer_up();
- + break;
- + case PLA_DOWN: case PLA_DOWN_REPEAT:
- + viewer_down();
- + break;
- + case PLA_FIRE:
- + viewer_search();
- + break;
- + case PLA_QUIT:
- + viewer_exit(VIEWER_EXIT);
- + break;
- + case PLA_START:
- + viewer_exit(VIEWER_NEW);
- + break;
- + case PLA_MENU:
- + dict_menu();
- + break;
- +#ifdef VIEWER_HAS_SHORTCUT
- + default:
- + if (rb->button_status() & BUTTON_VIEWER_SHORTCUT)
- + viewer_shortcut();
- + break;
- +#endif
- +
- + }
- +}
- +
- +//! Parses #redirect from MediaWiki
- +int parse_mw_redirect(struct DictEntry *a, const char *desc)
- +{
- + char *p;
- + int len = 0;
- + int32_t index;
- + static const char redirect[] = "#redirect";
- +
- + if ( rb->strncasecmp(desc, redirect, sizeof(redirect)-1) )
- + return 0;
- +
- + /* get destination article */
- + p = rb->strchr(desc+sizeof(redirect)-1, '[') + 2;
- + while (p[len] != ']' && p[len] != '#')
- + len++;
- +
- + rb->strlcpy(a->name, p, len);
- + a->name[len] = '\0';
- +
- + /* replace '_' with ' ' */
- + for (p=a->name; *p; p++)
- + {
- + if (*p == '_')
- + *p = ' ';
- + }
- +
- +
- + index = dict_index_binary_search(a->name, dict_index_strcmp);
- + if (index < 0)
- + {
- + dict_error("Illegal redirect: %s", a->name);
- + return 0;
- + }
- + dict_index_entry(index, a);
- +
- + return 1;
- +}
- +
- +//! Dict main loop
- +enum dict_action dict_main(void)
- +{
- + struct DictEntry result;
- + char search[WORDLEN], old[WORDLEN];
- + char *desc;
- + int n, desc_size = 0, header_len = 0;
- + bool new_search = false;
- +
- + search[0] = '\0';
- +
- + viewer_init(rb);
- + viewer_set_scroll(Conf.viewer_scroll);
- + viewer_set_backlight(Conf.viewer_backlight);
- + viewer_set_shortcut(Conf.viewer_shortcut);
- + viewer_set_callback(dict_viewer_callback);
- +
- + while (true)
- + {
- +#ifndef HAVE_FLASH_STORAGE
- + /* keep the disk running */
- + rb->storage_spindown(255);
- +#ifndef SIMULATOR
- +// rb->ata_wakeup();
- +#endif
- +#endif /*HAVE_FLASH_STORAGE*/
- +
- + rb->strcpy(old, search);
- + rb->kbd_input(search, WORDLEN);
- + /* exit if the search string is empty or the user didn't change it */
- + if (!rb->strlen(search) ||
- + (!new_search && !rb->strncmp(old, search, sizeof(old)) ))
- + {
- + return DICT_OK;
- + }
- + new_search = false;
- +
- + result.index = dict_index_find_startingWith(search);
- + switch (result.index)
- + {
- + case DICT_NOT_FOUND:
- + dict_error("No results for \"%s\"", search);
- + continue;
- + case DICT_QUIT:
- + continue;
- + case DICT_USB_CONNECTED:
- + return DICT_USB_CONNECTED;
- + }
- +
- + /* get result data */
- + dict_index_entry(result.index, &result);
- + do {
- + if (desc_size > 0)
- + dict_free(desc_size);
- +
- + /* make title */
- + header_len = rb->strlen(result.name) + 2;
- + /* increase the buffer to put a title in front of the article */
- + desc_size = result.data.size + header_len + 1;
- + desc = (char *)dict_malloc(desc_size);
- +
- + /* set desc pointer to beginning of the description */
- + if (!dict_desc_read(&result.data, desc+header_len))
- + return DICT_ERROR;
- +
- + } while (parse_mw_redirect(&result, desc+header_len));
- +
- + DEBUGF("\
- +result:\n\
- + name: %s\n\
- + index: %ld\n\
- + offset: %llu (%llx)\n\
- + size: %lu\n",
- + result.name, result.index, result.data.offset,
- + result.data.offset, result.data.size);
- +
- +#ifndef HAVE_FLASH_STORAGE
- + rb->storage_spindown(rb->global_settings->disk_spindown);
- +#endif
- +
- + rb->snprintf(desc, header_len, "%s\n", result.name);
- + desc[header_len-1] = '\n';
- + desc[desc_size-1] = '\0';
- +
- + desc_size += dict_malloc_align();
- + n = viewer_set_text(dict_malloc(0), desc);
- + dict_malloc(n);
- + desc_size += n;
- +
- + while (!new_search)
- + {
- + switch(viewer_run())
- + {
- + case VIEWER_NEW:
- + new_search = true;
- + continue;
- + case VIEWER_ATTACHED_USB:
- + return DICT_USB_CONNECTED;
- + default:
- + return DICT_OK;
- + }
- + }
- +
- + dict_free(desc_size);
- + }
- +}
- +
- +enum plugin_status plugin_start(const void* file)
- +{
- + enum plugin_status ret;
- +
- + switch (dict_init(file))
- + {
- + case DICT_ERROR:
- + return PLUGIN_ERROR;
- + case DICT_USB_CONNECTED:
- + return PLUGIN_USB_CONNECTED;
- + default:
- + break;
- + }
- +
- + switch (dict_main())
- + {
- + case DICT_OK:
- + ret = PLUGIN_OK;
- + break;
- + case DICT_USB_CONNECTED:
- + ret = PLUGIN_USB_CONNECTED;
- + break;
- + default:
- + ret = PLUGIN_ERROR;
- + break;
- + }
- +
- +#ifndef HAVE_FLASH_STORAGE
- + /* reset disk setting */
- + rb->storage_spindown(rb->global_settings->disk_spindown);
- +#endif
- +
- + dict_close();
- +
- + return ret;
- +}
- Index: apps/plugins/lib/viewer.c
- ===================================================================
- --- apps/plugins/lib/viewer.c (Revision 0)
- +++ apps/plugins/lib/viewer.c (Revision 0)
- @@ -0,0 +1,516 @@
- +/***************************************************************************
- +* __________ __ ___.
- +* Open \______ \ ____ ____ | | _\_ |__ _______ ___
- +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- +* \/ \/ \/ \/ \/
- +* $Id: viewer.c 12008 2007-01-14 13:48:09Z dave $
- +*
- +* Copyright (C) 2007 Timo Horstschäfer
- +*
- +*
- +* All files in this archive are subject to the GNU General Public License.
- +* See the file COPYING in the source tree root for full license agreement.
- +*
- +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- +* KIND, either express or implied.
- +*
- +****************************************************************************/
- +
- +#include "plugin.h"
- +#include "pluginlib_actions.h"
- +#include "viewer.h"
- +
- +#define VIEWER_LINE_BUF 255
- +#define VIEWER_SCROLLBAR_WIDTH 4
- +#define MAX_SEARCHLEN 255
- +
- +/** text structure */
- +struct viewer_txt
- +{
- + const char *p; /**< Text pointer */
- + int len; /**< Text size */
- + int pos; /**< Current line number */
- +
- + int lines; /**< Number of lines */
- + const char **line; /**< Array of line pointers */
- +
- + int sections; /**< Number of sections */
- + int *section; /**< Array of section lines */
- + const char **section_name; /**< Name of each section */
- +};
- +
- +static void viewer_default_callback(int button);
- +
- +static struct viewer_txt *txt;
- +
- +/** Display and character dimensions*/
- +static int cols, rows;
- +#ifdef HAVE_REMOTE_LCD
- +static int remote_cols, remote_rows;
- +#endif
- +#ifdef HAVE_LCD_BITMAP
- +static int row_height;
- +#endif
- +
- +static char search[255];
- +static bool quit;
- +static int retval;
- +
- +/* Customization (also default settings) */
- +void (*viewer_shortcut)(void)
- + = (void *)viewer_menu_search;
- +static void (*viewer_callback)(int button)
- + = viewer_default_callback;
- +static int scroll = 0;
- +static int backlight = 2;
- +static int shortcut = 0;
- +
- +inline int viewer(const struct plugin_api *newrb, const char *text)
- +{
- + static long buffer[128];
- + viewer_init(newrb);
- + viewer_set_text(buffer, text);
- + return viewer_run();
- +}
- +
- +/** \brief Returns a pointer to the last character of a line.
- + * @param s Pointer to the actual line.
- + */
- +static char *viewer_endl(const char *s, int width)
- +{
- + const char *space = NULL;
- +
- + while (true)
- + {
- + if (*s == '\n' || *s == '\0')
- + return (char *)s;
- + if (*s == ' ')
- + space = s;
- + if (!--width)
- + break;
- + s += rb->utf8seek(s, 1);
- + }
- +
- + return (char *) ( (space) ? space : s );
- +}
- +
- +/** \brief Draws text on the display.
- + *
- + * Handles newline characters and line wrapping.
- + */
- +static void viewer_draw(const char *s)
- +{
- + const char *p, *eol;
- + int line, len;
- + char buf[VIEWER_LINE_BUF];
- + int left_margin=0;
- +
- + rb->lcd_clear_display();
- +
- + /* Some Rockbox function restore the backlight settings; reset it */
- + viewer_set_backlight(backlight);
- +
- +#ifdef HAVE_LCD_BITMAP
- + if (txt->lines > rows)
- + {
- + rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN], 0, 0,
- + VIEWER_SCROLLBAR_WIDTH-1, LCD_HEIGHT,
- + txt->lines+rows-1, txt->pos, txt->pos+rows,
- + VERTICAL);
- + left_margin=VIEWER_SCROLLBAR_WIDTH;
- + }
- +#endif
- +
- + /* draw main display */
- + for (p=s, line=0; line<rows; line++)
- + {
- + eol = viewer_endl(p, cols);
- +
- + len = eol-p;
- + // if (*eol != '\n' && *eol != '\0') //removed to fix missing last character at eol
- + len++;
- +
- + rb->strlcpy(buf, p, len);
- + buf[len] = '\0';
- +#ifdef HAVE_LCD_BITMAP
- + rb->lcd_putsxy(left_margin, line*row_height, buf);
- +#else
- + rb->lcd_puts(0,line,buf);
- +#endif
- + if (*eol)
- + p = eol + rb->utf8seek(eol, 1);
- + else
- + break;
- + }
- +
- + rb->lcd_update();
- +
- +#ifdef HAVE_REMOTE_LCD
- + rb->lcd_remote_clear_display();
- +
- + /* draw remote */
- + for (p=s, line=0; line<remote_rows; line++)
- + {
- + eol = viewer_endl(p, remote_cols);
- +
- + len = eol-p;
- + if (*eol != '\n' && *eol != '\0')
- + len++;
- +
- + rb->strlcpy(buf, p, len);
- + buf[len] = '\0';
- +
- + rb->lcd_remote_puts(0, line, buf);
- +
- + if (*eol)
- + p = eol + rb->utf8seek(eol, 1);
- + else
- + break;
- + }
- +
- + rb->lcd_remote_update();
- +#endif
- +}
- +
- +static void viewer_default_callback(int button)
- +{
- + switch (button)
- + {
- + case PLA_UP: case PLA_UP_REPEAT:
- + viewer_up();
- + break;
- + case PLA_DOWN: case PLA_DOWN_REPEAT:
- + viewer_down();
- + break;
- + case PLA_FIRE:
- + viewer_search();
- + break;
- + case PLA_QUIT:
- + viewer_exit(VIEWER_EXIT);
- + break;
- + case PLA_MENU:
- + viewer_menu();
- + break;
- +#ifdef VIEWER_HAS_SHORTCUT
- + default:
- + /* Could need some better way to access the REC-button */
- + if (rb->button_status() & BUTTON_VIEWER_SHORTCUT)
- + viewer_shortcut();
- + break;
- +#endif
- + }
- +}
- +
- +void viewer_init(const struct plugin_api *newrb)
- +{
- + rb = newrb;
- +
- +#ifdef HAVE_LCD_BITMAP
- + rb->lcd_getstringsize("o", &cols, &row_height);
- +# ifdef HAVE_REMOTE_LCD
- + remote_cols = LCD_REMOTE_WIDTH / cols;
- + remote_rows = LCD_REMOTE_HEIGHT / row_height;
- +# endif
- + cols = (LCD_WIDTH-VIEWER_SCROLLBAR_WIDTH) / cols;
- + rows = LCD_HEIGHT / row_height;
- +#else
- + cols = 11;
- + rows = 2;
- +#endif
- +
- + viewer_callback = viewer_default_callback;
- + scroll = 0;
- +}
- +
- +int viewer_run(void)
- +{
- + int button;
- + const struct button_mapping *viewer_contexts[] = {
- + generic_directions,
- + generic_actions,
- + };
- +
- + viewer_redraw();
- +
- + quit = false;
- + retval = VIEWER_EXIT;
- +
- + while (!quit)
- + {
- + rb->yield();
- + button = pluginlib_getaction(HZ, viewer_contexts, 2);
- +
- + if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
- + viewer_exit(VIEWER_ATTACHED_USB);
- +
- + viewer_callback(button);
- + viewer_redraw();
- + }
- +
- + /* restore backlight setting */
- + rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
- +
- + return retval;
- +}
- +
- +int viewer_line(const char *p)
- +{
- + int line;
- +
- + for (line=0; line<txt->lines; line++)
- + {
- + if (p < txt->line[line])
- + break;
- + }
- +
- + return line ? line-1 : line;
- +}
- +
- +int viewer_set_text(void *buffer, const char *text)
- +{
- + size_t buffer_used;
- + const char *p;
- +
- + txt = buffer;
- + buffer_used = sizeof(struct viewer_txt);
- +
- + txt->p = text;
- + txt->len = rb->strlen(txt->p);
- + txt->pos = 0;
- +
- + /* Create an array with the pointers to the beginning of each line */
- + txt->lines = 0;
- + txt->line = buffer + buffer_used;
- + for (p = txt->p; *p;)
- + {
- + txt->line[txt->lines++] = p;
- + p = viewer_endl(p, cols);
- + if (*p)
- + p += rb->utf8seek(p, 1);
- + }
- + buffer_used += txt->lines * sizeof txt->line;
- + return buffer_used;
- +}
- +
- +void viewer_set_callback(void (*newcallback)(int button))
- +{
- + viewer_callback = newcallback;
- +}
- +
- +void viewer_set_scroll(int newscroll)
- +{
- + scroll = newscroll < 0 ? 0 : newscroll;
- +}
- +
- +void viewer_set_pos(int line)
- +{
- + if (line < 0)
- + txt->pos = txt->lines-1 - (line%txt->lines);
- + else if (line >= txt->lines)
- + txt->pos = txt->lines-1;
- + else
- + txt->pos = line;
- +}
- +
- +void viewer_set_backlight(int newbacklight)
- +{
- + backlight = (newbacklight > 2) ? 2 : newbacklight;
- + switch (backlight)
- + {
- + case 0:
- + rb->backlight_set_timeout(0);
- + break;
- + case 1:
- + rb->backlight_set_timeout(1);
- + break;
- + default:
- + rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
- + break;
- + }
- +}
- +
- +void viewer_set_shortcut(int shortcutindex)
- +{
- + switch (shortcutindex)
- + {
- + default:
- + case 0:
- + shortcutindex = 0;
- + viewer_shortcut = (void *)viewer_menu_search;
- + break;
- + case 1:
- + viewer_shortcut = (void *)viewer_menu_backlight;
- + break;
- + case 2:
- + viewer_shortcut = (void *)viewer_menu_scroll;
- + break;
- + }
- + shortcut = shortcutindex;
- +}
- +
- +int viewer_get_scroll(void)
- +{
- + return scroll;
- +}
- +
- +int viewer_get_pos(void)
- +{
- + return txt->pos;
- +}
- +
- +int viewer_get_backlight(void)
- +{
- + return backlight;
- +}
- +
- +int viewer_get_shortcut(void)
- +{
- + return shortcut;
- +}
- +
- +void viewer_up(void)
- +{
- + int n = scroll ? scroll : rows;
- + txt->pos = (txt->pos < n) ? 0 : txt->pos - n;
- +}
- +
- +void viewer_down(void)
- +{
- + int n = scroll ? scroll : rows;
- +
- +#ifdef HAVE_REMOTE_LCD
- + if (txt->lines < remote_rows)
- +#else
- + if (txt->lines < rows)
- +#endif
- + return;
- +
- + if (txt->pos+n >= txt->lines)
- + txt->pos = txt->lines-1;
- + else
- + txt->pos += n;
- +}
- +
- +void viewer_redraw(void)
- +{
- + viewer_draw(txt->line[txt->pos]);
- +}
- +
- +bool viewer_search(void)
- +{
- + int line;
- + const char *p;
- + size_t n;
- +
- + if (!search[0])
- + return false;
- +
- + n = rb->strlen(search);
- + line = (txt->pos == txt->lines-1) ? 0 : txt->pos+1;
- + p = txt->line[line];
- + while (true)
- + {
- + if (!*p)
- + p = txt->p;
- +
- + /* just a slow linear search */
- + if (rb->strncasecmp(search, p, n) == 0)
- + break;
- +
- + if (p == txt->line[txt->pos])
- + return false;
- +
- + p += rb->utf8seek(p, 1);
- + }
- +
- + viewer_set_pos(viewer_line(p));
- + return true;
- +}
- +
- +void viewer_exit(int newretval)
- +{
- + retval = newretval;
- + quit = true;
- +}
- +
- +/* Viewer menu */
- +bool viewer_menu_search(void)
- +{
- + rb->kbd_input(search, sizeof(search));
- + if (viewer_search())
- + return true;
- + else
- + {
- + rb->splashf(HZ, "\"%s\" not found", search);
- + return false;
- + }
- +}
- +
- +bool viewer_menu_scroll(void)
- +{
- + static const struct opt_items scroll_menu[] = {
- + { "Full page", -1 },
- + { "1 line", -1 },
- + { "2 lines", -1 },
- + { "3 lines", -1 },
- + { "4 lines", -1 },
- + { "5 lines", -1 },
- + };
- +
- + return rb->set_option("Scrolling", &scroll, INT, scroll_menu, 6, NULL);
- +}
- +
- +bool viewer_menu_backlight(void)
- +{
- + static const struct opt_items backlight_menu[] = {
- + { "Off", -1 },
- + { "On", -1 },
- + { "use Rockox setting", -1 },
- + };
- +
- + return rb->set_option("Backlight", &backlight, INT, backlight_menu, 3,
- + viewer_set_backlight);
- +}
- +
- +bool viewer_menu_shortcut(void)
- +{
- + static const struct opt_items shortcut_menu[] = {
- + { "Search...", -1 },
- + { "Backlight", -1 },
- + { "Scrolling", -1 },
- + };
- +
- + return rb->set_option("REC shortcut", &shortcut, INT, shortcut_menu, 3,
- + viewer_set_shortcut);
- +}
- +
- +MENUITEM_FUNCTION(search_item, MENU_FUNC_CHECK_RETVAL, "Search...",
- + viewer_menu_search, NULL, NULL, Icon_NOICON);
- +MENUITEM_FUNCTION(scroll_item, 0, "Scrolling",
- + viewer_menu_scroll, NULL, NULL, Icon_NOICON);
- +MENUITEM_FUNCTION(backlight_item, 0, "Backlight",
- + viewer_menu_backlight, NULL, NULL, Icon_NOICON);
- +MENUITEM_FUNCTION(shortcut_item, 0, "REC shortcut",
- + viewer_menu_shortcut, NULL, NULL, Icon_NOICON);
- +
- +#ifdef VIEWER_HAS_SHORTCUT
- +#define VIEWER_SC_ITEM ,&shortcut_item
- +#else
- +#define VIEWER_SC_ITEM
- +#endif
- +MAKE_MENU(viewer_control_menu, "Viewer Control", NULL, Icon_NOICON,
- + &search_item, &scroll_item, &backlight_item VIEWER_SC_ITEM);
- +
- +bool viewer_menu(void)
- +{
- + switch(rb->do_menu(&viewer_control_menu, NULL, NULL, false))
- + {
- + case MENU_ATTACHED_USB:
- + case true:
- + return true;
- + default:
- + return false;
- + }
- +}
- Index: apps/plugins/lib/SOURCES
- ===================================================================
- --- apps/plugins/lib/SOURCES (Revision 23417)
- +++ apps/plugins/lib/SOURCES (Arbeitskopie)
- @@ -5,6 +5,7 @@
- playback_control.c
- rgb_hsv.c
- buflib.c
- +viewer.c
- display_text.c
- strncpy.c
- #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4)
- Index: apps/plugins/lib/viewer.h
- ===================================================================
- --- apps/plugins/lib/viewer.h (Revision 0)
- +++ apps/plugins/lib/viewer.h (Revision 0)
- @@ -0,0 +1,84 @@
- +/***************************************************************************
- +* __________ __ ___.
- +* Open \______ \ ____ ____ | | _\_ |__ _______ ___
- +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- +* \/ \/ \/ \/ \/
- +* $Id: viewer.h 12008 2007-01-14 13:48:09Z dave $
- +*
- +* Copyright (C) 2007 Timo Horstschäfer
- +*
- +*
- +* All files in this archive are subject to the GNU General Public License.
- +* See the file COPYING in the source tree root for full license agreement.
- +*
- +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- +* KIND, either express or implied.
- +*
- +****************************************************************************/
- +
- +#include "plugin.h"
- +
- +#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
- + (CONFIG_KEYPAD == IRIVER_H300_PAD) || \
- + (CONFIG_KEYPAD == SANSA_E200_PAD)
- +#define VIEWER_HAS_SHORTCUT
- +#define BUTTON_VIEWER_SHORTCUT BUTTON_REC
- +#endif
- +
- +/** \brief Shows a text viewer.
- + *
- + * How to view some text:
- + * viewer(api, textptr); // Text must be zero-terminated.
- + *
- + * For full control, call each function seperately:
- + * viewer_init(rb); // Must be done once in a plugin.
- + * viewer_set_text(bufferptr, textptr);
- + * viewer_run(); // Display the text.
- + *
- + * viewer() is just a short form for all three calls.
- + *
- + * @param text Zero-terminated string.
- + */
- +int viewer(const struct plugin_api *api, const char *text);
- +#define VIEWER_ATTACHED_USB (-2)
- +#define VIEWER_EXIT 0
- +#define VIEWER_CUSTOM (VIEWER_EXIT+1)
- +/**< Use values starting with VIEWER_CUSTOM for your own return values. */
- +
- +void viewer_init(const struct plugin_api *api);
- +int viewer_run(void);
- +
- +/** Get the line to which the address belongs to. */
- +int viewer_line(const char *p);
- +
- +/** Initialize the viewer with a new text.
- + *
- + * @param buffer A small buffer.
- + * @param text The new text to be displayed.
- + * @return Needed size of the buffer.
- + */
- +int viewer_set_text(void *buffer, const char *txt);
- +void viewer_set_callback(void (*callback)(int button));
- +void viewer_set_scroll(int newscroll);
- +void viewer_set_pos(int line);
- +void viewer_set_backlight(int newbacklight);
- +void viewer_set_shortcut(int shortcutindex);
- +
- +int viewer_get_scroll(void);
- +int viewer_get_pos(void);
- +int viewer_get_backlight(void);
- +int viewer_get_shortcut(void);
- +
- +/** Functions to control the viewer in the callback function. */
- +void viewer_up(void);
- +void viewer_down(void);
- +bool viewer_search(void);
- +bool viewer_menu(void);
- +void viewer_redraw(void);
- +void (*viewer_shortcut)(void);
- +bool viewer_menu_search(void);
- +bool viewer_menu_scroll(void);
- +bool viewer_menu_backlight(void);
- +void viewer_exit(int retval);
- Index: apps/plugins/SOURCES
- ===================================================================
- --- apps/plugins/SOURCES (Revision 23417)
- +++ apps/plugins/SOURCES (Arbeitskopie)
- @@ -3,6 +3,7 @@
- credits.c
- cube.c
- dict.c
- +dict2.c
- jackpot.c
- keybox.c
- logo.c
- Index: apps/plugins/viewers.config
- ===================================================================
- --- apps/plugins/viewers.config (Revision 23417)
- +++ apps/plugins/viewers.config (Arbeitskopie)
- @@ -1,6 +1,8 @@
- ch8,viewers/chip8,0
- txt,viewers/viewer,1
- nfo,viewers/viewer,1
- +idx,viewers/dict2,1
- +lidx,viewers/dict2,1
- txt,apps/text_editor,2
- jpg,viewers/jpeg,2
- jpe,viewers/jpeg,2
- Index: apps/settings.h
- ===================================================================
- --- apps/settings.h (Revision 23417)
- +++ apps/settings.h (Arbeitskopie)
- @@ -78,6 +78,7 @@
- #define RECPRESETS_DIR ROCKBOX_DIR "/recpresets"
- #define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
- #define PLAYLIST_CATALOG_DEFAULT_DIR "/Playlists"
- +#define DICTS_DIR "/dicts"
- #define VIEWERS_CONFIG ROCKBOX_DIR "/viewers.config"
- #define CONFIGFILE ROCKBOX_DIR "/config.cfg"
- @@ -144,7 +145,7 @@
- enum { SHOW_ALL, SHOW_SUPPORTED, SHOW_MUSIC, SHOW_PLAYLIST, SHOW_ID3DB,
- NUM_FILTER_MODES,
- SHOW_WPS, SHOW_RWPS, SHOW_SBS, SHOW_RSBS, SHOW_FMR, SHOW_CFG,
- - SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_PLUGINS};
- + SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_DICTS, SHOW_PLUGINS};
- /* file and dir sort options */
- enum { SORT_ALPHA, SORT_DATE, SORT_DATE_REVERSED, SORT_TYPE, /* available as settings */
- Index: apps/filetree.c
- ===================================================================
- --- apps/filetree.c (Revision 23417)
- +++ apps/filetree.c (Arbeitskopie)
- @@ -328,7 +328,8 @@
- ((*c->dirfilter == SHOW_MUSIC &&
- (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_AUDIO) &&
- (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_M3U) ||
- - (*c->dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)))) ||
- + ((*c->dirfilter == SHOW_SUPPORTED || *c->dirfilter == SHOW_DICTS)&&
- + !filetype_supported(dptr->attr)))) ||
- (*c->dirfilter == SHOW_WPS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_WPS) ||
- #ifdef HAVE_LCD_BITMAP
- (*c->dirfilter == SHOW_FONT && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_FONT) ||
- @@ -671,6 +672,7 @@
- if (*c->dirfilter > NUM_FILTER_MODES &&
- *c->dirfilter != SHOW_CFG &&
- *c->dirfilter != SHOW_FONT &&
- + *c->dirfilter != SHOW_DICTS &&
- *c->dirfilter != SHOW_PLUGINS)
- {
- exit_func = true;
- Index: apps/root_menu.c
- ===================================================================
- --- apps/root_menu.c (Revision 23417)
- +++ apps/root_menu.c (Arbeitskopie)
- @@ -216,6 +216,10 @@
- tc->selected_item = last_db_selection;
- break;
- #endif
- + case GO_TO_BROWSEDICTS:
- + filter = SHOW_DICTS;
- + snprintf(folder, MAX_PATH, "%s/", DICTS_DIR);
- + break;
- case GO_TO_BROWSEPLUGINS:
- filter = SHOW_PLUGINS;
- strlcpy(folder, PLUGIN_DIR, MAX_PATH);
- @@ -355,6 +359,7 @@
- #endif
- [GO_TO_RECENTBMARKS] = { load_bmarks, NULL, &bookmark_settings_menu },
- + [GO_TO_BROWSEDICTS] = { browser, (void*)GO_TO_BROWSEDICTS, NULL },
- [GO_TO_BROWSEPLUGINS] = { plugins_menu, NULL, NULL },
- };
- @@ -368,6 +373,8 @@
- MENUITEM_RETURNVALUE(db_browser, ID2P(LANG_TAGCACHE), GO_TO_DBBROWSER,
- NULL, Icon_Audio);
- #endif
- +MENUITEM_RETURNVALUE(dicts_browser, ID2P(LANG_DICTIONARIES), GO_TO_BROWSEDICTS,
- + NULL, Icon_NOICON);
- MENUITEM_RETURNVALUE(rocks_browser, ID2P(LANG_PLUGINS), GO_TO_BROWSEPLUGINS,
- NULL, Icon_Plugin);
- static char *get_wps_item_name(int selected_item, void * data, char *buffer)
- @@ -419,7 +426,7 @@
- #if CONFIG_TUNER
- &fm,
- #endif
- - &playlist_options, &rocks_browser, &info_menu
- + &playlist_options, &dicts_browser, &rocks_browser, &info_menu
- #ifdef HAVE_LCD_CHARCELLS
- ,&do_shutdown_item
- Index: apps/root_menu.h
- ===================================================================
- --- apps/root_menu.h (Revision 23417)
- +++ apps/root_menu.h (Arbeitskopie)
- @@ -50,6 +50,7 @@
- /* Do Not add any items above here unless you want it to be able to
- be the "start screen" after a boot up. The setting in settings_list.c
- will need editing if this is the case. */
- + GO_TO_BROWSEDICTS,
- GO_TO_BROWSEPLUGINS,
- GO_TO_TIMESCREEN,
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement