]> git.sesse.net Git - vlc/commitdiff
Recommit 9469->9479 + fix wxT/wxU
authorClément Stenac <zorglub@videolan.org>
Tue, 7 Dec 2004 14:18:47 +0000 (14:18 +0000)
committerClément Stenac <zorglub@videolan.org>
Tue, 7 Dec 2004 14:18:47 +0000 (14:18 +0000)
modules/access/http.c
modules/codec/cmml/cmml.c
modules/codec/cmml/intf.c
modules/codec/speex.c
modules/demux/mjpeg.c
modules/demux/ogg.c
modules/gui/skins2/src/vout_window.hpp
modules/gui/wxwindows/iteminfo.cpp
modules/gui/wxwindows/playlist.cpp
modules/gui/wxwindows/wxwindows.h
modules/services_discovery/sap.c

index 6d716ea9eee2883e2e49451783176fa7147d66ab..863367d6d223ef80e7164366c4679c20701b5e99 100644 (file)
@@ -67,6 +67,10 @@ static void Close( vlc_object_t * );
 #define RECONNECT_LONGTEXT N_("Will automatically attempt a re-connection " \
     "in case it was untimely closed.")
 
+#define CONTINUOUS_TEXT N_("Continuous stream")
+#define CONTINUOUS_LONGTEXT N_("Enable this option to read a file that is " \
+    "being constantly updated (for example, a JPG file on a server)")
+
 vlc_module_begin();
     set_description( _("HTTP input") );
     set_capability( "access2", 0 );
@@ -81,10 +85,13 @@ vlc_module_begin();
                 AGENT_LONGTEXT, VLC_FALSE );
     add_bool( "http-reconnect", 0, NULL, RECONNECT_TEXT,
               RECONNECT_LONGTEXT, VLC_TRUE );
+    add_bool( "http-continuous", 0, NULL, CONTINUOUS_TEXT,
+              CONTINUOUS_LONGTEXT, VLC_TRUE );
 
     add_shortcut( "http" );
     add_shortcut( "http4" );
     add_shortcut( "http6" );
+    add_shortcut( "unsv" );
     set_callbacks( Open, Close );
 vlc_module_end();
 
@@ -124,8 +131,11 @@ struct access_sys_t
     char       *psz_icy_genre;
     char       *psz_icy_title;
 
+    int i_remaining;
+
     vlc_bool_t b_seekable;
     vlc_bool_t b_reconnect;
+    vlc_bool_t b_continuous;
     vlc_bool_t b_pace_control;
 };
 
@@ -137,6 +147,7 @@ static int Control( access_t *, int, va_list );
 /* */
 static void ParseURL( access_sys_t *, char *psz_url );
 static int  Connect( access_t *, int64_t );
+static int Request( access_t *p_access, int64_t i_tell );
 
 /*****************************************************************************
  * Open:
@@ -201,6 +212,7 @@ static int Open( vlc_object_t *p_this )
     p_sys->psz_icy_name = NULL;
     p_sys->psz_icy_genre = NULL;
     p_sys->psz_icy_title = NULL;
+    p_sys->i_remaining = 0;
 
     /* Parse URI */
     ParseURL( p_sys, p_access->psz_path );
@@ -269,6 +281,7 @@ static int Open( vlc_object_t *p_this )
     }
 
     p_sys->b_reconnect = var_CreateGetBool( p_access, "http-reconnect" );
+    p_sys->b_continuous = var_CreateGetBool( p_access, "http-continuous" );
 
     /* Connect */
     if( Connect( p_access, 0 ) )
@@ -420,6 +433,7 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
             return 0;
         }
     }
+
     if( p_sys->b_chunked )
     {
         if( p_sys->i_chunk < 0 )
@@ -454,11 +468,24 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
         }
     }
 
+    if( p_sys->b_continuous && i_len > p_sys->i_remaining )
+    {
+        /* Only ask for the remaining length */
+        int i_new_len = p_sys->i_remaining;
+        if( i_new_len == 0 )
+        {
+            Request( p_access, 0 );
+            i_read = Read( p_access, p_buffer, i_len );
+            return i_read;
+        }
+        i_len = i_new_len;
+    }
+
     if( p_sys->i_icy_meta > 0 && p_access->info.i_pos > 0 )
     {
-        int64_t i_next = p_sys->i_icy_meta - 
+        int64_t i_next = p_sys->i_icy_meta -
                                     p_access->info.i_pos % p_sys->i_icy_meta;
-        
+
         if( i_next == p_sys->i_icy_meta )
         {
             if( ReadICYMeta( p_access ) )
@@ -472,6 +499,7 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
     }
 
     i_read = net_Read( p_access, p_sys->fd, NULL, p_buffer, i_len, VLC_FALSE );
+
     if( i_read > 0 )
     {
         p_access->info.i_pos += i_read;
@@ -489,6 +517,13 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
     }
     else if( i_read == 0 )
     {
+        if( p_sys->b_continuous )
+        {
+            Request( p_access, 0 );
+            p_sys->b_continuous = VLC_FALSE;
+            i_read = Read( p_access, p_buffer, i_len );
+            p_sys->b_continuous = VLC_TRUE;
+        }
         if( p_sys->b_reconnect )
         {
             msg_Dbg( p_access, "got disconnected, trying to reconnect" );
@@ -508,6 +543,11 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len )
         if( i_read == 0 ) p_access->info.b_eof = VLC_TRUE;
     }
 
+    if( p_sys->b_continuous )
+    {
+        p_sys->i_remaining -= i_read;
+    }
+
     return i_read;
 }
 
@@ -760,6 +800,14 @@ static int Connect( access_t *p_access, int64_t i_tell )
         return VLC_EGENERIC;
     }
 
+    return Request( p_access,i_tell );
+}
+
+
+static int Request( access_t *p_access, int64_t i_tell )
+{
+    access_sys_t   *p_sys = p_access->p_sys;
+    char           *psz;
     if( p_sys->b_proxy )
     {
         if( p_sys->url.psz_path )
@@ -792,7 +840,7 @@ static int Connect( access_t *p_access, int64_t i_tell )
                         p_sys->url.i_port );
         }
         else
-        {        
+        {
             net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
                         "GET %s HTTP/1.%d\r\nHost: %s\r\n",
                         psz_path, p_sys->i_version, p_sys->url.psz_host );
@@ -807,6 +855,7 @@ static int Connect( access_t *p_access, int64_t i_tell )
         net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
                     "Range: bytes="I64Fd"-\r\n", i_tell );
     }
+
     /* Authentification */
     if( p_sys->psz_user && *p_sys->psz_user )
     {
@@ -827,7 +876,17 @@ static int Connect( access_t *p_access, int64_t i_tell )
     net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "Icy-MetaData: 1\r\n" );
 
 
