@@ -80,6 +80,7 @@ struct tagentry {
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,6 +91,7 @@ enum table {
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,6 +915,21 @@ static int compare(const void *p1, const void *p2)
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,7 +1614,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,8 +1678,17 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,16 +1711,29 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,6 +1745,8 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,7 +1768,15 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,13 +1793,22 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,25 +1818,33 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,8 +1858,17 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,6 +1882,7 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,7 +1919,8 @@ static int retrieve_entries(struct tree_context *c, int offset, bool init)
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,6 +2062,7 @@ int tagtree_load(struct tree_context* c)
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,10 +2138,10 @@ int tagtree_enter(struct tree_context* c, bool is_visible)
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,6 +2273,7 @@ int tagtree_enter(struct tree_context* c, bool is_visible)
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,7 +2583,8 @@ static bool insert_all_playlist(struct tree_context *c,
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,6 +2826,7 @@ char *tagtree_get_title(struct tree_context* c)
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,6 +2849,7 @@ int tagtree_get_attr(struct tree_context* c)
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
0 commit comments