Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

[Tagtree] Add a new button to list automatically all tracks in all albums of the current view

This feature allow easily to start playing all albums from an artist by following the albums tracks orders, just like the Stock OS does on the iPods when you try to listen to all songs from an artist.

It is just a new opportunity, I did not touch the former "All tracks" button which sorts everything by title automatically since it is also very useful (and stock OS don't have this one, and sorting Alphabetically is very useful to listen to all versions of one track from an artist view).

Change-Id: Icf2a29bffe49c4e72f9c81d9727310b84c1150e4

authored by

Paul Sauro and committed by
Solomon Peachy
f2356303 620a190b

+126 -15
+14
apps/lang/english.lang
··· 16850 16850 </voice> 16851 16851 </phrase> 16852 16852 <phrase> 16853 + id: LANG_TAGNAVI_ALL_TRACKS_SORTED_BY_ALBUM 16854 + desc: "[By album]" entry in tag browser 16855 + user: core 16856 + <source> 16857 + *: "[By album]" 16858 + </source> 16859 + <dest> 16860 + *: "[By album]" 16861 + </dest> 16862 + <voice> 16863 + *: "All tracks sorted by album" 16864 + </voice> 16865 + </phrase> 16866 + <phrase> 16853 16867 id: LANG_HP_LO_SELECT 16854 16868 desc: Output Select 16855 16869 user: core
+14
apps/lang/francais.lang
··· 2195 2195 </voice> 2196 2196 </phrase> 2197 2197 <phrase> 2198 + id: LANG_TAGNAVI_ALL_TRACKS_SORTED_BY_ALBUM 2199 + desc: "[By album]" entry in tag browser 2200 + user: core 2201 + <source> 2202 + *: "[By album]" 2203 + </source> 2204 + <dest> 2205 + *: "[Par album]" 2206 + </dest> 2207 + <voice> 2208 + *: "Toutes les pistes triées par album" 2209 + </voice> 2210 + </phrase> 2211 + <phrase> 2198 2212 id: LANG_DISPLAY 2199 2213 desc: in settings_menu() 2200 2214 user: core
+97 -15
apps/tagtree.c
··· 80 80 int newtable; 81 81 int extraseek; 82 82 int customaction; 83 + char* album_name; 83 84 }; 84 85 85 86 static struct tagentry* tagtree_get_entry(struct tree_context *c, int id); ··· 90 91 TABLE_ROOT = 1, 91 92 TABLE_NAVIBROWSE, 92 93 TABLE_ALLSUBENTRIES, 94 + TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS, 93 95 TABLE_PLAYTRACK, 94 96 }; 95 97 ··· 913 915 return qsort_fn(e1->name, e2->name, MAX_PATH); 914 916 } 915 917 918 + static int compare_with_albums(const void *p1, const void *p2) 919 + { 920 + struct tagentry *e1 = (struct tagentry *)p1; 921 + struct tagentry *e2 = (struct tagentry *)p2; 922 + int sort_album_res = qsort_fn( 923 + e1->album_name == NULL ? "" : e1->album_name, 924 + e2->album_name == NULL ? "" : e2->album_name, MAX_PATH); 925 + if (sort_album_res != 0) 926 + { 927 + /* If album name is different */ 928 + return sort_album_res; 929 + } 930 + return qsort_fn(e1->name, e2->name, MAX_PATH); 931 + } 932 + 916 933 static void tagtree_buffer_event(unsigned short id, void *ev_data) 917 934 { 918 935 (void)id; ··· 1597 1614 #endif 1598 1615 , 0, 0, 0); 1599 1616 1600 - if (c->currtable == TABLE_ALLSUBENTRIES) 1617 + if (c->currtable == TABLE_ALLSUBENTRIES || c->currtable == TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS) 1601 1618 { 1602 1619 tag = tag_title; 1603 1620 level--; ··· 1661 1678 fmt = NULL; 1662 1679 for (i = 0; i < format_count; i++) 1663 1680 { 1664 - if (formats[i]->group_id == csi->format_id[level]) 1665 - fmt = formats[i]; 1681 + if (c->currtable == TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS) 1682 + { 1683 + /* If it is sorted by albums, we need to use the proper view 1684 + that includes the disc number etc so sorting will be correct for each albums. 1685 + Otherwise, tracks will be sorted by title names */ 1686 + if (formats[i]->group_id != csi->format_id[level + 1]) 1687 + continue; 1688 + } 1689 + else if (formats[i]->group_id != csi->format_id[level]) 1690 + continue; 1691 + fmt = formats[i]; 1666 1692 } 1667 1693 1668 1694 if (fmt) ··· 1685 1711 1686 1712 if (tag != tag_title && tag != tag_filename) 1687 1713 { 1688 - if (offset == 0) 1714 + bool show_album_sorted = (tag == tag_album); 1715 + int show_album_sorted_offset = (show_album_sorted ? 1 : 0); 1716 + if (offset == 0 && show_album_sorted) 1717 + { 1718 + dptr->newtable = TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS; 1719 + dptr->name = ID2P(LANG_TAGNAVI_ALL_TRACKS_SORTED_BY_ALBUM); 1720 + dptr->extraseek = 0; 1721 + dptr->customaction = ONPLAY_NO_CUSTOMACTION; 1722 + dptr++; 1723 + current_entry_count++; 1724 + c->special_entry_count++; 1725 + } 1726 + if (offset <= (show_album_sorted_offset)) 1689 1727 { 1690 1728 dptr->newtable = TABLE_ALLSUBENTRIES; 1691 1729 dptr->name = ID2P(LANG_TAGNAVI_ALL_TRACKS); 1730 + dptr->extraseek = 0; 1692 1731 dptr->customaction = ONPLAY_NO_CUSTOMACTION; 1693 1732 dptr++; 1694 1733 current_entry_count++; 1695 1734 c->special_entry_count++; 1696 1735 } 1697 - if (offset <= 1) 1736 + if (offset <= (1 + show_album_sorted_offset)) 1698 1737 { 1699 1738 dptr->newtable = TABLE_NAVIBROWSE; 1700 1739 dptr->name = ID2P(LANG_TAGNAVI_RANDOM); ··· 1706 1745 } 1707 1746 1708 1747 total_count += 2; 1748 + if (show_album_sorted) 1749 + total_count++; 1709 1750 } 1710 1751 1711 1752 while (tagcache_get_next(&tcs, tcs_buf, tcs_bufsz)) ··· 1727 1768 /* Check the format */ 1728 1769 for (i = 0; i < format_count; i++) 1729 1770 { 1730 - if (formats[i]->group_id != csi->format_id[level]) 1771 + if (c->currtable == TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS) 1772 + { 1773 + /* If it is sorted by albums, we need to use the proper view 1774 + that includes the disc number etc so sorting will be correct for each albums. 1775 + Otherwise, tracks will be sorted by title names */ 1776 + if (formats[i]->group_id != csi->format_id[level + 1]) 1777 + continue; 1778 + } 1779 + else if (formats[i]->group_id != csi->format_id[level]) 1731 1780 continue; 1732 1781 1733 1782 if (tagcache_check_clauses(&tcs, formats[i]->clause, ··· 1744 1793 { /* Fallback to basename */ 1745 1794 char *lastname = dptr->name; 1746 1795 dptr->name = core_get_data(c->cache.name_buffer_handle)+namebufused; 1747 - if (tagcache_retrieve(&tcs, tcs.idx_id, tag_virt_basename, dptr->name, 1796 + if ((c->cache.name_buffer_size - namebufused) > 0 && 1797 + tagcache_retrieve(&tcs, tcs.idx_id, tag_virt_basename, dptr->name, 1748 1798 c->cache.name_buffer_size - namebufused)) 1749 1799 { 1750 1800 namebufused += strlen(dptr->name)+1; 1801 + dptr->album_name = core_get_data(c->cache.name_buffer_handle)+namebufused; 1802 + if ((c->cache.name_buffer_size - namebufused) > 0 && 1803 + tagcache_retrieve(&tcs, tcs.idx_id, tag_album, dptr->album_name, 1804 + c->cache.name_buffer_size - namebufused)) 1805 + namebufused += strlen(dptr->album_name)+1; 1806 + else 1807 + dptr->album_name = NULL; 1751 1808 goto entry_skip_formatter; 1752 1809 } 1753 1810 dptr->name = lastname; /* restore last entry if filename failed */ 1811 + dptr->album_name = NULL; 1754 1812 } 1755 1813 1756 1814 tcs.result = str(LANG_TAGNAVI_UNTAGGED); ··· 1760 1818 1761 1819 if (!tcs.ramresult || fmt) 1762 1820 { 1821 + 1763 1822 dptr->name = core_get_data(c->cache.name_buffer_handle)+namebufused; 1764 1823 1765 1824 if (fmt) 1766 1825 { 1767 1826 int ret = format_str(&tcs, fmt, dptr->name, 1768 1827 c->cache.name_buffer_size - namebufused); 1769 - if (ret >= 0) 1828 + bool error_on_str_format = ret < 0; 1829 + if (!error_on_str_format) 1770 1830 { 1771 1831 namebufused += strlen(dptr->name)+1; /* include NULL */ 1832 + dptr->album_name = core_get_data(c->cache.name_buffer_handle)+namebufused; 1833 + if ((c->cache.name_buffer_size - namebufused) > 0 && 1834 + tagcache_retrieve(&tcs, tcs.idx_id, tag_album, dptr->album_name, 1835 + c->cache.name_buffer_size - namebufused)) 1836 + namebufused += strlen(dptr->album_name)+1; 1837 + else 1838 + dptr->album_name = NULL; 1772 1839 } 1773 1840 else 1774 1841 { 1775 - dptr->name[0] = '\0'; 1776 1842 if (ret == -4) /* buffer full */ 1777 1843 { 1778 1844 logf("chunk mode #2: %d", current_entry_count); 1779 1845 c->dirfull = true; 1780 1846 sort = false; 1781 - break ; 1847 + break; 1782 1848 } 1783 1849 1784 1850 logf("format_str() failed"); ··· 1792 1858 { 1793 1859 tcs_get_basename(&tcs, is_basename); 1794 1860 namebufused += tcs.result_len; 1795 - if (namebufused < c->cache.name_buffer_size) 1861 + bool buffer_full = (namebufused >= c->cache.name_buffer_size); 1862 + if (!buffer_full) 1863 + { 1864 + dptr->album_name = core_get_data(c->cache.name_buffer_handle)+namebufused; 1865 + if (tagcache_retrieve(&tcs, tcs.idx_id, tag_album, dptr->album_name, 1866 + c->cache.name_buffer_size - namebufused)) 1867 + namebufused += strlen(dptr->album_name)+1; 1868 + else 1869 + dptr->album_name = NULL; 1796 1870 strcpy(dptr->name, tcs.result); 1871 + } 1797 1872 else 1798 1873 { 1799 1874 logf("chunk mode #2a: %d", current_entry_count); ··· 1807 1882 { 1808 1883 tcs_get_basename(&tcs, is_basename); 1809 1884 dptr->name = tcs.result; 1885 + dptr->album_name = NULL; 1810 1886 } 1811 1887 entry_skip_formatter: 1812 1888 dptr++; ··· 1843 1919 qsort(&entries[c->special_entry_count], 1844 1920 current_entry_count - c->special_entry_count, 1845 1921 sizeof(struct tagentry), 1846 - compare); 1922 + c->currtable == TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS ? compare_with_albums : compare 1923 + ); 1847 1924 } 1848 1925 1849 1926 if (!init) ··· 1985 2062 break; 1986 2063 1987 2064 case TABLE_ALLSUBENTRIES: 2065 + case TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS: 1988 2066 case TABLE_NAVIBROWSE: 1989 2067 logf("navibrowse..."); 1990 2068 ··· 2060 2138 if (seek == -1) /* <Random> menu item was selected */ 2061 2139 { 2062 2140 is_random_item = true; 2063 - if(c->filesindir<=2) /* Menu contains only <All> and <Random> menu items */ 2141 + if(c->filesindir<=c->special_entry_count) /* Menu contains only special entries */ 2064 2142 return 0; 2065 2143 srand(current_tick); 2066 - dptr = (tagtree_get_entry(c, 2+(rand() % (c->filesindir-2)))); 2144 + dptr = (tagtree_get_entry(c, c->special_entry_count+(rand() % (c->filesindir-c->special_entry_count)))); 2067 2145 seek = dptr->extraseek; 2068 2146 } 2069 2147 newextra = dptr->newtable; ··· 2195 2273 2196 2274 case TABLE_NAVIBROWSE: 2197 2275 case TABLE_ALLSUBENTRIES: 2276 + case TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS: 2198 2277 if (newextra == TABLE_PLAYTRACK) 2199 2278 { 2200 2279 adjust_selection = false; ··· 2504 2583 static bool goto_allsubentries(int newtable) 2505 2584 { 2506 2585 int i = 0; 2507 - while (i < 2 && (newtable == TABLE_NAVIBROWSE || newtable == TABLE_ALLSUBENTRIES)) 2586 + while (i < 2 && (newtable == TABLE_NAVIBROWSE || newtable == TABLE_ALLSUBENTRIES 2587 + || newtable == TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS)) 2508 2588 { 2509 2589 tagtree_enter(tc, false); 2510 2590 tagtree_load(tc); ··· 2746 2826 2747 2827 case TABLE_NAVIBROWSE: 2748 2828 case TABLE_ALLSUBENTRIES: 2829 + case TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS: 2749 2830 logf("%s (NAVI/ALLSUB) idx: %d %s", __func__, 2750 2831 c->currextra, current_title[c->currextra]); 2751 2832 return current_title[c->currextra]; ··· 2768 2849 break; 2769 2850 2770 2851 case TABLE_ALLSUBENTRIES: 2852 + case TABLE_ALLSUBENTRIES_SORTED_BY_ALBUMS: 2771 2853 attr = FILE_ATTR_AUDIO; 2772 2854 break; 2773 2855
+1
apps/tree.h
··· 35 35 unsigned time_write; /* Last write time */ 36 36 #ifdef HAVE_TAGCACHE 37 37 int customaction; /* db use */ 38 + char* album_name; /* db use */ 38 39 #endif 39 40 }; 40 41