-    net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "Connection: Close\r\n");
+    if( p_sys->b_continuous && p_sys->i_version == 1 )
+    {
+        net_Printf( VLC_OBJECT( p_access ), p_sys->fd, NULL,
+                    "Connection: keep-alive\r\n" );
+    }
+    else
+    {
+        net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL,
+                    "Connection: Close\r\n");
+        p_sys->b_continuous = VLC_FALSE;
+    }
 
     if( net_Printf( VLC_OBJECT(p_access), p_sys->fd, NULL, "\r\n" ) < 0 )
     {
@@ -907,8 +966,17 @@ static int Connect( access_t *p_access, int64_t i_tell )
 
         if( !strcasecmp( psz, "Content-Length" ) )
         {
-            p_access->info.i_size = i_tell + atoll( p );
-            msg_Dbg( p_access, "stream size="I64Fd, p_access->info.i_size );
+            if( p_sys->b_continuous )
+            {
+                p_access->info.i_size = -1;
+                msg_Dbg( p_access, "this frame size="I64Fd, atoll(p ) );
+                p_sys->i_remaining = atoll( p );
+            }
+            else
+            {
+                p_access->info.i_size = i_tell + atoll( p );
+                msg_Dbg( p_access, "stream size="I64Fd, p_access->info.i_size );
+            }
         }
         else if( !strcasecmp( psz, "Location" ) )
         {
@@ -924,7 +992,7 @@ static int Connect( access_t *p_access, int64_t i_tell )
         else if( !strcasecmp( psz, "Pragma" ) )
         {
             if( !strcasecmp( psz, "Pragma: features" ) )
-               p_sys->b_mms = VLC_TRUE;
+                p_sys->b_mms = VLC_TRUE;
             if( p_sys->psz_pragma ) free( p_sys->psz_pragma );
             p_sys->psz_pragma = strdup( p );
             msg_Dbg( p_access, "Pragma: %s", p_sys->psz_pragma );
@@ -935,11 +1003,12 @@ static int Connect( access_t *p_access, int64_t i_tell )
             if( !strncasecmp( p, "Icecast", 7 ) ||
                 !strncasecmp( p, "Nanocaster", 10 ) )
             {
-                /* Remember if this is Icecast 
-                 * we need to force mp3 in some cases without breaking autodetection */
+                /* Remember if this is Icecast
+                 * we need to force mp3 in some cases without breaking
+                 *  autodetection */
 
-                /* Let live365 streams (nanocaster) piggyback on the icecast routine. 
-                 * They look very similar */
+                /* Let live 65 streams (nanocaster) piggyback on the icecast
+                 * routine. They look very similar */
 
                 p_sys->b_reconnect = VLC_TRUE;
                 p_sys->b_pace_control = VLC_FALSE;
index 9650d0bcdc15707dd46b7d9f36257e63fc53e46d..30e272ed09fcaaeaf6df471088ea827eb88f5879 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "xtag.h"
 
-#undef CMML_DEBUG
+#undef  CMML_DEBUG
 
 /*****************************************************************************
  * decoder_sys_t : decoder descriptor
@@ -50,12 +50,12 @@ struct decoder_sys_t
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int  OpenDecoder   ( vlc_object_t * );
-static void CloseDecoder  ( vlc_object_t * );
+static int           OpenDecoder   ( vlc_object_t * );
+static void          CloseDecoder  ( vlc_object_t * );
 
-static void DecodeBlock   ( decoder_t *, block_t ** );
+static subpicture_t *DecodeBlock   ( decoder_t *, block_t ** );
 
-static void ParseText     ( decoder_t *, block_t * );
+static void          ParseText     ( decoder_t *, block_t * );
 
 /*****************************************************************************
  * Exported prototypes
@@ -140,17 +140,32 @@ static int OpenDecoder( vlc_object_t *p_this )
  ****************************************************************************
  * This function must be fed with complete subtitles units.
  ****************************************************************************/
-static void DecodeBlock( decoder_t *p_dec, block_t **pp_block )
+static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
+    subpicture_t *p_spu;
+
     if( !pp_block || *pp_block == NULL )
     {
-        return;
+        return NULL;
     }
 
     ParseText( p_dec, *pp_block );
 
     block_Release( *pp_block );
     *pp_block = NULL;
+
+    /* allocate an empty subpicture to return.  the actual subpicture
+     * displaying is done in the DisplayAnchor function in intf.c (called from
+     * DisplayPendingAnchor, which in turn is called from the main RunIntf
+     * loop). */
+    p_spu = p_dec->pf_spu_buffer_new( p_dec );
+    if( !p_spu )
+    {
+        msg_Dbg( p_dec, "couldn't allocate new subpicture" );
+        return NULL;
+    }
+
+    return p_spu;
 }
 
 /*****************************************************************************
index f30108b826c2e846b9c30e00acabfd31ab56bde4..e409851d3a11be40fab010428526b7a026159d18 100644 (file)
@@ -53,7 +53,6 @@
 #undef  CMML_INTF_USE_TIMED_URIS
 
 #undef  CMML_INTF_DEBUG
-#undef  CMML_INTF_SUBPICTURE_DEBUG
 #undef  CMML_INTF_HISTORY_DEBUG
 
 /*****************************************************************************
@@ -149,10 +148,11 @@ void E_(CloseIntf) ( vlc_object_t *p_this )
     msg_Dbg( p_intf, "freeing CMML interface" );
 #endif
 
-    /* Erase the anchor text description from the video output if it exists */
+    /* erase the anchor text description from the video output if it exists */
     p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
     if( p_vout )
     {
+        /* enable CMML as a subtitle track */
         spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR, DEFAULT_CHAN );
         vlc_object_release( p_vout );
     }
@@ -160,7 +160,7 @@ void E_(CloseIntf) ( vlc_object_t *p_this )
     var_DelCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
 
     vlc_object_release( p_intf->p_sys->p_cmml_decoder );
-   
+
     free( p_intf->p_sys );
 }
 
@@ -484,7 +484,7 @@ static void FollowAnchor ( intf_thread_t *p_intf )
             history_t *p_history = NULL;
             history_item_t *p_history_item = NULL;
             char *psz_timed_url;
-            
+
             p_history = GetHistory( p_playlist );
 
             /* create history item */
@@ -821,9 +821,8 @@ static int DisplayAnchor( intf_thread_t *p_intf,
 
         if( psz_anchor_url )
         {
-            /* Should display subtitle underlined and in blue,
-             * but it looks like VLC doesn't implement any
-             * text styles yet.  D'oh! */
+            /* Should display subtitle underlined and in blue, but it looks
+             * like VLC doesn't implement any text styles yet.  D'oh! */
             p_style = &blue_with_underline;
 
         }
@@ -836,11 +835,6 @@ static int DisplayAnchor( intf_thread_t *p_intf,
                 i_margin_h, i_margin_v, i_now, 0 ) == VLC_SUCCESS )
         {
             /* Displayed successfully */
-#ifdef CMML_INTF_SUBPICTURE_DEBUG
-            msg_Dbg( p_intf, "subpicture created at (%d, %d) (%d, %d)",
-                     p_subpicture->i_x, p_subpicture->i_y,
-                     p_subpicture->i_width, p_subpicture->i_height );
-#endif
         }
         else
         {
index 666a2c9233373efaa470708dbd04fa67cddfcaf9..fd36bd71b68ae189d8c97db3443f5b49eb9f3558 100755 (executable)
@@ -463,8 +463,8 @@ static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
             return NULL;
         }
 
-        i_ret = speex_decode( p_sys->p_state, &p_sys->bits,
-                              (int16_t *)p_aout_buffer->p_buffer );
+        i_ret = speex_decode_int( p_sys->p_state, &p_sys->bits,
+                                  (int16_t *)p_aout_buffer->p_buffer );
         if( i_ret == -1 )
         {
             /* End of stream */
@@ -483,8 +483,9 @@ static aout_buffer_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket )
         }
 
         if( p_sys->p_header->nb_channels == 2 )
