new text viewer
[kugel-rb.git] / apps / plugins / textviewer / tv_bookmark.c
blob261a319e2659b8be8b5fb63ef9c111429917644d
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"
26 /* text viewer bookmark functions */
28 enum
30 BOOKMARK_LAST = 1,
31 BOOKMARK_USER,
34 #ifndef HAVE_LCD_BITMAP
35 #define BOOKMARK_ICON "\xee\x84\x81\x00"
36 #endif
38 #define BOOKMARK_SIZE 8
39 #define MAX_BOOKMARKS 10 /* user setting bookmarks + last read page */
42 struct bookmark_info bookmarks[MAX_BOOKMARKS];
43 static int bookmark_count;
45 static int bm_comp(const void *a, const void *b)
47 struct bookmark_info *pa;
48 struct bookmark_info *pb;
50 pa = (struct bookmark_info*)a;
51 pb = (struct bookmark_info*)b;
53 if (pa->page != pb->page)
54 return pa->page - pb->page;
56 return pa->line - pb->line;
59 int viewer_find_bookmark(int page, int line)
61 int i;
63 for (i = 0; i < bookmark_count; i++)
65 if (bookmarks[i].page == page && bookmarks[i].line == line)
66 return i;
68 return -1;
71 void viewer_add_bookmark(int page, int line)
73 if (bookmark_count >= MAX_BOOKMARKS-1)
74 return;
76 bookmarks[bookmark_count].file_position
77 = file_pos + screen_top_ptr - buffer;
78 bookmarks[bookmark_count].page = page;
79 bookmarks[bookmark_count].line = line;
80 bookmarks[bookmark_count].flag = BOOKMARK_USER;
81 bookmark_count++;
84 static int viewer_add_last_read_bookmark(void)
86 int i;
88 i = viewer_find_bookmark(cpage, cline);
89 if (i >= 0)
90 bookmarks[i].flag |= BOOKMARK_LAST;
91 else
93 viewer_add_bookmark();
94 i = bookmark_count-1;
95 bookmarks[i].flag = BOOKMARK_LAST;
97 return i;
100 static void viewer_remove_bookmark(int i)
102 int j;
104 if (i < 0 || i >= bookmark_count)
105 return;
107 for (j = i+1; j < bookmark_count; j++)
108 rb->memcpy(&bookmarks[j-1], &bookmarks[j],
109 sizeof(struct bookmark_info));
111 bookmark_count--;
114 void viewer_remove_last_read_bookmark(void)
116 int i, j;
118 for (i = 0; i < bookmark_count; i++)
120 if (bookmarks[i].flag & BOOKMARK_LAST)
122 if (bookmarks[i].flag == BOOKMARK_LAST)
124 for (j = i+1; j < bookmark_count; j++)
125 rb->memcpy(&bookmarks[j-1], &bookmarks[j],
126 sizeof(struct bookmark_info));
128 bookmark_count--;
130 else
131 bookmarks[i].flag = BOOKMARK_USER;
132 break;
138 * the function that a bookmark add when there is not a bookmark in the given position
139 * or the bookmark remove when there exist a bookmark in the given position.
142 void viewer_add_remove_bookmark(int page, int line)
144 int idx = viewer_find_bookmark(cpage, cline);
146 if (idx < 0)
148 if (bookmark_count >= MAX_BOOKMARKS-1)
149 rb->splash(HZ/2, "No more add bookmark.");
150 else
152 viewer_add_bookmark(page, line);
153 rb->splash(HZ/2, "Bookmark add.");
156 viewer_remove_bookmark(idx);
157 rb->splash(HZ/2, "Bookmark remove.");
160 static int viewer_get_last_read_bookmark(void)
162 int i;
164 for (i = 0; i < bookmark_count; i++)
166 if (bookmarks[i].flag & BOOKMARK_LAST)
167 return i;
169 return -1;
172 void viewer_select_bookmark(int initval)
174 int i;
175 int ipage = 0;
176 int iline = 0;
177 int screen_pos;
178 int screen_top;
179 int selected = -1;
181 struct opt_items items[bookmark_count];
182 unsigned char names[bookmark_count][38];
184 if (initval >= 0 && initval < bookmark_count)
186 ipage = bookmarks[initval].page;
187 iline = bookmarks[initval].line;
190 rb->qsort(bookmarks, bookmark_count, sizeof(struct bookmark_info),
191 bm_comp);
193 for (i = 0; i < bookmark_count; i++)
195 rb->snprintf(names[i], sizeof(names[0]),
196 #if CONFIG_KEYPAD != PLAYER_PAD
197 "%sPage: %d Line: %d",
198 #else
199 "%sP:%d L:%d",
200 #endif
201 (bookmarks[i].flag&BOOKMARK_LAST)? "*":" ",
202 bookmarks[i].page,
203 bookmarks[i].line);
204 items[i].string = names[i];
205 items[i].voice_id = -1;
206 if (selected < 0 && bookmarks[i].page == ipage && bookmarks[i].line == iline)
207 selected = i;
210 rb->set_option("Select bookmark", &selected, INT, items,
211 sizeof(items) / sizeof(items[0]), NULL);
213 if (selected < 0 || selected >= bookmark_count)
215 if (initval < 0 || (selected = viewer_get_last_read_bookmark()) < 0)
217 if (initval < 0)
218 rb->splash(HZ, "Start the first page.");
219 file_pos = 0;
220 screen_top_ptr = buffer;
221 cpage = 1;
222 cline = 1;
223 buffer_end = BUFFER_END();
224 return;
228 screen_pos = bookmarks[selected].file_position;
229 screen_top = screen_pos % buffer_size;
230 file_pos = screen_pos - screen_top;
231 screen_top_ptr = buffer + screen_top;
232 cpage = bookmarks[selected].page;
233 cline = bookmarks[selected].line;
234 buffer_end = BUFFER_END();
238 static bool viewer_read_bookmark_info(int bfd, struct bookmark_info *b)
240 unsigned char buf[BOOKMARK_SIZE];
242 if (rb->read(bfd, buf, sizeof(buf)) != sizeof(buf))
243 return false;
245 b->file_position = (buf[0] << 24)|(buf[1] << 16)|(buf[2] << 8)|buf[3];
246 b->page = (buf[4] << 8)|buf[5];
247 b->line = buf[6];
248 b->flag = buf[7];
250 return true;
253 bool viewer_read_bookmark_infos(int fd)
255 unsigned char c;
256 int i;
258 if (rb->read(fd, &c, 1) != 1)
260 bookmark_count = 0;
261 return false;
264 bookmark_count = c;
265 if (bookmark_count > MAX_BOOKMARKS)
266 bookmark_count = MAX_BOOKMARKS;
268 for (i = 0; i < bookmark_count; i++)
270 if (!viewer_read_bookmark_info(fd, &bookmarks[i]))
272 bookmark_count = i;
273 return false;
276 return true;
279 static bool viewer_write_bookmark_info(int bfd, struct bookmark_info *b)
281 unsigned char buf[BOOKMARK_SIZE];
282 unsigned char *p = buf;
283 unsigned long ul;
285 ul = b->file_position;
286 *p++ = ul >> 24;
287 *p++ = ul >> 16;
288 *p++ = ul >> 8;
289 *p++ = ul;
291 ul = b->page;
292 *p++ = ul >> 8;
293 *p++ = ul;
295 *p++ = b->line;
296 *p = b->flag;
298 return (rb->write(bfd, buf, sizeof(buf)) == sizeof(buf));
301 bool viewer_write_bookmark_infos(int fd)
303 unsigned char c = bookmark_count;
304 int i;
306 if (rb->write(fd, &c, 1) != 1)
307 return false;
309 for (i = 0; i < bookmark_count; i++)
311 if (!viewer_write_bookmark_info(fd, &bookmarks[i]))
312 return false;
315 return true;
318 bool copy_bookmark_file(int sfd, int dfd, off_t start, off_t size)
320 off_t rsize;
322 if (rb->lseek(sfd, start, SEEK_SET) < 0)
323 return false;
325 while (size > 0)
327 if (size > buffer_size)
328 rsize = buffer_size;
329 else
330 rsize = size;
331 size -= rsize;
333 if (rb->read(sfd, buffer, rsize) != rsize ||
334 rb->write(dfd, buffer, rsize) != rsize)
335 return false;
337 return true;