diff options
Diffstat (limited to 'apps/tagtree.c')
-rw-r--r-- | apps/tagtree.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/apps/tagtree.c b/apps/tagtree.c index 11be1425d5..cad12e2a79 100644 --- a/apps/tagtree.c +++ b/apps/tagtree.c | |||
@@ -191,6 +191,7 @@ static int current_entry_count; | |||
191 | 191 | ||
192 | static struct tree_context *tc; | 192 | static struct tree_context *tc; |
193 | 193 | ||
194 | static int max_history_level; /* depth of menu levels with applicable history */ | ||
194 | static int selected_item_history[MAX_DIR_LEVELS]; | 195 | static int selected_item_history[MAX_DIR_LEVELS]; |
195 | static int table_history[MAX_DIR_LEVELS]; | 196 | static int table_history[MAX_DIR_LEVELS]; |
196 | static int extra_history[MAX_DIR_LEVELS]; | 197 | static int extra_history[MAX_DIR_LEVELS]; |
@@ -1248,6 +1249,7 @@ static void tagtree_unload(struct tree_context *c) | |||
1248 | 1249 | ||
1249 | void tagtree_init(void) | 1250 | void tagtree_init(void) |
1250 | { | 1251 | { |
1252 | max_history_level = 0; | ||
1251 | format_count = 0; | 1253 | format_count = 0; |
1252 | menu_count = 0; | 1254 | menu_count = 0; |
1253 | menu = NULL; | 1255 | menu = NULL; |
@@ -1818,7 +1820,16 @@ int tagtree_load(struct tree_context* c) | |||
1818 | return count; | 1820 | return count; |
1819 | } | 1821 | } |
1820 | 1822 | ||
1821 | int tagtree_enter(struct tree_context* c) | 1823 | /* Enters menu or table for selected item in the database. |
1824 | * | ||
1825 | * Call this with the is_visible parameter set to false to | ||
1826 | * prevent selected_item_history from being updated or applied, in | ||
1827 | * case the menus aren't displayed to the user. | ||
1828 | * Before calling tagtree_enter again with the parameter set to | ||
1829 | * true, make sure that you are back at the previous dirlevel, by | ||
1830 | * calling tagtree_exit as needed, with is_visible set to false. | ||
1831 | */ | ||
1832 | int tagtree_enter(struct tree_context* c, bool is_visible) | ||
1822 | { | 1833 | { |
1823 | int rc = 0; | 1834 | int rc = 0; |
1824 | struct tagentry *dptr; | 1835 | struct tagentry *dptr; |
@@ -1826,14 +1837,17 @@ int tagtree_enter(struct tree_context* c) | |||
1826 | int newextra; | 1837 | int newextra; |
1827 | int seek; | 1838 | int seek; |
1828 | int source; | 1839 | int source; |
1840 | bool is_random_item = false; | ||
1841 | bool adjust_selection = true; | ||
1829 | 1842 | ||
1830 | dptr = tagtree_get_entry(c, c->selected_item); | 1843 | dptr = tagtree_get_entry(c, c->selected_item); |
1831 | 1844 | ||
1832 | c->dirfull = false; | 1845 | c->dirfull = false; |
1833 | seek = dptr->extraseek; | 1846 | seek = dptr->extraseek; |
1834 | if (seek == -1) | 1847 | if (seek == -1) /* <Random> menu item was selected */ |
1835 | { | 1848 | { |
1836 | if(c->filesindir<=2) | 1849 | is_random_item = true; |
1850 | if(c->filesindir<=2) /* Menu contains only <All> and <Random> menu items */ | ||
1837 | return 0; | 1851 | return 0; |
1838 | srand(current_tick); | 1852 | srand(current_tick); |
1839 | dptr = (tagtree_get_entry(c, 2+(rand() % (c->filesindir-2)))); | 1853 | dptr = (tagtree_get_entry(c, 2+(rand() % (c->filesindir-2)))); |
@@ -1844,7 +1858,21 @@ int tagtree_enter(struct tree_context* c) | |||
1844 | if (c->dirlevel >= MAX_DIR_LEVELS) | 1858 | if (c->dirlevel >= MAX_DIR_LEVELS) |
1845 | return 0; | 1859 | return 0; |
1846 | 1860 | ||
1847 | selected_item_history[c->dirlevel]=c->selected_item; | 1861 | if (is_visible) /* update selection history only for user-selected items */ |
1862 | { | ||
1863 | /* We need to discard selected item history for levels | ||
1864 | descending from current one if selection has changed */ | ||
1865 | if (max_history_level < c->dirlevel + 1 | ||
1866 | || (max_history_level > c->dirlevel | ||
1867 | && selected_item_history[c->dirlevel] != c->selected_item) | ||
1868 | || is_random_item) | ||
1869 | { | ||
1870 | max_history_level = c->dirlevel + 1; | ||
1871 | selected_item_history[c->dirlevel + 1] = 0; | ||
1872 | } | ||
1873 | |||
1874 | selected_item_history[c->dirlevel]=c->selected_item; | ||
1875 | } | ||
1848 | table_history[c->dirlevel] = c->currtable; | 1876 | table_history[c->dirlevel] = c->currtable; |
1849 | extra_history[c->dirlevel] = c->currextra; | 1877 | extra_history[c->dirlevel] = c->currextra; |
1850 | c->dirlevel++; | 1878 | c->dirlevel++; |
@@ -1853,8 +1881,6 @@ int tagtree_enter(struct tree_context* c) | |||
1853 | tree_lock_cache(c); | 1881 | tree_lock_cache(c); |
1854 | core_pin(tagtree_handle); | 1882 | core_pin(tagtree_handle); |
1855 | 1883 | ||
1856 | bool reset_selection = true; | ||
1857 | |||
1858 | switch (c->currtable) { | 1884 | switch (c->currtable) { |
1859 | case ROOT: | 1885 | case ROOT: |
1860 | c->currextra = newextra; | 1886 | c->currextra = newextra; |
@@ -1890,6 +1916,10 @@ int tagtree_enter(struct tree_context* c) | |||
1890 | if (source == source_constant) | 1916 | if (source == source_constant) |
1891 | continue; | 1917 | continue; |
1892 | 1918 | ||
1919 | /* discard history for lower levels when doing runtime searches */ | ||
1920 | if (is_visible) | ||
1921 | max_history_level = c->dirlevel - 1; | ||
1922 | |||
1893 | searchstring=csi->clause[i][j]->str; | 1923 | searchstring=csi->clause[i][j]->str; |
1894 | *searchstring = '\0'; | 1924 | *searchstring = '\0'; |
1895 | 1925 | ||
@@ -1919,7 +1949,7 @@ int tagtree_enter(struct tree_context* c) | |||
1919 | rc = kbd_input(searchstring, SEARCHSTR_SIZE, NULL); | 1949 | rc = kbd_input(searchstring, SEARCHSTR_SIZE, NULL); |
1920 | if (rc < 0 || !searchstring[0]) | 1950 | if (rc < 0 || !searchstring[0]) |
1921 | { | 1951 | { |
1922 | tagtree_exit(c); | 1952 | tagtree_exit(c, is_visible); |
1923 | tree_unlock_cache(c); | 1953 | tree_unlock_cache(c); |
1924 | core_unpin(tagtree_handle); | 1954 | core_unpin(tagtree_handle); |
1925 | return 0; | 1955 | return 0; |
@@ -1940,7 +1970,7 @@ int tagtree_enter(struct tree_context* c) | |||
1940 | case ALLSUBENTRIES: | 1970 | case ALLSUBENTRIES: |
1941 | if (newextra == PLAYTRACK) | 1971 | if (newextra == PLAYTRACK) |
1942 | { | 1972 | { |
1943 | reset_selection = false; | 1973 | adjust_selection = false; |
1944 | 1974 | ||
1945 | if (global_settings.party_mode && audio_status()) { | 1975 | if (global_settings.party_mode && audio_status()) { |
1946 | splash(HZ, ID2P(LANG_PARTY_MODE)); | 1976 | splash(HZ, ID2P(LANG_PARTY_MODE)); |
@@ -1973,9 +2003,12 @@ int tagtree_enter(struct tree_context* c) | |||
1973 | break; | 2003 | break; |
1974 | } | 2004 | } |
1975 | 2005 | ||
1976 | if (reset_selection) | 2006 | if (adjust_selection) |
1977 | { | 2007 | { |
1978 | c->selected_item=0; | 2008 | if (is_visible && c->dirlevel <= max_history_level) |
2009 | c->selected_item = selected_item_history[c->dirlevel]; | ||
2010 | else | ||
2011 | c->selected_item = 0; | ||
1979 | } | 2012 | } |
1980 | 2013 | ||
1981 | tree_unlock_cache(c); | 2014 | tree_unlock_cache(c); |
@@ -1984,12 +2017,16 @@ int tagtree_enter(struct tree_context* c) | |||
1984 | return rc; | 2017 | return rc; |
1985 | } | 2018 | } |
1986 | 2019 | ||
1987 | void tagtree_exit(struct tree_context* c) | 2020 | /* Exits current database menu or table */ |
2021 | void tagtree_exit(struct tree_context* c, bool is_visible) | ||
1988 | { | 2022 | { |
2023 | if (is_visible) /* update selection history only for user-selected items */ | ||
2024 | selected_item_history[c->dirlevel] = c->selected_item; | ||
1989 | c->dirfull = false; | 2025 | c->dirfull = false; |
1990 | if (c->dirlevel > 0) | 2026 | if (c->dirlevel > 0) |
1991 | c->dirlevel--; | 2027 | c->dirlevel--; |
1992 | c->selected_item=selected_item_history[c->dirlevel]; | 2028 | if (is_visible) |
2029 | c->selected_item=selected_item_history[c->dirlevel]; | ||
1993 | c->currtable = table_history[c->dirlevel]; | 2030 | c->currtable = table_history[c->dirlevel]; |
1994 | c->currextra = extra_history[c->dirlevel]; | 2031 | c->currextra = extra_history[c->dirlevel]; |
1995 | } | 2032 | } |
@@ -2083,6 +2120,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue) | |||
2083 | { | 2120 | { |
2084 | char buf[MAX_PATH]; | 2121 | char buf[MAX_PATH]; |
2085 | int dirlevel = tc->dirlevel; | 2122 | int dirlevel = tc->dirlevel; |
2123 | int selected_item = tc->selected_item; | ||
2086 | int newtable; | 2124 | int newtable; |
2087 | 2125 | ||
2088 | show_search_progress( | 2126 | show_search_progress( |
@@ -2112,7 +2150,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue) | |||
2112 | 2150 | ||
2113 | if (newtable == NAVIBROWSE) | 2151 | if (newtable == NAVIBROWSE) |
2114 | { | 2152 | { |
2115 | tagtree_enter(tc); | 2153 | tagtree_enter(tc, false); |
2116 | tagtree_load(tc); | 2154 | tagtree_load(tc); |
2117 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | 2155 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; |
2118 | } | 2156 | } |
@@ -2125,7 +2163,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue) | |||
2125 | /* Now the current table should be allsubentries. */ | 2163 | /* Now the current table should be allsubentries. */ |
2126 | if (newtable != PLAYTRACK) | 2164 | if (newtable != PLAYTRACK) |
2127 | { | 2165 | { |
2128 | tagtree_enter(tc); | 2166 | tagtree_enter(tc, false); |
2129 | tagtree_load(tc); | 2167 | tagtree_load(tc); |
2130 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; | 2168 | newtable = tagtree_get_entry(tc, tc->selected_item)->newtable; |
2131 | 2169 | ||
@@ -2134,7 +2172,7 @@ bool tagtree_insert_selection_playlist(int position, bool queue) | |||
2134 | { | 2172 | { |
2135 | logf("newtable: %d !!", newtable); | 2173 | logf("newtable: %d !!", newtable); |
2136 | while (tc->dirlevel > dirlevel) | 2174 | while (tc->dirlevel > dirlevel) |
2137 | tagtree_exit(tc); | 2175 | tagtree_exit(tc, false); |
2138 | tagtree_load(tc); | 2176 | tagtree_load(tc); |
2139 | return false; | 2177 | return false; |
2140 | } | 2178 | } |
@@ -2151,7 +2189,8 @@ bool tagtree_insert_selection_playlist(int position, bool queue) | |||
2151 | 2189 | ||
2152 | /* Finally return the dirlevel to its original value. */ | 2190 | /* Finally return the dirlevel to its original value. */ |
2153 | while (tc->dirlevel > dirlevel) | 2191 | while (tc->dirlevel > dirlevel) |
2154 | tagtree_exit(tc); | 2192 | tagtree_exit(tc, false); |
2193 | tc->selected_item = selected_item; | ||
2155 | tagtree_load(tc); | 2194 | tagtree_load(tc); |
2156 | 2195 | ||
2157 | return true; | 2196 | return true; |