-            speex_decode_stereo( (int16_t *)p_aout_buffer->p_buffer,
-                                 p_sys->p_header->frame_size, &p_sys->stereo );
+            speex_decode_stereo_int( (int16_t *)p_aout_buffer->p_buffer,
+                                     p_sys->p_header->frame_size,
+                                     &p_sys->stereo );
 
         /* Date management */
         p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
@@ -744,15 +745,15 @@ static block_t *Encode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
 
         /* Encode current frame */
         if( p_enc->fmt_in.audio.i_channels == 2 )
-            speex_encode_stereo( p_samples, p_sys->i_frame_length,
-                                 &p_sys->bits );
+            speex_encode_stereo_int( p_samples, p_sys->i_frame_length,
+                                     &p_sys->bits );
 
 #if 0
         if( p_sys->preprocess )
             speex_preprocess( p_sys->preprocess, p_samples, NULL );
 #endif
 
-        speex_encode( p_sys->p_state, p_samples, &p_sys->bits );
+        speex_encode_int( p_sys->p_state, p_samples, &p_sys->bits );
 
         p_buffer += p_sys->i_frame_size;
         p_sys->i_samples_delay -= p_sys->i_frame_length;
index 0cad26d06df43099adfec4bd4bb079b3f2f0a635..75b29458f17e17d9a3c25337c7d438b8dbcc69d6 100644 (file)
@@ -65,6 +65,7 @@ struct demux_sys_t
 
     vlc_bool_t      b_still;
     mtime_t         i_still_end;
+    mtime_t         i_still_length;
 
     mtime_t         i_time;
     mtime_t         i_frame_length;
@@ -75,7 +76,7 @@ struct demux_sys_t
 };
 
 /*****************************************************************************
- * Peek: Helper function to peek data with incremental size. 
+ * Peek: Helper function to peek data with incremental size.
  * \return VLC_FALSE if peek no more data, VLC_TRUE otherwise.
  *****************************************************************************/
 static vlc_bool_t Peek( demux_t *p_demux, vlc_bool_t b_first )
@@ -277,7 +278,7 @@ static int SendBlock( demux_t *p_demux, int i )
 
     if( p_sys->b_still )
     {
-        p_sys->i_still_end = mdate() + I64C(5000000);
+        p_sys->i_still_end = mdate() + p_sys->i_still_length;
     }
 
     return 1;
@@ -327,6 +328,11 @@ static int Open( vlc_object_t * p_this )
         goto error;
     }
 
+
+    var_Create( p_demux, "mjpeg-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
+    var_Get( p_demux, "mjpeg-fps", &val );
+    p_sys->i_frame_length = 0;
+
     /* Check for jpeg file extension */
     p_sys->b_still = VLC_FALSE;
     p_sys->i_still_end = 0;
@@ -335,12 +341,17 @@ static int Open( vlc_object_t * p_this )
                      !strcasecmp( psz_ext, ".jpg" ) ) )
     {
         p_sys->b_still = VLC_TRUE;
+        if( val.f_float)
+        {
+            p_sys->i_still_length =1000000.0 / val.f_float;
+        }
+        else
+        {
+            /* Defaults to 1fps */
+            p_sys->i_still_length = 1000000;
+        }
     }
-
-    var_Create( p_demux, "mjpeg-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
-    var_Get( p_demux, "mjpeg-fps", &val );
-    p_sys->i_frame_length = 0;
-    if( val.f_float )
+    else if ( val.f_float )
     {
         p_sys->i_frame_length = 1000000.0 / val.f_float;
     }
@@ -373,7 +384,7 @@ static int MjpgDemux( demux_t *p_demux )
     }
     else if( p_sys->b_still && p_sys->i_still_end )
     {
-        msleep( 40000 );
+        msleep( 400 );
         return 1;
     }
 
index e3392df8baba5f320d52cb4aa61611d62dcd73df..bbe3484741cfb33120e79f231a2b488fc747eae5 100644 (file)
@@ -1338,6 +1338,13 @@ static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
 
             p_stream->b_force_backup = 1;
         }
