diff options
author | Björn Stenberg <bjorn@haxx.se> | 2005-01-18 22:45:00 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2005-01-18 22:45:00 +0000 |
commit | 84c7d8802106266c94d0a30827dff418a2fcac6d (patch) | |
tree | 17a4d8a7f5375584783925dd3b44203245413755 /apps/tree.c | |
parent | f9c06226d6c3f756437dc45d573d23f14699e728 (diff) | |
download | rockbox-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.c | 202 |
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; | |||
92 | bool boot_changed = false; | 92 | bool boot_changed = false; |
93 | 93 | ||
94 | char lastfile[MAX_PATH]; | 94 | char lastfile[MAX_PATH]; |
95 | char lastdir[MAX_PATH]; | 95 | static char lastdir[MAX_PATH]; |
96 | static int lasttable, lastextra, lastfirstpos; | ||
97 | static int max_files = 0; | ||
96 | 98 | ||
97 | static bool reload_dir = false; | 99 | static 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 */ |
484 | void resume_directory(const char *dir) | 499 | void 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)); |