Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

sort.c

00001 /*****************************************************************************
00002  * sort.c : Playlist sorting functions
00003  *****************************************************************************
00004  * Copyright (C) 1999-2004 the VideoLAN team
00005  * $Id: sort.c 12564 2005-09-15 17:42:24Z zorglub $
00006  *
00007  * Authors: Clément Stenac <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 #include <stdlib.h>                                      /* free(), strtol() */
00024 #include <stdio.h>                                              /* sprintf() */
00025 #include <string.h>                                            /* strerror() */
00026 
00027 #include <vlc/vlc.h>
00028 #include <vlc/input.h>
00029 #include <vlc/vout.h>
00030 #include <vlc/sout.h>
00031 
00032 #include "vlc_playlist.h"
00033 
00034 
00035 int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
00036                 playlist_item_t **pp_items, int i_mode,
00037                 int i_type );
00038 
00039 
00047 int playlist_Sort( playlist_t * p_playlist , int i_mode, int i_type )
00048 {
00049     int  i_id = -1;
00050     vlc_value_t val;
00051     val.b_bool = VLC_TRUE;
00052 
00053     vlc_mutex_lock( &p_playlist->object_lock );
00054 
00055     p_playlist->i_sort = i_mode;
00056     p_playlist->i_order = i_type;
00057 
00058     if( p_playlist->i_index >= 0 )
00059     {
00060         i_id = p_playlist->pp_items[p_playlist->i_index]->input.i_id;
00061     }
00062 
00063     playlist_ItemArraySort( p_playlist, p_playlist->i_size,
00064                     p_playlist->pp_items, i_mode, i_type );
00065 
00066     if( i_id != -1 )
00067     {
00068         p_playlist->i_index = playlist_GetPositionById( p_playlist, i_id );
00069     }
00070 
00071     /* ensure we are in no-view mode */
00072     p_playlist->status.i_view = -1;
00073 
00074     vlc_mutex_unlock( &p_playlist->object_lock );
00075 
00076     /* Notify the interfaces */
00077     var_Set( p_playlist, "intf-change", val );
00078 
00079     return VLC_SUCCESS;
00080 }
00081 
00093 int playlist_NodeSort( playlist_t * p_playlist , playlist_item_t *p_node,
00094                        int i_mode, int i_type )
00095 {
00096 
00097     playlist_ItemArraySort( p_playlist,p_node->i_children,
00098                             p_node->pp_children, i_mode, i_type );
00099 
00100     p_node->i_serial++;
00101 
00102     return VLC_SUCCESS;
00103 }
00104 
00117 int playlist_RecursiveNodeSort( playlist_t *p_playlist, playlist_item_t *p_node,
00118                                 int i_mode, int i_type )
00119 {
00120     int i;
00121 
00122     playlist_NodeSort( p_playlist, p_node, i_mode, i_type );
00123     for( i = 0 ; i< p_node->i_children; i++ )
00124     {
00125         if( p_node->pp_children[i]->i_children != -1 )
00126         {
00127             playlist_RecursiveNodeSort( p_playlist, p_node->pp_children[i],
00128                                         i_mode,i_type );
00129         }
00130     }
00131 
00132     return VLC_SUCCESS;
00133 
00134 }
00135 
00136 
00137 int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
00138                 playlist_item_t **pp_items, int i_mode,
00139                 int i_type )
00140 {
00141     int i , i_small , i_position;
00142     playlist_item_t *p_temp;
00143     vlc_value_t val;
00144     val.b_bool = VLC_TRUE;
00145 
00146     if( i_mode == SORT_RANDOM )
00147     {
00148         for( i_position = 0; i_position < i_items ; i_position ++ )
00149         {
00150             int i_new;
00151 
00152             if( i_items > 1 )
00153                 i_new = rand() % (i_items - 1);
00154             else
00155                 i_new = 0;
00156             p_temp = pp_items[i_position];
00157             pp_items[i_position] = pp_items[i_new];
00158             pp_items[i_new] = p_temp;
00159         }
00160 
00161         return VLC_SUCCESS;
00162     }
00163 
00164     for( i_position = 0; i_position < i_items -1 ; i_position ++ )
00165     {
00166         i_small  = i_position;
00167         for( i = i_position + 1 ; i< i_items ; i++)
00168         {
00169             int i_test = 0;
00170 
00171             if( i_mode == SORT_TITLE )
00172             {
00173                 i_test = strcasecmp( pp_items[i]->input.psz_name,
00174                                          pp_items[i_small]->input.psz_name );
00175             }
00176             else if( i_mode == SORT_TITLE_NUMERIC )
00177             {
00178                 i_test = atoi( pp_items[i]->input.psz_name ) -
00179                          atoi( pp_items[i_small]->input.psz_name );
00180             }
00181             else if( i_mode == SORT_DURATION )
00182             {
00183                 i_test = pp_items[i]->input.i_duration -
00184                              pp_items[i_small]->input.i_duration;
00185             }
00186             else if( i_mode == SORT_AUTHOR )
00187             {
00188                 char *psz_a = vlc_input_item_GetInfo(
00189                                  &pp_items[i]->input,
00190                                  _( "Meta-information"), _("Artist") );
00191                 char *psz_b = vlc_input_item_GetInfo(
00192                                  &pp_items[i_small]->input,
00193                                  _( "Meta-information"), _("Artist") );
00194                 if( pp_items[i]->i_children == -1 &&
00195                     pp_items[i_small]->i_children >= 0 )
00196                 {
00197                     i_test = 1;
00198                 }
00199                 else if( pp_items[i]->i_children >= 0 &&
00200                          pp_items[i_small]->i_children == -1 )
00201                 {
00202                     i_test = -1;
00203                 }
00204                 // both are nodes
00205                 else if( pp_items[i]->i_children >= 0 &&
00206                          pp_items[i_small]->i_children >= 0 )
00207                 {
00208                     i_test = strcasecmp( pp_items[i]->input.psz_name,
00209                                          pp_items[i_small]->input.psz_name );
00210                 }
00211                 else if( psz_a == NULL && psz_b != NULL )
00212                 {
00213                     i_test = 1;
00214                 }
00215                 else if( psz_a != NULL && psz_b == NULL )
00216                 {
00217                     i_test = -1;
00218                 }
00219                 else if( psz_a == NULL && psz_b == NULL )
00220                 {
00221                     i_test = strcasecmp( pp_items[i]->input.psz_name,
00222                                          pp_items[i_small]->input.psz_name );
00223                 }
00224                 else
00225                 {
00226                     i_test = strcmp( psz_b, psz_a );
00227                 }
00228             }
00229             else if( i_mode == SORT_ALBUM )
00230             {
00231                 char *psz_a = vlc_input_item_GetInfo(
00232                                  &pp_items[i]->input,
00233                                  _( "Meta-information"), _("Album/movie/show title") );
00234                 char *psz_b = vlc_input_item_GetInfo(
00235                                  &pp_items[i_small]->input,
00236                                  _( "Meta-information"), _("Album/movie/show title") );
00237                 if( pp_items[i]->i_children == -1 &&
00238                     pp_items[i_small]->i_children >= 0 )
00239                 {
00240                     i_test = 1;
00241                 }
00242                 else if( pp_items[i]->i_children >= 0 &&
00243                          pp_items[i_small]->i_children == -1 )
00244                 {
00245                     i_test = -1;
00246                 }
00247                 // both are nodes
00248                 else if( pp_items[i]->i_children >= 0 &&
00249                          pp_items[i_small]->i_children >= 0 )
00250                 {
00251                     i_test = strcasecmp( pp_items[i]->input.psz_name,
00252                                          pp_items[i_small]->input.psz_name );
00253                 }
00254                 else if( psz_a == NULL && psz_b != NULL )
00255                 {
00256                     i_test = 1;
00257                 }
00258                 else if( psz_a != NULL && psz_b == NULL )
00259                 {
00260                     i_test = -1;
00261                 }
00262                 else if( psz_a == NULL && psz_b == NULL )
00263                 {
00264                     i_test = strcasecmp( pp_items[i]->input.psz_name,
00265                                          pp_items[i_small]->input.psz_name );
00266                 }
00267                 else
00268                 {
00269                     i_test = strcmp( psz_b, psz_a );
00270                 }
00271             }
00272             else if( i_mode == SORT_TITLE_NODES_FIRST )
00273             {
00274                 /* Alphabetic sort, all nodes first */
00275 
00276                 if( pp_items[i]->i_children == -1 &&
00277                     pp_items[i_small]->i_children >= 0 )
00278                 {
00279                     i_test = 1;
00280                 }
00281                 else if( pp_items[i]->i_children >= 0 &&
00282                          pp_items[i_small]->i_children == -1 )
00283                 {
00284                     i_test = -1;
00285                 }
00286                 else
00287                 {
00288                     i_test = strcasecmp( pp_items[i]->input.psz_name,
00289                                          pp_items[i_small]->input.psz_name );
00290                 }
00291             }
00292 
00293             if( ( i_type == ORDER_NORMAL  && i_test < 0 ) ||
00294                 ( i_type == ORDER_REVERSE && i_test > 0 ) )
00295             {
00296                 i_small = i;
00297             }
00298         }
00299         p_temp = pp_items[i_position];
00300         pp_items[i_position] = pp_items[i_small];
00301         pp_items[i_small] = p_temp;
00302     }
00303     return VLC_SUCCESS;
00304 }
00305 
00306 
00307 int playlist_NodeGroup( playlist_t * p_playlist , int i_view,
00308                         playlist_item_t *p_root,
00309                         playlist_item_t **pp_items,int i_item,
00310                         int i_mode, int i_type )
00311 {
00312     char *psz_search = NULL;
00313     int i_nodes = 0;
00314     playlist_item_t **pp_nodes = NULL;
00315     playlist_item_t *p_node;
00316     vlc_bool_t b_found;
00317     int i,j;
00318     for( i = 0; i< i_item ; i++ )
00319     {
00320         if( psz_search ) free( psz_search );
00321         if( i_mode == SORT_TITLE )
00322         {
00323             psz_search = strdup( pp_items[i]->input.psz_name );
00324         }
00325         else if ( i_mode == SORT_AUTHOR )
00326         {
00327             psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
00328                             _("Meta-information"), _( "Artist" ) );
00329         }
00330         else if ( i_mode == SORT_ALBUM )
00331         {
00332             psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
00333                             _("Meta-information"), _( "Album/movie/show title" ) );
00334         }
00335         else if ( i_mode == SORT_GENRE )
00336         {
00337             psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
00338                             _("Meta-information"), _( "Genre" ) );
00339         }
00340 
00341         if( psz_search && !strcmp( psz_search, "" ) )
00342         {
00343             free( psz_search );
00344             psz_search = strdup( _("Undefined") );
00345         }
00346 
00347         b_found = VLC_FALSE;
00348         for( j = 0 ; j< i_nodes; j++ )
00349         {
00350            if( !strcasecmp( psz_search, pp_nodes[j]->input.psz_name ) )
00351            {
00352                 playlist_NodeAppend( p_playlist, i_view,
00353                                      pp_items[i], pp_nodes[j] );
00354                 b_found = VLC_TRUE;
00355                 break;
00356            }
00357         }
00358         if( !b_found )
00359         {
00360             p_node = playlist_NodeCreate( p_playlist, i_view,psz_search,
00361                                           NULL );
00362             INSERT_ELEM( pp_nodes, i_nodes, i_nodes, p_node );
00363             playlist_NodeAppend( p_playlist, i_view,
00364                                  pp_items[i],p_node );
00365         }
00366     }
00367 
00368     /* Now, sort the nodes by name */
00369     playlist_ItemArraySort( p_playlist, i_nodes, pp_nodes, SORT_TITLE,
00370                             i_type );
00371 
00372     /* Now, sort each node and append it to the root node*/
00373     for( i = 0 ; i< i_nodes ; i++ )
00374     {
00375         playlist_ItemArraySort( p_playlist, pp_nodes[i]->i_children,
00376                                 pp_nodes[i]->pp_children, SORT_TITLE, i_type );
00377 
00378         playlist_NodeAppend( p_playlist, i_view,
00379                              pp_nodes[i], p_root );
00380     }
00381     return VLC_SUCCESS;
00382 }

Generated on Tue Dec 20 10:15:01 2005 for vlc-0.8.4a by  doxygen 1.4.2