+        else if( !strncmp(content_type_string, "audio/x-speex", 14) )
+        {
+            p_stream->fmt.i_cat = AUDIO_ES;
+            p_stream->fmt.i_codec = VLC_FOURCC( 's','p','x',' ' );
+
+            p_stream->b_force_backup = 1;
+        }
         else if( !strncmp(content_type_string, "video/x-theora", 14) )
         {
             p_stream->fmt.i_cat = VIDEO_ES;
index 7e752ed4f11c32b85e5a4a8b6312f1b9c68ba6b4..0510c1f69fd83531ac91431e425158f1969a6333 100644 (file)
@@ -30,24 +30,18 @@ class OSGraphics;
 
 
 /// Class to handle a video output window
-class VoutWindow: public GenericWindow
+class VoutWindow: private GenericWindow
 {
     public:
         VoutWindow( intf_thread_t *pIntf, int xPos, int yPos,
                     bool dragDrop, bool playOnDrop, GenericWindow &rParent );
         virtual ~VoutWindow();
 
-        /// These methods are redefined here to make them public
+        /// Make some functions public
         //@{
-        /// Show the window
-        virtual void show() { GenericWindow::show(); }
-
-        /// Hide the window
-        virtual void hide() { GenericWindow::hide(); }
-
-        /// Move the window
-        virtual void move( int left, int top )
-            { GenericWindow::move( left, top ); }
+        using GenericWindow::show;
+        using GenericWindow::hide;
+        using GenericWindow::move;
         //@}
 
         /// Resize the window
index 0a212b9eb3b98789ad61c2aa961ec92da27a7dc6..8c12d31b169296909a43d1462672a0bbda9bce97 100644 (file)
@@ -223,22 +223,6 @@ void ItemInfoDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
     p_item->input.psz_uri = strdup( uri_text->GetLineText(0).mb_str() );
     playlist_ItemAddInfo( p_item,"General","Author",
                             author_text->GetLineText(0).mb_str() );
-    vlc_bool_t b_old_enabled = p_item->b_enabled;
-
-    playlist_t * p_playlist =
-          (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                       FIND_ANYWHERE );
-    if( p_playlist != NULL )
-    {
-        if( b_old_enabled == VLC_FALSE && enabled_checkbox->IsChecked() )
-            p_playlist->i_enabled ++;
-        else if( b_old_enabled == VLC_TRUE && !enabled_checkbox->IsChecked() )
-            p_playlist->i_enabled --;
-
-        vlc_object_release( p_playlist );
-    }
-
-    p_item->b_enabled = enabled_checkbox->IsChecked() ? VLC_TRUE : VLC_FALSE ;
     vlc_mutex_unlock( &p_item->input.lock );
     EndModal( wxID_OK );
 }
index f2ceddcf21a12cb6beee1078794c15b16b9e7bd6..e5d33244af1f6642c8156633fb6f1164dc509b74 100644 (file)
@@ -76,8 +76,6 @@ enum
 
     SortTitle_Event,
     RSortTitle_Event,
-    SortAuthor_Event,
-    RSortAuthor_Event,
     Randomize_Event,
 
     EnableSelection_Event,
@@ -90,10 +88,6 @@ enum
     Repeat_Event,
     SelectAll_Event,
 
-    Up_Event,
-    Down_Event,
-    Infos_Event,
-
     PopupPlay_Event,
     PopupPlayThis_Event,
     PopupSort_Event,
@@ -137,8 +131,6 @@ BEGIN_EVENT_TABLE(Playlist, wxFrame)
 
     EVT_MENU(SortTitle_Event, Playlist::OnSort)
     EVT_MENU(RSortTitle_Event, Playlist::OnSort)
-    EVT_MENU(SortAuthor_Event, Playlist::OnSort)
-    EVT_MENU(RSortAuthor_Event, Playlist::OnSort)
 
     EVT_MENU(Randomize_Event, Playlist::OnSort)
 
@@ -147,7 +139,6 @@ BEGIN_EVENT_TABLE(Playlist, wxFrame)
     EVT_MENU(InvertSelection_Event, Playlist::OnInvertSelection)
     EVT_MENU(DeleteSelection_Event, Playlist::OnDeleteSelection)
     EVT_MENU(SelectAll_Event, Playlist::OnSelectAll)
-    EVT_MENU(Infos_Event, Playlist::OnInfos)
 
     EVT_MENU_OPEN( Playlist::OnMenuOpen )
     EVT_MENU( -1, Playlist::OnMenuEvent )
@@ -172,10 +163,6 @@ BEGIN_EVENT_TABLE(Playlist, wxFrame)
     /* Button events */
     EVT_BUTTON( Search_Event, Playlist::OnSearch)
     EVT_BUTTON( Save_Event, Playlist::OnSave)
-    EVT_BUTTON( Infos_Event, Playlist::OnInfos)
-
-    EVT_BUTTON( Up_Event, Playlist::OnUp)
-    EVT_BUTTON( Down_Event, Playlist::OnDown)
 
     EVT_TEXT(SearchText_Event, Playlist::OnSearchTextChange)
 
@@ -222,9 +209,9 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     p_sd_menu = SDMenu();
 
     i_current_view = VIEW_SIMPLE;
+    b_changed_view = VLC_FALSE;
 
     i_title_sorted = 0;
-    i_author_sorted = 0;
     i_group_sorted = 0;
     i_duration_sorted = 0;
 
@@ -251,9 +238,6 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     sort_menu->Append( SortTitle_Event, wxU(_("Sort by &title")) );
     sort_menu->Append( RSortTitle_Event, wxU(_("&Reverse sort by title")) );
     sort_menu->AppendSeparator();
-    sort_menu->Append( SortAuthor_Event, wxU(_("Sort by &author")) );
-    sort_menu->Append( RSortAuthor_Event, wxU(_("Reverse sort by author")) );
-    sort_menu->AppendSeparator();
     sort_menu->Append( Randomize_Event, wxU(_("&Shuffle Playlist")) );
 
     /* Create our "Selection" menu */
@@ -404,11 +388,6 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     Rebuild();
 }
 
-void Playlist::OnSize( wxSizeEvent& event)
-{
-    event.Skip();
-}
-
 Playlist::~Playlist()
 {
     playlist_t *p_playlist =
@@ -426,8 +405,10 @@ Playlist::~Playlist()
 }
 
 /**********************************************************************
- * Update one playlist item
+ * Update functions
  **********************************************************************/
+
+/* Update a node */
 void Playlist::UpdateNode( playlist_t *p_playlist, playlist_item_t *p_node,
                            wxTreeItemId node )
 {
@@ -457,6 +438,7 @@ void Playlist::UpdateNode( playlist_t *p_playlist, playlist_item_t *p_node,
     }
 
 }
+
 /* Creates the node p_node as last child of parent */
 void Playlist::CreateNode( playlist_t *p_playlist, playlist_item_t *p_node,
                            wxTreeItemId parent )
@@ -470,6 +452,7 @@ void Playlist::CreateNode( playlist_t *p_playlist, playlist_item_t *p_node,
     UpdateNodeChildren( p_playlist, p_node, node );
 }
 
+/* Update all children (recursively) of this node */
 void Playlist::UpdateNodeChildren( playlist_t *p_playlist,
                                    playlist_item_t *p_node,
                                    wxTreeItemId node )
@@ -498,97 +481,62 @@ void Playlist::UpdateNodeChildren( playlist_t *p_playlist,
     }
 }
 
-wxTreeItemId Playlist::FindItem( wxTreeItemId root, playlist_item_t *p_item )
+/* Set current item */
+void Playlist::SetCurrentItem( wxTreeItemId item )
 {
-    long cookie;
-    PlaylistItem *p_wxcurrent;
-    wxTreeItemId search;
-    wxTreeItemId item = treectrl->GetFirstChild( root, cookie );
-    wxTreeItemId child;
-
-    p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( root );
-
-    if( p_wxcurrent->p_item == p_item )
+    if( item.IsOk() )
     {
-        return root;
+        treectrl->SetItemBold( item, true );
+        treectrl->EnsureVisible( item );
     }
+}
+
+/* Update an item in the tree */
+void Playlist::UpdateTreeItem( playlist_t *p_playlist, wxTreeItemId item )
+{
+    playlist_item_t *p_item  =
+            ((PlaylistItem *)treectrl->GetItemData( item ))->p_item;
 
     if( !p_item )
     {
-        wxTreeItemId dummy;
-        return dummy;
+        return;
     }
 
-    while( item.IsOk() )
-    {
-        p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( item );
-        if( p_wxcurrent->p_item == p_item )
-        {
-            return item;
-        }
-        if( treectrl->ItemHasChildren( item ) )
-        {
-            wxTreeItemId search = FindItem( item, p_item );
-            if( search.IsOk() )
-            {
-                return search;
-            }
-        }
-        item = treectrl->GetNextChild( root, cookie);
-    }
-    /* Not found */
-    wxTreeItemId dummy;
-    return dummy;
-}
+    wxString msg;
+    char *psz_author = playlist_ItemGetInfo( p_item, _("Meta-information"),
+                                                     _("Artist"));
+    char psz_duration[MSTRTIME_MAX_SIZE];
+    mtime_t dur = p_item->input.i_duration;
 
