summaryrefslogtreecommitdiff
path: root/apps/tree.c
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2005-01-18 22:45:00 +0000
committerBjörn Stenberg <bjorn@haxx.se>2005-01-18 22:45:00 +0000
commit84c7d8802106266c94d0a30827dff418a2fcac6d (patch)
tree17a4d8a7f5375584783925dd3b44203245413755 /apps/tree.c
parentf9c06226d6c3f756437dc45d573d23f14699e728 (diff)
downloadrockbox-84c7d8802106266c94d0a30827dff418a2fcac6d.tar.gz
rockbox-84c7d8802106266c94d0a30827dff418a2fcac6d.zip
Added support for very large tables in ID3 database.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5595 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/tree.c')
-rw-r--r--apps/tree.c202
1 files changed, 132 insertions, 70 deletions
diff --git a/apps/tree.c b/apps/tree.c
index b844060322..2ba4585047 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -92,7 +92,9 @@ static struct tree_context tc;
92bool boot_changed = false; 92bool boot_changed = false;
93 93
94char lastfile[MAX_PATH]; 94char lastfile[MAX_PATH];
95char lastdir[MAX_PATH]; 95static char lastdir[MAX_PATH];
96static int lasttable, lastextra, lastfirstpos;
97static int max_files = 0;
96 98
97static bool reload_dir = false; 99static bool reload_dir = false;
98 100
@@ -245,10 +247,9 @@ static int showdir(void)
245 struct entry *dircache = tc.dircache; 247 struct entry *dircache = tc.dircache;
246 int i; 248 int i;
247 int tree_max_on_screen; 249 int tree_max_on_screen;
248 bool dir_buffer_full = false;
249 int start = tc.dirstart; 250 int start = tc.dirstart;
250 bool id3db = global_settings.dirfilter == SHOW_ID3DB; 251 bool id3db = global_settings.dirfilter == SHOW_ID3DB;
251 252 bool newdir = false;
252#ifdef HAVE_LCD_BITMAP 253#ifdef HAVE_LCD_BITMAP
253 const char* icon; 254 const char* icon;
254 int line_height; 255 int line_height;
@@ -264,17 +265,30 @@ static int showdir(void)
264 265
265 /* new file dir? load it */ 266 /* new file dir? load it */
266 if (id3db) { 267 if (id3db) {
267 if (db_load(&tc, &dir_buffer_full) < 0) 268 if (tc.currtable != lasttable ||
268 return -1; 269 tc.currextra != lastextra ||
270 tc.firstpos != lastfirstpos)
271 {
272 if (db_load(&tc) < 0)
273 return -1;
274 lasttable = tc.currtable;
275 lastextra = tc.currextra;
276 lastfirstpos = tc.firstpos;
277 newdir = true;
278 }
269 } 279 }
270 else { 280 else {
271 if (strncmp(tc.currdir, lastdir, sizeof(lastdir)) || reload_dir) { 281 if (strncmp(tc.currdir, lastdir, sizeof(lastdir)) || reload_dir) {
272 if (ft_load(&tc, &dir_buffer_full) < 0) 282 if (ft_load(&tc) < 0)
273 return -1; 283 return -1;
284 strcpy(lastdir, tc.currdir);
285 newdir = true;
274 } 286 }
275 } 287 }
276 288
277 if ( dir_buffer_full || tc.filesindir == global_settings.max_files_in_dir ) { 289 if (newdir && !id3db &&
290 (tc.dirfull || tc.filesindir == global_settings.max_files_in_dir) )
291 {
278#ifdef HAVE_LCD_CHARCELLS 292#ifdef HAVE_LCD_CHARCELLS
279 lcd_double_height(false); 293 lcd_double_height(false);
280#endif 294#endif
@@ -383,10 +397,11 @@ static int showdir(void)
383 } 397 }
384 398
385#ifdef HAVE_LCD_BITMAP 399#ifdef HAVE_LCD_BITMAP
386 if (global_settings.scrollbar && (tc.filesindir > tree_max_on_screen)) 400 if (global_settings.scrollbar && (tc.dirlength > tree_max_on_screen))
387 scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1, 401 scrollbar(SCROLLBAR_X, SCROLLBAR_Y, SCROLLBAR_WIDTH - 1,
388 tree_max_on_screen * line_height, tc.filesindir, start, 402 tree_max_on_screen * line_height, tc.dirlength,
389 start + tree_max_on_screen, VERTICAL); 403 start + tc.firstpos,
404 start + tc.firstpos + tree_max_on_screen, VERTICAL);
390 405
391#if CONFIG_KEYPAD == RECORDER_PAD 406#if CONFIG_KEYPAD == RECORDER_PAD
392 if(global_settings.buttonbar) { 407 if(global_settings.buttonbar) {
@@ -483,10 +498,8 @@ static bool ask_resume(bool ask_once)
483/* load tracks from specified directory to resume play */ 498/* load tracks from specified directory to resume play */
484void resume_directory(const char *dir) 499void resume_directory(const char *dir)
485{ 500{
486 bool buffer_full;
487
488 strcpy(tc.currdir, dir); 501 strcpy(tc.currdir, dir);
489 if (!ft_load(&tc, &buffer_full)) 502 if (!ft_load(&tc))
490 return; 503 return;
491 lastdir[0] = 0; 504 lastdir[0] = 0;
492 505
@@ -586,10 +599,10 @@ static bool check_changed_id3mode(bool currmode)
586 if (currmode != (global_settings.dirfilter == SHOW_ID3DB)) { 599 if (currmode != (global_settings.dirfilter == SHOW_ID3DB)) {
587 currmode = global_settings.dirfilter == SHOW_ID3DB; 600 currmode = global_settings.dirfilter == SHOW_ID3DB;
588 if (currmode) { 601 if (currmode) {
589 db_load(&tc, NULL); 602 db_load(&tc);
590 } 603 }
591 else 604 else
592 ft_load(&tc, NULL); 605 ft_load(&tc);
593 } 606 }
594 return currmode; 607 return currmode;
595} 608}
@@ -624,6 +637,10 @@ static bool dirbrowse(void)
624 tc.dircursor=0; 637 tc.dircursor=0;
625 tc.dirstart=0; 638 tc.dirstart=0;
626 tc.dirlevel=0; 639 tc.dirlevel=0;
640 tc.firstpos=0;
641 lasttable = -1;
642 lastextra = -1;
643 lastfirstpos = 0;
627 644
628 if (*tc.dirfilter < NUM_FILTER_MODES) 645 if (*tc.dirfilter < NUM_FILTER_MODES)
629 start_resume(true); 646 start_resume(true);
@@ -778,39 +795,59 @@ static bool dirbrowse(void)
778 case TREE_RC_PREV: 795 case TREE_RC_PREV:
779 case TREE_RC_PREV | BUTTON_REPEAT: 796 case TREE_RC_PREV | BUTTON_REPEAT:
780#endif 797#endif
781 if(tc.filesindir) { 798 if (!tc.filesindir)
782 if(tc.dircursor) { 799 break;
783 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); 800
784 tc.dircursor--; 801 if (tc.dircursor) {
785 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); 802 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
786 } 803 tc.dircursor--;
787 else { 804 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
788 if (tc.dirstart) { 805 }
806 else {
807 if (tc.dirstart || tc.firstpos) {
808 if (tc.dirstart)
789 tc.dirstart--; 809 tc.dirstart--;
790 numentries = showdir();
791 update_all=true;
792 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
793 }
794 else { 810 else {
795 if (numentries < tree_max_on_screen) { 811 if (tc.firstpos > max_files/2) {
796 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, 812 tc.firstpos -= max_files/2;
797 false); 813 tc.dirstart += max_files/2;
798 tc.dircursor = numentries - 1; 814 tc.dirstart--;
799 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
800 true);
801 } 815 }
802 else { 816 else {
803 tc.dirstart = numentries - tree_max_on_screen; 817 tc.dirstart = tc.firstpos - 1;
804 tc.dircursor = tree_max_on_screen - 1; 818 tc.firstpos = 0;
805 numentries = showdir();
806 update_all = true;
807 put_cursorxy(CURSOR_X, CURSOR_Y +
808 tree_max_on_screen - 1, true);
809 } 819 }
810 } 820 }
821 restore = true;
822 }
823 else {
824 if (numentries < tree_max_on_screen) {
825 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
826 false);
827 tc.dircursor = numentries - 1;
828 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
829 true);
830 }
831 else if (id3db && tc.dirfull) {
832 /* load last dir segment */
833 /* use max_files/2 in case names are longer than
834 AVERAGE_FILE_LENGTH */
835 tc.firstpos = tc.dirlength - max_files/2;
836 tc.dirstart = tc.firstpos;
837 tc.dircursor = tree_max_on_screen - 1;
838 numentries = showdir();
839 update_all = true;
840 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor,
841 true);
842 }
843 else {
844 tc.dirstart = numentries - tree_max_on_screen;
845 tc.dircursor = tree_max_on_screen - 1;
846 restore = true;
847 }
811 } 848 }
812 need_update = true;
813 } 849 }
850 need_update = true;
814 break; 851 break;
815 852
816 case TREE_NEXT: 853 case TREE_NEXT:
@@ -819,46 +856,67 @@ static bool dirbrowse(void)
819 case TREE_RC_NEXT: 856 case TREE_RC_NEXT:
820 case TREE_RC_NEXT | BUTTON_REPEAT: 857 case TREE_RC_NEXT | BUTTON_REPEAT:
821#endif 858#endif
822 if(tc.filesindir) 859 if (!tc.filesindir)
823 { 860 break;
824 if (tc.dircursor + tc.dirstart + 1 < numentries ) { 861
825 if(tc.dircursor+1 < tree_max_on_screen) { 862 if (tc.dircursor + tc.dirstart + 1 < numentries ) {
826 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); 863 if(tc.dircursor+1 < tree_max_on_screen) {
827 tc.dircursor++; 864 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
828 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true); 865 tc.dircursor++;
829 } 866 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
830 else {
831 tc.dirstart++;
832 numentries = showdir();
833 update_all = true;
834 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
835 }
836 } 867 }
837 else { 868 else {
838 if(numentries < tree_max_on_screen) { 869 tc.dirstart++;
839 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false); 870 restore = true;
840 tc.dirstart = tc.dircursor = 0;
841 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
842 }
843 else {
844 tc.dirstart = tc.dircursor = 0;
845 numentries = showdir();
846 update_all=true;
847 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
848 }
849 } 871 }
850 need_update = true;
851 } 872 }
873 else if (id3db && (tc.firstpos || tc.dirfull)) {
874 if (tc.dircursor + tc.dirstart + tc.firstpos + 1 >= tc.dirlength) {
875 /* wrap and load first dir segment */
876 tc.firstpos = tc.dirstart = tc.dircursor = 0;
877 }
878 else {
879 /* load next dir segment */
880 tc.firstpos += tc.dirstart;
881 tc.dirstart = 0;
882 }
883 restore = true;
884 }
885 else {
886 if(numentries < tree_max_on_screen) {
887 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, false);
888 tc.dirstart = tc.dircursor = 0;
889 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
890 }
891 else {
892 tc.dirstart = tc.dircursor = 0;
893 numentries = showdir();
894 update_all=true;
895 put_cursorxy(CURSOR_X, CURSOR_Y + tc.dircursor, true);
896 }
897 }
898 need_update = true;
852 break; 899 break;
853 900
854#ifdef TREE_PGUP 901#ifdef TREE_PGUP
855 case TREE_PGUP: 902 case TREE_PGUP:
856 case TREE_PGUP | BUTTON_REPEAT: 903 case TREE_PGUP | BUTTON_REPEAT:
857 if ( tc.dirstart ) { 904 if (tc.dirstart) {
858 tc.dirstart -= tree_max_on_screen; 905 tc.dirstart -= tree_max_on_screen;
859 if ( tc.dirstart < 0 ) 906 if ( tc.dirstart < 0 )
860 tc.dirstart = 0; 907 tc.dirstart = 0;
861 } 908 }
909 else if (tc.firstpos) {
910 if (tc.firstpos > max_files/2) {
911 tc.firstpos -= max_files/2;
912 tc.dirstart += max_files/2;
913 tc.dirstart -= tree_max_on_screen;
914 }
915 else {
916 tc.dirstart = tc.firstpos - tree_max_on_screen;
917 tc.firstpos = 0;
918 }
919 }
862 else 920 else
863 tc.dircursor = 0; 921 tc.dircursor = 0;
864 restore = true; 922 restore = true;
@@ -868,10 +926,14 @@ static bool dirbrowse(void)
868 case TREE_PGDN | BUTTON_REPEAT: 926 case TREE_PGDN | BUTTON_REPEAT:
869 if ( tc.dirstart < numentries - tree_max_on_screen ) { 927 if ( tc.dirstart < numentries - tree_max_on_screen ) {
870 tc.dirstart += tree_max_on_screen; 928 tc.dirstart += tree_max_on_screen;
871 if ( tc.dirstart > 929 if ( tc.dirstart > numentries - tree_max_on_screen )
872 numentries - tree_max_on_screen )
873 tc.dirstart = numentries - tree_max_on_screen; 930 tc.dirstart = numentries - tree_max_on_screen;
874 } 931 }
932 else if (id3db && tc.dirfull) {
933 /* load next dir segment */
934 tc.firstpos += tc.dirstart;
935 tc.dirstart = 0;
936 }
875 else 937 else
876 tc.dircursor = numentries - tc.dirstart - 1; 938 tc.dircursor = numentries - tc.dirstart - 1;
877 restore = true; 939 restore = true;
@@ -1334,7 +1396,7 @@ void tree_init(void)
1334{ 1396{
1335 /* We copy the settings value in case it is changed by the user. We can't 1397 /* We copy the settings value in case it is changed by the user. We can't
1336 use it until the next reboot. */ 1398 use it until the next reboot. */
1337 int max_files = global_settings.max_files_in_dir; 1399 max_files = global_settings.max_files_in_dir;
1338 1400
1339 /* initialize tree context struct */ 1401 /* initialize tree context struct */
1340 memset(&tc, 0, sizeof(tc)); 1402 memset(&tc, 0, sizeof(tc));