]> git.sesse.net Git - vlc/commitdiff
Grmbl, it was obvious I would forget to add the new files
authorClément Stenac <zorglub@videolan.org>
Wed, 29 Oct 2003 18:00:46 +0000 (18:00 +0000)
committerClément Stenac <zorglub@videolan.org>
Wed, 29 Oct 2003 18:00:46 +0000 (18:00 +0000)
modules/gui/wxwindows/stream.cpp [new file with mode: 0644]
src/playlist/group.c [new file with mode: 0644]
src/playlist/item.c [new file with mode: 0644]
src/playlist/loadsave.c [new file with mode: 0644]
src/playlist/sort.c [new file with mode: 0644]

diff --git a/modules/gui/wxwindows/stream.cpp b/modules/gui/wxwindows/stream.cpp
new file mode 100644 (file)
index 0000000..476f733
--- /dev/null
@@ -0,0 +1,264 @@
+/*****************************************************************************
+ * stream.cpp : wxWindows plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000-2001 VideoLAN
+ * $Id: stream.cpp,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <errno.h>                                                 /* ENOMEM */
+#include <string.h>                                            /* strerror() */
+#include <stdio.h>
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+
+#include "wxwindows.h"
+
+#include <wx/statline.h>
+
+
+#define STREAM_INTRO N_( "Stream with VLC in three steps" )
+#define STREAM_STEP1 N_( "Step 1 : Select what to stream" )
+#define STREAM_STEP2 N_( "Step 2 : Define streaming method" )
+#define STREAM_STEP3 N_( "Step 3 : Start streaming" )
+
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/* IDs for the controls and the menu commands */
+enum
+{
+    Open_Event,
+    Sout_Event,
+    Start_Event,
+    Close_Event
+};
+
+BEGIN_EVENT_TABLE(StreamDialog, wxFrame)
+    /* Button events */
+    EVT_BUTTON(wxID_OK, StreamDialog::OnClose)
+
+    EVT_BUTTON(Open_Event,StreamDialog::OnOpen)
+    EVT_BUTTON(Sout_Event,StreamDialog::OnSout)
+    EVT_BUTTON(Start_Event,StreamDialog::OnStart)
+
+    /* Hide the window when the user closes the window */
+    EVT_CLOSE(StreamDialog::OnClose)
+
+END_EVENT_TABLE()
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+StreamDialog::StreamDialog( intf_thread_t *_p_intf, wxWindow *p_parent ):
+    wxFrame( p_parent, -1, wxU(_("Stream")), wxDefaultPosition,
+             wxDefaultSize, wxDEFAULT_FRAME_STYLE )
+{
+    /* Initializations */
+    p_intf = _p_intf;
+    SetIcon( *p_intf->p_sys->p_icon );
+    SetAutoLayout( TRUE );
+
+    p_open_dialog = NULL;
+    p_sout_dialog = NULL;
+
+    /* Create a panel to put everything in */
+    wxPanel *panel = new wxPanel( this, -1 );
+    panel->SetAutoLayout( TRUE );
+
+    wxStaticText *intro_label = new wxStaticText( panel,
+                          -1 , wxU(_( STREAM_INTRO )));
+
+
+    wxStaticText *step1_label = new wxStaticText( panel,
+                           -1 , wxU(_( STREAM_STEP1 )));
+
+    step2_label = new wxStaticText( panel,
+                 -1 , wxU(_( STREAM_STEP2 )));
+
+    step3_label = new wxStaticText( panel,
+                 -1 , wxU(_( STREAM_STEP3 )));
+
+    wxButton *open_button = new wxButton( panel,
+                  Open_Event, wxU(_("Open...")));
+
+    sout_button = new wxButton( panel,
+                   Sout_Event, wxU(_("Choose...")));
+
+    start_button = new wxButton( panel,
+                   Start_Event, wxU(_("Start !")));
+
+
+    step2_label->Disable();
+    step3_label->Disable();
+
+    sout_button->Disable();
+    start_button->Disable();
+
+    /* Place everything in sizers */
+    wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
+    wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
+
+    wxBoxSizer *step1_sizer = new wxBoxSizer( wxHORIZONTAL );
+    wxBoxSizer *step2_sizer = new wxBoxSizer( wxHORIZONTAL );
+    wxBoxSizer *step3_sizer = new wxBoxSizer( wxHORIZONTAL );
+
+    step1_sizer->Add( step1_label, 1, wxALL | wxEXPAND | wxALIGN_LEFT, 10 );
+    step1_sizer->Add( open_button, 1, wxALL | wxEXPAND | wxALIGN_RIGHT, 10 );
+
+    step2_sizer->Add( step2_label, 1, wxALL | wxEXPAND | wxALIGN_LEFT, 10 );
+    step2_sizer->Add( sout_button, 1, wxALL | wxEXPAND | wxALIGN_RIGHT, 10 );
+
+    step3_sizer->Add( step3_label,  1, wxALL | wxEXPAND | wxLEFT, 10 );
+    step3_sizer->Add( start_button, 1, wxALL | wxEXPAND | wxLEFT, 10 );
+
+    panel_sizer->Add( intro_label, 0, wxEXPAND | wxALL, 10 );
+
+    panel_sizer->Add( new wxStaticLine( panel, 0), 0,
+                      wxEXPAND | wxLEFT | wxRIGHT, 2 );
+    panel_sizer->Add( step1_sizer, 0, wxEXPAND, 10 );
+    panel_sizer->Add( new wxStaticLine( panel, 0), 0,
+                      wxEXPAND | wxLEFT | wxRIGHT, 2 );
+    panel_sizer->Add( step2_sizer, 0, wxEXPAND, 10 );
+    panel_sizer->Add( new wxStaticLine( panel, 0), 0,
+                      wxEXPAND | wxLEFT | wxRIGHT, 2 );
+    panel_sizer->Add( step3_sizer, 0, wxEXPAND, 10 );
+
+    panel_sizer->Layout();
+    panel->SetSizerAndFit( panel_sizer );
+    main_sizer->Add( panel, 1, wxEXPAND, 0 );
+    main_sizer->Layout();
+    SetSizerAndFit( main_sizer );
+
+}
+
+/*****************************************************************************
+ * Destructor.
+ *****************************************************************************/
+StreamDialog::~StreamDialog()
+{
+    if( p_open_dialog ) delete p_open_dialog;
+    if( p_sout_dialog ) delete p_sout_dialog;
+}
+
+void StreamDialog::OnOpen( wxCommandEvent& event )
+{
+    if( !p_open_dialog )
+    {
+        p_open_dialog = new OpenDialog(
+                    p_intf, this, FILE_ACCESS, 1 , OPEN_STREAM );
+    }
+
+    if( p_open_dialog)
+    {
+       p_open_dialog->Show();
+       mrl = p_open_dialog->mrl;
+       sout_button->Enable();
+       step2_label->Enable();
+    }
+}
+
+void StreamDialog::OnSout( wxCommandEvent& event )
+{
+    /* Show/hide the sout dialog */
+    if( p_sout_dialog == NULL )
+        p_sout_dialog = new SoutDialog( p_intf, this );
+
+    if( p_sout_dialog && p_sout_dialog->ShowModal() == wxID_OK )
+    {
+        sout_mrl = p_sout_dialog->GetOptions();
+        start_button->Enable();
+        step3_label->Enable();
+    }
+}
+
+void StreamDialog::OnStart( wxCommandEvent& event )
+{
+    /* Update the playlist */
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL ) return;
+
+    for( int i = 0; i < (int)p_open_dialog->mrl.GetCount(); i++ )
+    {
+        int i_options = 0, i_total_options;
+        char **ppsz_options = NULL;
+
+        /* Count the input options */
+        while( i + i_options + 1 < (int)p_open_dialog->mrl.GetCount() &&
+               ((const char *)p_open_dialog->mrl[i + i_options + 1].
+                                             mb_str())[0] == ':' )
+        {
+            i_options++;
+        }
+
+        /* Allocate ppsz_options */
+        for( int j = 0; j < i_options; j++ )
+        {
+            if( !ppsz_options )
+                ppsz_options = (char **)malloc( sizeof(char *) * i_options );
+
+            ppsz_options[j] = strdup( p_open_dialog->mrl[i + j  + 1].mb_str() );
+        }
+
+        i_total_options = i_options;
+
+        /* Get the options from the stream output dialog */
+        if( sout_mrl.GetCount() )
+        {
+            ppsz_options = (char **)realloc( ppsz_options, sizeof(char *) *
+                               (i_total_options + sout_mrl.GetCount()) );
+
+            for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
+            {
+                ppsz_options[i_total_options + j] =
+                    strdup( sout_mrl[j].mb_str() );
+            }
+
+            i_total_options += sout_mrl.GetCount();
+
+        }
+        msg_Dbg(p_intf,"playings %s",p_open_dialog->mrl[i].mb_str());
+        playlist_Add( p_playlist, (const char *)p_open_dialog->mrl[i].mb_str(),
+                      (const char **)ppsz_options, i_total_options,
+                      PLAYLIST_APPEND | (i ? 0 : PLAYLIST_GO), PLAYLIST_END );
+        /* clean up */
+        for( int j = 0; j < i_total_options; j++ )
+            free( ppsz_options[j] );
+        if( ppsz_options ) free( ppsz_options );
+
+        i += i_options;
+   }
+ vlc_object_release( p_playlist );
+
+  Hide();
+}
+
+
+void StreamDialog::OnClose( wxCommandEvent& event )
+{
+    Hide();
+}
diff --git a/src/playlist/group.c b/src/playlist/group.c
new file mode 100644 (file)
index 0000000..1d144d0
--- /dev/null
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * playlist.c : Playlist groups management functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: group.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+#include <stdlib.h>                                      /* free(), strtol() */
+#include <stdio.h>                                              /* sprintf() */
+#include <string.h>                                            /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "vlc_playlist.h"
+
+
+/**
+ * Create a group
+ *
+ * Create a new group
+ * \param p_playlist pointer to a playlist
+ * \param psz_name the name of the group to be created
+ * \return a pointer to the created group, or NULL on error
+ */
+playlist_group_t * playlist_CreateGroup(playlist_t * p_playlist, char *psz_name)
+{
+    playlist_group_t *p_group;
+
+    int i;
+    for( i=0 ; i< p_playlist->i_groups; i++ )
+    {
+        if( !strcasecmp(p_playlist->pp_groups[i]->psz_name , psz_name ) )
+        {
+            msg_Info( p_playlist, "This group already exists !");
+            return NULL;
+        }
+    }
+
+    /* Allocate the group structure */
+    p_group = (playlist_group_t *)malloc( sizeof(playlist_group_t) );
+    if( !p_group )
+    {
+        msg_Err( p_playlist, "out of memory" );
+        return NULL;
+    }
+
+    p_group->psz_name = strdup( psz_name );
+    p_group->i_id = ++p_playlist->i_max_id;
+
+    msg_Dbg(p_playlist,"Creating group %s with id %i at position %i",
+                     p_group->psz_name,
+                     p_group->i_id,
+                     p_playlist->i_groups);
+
+    INSERT_ELEM ( p_playlist->pp_groups,
+                  p_playlist->i_groups,
+                  p_playlist->i_groups,
+                  p_group );
+
+    return p_group;
+}
+
+/**
+ * Destroy a group
+ *
+ * \param p_playlist the playlist to remove the group from
+ * \param i_id the identifier of the group to remove
+ * \return 0 on success
+ */
+int playlist_DeleteGroup( playlist_t *p_playlist, int i_id )
+{
+    int i;
+
+    for( i=0 ; i<= p_playlist->i_groups; i++ )
+    {
+        if( p_playlist->pp_groups[i]->i_id == i_id )
+        {
+            if( p_playlist->pp_groups[i]->psz_name )
+            {
+                free( p_playlist->pp_groups[i]->psz_name );
+            }
+            REMOVE_ELEM( p_playlist->pp_groups,
+                         p_playlist->i_groups,
+                         i);
+        }
+    }
+    return 0;
+}
+
+/**
+ * Find the name with the ID
+ *
+ * \param p_playlist the playlist where to find the group
+ * \param i_id the ID to search for
+ * \return the name of the group
+ */
+char *playlist_FindGroup( playlist_t *p_playlist, int i_id )
+{
+    int i;
+    for( i=0 ; i<= p_playlist->i_groups; i++ )
+    {
+        if( p_playlist->pp_groups[i]->i_id == i_id )
+        {
+            if( p_playlist->pp_groups[i]->psz_name)
+            return strdup( p_playlist->pp_groups[i]->psz_name );
+        }
+    }
+    return NULL;
+}
diff --git a/src/playlist/item.c b/src/playlist/item.c
new file mode 100644 (file)
index 0000000..3528271
--- /dev/null
@@ -0,0 +1,496 @@
+/*****************************************************************************
+ * item.c : Playlist item functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: item.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+#include <stdlib.h>                                      /* free(), strtol() */
+#include <stdio.h>                                              /* sprintf() */
+#include <string.h>                                            /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "vlc_playlist.h"
+
+/**
+ * Add an MRL to the playlist. This is a simplified version of
+ * playlist_AddExt inculded for convenince. It equals calling playlist_AddExt
+ * with psz_name == psz_target and i_duration == -1
+ */
+
+int playlist_Add( playlist_t *p_playlist, const char *psz_target,
+                  const char **ppsz_options, int i_options,
+                  int i_mode, int i_pos )
+{
+    return playlist_AddExt( p_playlist, psz_target, psz_target, -1,
+                            ppsz_options, i_options, i_mode, i_pos );
+}
+
+/**
+ * Add a MRL into the playlist.
+ *
+ * \param p_playlist the playlist to add into
+ * \param psz_uri the mrl to add to the playlist
+ * \param psz_name a text giving a name or description of this item
+ * \param i_duration a hint about the duration of this item, in miliseconds, or
+ *        -1 if unknown.
+ * \param ppsz_options array of options
+ * \param i_options number of items in ppsz_options
+ * \param i_mode the mode used when adding
+ * \param i_pos the position in the playlist where to add. If this is
+ *        PLAYLIST_END the item will be added at the end of the playlist
+ *        regardless of it's size
+ * \return always returns 0
+*/
+int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
+                     const char * psz_name, mtime_t i_duration,
+                     const char **ppsz_options, int i_options, int i_mode,
+                     int i_pos )
+{
+    playlist_item_t * p_item;
+
+    p_item = malloc( sizeof( playlist_item_t ) );
+    if( p_item == NULL )
+    {
+        msg_Err( p_playlist, "out of memory" );
+    }
+
+    p_item->psz_name   = strdup( psz_name );
+    p_item->psz_uri    = strdup( psz_uri );
+    p_item->psz_author = strdup( "" );
+    p_item->i_duration = i_duration;
+    p_item->i_type = 0;
+    p_item->i_status = 0;
+    p_item->b_autodeletion = VLC_FALSE;
+    p_item->b_enabled = VLC_TRUE;
+    p_item->i_group = PLAYLIST_TYPE_MANUAL;
+
+    p_item->ppsz_options = NULL;
+    p_item->i_options = i_options;
+
+    if( i_options )
+    {
+        int i;
+
+        p_item->ppsz_options = (char **)malloc( i_options * sizeof(char *) );
+        for( i = 0; i < i_options; i++ )
+            p_item->ppsz_options[i] = strdup( ppsz_options[i] );
+
+    }
+
+    return playlist_AddItem( p_playlist, p_item, i_mode, i_pos );
+}
+
+/**
+ * Add a playlist item into a playlist
+ *
+ * \param p_playlist the playlist to insert into
+ * \param p_item the playlist item to insert
+ * \param i_mode the mode used when adding
+ * \param i_pos the possition in the playlist where to add. If this is
+ *        PLAYLIST_END the item will be added at the end of the playlist
+ *        regardless of it's size
+ * \return always returns 0
+*/
+int playlist_AddItem( playlist_t *p_playlist, playlist_item_t * p_item,
+                int i_mode, int i_pos)
+{
+    vlc_value_t     val;
+
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    /*
+     * CHECK_INSERT : checks if the item is already enqued before
+     * enqueing it
+     */
+    if ( i_mode & PLAYLIST_CHECK_INSERT )
+    {
+         int j;
+
+         if ( p_playlist->pp_items )
+         {
+             for ( j = 0; j < p_playlist->i_size; j++ )
+             {
+                 if ( !strcmp( p_playlist->pp_items[j]->psz_uri, p_item->psz_uri ) )
+                 {
+                      if( p_item->psz_name )
+                      {
+                          free( p_item->psz_name );
+                      }
+                      if( p_item->psz_uri )
+                      {
+                          free( p_item->psz_uri );
+                      }
+                      free( p_item );
+                      vlc_mutex_unlock( &p_playlist->object_lock );
+                      return 0;
+                 }
+             }
+         }
+         i_mode &= ~PLAYLIST_CHECK_INSERT;
+         i_mode |= PLAYLIST_APPEND;
+    }
+
+
+    msg_Dbg( p_playlist, "adding playlist item « %s » ( %s )", p_item->psz_name, p_item->psz_uri);
+
+    /* Create the new playlist item */
+
+
+    /* Do a few boundary checks and allocate space for the item */
+    if( i_pos == PLAYLIST_END )
+    {
+        if( i_mode & PLAYLIST_INSERT )
+        {
+            i_mode &= ~PLAYLIST_INSERT;
+            i_mode |= PLAYLIST_APPEND;
+        }
+
+        i_pos = p_playlist->i_size - 1;
+    }
+
+    if( !(i_mode & PLAYLIST_REPLACE)
+         || i_pos < 0 || i_pos >= p_playlist->i_size )
+    {
+        /* Additional boundary checks */
+        if( i_mode & PLAYLIST_APPEND )
+        {
+            i_pos++;
+        }
+
+        if( i_pos < 0 )
+        {
+            i_pos = 0;
+        }
+        else if( i_pos > p_playlist->i_size )
+        {
+            i_pos = p_playlist->i_size;
+        }
+
+        INSERT_ELEM( p_playlist->pp_items,
+                     p_playlist->i_size,
+                     i_pos,
+                     p_item );
+        p_playlist->i_enabled ++;
+
+        if( p_playlist->i_index >= i_pos )
+        {
+            p_playlist->i_index++;
+        }
+    }
+    else
+    {
+        /* i_mode == PLAYLIST_REPLACE and 0 <= i_pos < p_playlist->i_size */
+        if( p_playlist->pp_items[i_pos]->psz_name )
+        {
+            free( p_playlist->pp_items[i_pos]->psz_name );
+        }
+        if( p_playlist->pp_items[i_pos]->psz_uri )
+        {
+            free( p_playlist->pp_items[i_pos]->psz_uri );
+        }
+        /* XXX: what if the item is still in use? */
+        free( p_playlist->pp_items[i_pos] );
+        p_playlist->pp_items[i_pos] = p_item;
+    }
+
+    if( i_mode & PLAYLIST_GO )
+    {
+        p_playlist->i_index = i_pos;
+        if( p_playlist->p_input )
+        {
+            input_StopThread( p_playlist->p_input );
+        }
+        p_playlist->i_status = PLAYLIST_RUNNING;
+    }
+
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    return 0;
+}
+
+/**
+ * delete an item from a playlist.
+ *
+ * \param p_playlist the playlist to remove from.
+ * \param i_pos the position of the item to remove
+ * \return returns 0
+ */
+int playlist_Delete( playlist_t * p_playlist, int i_pos )
+{
+    vlc_value_t     val;
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    if( i_pos >= 0 && i_pos < p_playlist->i_size )
+    {
+        msg_Dbg( p_playlist, "deleting playlist item « %s »",
+                             p_playlist->pp_items[i_pos]->psz_name );
+
+        if( p_playlist->pp_items[i_pos]->psz_name )
+        {
+            free( p_playlist->pp_items[i_pos]->psz_name );
+        }
+        if( p_playlist->pp_items[i_pos]->psz_uri )
+        {
+            free( p_playlist->pp_items[i_pos]->psz_uri );
+        }
+        if( p_playlist->pp_items[i_pos]->psz_author )
+        {
+            free( p_playlist->pp_items[i_pos]->psz_author );
+        }
+        if( p_playlist->pp_items[i_pos]->i_options )
+        {
+            int i;
+
+            for( i = 0; i < p_playlist->pp_items[i_pos]->i_options; i++ )
+                free( p_playlist->pp_items[i_pos]->ppsz_options[i] );
+
+            free( p_playlist->pp_items[i_pos]->ppsz_options );
+        }
+
+        /* XXX: what if the item is still in use? */
+        free( p_playlist->pp_items[i_pos] );
+
+        if( i_pos <= p_playlist->i_index )
+        {
+            p_playlist->i_index--;
+        }
+
+        /* Renumber the playlist */
+        REMOVE_ELEM( p_playlist->pp_items,
+                     p_playlist->i_size,
+                     i_pos );
+        if( p_playlist->i_enabled > 0 )
+            p_playlist->i_enabled--;
+    }
+
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    return 0;
+}
+
+/**
+ * Disables a playlist item
+ *
+ * \param p_playlist the playlist to disable from.
+ * \param i_pos the position of the item to disable
+ * \return returns 0
+ */
+int playlist_Disable( playlist_t * p_playlist, int i_pos )
+{
+    vlc_value_t     val;
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+
+    if( i_pos >= 0 && i_pos < p_playlist->i_size )
+    {
+        msg_Dbg( p_playlist, "disabling playlist item « %s »",
+                             p_playlist->pp_items[i_pos]->psz_name );
+
+        if( p_playlist->pp_items[i_pos]->b_enabled == VLC_TRUE )
+            p_playlist->i_enabled--;
+        p_playlist->pp_items[i_pos]->b_enabled = VLC_FALSE;
+    }
+
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    return 0;
+}
+
+/**
+ * Enables a playlist item
+ *
+ * \param p_playlist the playlist to enable from.
+ * \param i_pos the position of the item to enable
+ * \return returns 0
+ */
+int playlist_Enable( playlist_t * p_playlist, int i_pos )
+{
+    vlc_value_t     val;
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    if( i_pos >= 0 && i_pos < p_playlist->i_size )
+    {
+        msg_Dbg( p_playlist, "enabling playlist item « %s »",
+                             p_playlist->pp_items[i_pos]->psz_name );
+
+        if( p_playlist->pp_items[i_pos]->b_enabled == VLC_FALSE )
+            p_playlist->i_enabled++;
+
+        p_playlist->pp_items[i_pos]->b_enabled = VLC_TRUE;
+    }
+
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    return 0;
+}
+
+/**
+ * Disables a playlist group
+ *
+ * \param p_playlist the playlist to disable from.
+ * \param i_pos the id of the group to disable
+ * \return returns 0
+ */
+int playlist_DisableGroup( playlist_t * p_playlist, int i_group)
+{
+    vlc_value_t     val;
+    int i;
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    msg_Dbg(p_playlist,"Disabling group %i",i_group);
+    for( i = 0 ; i< p_playlist->i_size; i++ )
+    {
+        if( p_playlist->pp_items[i]->i_group == i_group )
+        {
+            msg_Dbg( p_playlist, "disabling playlist item « %s »",
+                           p_playlist->pp_items[i]->psz_name );
+
+            if( p_playlist->pp_items[i]->b_enabled == VLC_TRUE )
+                p_playlist->i_enabled--;
+
+            p_playlist->pp_items[i]->b_enabled = VLC_FALSE;
+        }
+    }
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    return 0;
+}
+
+/**
+ * Enables a playlist group
+ *
+ * \param p_playlist the playlist to enable from.
+ * \param i_pos the id of the group to enable
+ * \return returns 0
+ */
+int playlist_EnableGroup( playlist_t * p_playlist, int i_group)
+{
+    vlc_value_t     val;
+    int i;
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    for( i = 0 ; i< p_playlist->i_size; i++ )
+    {
+        if( p_playlist->pp_items[i]->i_group == i_group )
+        {
+            msg_Dbg( p_playlist, "enabling playlist item « %s »",
+                           p_playlist->pp_items[i]->psz_name );
+
+            if( p_playlist->pp_items[i]->b_enabled == VLC_FALSE )
+                p_playlist->i_enabled++;
+
+            p_playlist->pp_items[i]->b_enabled = VLC_TRUE;
+        }
+    }
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    return 0;
+}
+
+/**
+ * Move an item in a playlist
+ *
+ * Move the item in the playlist with position i_pos before the current item
+ * at position i_newpos.
+ * \param p_playlist the playlist to move items in
+ * \param i_pos the position of the item to move
+ * \param i_newpos the position of the item that will be behind the moved item
+ *        after the move
+ * \return returns 0
+ */
+int playlist_Move( playlist_t * p_playlist, int i_pos, int i_newpos)
+{
+    vlc_value_t     val;
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    /* take into account that our own row disappears. */
+    if ( i_pos < i_newpos ) i_newpos--;
+
+    if( i_pos >= 0 && i_newpos >=0 && i_pos <= p_playlist->i_size
+                     && i_newpos <= p_playlist->i_size )
+    {
+        playlist_item_t * temp;
+
+        msg_Dbg( p_playlist, "moving playlist item « %s » (%i -> %i)",
+                             p_playlist->pp_items[i_pos]->psz_name, i_pos,
+                             i_newpos );
+
+        if( i_pos == p_playlist->i_index )
+        {
+            p_playlist->i_index = i_newpos;
+        }
+        else if( i_pos > p_playlist->i_index && i_newpos <= p_playlist->i_index )
+        {
+            p_playlist->i_index++;
+        }
+        else if( i_pos < p_playlist->i_index && i_newpos >= p_playlist->i_index )
+        {
+            p_playlist->i_index--;
+        }
+
+        if ( i_pos < i_newpos )
+        {
+            temp = p_playlist->pp_items[i_pos];
+            while ( i_pos < i_newpos )
+            {
+                p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos+1];
+                i_pos++;
+            }
+            p_playlist->pp_items[i_newpos] = temp;
+        }
+        else if ( i_pos > i_newpos )
+        {
+            temp = p_playlist->pp_items[i_pos];
+            while ( i_pos > i_newpos )
+            {
+                p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos-1];
+                i_pos--;
+            }
+            p_playlist->pp_items[i_newpos] = temp;
+        }
+    }
+
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    return 0;
+}
diff --git a/src/playlist/loadsave.c b/src/playlist/loadsave.c
new file mode 100644 (file)
index 0000000..a059356
--- /dev/null
@@ -0,0 +1,192 @@
+/*****************************************************************************
+ * loadsave.c : Playlist loading / saving functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: loadsave.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+#include <stdlib.h>                                      /* free(), strtol() */
+#include <stdio.h>                                              /* sprintf() */
+#include <string.h>                                            /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+
+#include "vlc_playlist.h"
+
+#define PLAYLIST_FILE_HEADER_0_5  "# vlc playlist file version 0.5"
+#define PLAYLIST_FILE_HEADER_0_6  "# vlc playlist file version 0.6"
+
+
+/*****************************************************************************
+ * playlist_LoadFile: load a playlist file.
+ ****************************************************************************/
+int playlist_LoadFile( playlist_t * p_playlist, const char *psz_filename )
+{
+    FILE *file;
+    char line[1024];
+    int i_current_status;
+    int i_format;
+    int i;
+
+    msg_Dbg( p_playlist, "opening playlist file %s", psz_filename );
+
+    file = fopen( psz_filename, "rt" );
+    if( !file )
+    {
+        msg_Err( p_playlist, "playlist file %s does not exist", psz_filename );
+        return -1;
+    }
+    fseek( file, 0L, SEEK_SET );
+
+    /* check the file is not empty */
+    if ( ! fgets( line, 1024, file ) )
+    {
+        msg_Err( p_playlist, "playlist file %s is empty", psz_filename );
+        fclose( file );
+        return -1;
+    }
+
+    /* get rid of line feed */
+    if( line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\r' )
+    {
+       line[strlen(line)-1] = (char)0;
+       if( line[strlen(line)-1] == '\r' ) line[strlen(line)-1] = (char)0;
+    }
+    /* check the file format is valid */
+    if ( !strcmp ( line , PLAYLIST_FILE_HEADER_0_5 ) )
+    {
+       i_format = 5;
+    }
+    else if( !strcmp ( line , PLAYLIST_FILE_HEADER_0_6 ) )
+    {
+       i_format = 6;
+    }
+    else
+    {
+        msg_Err( p_playlist, "playlist file %s format is unsupported"
+                , psz_filename );
+        fclose( file );
+        return -1;
+    }
+
+    /* stop playing */
+    i_current_status = p_playlist->i_status;
+    if ( p_playlist->i_status != PLAYLIST_STOPPED )
+    {
+        playlist_Stop ( p_playlist );
+    }
+
+    /* delete current content of the playlist */
+    for( i = p_playlist->i_size - 1; i >= 0; i-- )
+    {
+        playlist_Delete ( p_playlist , i );
+    }
+
+    /* simply add each line */
+    while( fgets( line, 1024, file ) )
+    {
+       /* ignore comments or empty lines */
+       if( (line[0] == '#') || (line[0] == '\r') || (line[0] == '\n')
+               || (line[0] == (char)0) )
+           continue;
+
+       /* get rid of line feed */
+       if( line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\r' )
+       {
+           line[strlen(line)-1] = (char)0;
+           if( line[strlen(line)-1] == '\r' ) line[strlen(line)-1] = (char)0;
+       }
+       if( i_format == 5 )
+       {
+           playlist_Add ( p_playlist , (char *)&line ,
+                      0, 0, PLAYLIST_APPEND , PLAYLIST_END );
+       }
+       else
+       {
+           msg_Warn( p_playlist, "Not supported yet");
+       }
+    }
+
+    /* start playing */
+    if ( i_current_status != PLAYLIST_STOPPED )
+    {
+        playlist_Play ( p_playlist );
+    }
+
+    fclose( file );
+
+    return 0;
+}
+
+/*****************************************************************************
+ * playlist_SaveFile: Save a playlist in a file.
+ *****************************************************************************/
+int playlist_SaveFile( playlist_t * p_playlist, const char * psz_filename )
+{
+    FILE *file;
+    int i;
+
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    msg_Dbg( p_playlist, "saving playlist file %s", psz_filename );
+
+    file = fopen( psz_filename, "wt" );
+    if( !file )
+    {
+        msg_Err( p_playlist , "could not create playlist file %s"
+                , psz_filename );
+        return -1;
+    }
+    /* Save is done in 0_5 mode at the moment*/
+
+    fprintf( file , PLAYLIST_FILE_HEADER_0_5 "\n" );
+
+    for ( i = 0 ; i < p_playlist->i_size ; i++ )
+    {
+        fprintf( file , p_playlist->pp_items[i]->psz_uri );
+        fprintf( file , "\n" );
+    }
+#if 0
+    fprintf( file, PLAYLIST_FILE_HEADER_0_6 "\n" );
+
+    for ( i=0 ; i< p_playlist->i_size ; i++ )
+    {
+        fprintf( file, p_playlist->pp_items[i]->psz_uri );
+        fprintf( file, "||" );
+        fprintf( file, p_playlist->pp_items[i]->psz_name );
+        fprintf( file, "||" );
+        fprintf( file, "%i",p_playlist->pp_items[i]->b_enabled = VLC_TRUE ?
+                       1:0 );
+        fprintf( file, "||" );
+        fprintf( file, "%i", p_playlist->pp_items[i]->i_group );
+        fprintf( file, "||" );
+        fprintf( file, p_playlist->pp_items[i]->psz_author );
+        fprintf( file , "\n" );
+    }
+#endif
+    fclose( file );
+
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    return 0;
+}
diff --git a/src/playlist/sort.c b/src/playlist/sort.c
new file mode 100644 (file)
index 0000000..8f97980
--- /dev/null
@@ -0,0 +1,157 @@
+/*****************************************************************************
+ * sort.c : Playlist sorting functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: sort.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+#include <stdlib.h>                                      /* free(), strtol() */
+#include <stdio.h>                                              /* sprintf() */
+#include <string.h>                                            /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "vlc_playlist.h"
+
+/**
+ * Sort the playlist by title
+ * \param p_playlist the playlist
+ * \param i_type: SORT_NORMAL or SORT_REVERSE (reversed order)
+ * \return 0 on success
+ */
+int playlist_SortTitle( playlist_t * p_playlist , int i_type )
+{
+    int i , i_small , i_position;
+    playlist_item_t *p_temp;
+
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    for( i_position = 0; i_position < p_playlist->i_size -1 ; i_position ++ )
+    {
+        i_small  = i_position;
+        for( i = i_position + 1 ; i<  p_playlist->i_size ; i++)
+        {
+            int i_test;
+
+            i_test = strcasecmp( p_playlist->pp_items[i]->psz_name,
+                                 p_playlist->pp_items[i_small]->psz_name );
+
+            if( ( i_type == SORT_NORMAL  && i_test < 0 ) ||
+                ( i_type == SORT_REVERSE && i_test > 0 ) )
+            {
+                i_small = i;
+            }
+        }
+        /* Keep the correct current index */
+        if( i_small == p_playlist->i_index )
+            p_playlist->i_index = i_position;
+        else if( i_position == p_playlist->i_index )
+            p_playlist->i_index = i_small;
+
+        p_temp = p_playlist->pp_items[i_position];
+        p_playlist->pp_items[i_position] = p_playlist->pp_items[i_small];
+        p_playlist->pp_items[i_small] = p_temp;
+    }
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    return 0;
+}
+
+/**
+ * Sort the playlist by author
+ * \param p_playlist the playlist
+ * \param i_type: SORT_NORMAL or SORT_REVERSE (reversed order)
+ * \return 0 on success
+ */
+int playlist_SortAuthor( playlist_t * p_playlist , int i_type )
+{
+    int i , i_small , i_position;
+    playlist_item_t *p_temp;
+
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    for( i_position = 0; i_position < p_playlist->i_size -1 ; i_position ++ )
+    {
+        i_small  = i_position;
+        for( i = i_position + 1 ; i<  p_playlist->i_size ; i++)
+        {
+            int i_test;
+
+            i_test = strcasecmp( p_playlist->pp_items[i]->psz_author,
+                                 p_playlist->pp_items[i_small]->psz_author );
+
+            if( ( i_type == SORT_NORMAL  && i_test < 0 ) ||
+                ( i_type == SORT_REVERSE && i_test > 0 ) )
+            {
+                i_small = i;
+            }
+        }
+        /* Keep the correct current index */
+        if( i_small == p_playlist->i_index )
+            p_playlist->i_index = i_position;
+        else if( i_position == p_playlist->i_index )
+            p_playlist->i_index = i_small;
+
+        p_temp = p_playlist->pp_items[i_position];
+        p_playlist->pp_items[i_position] = p_playlist->pp_items[i_small];
+        p_playlist->pp_items[i_small] = p_temp;
+    }
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    return 0;
+}
+
+int playlist_SortGroup( playlist_t * p_playlist , int i_type )
+{
+    int i , i_small , i_position;
+    playlist_item_t *p_temp;
+
+    vlc_mutex_lock( &p_playlist->object_lock );
+
+    for( i_position = 0; i_position < p_playlist->i_size -1 ; i_position ++ )
+    {
+        i_small  = i_position;
+        for( i = i_position + 1 ; i<  p_playlist->i_size ; i++)
+        {
+            int i_test;
+
+            i_test = p_playlist->pp_items[i]->i_group -
+                                 p_playlist->pp_items[i_small]->i_group;
+
+            if( ( i_type == SORT_NORMAL  && i_test < 0 ) ||
+                ( i_type == SORT_REVERSE && i_test > 0 ) )
+            {
+                i_small = i;
+            }
+        }
+        /* Keep the correct current index */
+        if( i_small == p_playlist->i_index )
+            p_playlist->i_index = i_position;
+        else if( i_position == p_playlist->i_index )
+            p_playlist->i_index = i_small;
+
+        p_temp = p_playlist->pp_items[i_position];
+        p_playlist->pp_items[i_position] = p_playlist->pp_items[i_small];
+        p_playlist->pp_items[i_small] = p_temp;
+    }
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    return 0;
+}