-wxTreeItemId Playlist::FindItemByName( wxTreeItemId root, wxString search_string, wxTreeItemId current, vlc_bool_t *pb_current_found )
-{
-    long cookie;
-    PlaylistItem *p_wxcurrent;
-    wxTreeItemId search;
-    wxTreeItemId item = treectrl->GetFirstChild( root, cookie );
-    wxTreeItemId child;
+    if( dur != -1 )
+        secstotimestr( psz_duration, dur/1000000 );
+    else
+        memcpy( psz_duration, "-:--:--", sizeof("-:--:--") );
 
-    while( item.IsOk() )
+    if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE )
     {
-        if( treectrl->GetItemText( item).Lower().Contains(
-                                                 search_string.Lower() ) )
-        {
-            if( !current.IsOk() || *pb_current_found == VLC_TRUE )
-            {
-                return item;
-            }
-            else if( current.IsOk() && item == current )
-            {
-                *pb_current_found = VLC_TRUE;
-            }
-        }
-        if( treectrl->ItemHasChildren( item ) )
-        {
-            wxTreeItemId search = FindItemByName( item, search_string, current,
-                                                  pb_current_found );
-            if( search.IsOk() )
-            {
-                return search;
-            }
-        }
-        item = treectrl->GetNextChild( root, cookie);
+        msg.Printf( wxString( wxL2U( p_item->input.psz_name ) ) + wxU( " ( ") +
+                    wxString(wxL2U(psz_duration ) ) + wxU( ")") );
     }
-    /* Not found */
-    wxTreeItemId dummy;
-    return dummy;
-}
-
+    else
+    {
+        msg.Printf( wxString(wxU( psz_author )) + wxT(" - ") +
+                    wxString(wxL2U(p_item->input.psz_name)) + wxU( " ( ") +
+                    wxString(wxL2U(psz_duration ) ) + wxU( ")") );
+    }
+    treectrl->SetItemText( item , msg );
 
-void Playlist::SetCurrentItem( wxTreeItemId item )
-{
-    if( item.IsOk() )
+    if( p_playlist->status.p_item == p_item )
     {
-        treectrl->SetItemBold( item, true );
-        treectrl->EnsureVisible( item );
+        SetCurrentItem( item );
+    }
+    else
+    {
+        treectrl->SetItemBold( item, false );
     }
 }
 
+/* Process a AppendItem request */
 void Playlist::AppendItem( wxCommandEvent& event )
 {
     playlist_add_t *p_add = (playlist_add_t *)event.GetClientData();
@@ -596,6 +544,7 @@ void Playlist::AppendItem( wxCommandEvent& event )
     playlist_t *p_playlist =
         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                        FIND_ANYWHERE );
+    wxTreeItemId item,node;
     if( p_playlist == NULL )
     {
         event.Skip();
@@ -604,22 +553,18 @@ void Playlist::AppendItem( wxCommandEvent& event )
 
     if( p_add->i_view != i_current_view )
     {
-        vlc_object_release( p_playlist );
-        event.Skip();
-        return;
+        goto update;
     }
 
-    wxTreeItemId node = FindItem( treectrl->GetRootItem(), p_add->p_node );
+    node = FindItem( treectrl->GetRootItem(), p_add->p_node );
     if( !node.IsOk() )
     {
-        vlc_object_release( p_playlist );
-        event.Skip();
-        return;
+        goto update;
     }
 
-    wxTreeItemId item = treectrl->AppendItem( node,
-                           wxL2U( p_add->p_item->input.psz_name ), -1,-1,
-                           new PlaylistItem( p_add->p_item ) );
+    item = treectrl->AppendItem( node,
+                                 wxL2U( p_add->p_item->input.psz_name ), -1,-1,
+                                 new PlaylistItem( p_add->p_item ) );
     treectrl->SetItemImage( item, p_add->p_item->input.i_type );
 
     if( item.IsOk() && p_add->p_item->i_children == -1 )
@@ -627,13 +572,33 @@ void Playlist::AppendItem( wxCommandEvent& event )
         UpdateTreeItem( p_playlist, item );
     }
 
-    statusbar->SetStatusText( wxString::Format( wxU(_(
-                              "%i items in playlist")),
-                              p_playlist->i_size ), 0 );
+update:
+    int i_count = CountItems( treectrl->GetRootItem());
+    if( i_count != p_playlist->i_size )
+    {
+        statusbar->SetStatusText( wxString::Format( wxU(_(
+                                  "%i items in playlist (%i not shown)")),
+                                  p_playlist->i_size,
+                                  p_playlist->i_size - i_count ) );
+        if( !b_changed_view )
+        {
+            i_current_view = VIEW_CATEGORY;
+            b_changed_view = VLC_TRUE;
+            b_need_update = VLC_TRUE;
+        }
+    }
+    else
+    {
+        statusbar->SetStatusText( wxString::Format( wxU(_(
+                                  "%i items in playlist")),
+                                  p_playlist->i_size ), 0 );
+    }
 
     vlc_object_release( p_playlist );
+    return;
 }
 
+/* Process a updateitem request */
 void Playlist::UpdateItem( int i )
 {
     if( i < 0 ) return; /* Sanity check */
@@ -660,57 +625,112 @@ void Playlist::UpdateItem( int i )
     vlc_object_release(p_playlist);
 }
 
