text_viewer: rename preference values.
[kugel-rb.git] / apps / plugins / text_viewer / tv_bookmark.c
blobd569ed8d1181147cd94afd716bbf8482cd286a20
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Gilles Roux
11 * 2003 Garrett Derner
12 * 2010 Yoshihisa Uchida
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
23 #include "plugin.h"
24 #include "tv_bookmark.h"
25 #include "tv_pager.h"
26 #include "tv_preferences.h"
28 /* text viewer bookmark functions */
30 enum {
31 TV_BOOKMARK_SYSTEM = 1,
32 TV_BOOKMARK_USER = 2,
35 #define SERIALIZE_BOOKMARK_SIZE 8
37 struct tv_bookmark_info {
38 struct tv_screen_pos pos;
39 unsigned char flag;
42 /* bookmark stored array */
43 struct tv_bookmark_info bookmarks[TV_MAX_BOOKMARKS + 1];
44 static unsigned char bookmark_count;
46 static int tv_compare_screen_pos(const struct tv_screen_pos *p1, const struct tv_screen_pos *p2)
48 if (p1->page != p2->page)
49 return p1->page - p2->page;
51 return p1->line - p2->line;
54 static int bm_comp(const void *a, const void *b)
56 struct tv_bookmark_info *pa;
57 struct tv_bookmark_info *pb;
59 pa = (struct tv_bookmark_info*)a;
60 pb = (struct tv_bookmark_info*)b;
62 return tv_compare_screen_pos(&pa->pos, &pb->pos);
65 static int tv_add_bookmark(const struct tv_screen_pos *pos)
67 if (bookmark_count >= TV_MAX_BOOKMARKS)
68 return -1;
70 bookmarks[bookmark_count].pos = *pos;
71 bookmarks[bookmark_count].flag = TV_BOOKMARK_USER;
73 return bookmark_count++;
76 static void tv_remove_bookmark(int idx)
78 int k;
80 if (idx >= 0 && idx < bookmark_count)
82 for (k = idx + 1; k < bookmark_count; k++)
83 bookmarks[k-1] = bookmarks[k];
85 bookmark_count--;
89 static int tv_find_bookmark(const struct tv_screen_pos *pos)
91 int i;
93 for (i = 0; i < bookmark_count; i++)
95 if (tv_compare_screen_pos(&bookmarks[i].pos, pos) == 0)
96 return i;
98 return -1;
101 static void tv_change_preferences(const struct tv_preferences *oldp)
103 int i;
105 if (oldp == NULL)
106 return;
108 for (i = 0; i < bookmark_count; i++)
109 tv_convert_fpos(bookmarks[i].pos.file_pos, &bookmarks[i].pos);
112 void tv_init_bookmark(void)
114 tv_add_preferences_change_listner(tv_change_preferences);
117 int tv_get_bookmark_positions(struct tv_screen_pos *pos_array)
119 int i;
121 for(i = 0; i < bookmark_count; i++)
122 *pos_array++ = bookmarks[i].pos;
124 return bookmark_count;
127 void tv_toggle_bookmark(void)
129 const struct tv_screen_pos *pos = tv_get_screen_pos();
130 int idx = tv_find_bookmark(pos);
132 if (idx < 0)
134 if (tv_add_bookmark(pos) >= 0)
135 rb->splash(HZ/2, "Bookmark add");
136 else
137 rb->splash(HZ/2, "No more add bookmark");
138 return;
140 tv_remove_bookmark(idx);
141 rb->splash(HZ/2, "Bookmark remove");
144 void tv_create_system_bookmark(void)
146 const struct tv_screen_pos *pos = tv_get_screen_pos();
147 int idx = tv_find_bookmark(pos);
149 if (idx >= 0)
150 bookmarks[idx].flag |= TV_BOOKMARK_SYSTEM;
151 else
153 bookmarks[bookmark_count].pos = *pos;
154 bookmarks[bookmark_count].flag = TV_BOOKMARK_SYSTEM;
155 bookmark_count++;
159 void tv_select_bookmark(void)
161 int i;
162 struct tv_screen_pos select_pos;
164 for (i = 0; i < bookmark_count; i++)
166 if (bookmarks[i].flag & TV_BOOKMARK_SYSTEM)
167 break;
170 /* if does not find the system bookmark, add the system bookmark. */
171 if (i >= bookmark_count)
172 tv_create_system_bookmark();
174 if (bookmark_count == 1)
175 select_pos = bookmarks[0].pos;
176 else
178 int selected = -1;
179 struct opt_items items[bookmark_count];
180 unsigned char names[bookmark_count][24];
182 rb->qsort(bookmarks, bookmark_count, sizeof(struct tv_bookmark_info), bm_comp);
184 for (i = 0; i < bookmark_count; i++)
186 rb->snprintf(names[i], sizeof(names[0]),
187 #if CONFIG_KEYPAD != PLAYER_PAD
188 "%cPage: %d Line: %d",
189 #else
190 "%cP:%d L:%d",
191 #endif
192 (bookmarks[i].flag & TV_BOOKMARK_SYSTEM)? '*' : ' ',
193 bookmarks[i].pos.page + 1,
194 bookmarks[i].pos.line + 1);
195 items[i].string = names[i];
196 items[i].voice_id = -1;
199 rb->set_option("Select bookmark", &selected, INT, items,
200 bookmark_count, NULL);
202 if (selected >= 0 && selected < bookmark_count)
203 select_pos = bookmarks[selected].pos;
204 else
206 /* when does not select any bookmarks, move to the current page */
207 tv_copy_screen_pos(&select_pos);
209 if (select_pos.file_pos == 0)
210 rb->splash(HZ, "Start the first page");
211 else
212 rb->splash(HZ, "Return to the current page");
216 /* deletes the system bookmark */
217 for (i = 0; i < bookmark_count; i++)
219 if ((bookmarks[i].flag &= TV_BOOKMARK_USER) == 0)
221 tv_remove_bookmark(i);
222 break;
226 /* move to the select position */
227 if (preferences->vertical_scroll_mode == VS_PAGE)
228 select_pos.line = 0;
230 tv_move_screen(select_pos.page, select_pos.line, SEEK_SET);
233 /* serialize or deserialize of the bookmark array */
234 static bool tv_read_bookmark_info(int fd, struct tv_bookmark_info *b)
236 unsigned char buf[SERIALIZE_BOOKMARK_SIZE];
238 if (rb->read(fd, buf, sizeof(buf)) < 0)
239 return false;
241 b->pos.file_pos = (buf[0] << 24)|(buf[1] << 16)|(buf[2] << 8)|buf[3];
242 b->pos.page = (buf[4] << 8)|buf[5];
243 b->pos.line = buf[6];
244 b->flag = buf[7];
246 return true;
249 bool tv_deserialize_bookmarks(int fd)
251 int i;
252 bool res = true;
254 if (rb->read(fd, &bookmark_count, 1) < 0)
255 return false;
257 for (i = 0; i < bookmark_count; i++)
259 if (!tv_read_bookmark_info(fd, &bookmarks[i]))
261 res = false;
262 break;
266 bookmark_count = i;
267 return res;
270 static bool tv_write_bookmark_info(int fd, const struct tv_bookmark_info *b)
272 unsigned char buf[SERIALIZE_BOOKMARK_SIZE];
273 unsigned char *p = buf;
275 *p++ = b->pos.file_pos >> 24;
276 *p++ = b->pos.file_pos >> 16;
277 *p++ = b->pos.file_pos >> 8;
278 *p++ = b->pos.file_pos;
280 *p++ = b->pos.page >> 8;
281 *p++ = b->pos.page;
283 *p++ = b->pos.line;
284 *p = b->flag;
286 return (rb->write(fd, buf, SERIALIZE_BOOKMARK_SIZE) >= 0);
289 int tv_serialize_bookmarks(int fd)
291 int i;
293 if (rb->write(fd, &bookmark_count, 1) < 0)
294 return 0;
296 for (i = 0; i < bookmark_count; i++)
298 if (!tv_write_bookmark_info(fd, &bookmarks[i]))
299 break;
301 return i * SERIALIZE_BOOKMARK_SIZE + 1;