X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fplaylist%2Fsort.c;h=e7c5f6e116b056080cc8d00c0a6486ed24a70d04;hb=9706bc1b42009a7c777dbe1d32027dea40f6c848;hp=7478f1eb7c952c42d6202c6745253ff04946685e;hpb=1cb7ce6dc49d1be7a1659341caa782ffd763903b;p=vlc diff --git a/src/playlist/sort.c b/src/playlist/sort.c index 7478f1eb7c..e7c5f6e116 100644 --- a/src/playlist/sort.c +++ b/src/playlist/sort.c @@ -5,6 +5,7 @@ * $Id$ * * Authors: Clément Stenac + * Ilkka Ollakka * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +25,7 @@ # include "config.h" #endif -#include +#include #include "vlc_playlist.h" #include "playlist_internal.h" @@ -32,6 +33,7 @@ static int playlist_ItemArraySort( playlist_t *p_playlist, int i_items, playlist_item_t **pp_items, int i_mode, int i_type ); +static int playlist_cmp(const void *, const void *); /** * Sort a node. @@ -78,15 +80,19 @@ int playlist_RecursiveNodeSort( playlist_t *p_playlist, playlist_item_t *p_node, return VLC_SUCCESS; } +static int sort_mode = 0; +static int sort_type = 0; static int playlist_ItemArraySort( playlist_t *p_playlist, int i_items, playlist_item_t **pp_items, int i_mode, int i_type ) { - int i , i_small , i_position; + int i_position; playlist_item_t *p_temp; vlc_value_t val; - val.b_bool = VLC_TRUE; + val.b_bool = true; + sort_mode = i_mode; + sort_type = i_type; (void)p_playlist; // a bit surprising we don't need p_playlist! @@ -107,30 +113,36 @@ static int playlist_ItemArraySort( playlist_t *p_playlist, int i_items, return VLC_SUCCESS; } + qsort(pp_items,i_items,sizeof(pp_items[0]),playlist_cmp); + return VLC_SUCCESS; +} + +static int playlist_cmp(const void *first, const void *second) +{ -#define META_STRCASECMP_NAME( i, i_small ) { \ - char *psz_i = input_item_GetName( pp_items[i]->p_input ); \ - char *psz_ismall = input_item_GetName( pp_items[i_small]->p_input ); \ +#define META_STRCASECMP_NAME( ) { \ + char *psz_i = input_item_GetName( (*(playlist_item_t **)first)->p_input ); \ + char *psz_ismall = input_item_GetName( (*(playlist_item_t **)second)->p_input ); \ i_test = strcasecmp( psz_i, psz_ismall ); \ free( psz_i ); \ free( psz_ismall ); \ } -#define DO_META_SORT( node ) { \ - char *psz_a = input_item_GetMeta( pp_items[i]->p_input, vlc_meta_##node ); \ - char *psz_b = input_item_GetMeta( pp_items[i_small]->p_input, vlc_meta_##node ); \ +#define DO_META_SORT_ADV( node, integer ) { \ + char *psz_a = input_item_GetMeta( (*(playlist_item_t **)first)->p_input, vlc_meta_##node ); \ + char *psz_b = input_item_GetMeta( (*(playlist_item_t **)second)->p_input, vlc_meta_##node ); \ /* Nodes go first */ \ - if( pp_items[i]->i_children == -1 && pp_items[i_small]->i_children >= 0 ) \ + if( (*(playlist_item_t **)first)->i_children == -1 && (*(playlist_item_t **)second)->i_children >= 0 ) \ i_test = 1;\ - else if( pp_items[i]->i_children >= 0 &&\ - pp_items[i_small]->i_children == -1 ) \ + else if( (*(playlist_item_t **)first)->i_children >= 0 &&\ + (*(playlist_item_t **)second)->i_children == -1 ) \ i_test = -1; \ /* Both are nodes, sort by name */ \ - else if( pp_items[i]->i_children >= 0 && \ - pp_items[i_small]->i_children >= 0 ) \ + else if( (*(playlist_item_t **)first)->i_children >= 0 && \ + (*(playlist_item_t **)second)->i_children >= 0 ) \ { \ - META_STRCASECMP_NAME( i, i_small ) \ + META_STRCASECMP_NAME( ) \ } \ /* Both are items */ \ else if( psz_a == NULL && psz_b != NULL ) \ @@ -140,99 +152,95 @@ static int playlist_ItemArraySort( playlist_t *p_playlist, int i_items, /* No meta, sort by name */ \ else if( psz_a == NULL && psz_b == NULL ) \ { \ - META_STRCASECMP_NAME( i, i_small ); \ + META_STRCASECMP_NAME( ); \ } \ else \ { \ - i_test = strcmp( psz_a, psz_b ); \ + if( !integer ) i_test = strcmp( psz_a, psz_b ); \ + else i_test = atoi( psz_a ) - atoi( psz_b ); \ } \ free( psz_a ); \ free( psz_b ); \ } +#define DO_META_SORT( node ) DO_META_SORT_ADV( node, false ) - for( i_position = 0; i_position < i_items -1 ; i_position ++ ) + int i_test = 0; + + if( sort_mode == SORT_TITLE ) + { + META_STRCASECMP_NAME( ); + } + else if( sort_mode == SORT_TITLE_NUMERIC ) + { + char *psz_i = input_item_GetName( (*(playlist_item_t **)first)->p_input ); + char *psz_ismall = + input_item_GetName( (*(playlist_item_t **)second)->p_input ); + i_test = atoi( psz_i ) - atoi( psz_ismall ); + free( psz_i ); + free( psz_ismall ); + } + else if( sort_mode == SORT_DURATION ) + { + i_test = input_item_GetDuration( (*(playlist_item_t **)first)->p_input ) - + input_item_GetDuration( (*(playlist_item_t **)second)->p_input ); + } + else if( sort_mode == SORT_ARTIST ) + { + DO_META_SORT( Artist ); + /* sort by artist, album, tracknumber */ + if( i_test == 0 ) + DO_META_SORT( Album ); + if( i_test == 0 ) + DO_META_SORT_ADV( TrackNumber, true ); + } + else if( sort_mode == SORT_GENRE ) + { + DO_META_SORT( Genre ); + } + else if( sort_mode == SORT_ALBUM ) { - i_small = i_position; - for( i = i_position + 1 ; i< i_items ; i++) + DO_META_SORT( Album ); + /* Sort by tracknumber if albums are the same */ + if( i_test == 0 ) + DO_META_SORT_ADV( TrackNumber, true ); + } + else if( sort_mode == SORT_TRACK_NUMBER ) + { + DO_META_SORT_ADV( TrackNumber, true ); + } + else if( sort_mode == SORT_DESCRIPTION ) + { + DO_META_SORT( Description ); + } + else if( sort_mode == SORT_ID ) + { + i_test = (*(playlist_item_t **)first)->i_id - (*(playlist_item_t **)second)->i_id; + } + else if( sort_mode == SORT_TITLE_NODES_FIRST ) + { + /* Alphabetic sort, all nodes first */ + + if( (*(playlist_item_t **)first)->i_children == -1 && + (*(playlist_item_t **)second)->i_children >= 0 ) { - int i_test = 0; - - if( i_mode == SORT_TITLE ) - { - META_STRCASECMP_NAME( i, i_small ); - } - else if( i_mode == SORT_TITLE_NUMERIC ) - { - char *psz_i = input_item_GetName( pp_items[i]->p_input ); - char *psz_ismall = - input_item_GetName( pp_items[i_small]->p_input ); - i_test = atoi( psz_i ) - atoi( psz_ismall ); - free( psz_i ); - free( psz_ismall ); - } - else if( i_mode == SORT_DURATION ) - { - i_test = input_item_GetDuration( pp_items[i]->p_input ) - - input_item_GetDuration( pp_items[i_small]->p_input ); - } - else if( i_mode == SORT_ARTIST ) - { - DO_META_SORT( Artist ); - } - else if( i_mode == SORT_GENRE ) - { - DO_META_SORT( Genre ); - } - else if( i_mode == SORT_ALBUM ) - { - DO_META_SORT( Album ); - } - else if( i_mode == SORT_TRACK_NUMBER ) - { - DO_META_SORT( TrackNumber ); - } - else if( i_mode == SORT_DESCRIPTION ) - { - DO_META_SORT( Description ); - } - else if( i_mode == SORT_RATING ) - { - DO_META_SORT( Rating ); - } - else if( i_mode == SORT_ID ) - { - i_test = pp_items[i]->i_id - pp_items[i_small]->i_id; - } - else if( i_mode == SORT_TITLE_NODES_FIRST ) - { - /* Alphabetic sort, all nodes first */ - - if( pp_items[i]->i_children == -1 && - pp_items[i_small]->i_children >= 0 ) - { - i_test = 1; - } - else if( pp_items[i]->i_children >= 0 && - pp_items[i_small]->i_children == -1 ) - { - i_test = -1; - } - else - { - i_test = strcasecmp( pp_items[i]->p_input->psz_name, - pp_items[i_small]->p_input->psz_name ); - } - } - - if( ( i_type == ORDER_NORMAL && i_test < 0 ) || - ( i_type == ORDER_REVERSE && i_test > 0 ) ) - { - i_small = i; - } + i_test = 1; + } + else if( (*(playlist_item_t **)first)->i_children >= 0 && + (*(playlist_item_t **)second)->i_children == -1 ) + { + i_test = -1; + } + else + { + i_test = strcasecmp( (*(playlist_item_t **)first)->p_input->psz_name, + (*(playlist_item_t **)second)->p_input->psz_name ); } - p_temp = pp_items[i_position]; - pp_items[i_position] = pp_items[i_small]; - pp_items[i_small] = p_temp; } - return VLC_SUCCESS; + + if ( sort_type == ORDER_REVERSE ) + i_test = i_test * -1; +#undef DO_META_SORT +#undef DO_META_SORT_ADV + + return i_test; }