-void Playlist::UpdateTreeItem( playlist_t *p_playlist, wxTreeItemId item )
-{
-    playlist_item_t *p_item  =
-            ((PlaylistItem *)treectrl->GetItemData( item ))->p_item;
 
-    if( !p_item )
-    {
-        return;
-    }
 
-    wxString msg;
-    char *psz_author = playlist_ItemGetInfo( p_item, _("Meta-information"),
-                                                     _("Artist"));
-    char psz_duration[MSTRTIME_MAX_SIZE];
-    mtime_t dur = p_item->input.i_duration;
+/**********************************************************************
+ * Search functions (internal
+ **********************************************************************/
 
-    if( dur != -1 )
-        secstotimestr( psz_duration, dur/1000000 );
-    else
-        memcpy( psz_duration, "-:--:--", sizeof("-:--:--") );
+/* Find a wxItem from a playlist_item */
+wxTreeItemId Playlist::FindItem( wxTreeItemId root, playlist_item_t *p_item )
+{
+    long cookie;
+    PlaylistItem *p_wxcurrent;
+    wxTreeItemId search;
+    wxTreeItemId item = treectrl->GetFirstChild( root, cookie );
+    wxTreeItemId child;
 
-    if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE )
+    p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( root );
+
+    if( p_wxcurrent->p_item == p_item )
     {
-        msg.Printf( wxString( wxL2U( p_item->input.psz_name ) ) + wxU( " ( ") +
-                    wxString(wxL2U(psz_duration ) ) + wxU( ")") );
+        return root;
     }
-    else
+
+    if( !p_item )
     {
-        msg.Printf( wxString(wxU( psz_author )) + wxT(" - ") +
-                    wxString(wxL2U(p_item->input.psz_name)) + wxU( " ( ") +
-                    wxString(wxL2U(psz_duration ) ) + wxU( ")") );
+        wxTreeItemId dummy;
+        return dummy;
     }
-    treectrl->SetItemText( item , msg );
 
-    if( p_playlist->status.p_item == p_item )
+    while( item.IsOk() )
     {
-        SetCurrentItem( item );
+        p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( item );
+        if( p_wxcurrent->p_item == p_item )
+        {
+            return item;
+        }
+        if( treectrl->ItemHasChildren( item ) )
+        {
+            wxTreeItemId search = FindItem( item, p_item );
+            if( search.IsOk() )
+            {
+                return search;
+            }
+        }
+        item = treectrl->GetNextChild( root, cookie );
     }
-    else
+    /* Not found */
+    wxTreeItemId dummy;
+    return dummy;
+}
+
+int Playlist::CountItems( wxTreeItemId root )
+{
+    long cookie;
+    int count = 0;
+    wxTreeItemId item = treectrl->GetFirstChild( root, cookie );
+
+    while( item.IsOk() )
     {
-        treectrl->SetItemBold( item, false );
+        if( treectrl->ItemHasChildren( item ) )
+        {
+            count += CountItems( item );
+        }
+        else if( ( (PlaylistItem *)treectrl->GetItemData( item ) )->
+                            p_item->i_children == -1 )
+            count++;
+        item = treectrl->GetNextChild( root, cookie );
     }
-#if 0
-    if( p_item->b_enabled == VLC_FALSE )
+    return count;
+}
+
+/* Find a wxItem from a name (from current) */
+wxTreeItemId Playlist::FindItemByName( wxTreeItemId root, wxString search_string, wxTreeItemId current, vlc_bool_t *pb_current_found )
+{
+    long cookie;
+    wxTreeItemId search;
+    wxTreeItemId item = treectrl->GetFirstChild( root, cookie );
+    wxTreeItemId child;
+
+    while( item.IsOk() )
     {
-        wxListItem listitem;
-        listitem.m_itemId = i;
-        listitem.SetTextColour( *wxLIGHT_GREY);
-        listview->SetItem(listitem);
+        if( treectrl->GetItemText( item).Lower().Contains(
+                                                 search_string.Lower() ) )
+        {
+            if( !current.IsOk() || *pb_current_found == VLC_TRUE )
+            {
+                return item;
+            }
+            else if( current.IsOk() && item == current )
+            {
+                *pb_current_found = VLC_TRUE;
+            }
+        }
+        if( treectrl->ItemHasChildren( item ) )
+        {
+            wxTreeItemId search = FindItemByName( item, search_string, current,
+                                                  pb_current_found );
+            if( search.IsOk() )
+            {
+                return search;
+            }
+        }
+        item = treectrl->GetNextChild( root, cookie);
     }
-#endif
+    /* Not found */
+    wxTreeItemId dummy;
+    return dummy;
 }
 
 /**********************************************************************
@@ -726,6 +746,13 @@ void Playlist::Rebuild()
     {
         return;
     }
+    int i_count = CountItems( treectrl->GetRootItem()) ;
+
+    if( i_count > p_playlist->i_size && !b_changed_view )
+    {
+        i_current_view = VIEW_CATEGORY;
+        b_changed_view = VLC_TRUE;
+    }
 
     /* ...and rebuild it */
     vlc_mutex_lock( &p_playlist->object_lock );
@@ -755,38 +782,37 @@ void Playlist::Rebuild()
         item = root;
     }
 
-    SetCurrentItem( item );
-
-/*  GetChildrenCount does count internal nodes :(
-    if( treectrl->GetChildrenCount( root, true ) !=
-        p_playlist->i_size )
+    i_count = CountItems( treectrl->GetRootItem() );
+    if( i_count != p_playlist->i_size )
     {
-        statusbar->SetStatusText( wxString::Format( wxT(_(
+        statusbar->SetStatusText( wxString::Format( wxU(_(
                                   "%i items in playlist (%i not shown)")),
                                   p_playlist->i_size,
-                                  p_playlist->i_size -
-                                  treectrl->GetChildrenCount( root, true ) ) );
+                                  p_playlist->i_size - i_count ) );
     }
     else
     {
-*/
         statusbar->SetStatusText( wxString::Format( wxU(_(
                                   "%i items in playlist")),
                                   p_playlist->i_size ), 0 );
-//    }
+    }
 
+    SetCurrentItem( item );
 
     vlc_mutex_unlock( &p_playlist->object_lock );
 
     vlc_object_release( p_playlist );
 }
 
+
+
 void Playlist::ShowPlaylist( bool show )
 {
     if( show ) Rebuild();
     Show( show );
 }
 
+/* This function is called on a regular basis */
 void Playlist::UpdatePlaylist()
 {
     i_update_counter++;
@@ -832,6 +858,22 @@ void Playlist::DeleteItem( int item_id )
     vlc_object_release( p_playlist );
 }
 
+void Playlist::DeleteNode( playlist_item_t *p_item )
+{
+    playlist_t *p_playlist =
+        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                       FIND_ANYWHERE );
+    if( p_playlist == NULL )
+    {
+        return;
+    }
+
+    playlist_NodeDelete( p_playlist, p_item, VLC_TRUE );
+
+    vlc_object_release( p_playlist );
+}
+
+
 void Playlist::OnClose( wxCommandEvent& WXUNUSED(event) )
 {
     Hide();
@@ -926,53 +968,6 @@ void Playlist::OnAddMRL( wxCommandEvent& WXUNUSED(event) )
 
 }
 
-/********************************************************************
- * Move functions
- ********************************************************************/
-void Playlist::OnUp( wxCommandEvent& event )
-{
-    playlist_t *p_playlist =
-        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                       FIND_ANYWHERE );
-    if( p_playlist == NULL )
-    {
-        return;
-    }
-#if 0
-    /* We use the first selected item, so find it */
-    long i_item = listview->GetNextItem( -1, wxLIST_NEXT_ALL,
-                                         wxLIST_STATE_SELECTED);
-    if( i_item > 0 && i_item < p_playlist->i_size )
-    {
-        playlist_Move( p_playlist, i_item, i_item - 1 );
-        listview->Focus( i_item - 1 );
-    }
-#endif
-    vlc_object_release( p_playlist );
-}
-
-void Playlist::OnDown( wxCommandEvent& event )
-{
-    playlist_t *p_playlist =
-        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                       FIND_ANYWHERE );
-    if( p_playlist == NULL )
-    {
-        return;
-    }
-#if 0
-    /* We use the first selected item, so find it */
-    long i_item = listview->GetNextItem( -1, wxLIST_NEXT_ALL,
-                                         wxLIST_STATE_SELECTED );
-    if( i_item >= 0 && i_item < p_playlist->i_size - 1 )
-    {
-        playlist_Move( p_playlist, i_item, i_item + 2 );
-        listview->Focus( i_item + 1 );
-    }
-#endif
-    vlc_object_release( p_playlist );
-}
-
 /********************************************************************
  * Sorting functions
  ********************************************************************/
@@ -981,35 +976,32 @@ void Playlist::OnSort( wxCommandEvent& event )
     playlist_t *p_playlist =
         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                        FIND_ANYWHERE );
+    PlaylistItem *p_wxitem;
+    p_wxitem = (PlaylistItem *)treectrl->GetItemData( treectrl->GetRootItem() );
+
     if( p_playlist == NULL )
     {
         return;
     }
+    vlc_mutex_lock( &p_playlist->object_lock );
     switch( event.GetId() )
     {
         case SortTitle_Event:
-           playlist_SortTitle( p_playlist, ORDER_NORMAL );
-           break;
+            playlist_RecursiveNodeSort( p_playlist, p_wxitem->p_item,
+                                        SORT_TITLE_NODES_FIRST, ORDER_NORMAL );
+            break;
         case RSortTitle_Event:
-           playlist_SortTitle( p_playlist, ORDER_REVERSE );
-           break;
-        case SortAuthor_Event:
-           playlist_SortAuthor(p_playlist, ORDER_NORMAL );
-           break;
-        case RSortAuthor_Event:
-           playlist_SortAuthor( p_playlist, ORDER_REVERSE );
-           break;
-        case Randomize_Event:
-           playlist_Sort( p_playlist, SORT_RANDOM, ORDER_NORMAL );
-           break;
+            playlist_RecursiveNodeSort( p_playlist, p_wxitem->p_item,
+                                        SORT_TITLE_NODES_FIRST, ORDER_REVERSE );
     }
-    vlc_object_release( p_playlist );
+    vlc_mutex_unlock( &p_playlist->object_lock );
 
+    vlc_object_release( p_playlist );
     Rebuild();
 }
 
 /**********************************************************************
- * Search functions
+ * Search functions (user)
  **********************************************************************/
 void Playlist::OnSearchTextChange( wxCommandEvent& WXUNUSED(event) )
 {
@@ -1045,86 +1037,6 @@ void Playlist::OnSearch( wxCommandEvent& WXUNUSED(event) )
     }
 }
 
-#if 0
-    for( i_current = 0; i_current < listview->GetItemCount(); i_current++ )
-    {
-        if( listview->GetItemState( i_current, wxLIST_STATE_SELECTED ) ==
-              wxLIST_STATE_SELECTED )
-        {
-            i_first = i_current;
-            break;
-        }
-    }
-
-    if( i_first == listview->GetItemCount() )
-    {
-        i_first = -1;
-    }
-
-    for( i_current = i_first + 1; i_current < listview->GetItemCount();
-         i_current++ )
-    {
-        wxListItem listitem;
-        listitem.SetId( i_current );
-        listview->GetItem( listitem );
-        if( listitem.m_text.Lower().Contains( search_string.Lower() ) )
-        {
-            i_item = i_current;
-            b_ok = true;
-            break;
-        }
-        listitem.SetColumn( 1 );
-        listview->GetItem( listitem );
-        if( listitem.m_text.Lower().Contains( search_string.Lower() ) )
-        {
-            i_item = i_current;
-            b_ok = true;
-            break;
-        }
-    }
-    if( !b_ok )
-    {
-        for( i_current = -1 ; i_current < i_first - 1;
-             i_current++ )
-        {
-            wxListItem listitem;
-            listitem.SetId( i_current );
-            listview->GetItem( listitem );
-            if( listitem.m_text.Lower().Contains( search_string.Lower() ) )
-            {
-                i_item = i_current;
-                b_ok = true;
-                break;
-            }
-            listitem.SetColumn( 1 );
-            listview->GetItem( listitem );
-            if( listitem.m_text.Lower().Contains( search_string.Lower() ) )
-            {
-                i_item = i_current;
-                b_ok = true;
-                break;
-            }
-        }
-    }
-
-    if( i_item < 0 || i_item >= listview->GetItemCount() )
-    {
-        return;
-    }
-
-    for( long item = 0; item < listview->GetItemCount(); item++ )
-    {
-        listview->Select( item, FALSE );
-    }
-
-    wxListItem listitem;
-    listitem.SetId(i_item);
-    listitem.m_state = wxLIST_STATE_SELECTED;
-    listview->Select( i_item, TRUE );
-    listview->Focus( i_item );
-}
-#endif
-
 /**********************************************************************
  * Selection functions
  **********************************************************************/
@@ -1146,17 +1058,7 @@ void Playlist::OnEnableSelection( wxCommandEvent& WXUNUSED(event) )
     {
         return;
     }
-#if 0
-    for( long item = listview->GetItemCount() - 1; item >= 0; item-- )
-    {
-        if( listview->IsSelected( item ) )
-        {
-            /*XXX*/
-            playlist_Enable( p_playlist, item );
-            UpdateItem( item );
-        }
-    }
-#endif
+    msg_Warn( p_playlist, "not implemented");
     vlc_object_release( p_playlist);
 }
 
@@ -1169,17 +1071,9 @@ void Playlist::OnDisableSelection( wxCommandEvent& WXUNUSED(event) )
     {
         return;
     }
-#if 0
-    for( long item = listview->GetItemCount() - 1; item >= 0; item-- )
-    {
-        if( listview->IsSelected( item ) )
-        {
-            /*XXX*/
-            playlist_Disable( p_playlist, item );
-            UpdateItem( item );
-        }
-    }
-#endif
+
+    msg_Warn( p_playlist, "not implemented");
+
     vlc_object_release( p_playlist);
 }
 
@@ -1235,6 +1129,9 @@ void Playlist::OnRepeat( wxCommandEvent& event )
     vlc_object_release( p_playlist );
 }
 
+/********************************************************************
+ * Event
+ ********************************************************************/
 void Playlist::OnActivateItem( wxTreeEvent& event )
 {
     playlist_item_t *p_item,*p_node;
@@ -1287,14 +1184,6 @@ void Playlist::OnKeyDown( wxTreeEvent& event )
     }
 }
 
-void Playlist::ShowInfos( int i_item )
-{
-}
-
-void Playlist::OnInfos( wxCommandEvent& WXUNUSED(event) )
-{
-}
-
 void Playlist::OnEnDis( wxCommandEvent& event )
 {
     playlist_t *p_playlist =
@@ -1304,6 +1193,7 @@ void Playlist::OnEnDis( wxCommandEvent& event )
     {
         return;
     }
+    msg_Warn( p_intf, "not implemented" );
     vlc_object_release( p_playlist );
 }
 
@@ -1351,6 +1241,7 @@ void Playlist::OnMenuEvent( wxCommandEvent& event )
 
         if( p_view != NULL )
         {
+            b_changed_view = VLC_TRUE;
             i_current_view = i_new_view;
             playlist_ViewUpdate( p_playlist, i_new_view );
             Rebuild();
@@ -1360,6 +1251,7 @@ void Playlist::OnMenuEvent( wxCommandEvent& event )
         else if( i_new_view >= VIEW_FIRST_SORTED &&
                  i_new_view <= VIEW_LAST_SORTED )
         {
+            b_changed_view = VLC_TRUE;
             playlist_ViewInsert( p_playlist, i_new_view, "View" );
             playlist_ViewUpdate( p_playlist, i_new_view );
 
@@ -1434,7 +1326,6 @@ wxMenu *Playlist::SDMenu()
     {
         return NULL;
     }
-    vlc_value_t val, val_list, text_list;
     p_sd_menu = new wxMenu;
 
     vlc_list_t *p_list = vlc_list_find( p_playlist, VLC_OBJECT_MODULE,
@@ -1543,7 +1434,7 @@ void Playlist::OnPopupDel( wxMenuEvent& event )
     }
     else
     {
-        //DeleteNode( p_wxitem->p_item );
+        DeleteNode( p_wxitem->p_item );
     }
 }
 
index e6fa5f71efcb1fe4c2e7c729b89384a07ade3542..7949d147b9a8b9ff9784b39984ef4c91c9ba5a9f 100644 (file)
@@ -785,40 +785,52 @@ public:
 
 private:
     void DeleteItem( int item );
-    void ShowInfos( int item );
+    void DeleteNode( playlist_item_t *node );
 
     /* Event handlers (these functions should _not_ be virtual) */
 
-    void OnSize( wxSizeEvent &event );
-
     /* Menu Handlers */
     void OnAddFile( wxCommandEvent& event );
     void OnAddDir( wxCommandEvent& event );
     void OnAddMRL( wxCommandEvent& event );
     void OnClose( wxCommandEvent& event );
-    void OnSearch( wxCommandEvent& event );
-    void OnEnDis( wxCommandEvent& event );
-    void OnInfos( wxCommandEvent& event );
-    void OnSearchTextChange( wxCommandEvent& event );
+
+    void OnEnableSelection( wxCommandEvent& event );
+    void OnDisableSelection( wxCommandEvent& event );
+    void OnInvertSelection( wxCommandEvent& event );
+    void OnDeleteSelection( wxCommandEvent& event );
+    void OnSelectAll( wxCommandEvent& event );
+
     void OnOpen( wxCommandEvent& event );
     void OnSave( wxCommandEvent& event );
 
+    /* Search (user) */
+    void OnSearch( wxCommandEvent& event );
+    void OnSearchTextChange( wxCommandEvent& event );
+    wxTextCtrl *search_text;
+    wxButton *search_button;
+    wxTreeItemId search_current;
+
+    void OnEnDis( wxCommandEvent& event );
+
+    /* Sort */
+    int i_sort_mode;
     void OnSort( wxCommandEvent& event );
+    int i_title_sorted;
+    int i_group_sorted;
+    int i_duration_sorted;
 
+    /* Dynamic menus */
     void OnMenuEvent( wxCommandEvent& event );
     void OnMenuOpen( wxMenuEvent& event );
-
+    wxMenu *p_view_menu;
+    wxMenu *p_sd_menu;
     wxMenu *ViewMenu();
     wxMenu *SDMenu();
 
     void OnUp( wxCommandEvent& event);
     void OnDown( wxCommandEvent& event);
 
-    void OnEnableSelection( wxCommandEvent& event );
-    void OnDisableSelection( wxCommandEvent& event );
-    void OnInvertSelection( wxCommandEvent& event );
-    void OnDeleteSelection( wxCommandEvent& event );
-    void OnSelectAll( wxCommandEvent& event );
     void OnRandom( wxCommandEvent& event );
     void OnRepeat( wxCommandEvent& event );
     void OnLoop ( wxCommandEvent& event );
@@ -827,7 +839,11 @@ private:
     void OnKeyDown( wxTreeEvent& event );
     void OnNewGroup( wxCommandEvent& event );
 
-    /* Popup functions */
+    /* Popup  */
+    wxMenu *popup_menu;
+    wxTreeItemId i_popup_item;
+    playlist_item_t *p_popup_item;
+    playlist_item_t *p_popup_parent;
     void OnPopup( wxContextMenuEvent& event );
     void OnPopupPlay( wxMenuEvent& event );
     void OnPopupSort( wxMenuEvent& event );
@@ -840,46 +856,34 @@ private:
     void UpdateNode( playlist_t *, playlist_item_t*, wxTreeItemId );
     void UpdateNodeChildren( playlist_t *, playlist_item_t*, wxTreeItemId );
     void CreateNode( playlist_t *, playlist_item_t*, wxTreeItemId );
+    void UpdateTreeItem( playlist_t *, wxTreeItemId );
+    void SetCurrentItem( wxTreeItemId );
 
+    /* Search (internal) */
+    int CountItems( wxTreeItemId);
     wxTreeItemId FindItem( wxTreeItemId, playlist_item_t * );
-    wxTreeItemId FindItemByName( wxTreeItemId, wxString, wxTreeItemId, vlc_bool_t *);
-    void SetCurrentItem( wxTreeItemId );
-    void UpdateTreeItem( playlist_t *, wxTreeItemId );
+    wxTreeItemId FindItemByName( wxTreeItemId, wxString,
+                                 wxTreeItemId, vlc_bool_t *);
 
     /* Custom events */
     void OnPlaylistEvent( wxCommandEvent& event );
 
-    wxTextCtrl *search_text;
-    wxButton *search_button;
     DECLARE_EVENT_TABLE();
 
-    wxMenu *popup_menu;
-
-    wxMenu *p_view_menu;
-    wxMenu *p_sd_menu;
-
-    char **pp_sds;
 
+    /* Global widgets */
     wxStatusBar *statusbar;
-
     ItemInfoDialog *iteminfo_dialog;
 
-    intf_thread_t *p_intf;
-    wxTreeCtrl *treectrl;
     int i_update_counter;
-    int i_sort_mode;
 
+    intf_thread_t *p_intf;
+    wxTreeCtrl *treectrl;
     int i_current_view;
+    vlc_bool_t b_changed_view;
+    char **pp_sds;
 
-    wxTreeItemId i_popup_item;
-    wxTreeItemId search_current;
-    playlist_item_t *p_popup_item;
-    playlist_item_t *p_popup_parent;
 
-    int i_title_sorted;
-    int i_author_sorted;
-    int i_group_sorted;
-    int i_duration_sorted;
 };
 
 /* ItemInfo Dialog */
@@ -923,7 +927,6 @@ private:
     wxTreeCtrl *info_tree;
     wxTreeItemId info_root;
 
-    wxCheckBox *enabled_checkbox;
 };
 
 
index f39fc4548ac5b846dd20e5f5614be976d9b91aa7..fb1fce3a7210f36f8c8a6e10498e3be9f7a7a0d6 100644 (file)
@@ -738,20 +738,21 @@ static int ParseSAP( services_discovery_t *p_sd, uint8_t *p_buffer, int i_read )
     }
 
     /* Decide whether we should add a playlist item for this SDP */
+    /* Parse connection information (c= & m= ) */
+    if( ParseConnection( VLC_OBJECT(p_sd), p_sdp ) )
+    {
+        p_sdp->psz_uri = NULL;
+    }
 
     /* Multi-media or no-parse -> pass to LIVE.COM */
-    if( p_sdp->i_media > 1 || p_sd->p_sys->b_parse == VLC_FALSE )
+    if( p_sdp->i_media > 1 || ( p_sdp->i_media_type != 14 &&
+                                p_sdp->i_media_type != 32 &&
+                                p_sdp->i_media_type != 33) ||
+        p_sd->p_sys->b_parse == VLC_FALSE )
     {
+        if( p_sdp->psz_uri ) free( p_sdp->psz_uri );
         asprintf( &p_sdp->psz_uri, "sdp://%s", p_sdp->psz_sdp );
     }
-    else
-    {
-        /* Parse connection information (c= & m= ) */
-        if( ParseConnection( VLC_OBJECT(p_sd), p_sdp ) )
-        {
-            p_sdp->psz_uri = NULL;
-        }
-    }
 
     if( p_sdp->psz_uri == NULL ) return VLC_EGENERIC;