*****************************************************************************/
#include "dialogs/playlist.hpp"
#include "dialogs/iteminfo.hpp"
-#include "interface.hpp" // Needed for D&D - TODO: Split
#include "bitmaps/shuffle.xpm"
#include "bitmaps/repeat.xpm"
#include <wx/imaglist.h>
#include <vlc_meta.h>
-#include "charset.h"
+#include "vlc_charset.h"
#define HELP_SHUFFLE N_( "Shuffle" )
#define HELP_LOOP N_( "Repeat All" )
Search_Event,
/* controls */
+ Source_Event,
TreeCtrl_Event,
Browse_Event, /* For export playlist */
MenuDummy_Event = wxID_HIGHEST + 999,
FirstView_Event = wxID_HIGHEST + 1000,
+ CategoryView_Event, OneLevelView_Event,
LastView_Event = wxID_HIGHEST + 1100,
FirstSD_Event = wxID_HIGHEST + 2000,
EVT_MENU( PopupInfo_Event, Playlist::OnPopupInfo)
EVT_MENU( PopupAddNode_Event, Playlist::OnPopupAddNode)
+ /* Source selector */
+ EVT_LIST_ITEM_SELECTED( Source_Event, Playlist::OnSourceSelected )
/* Tree control events */
EVT_TREE_ITEM_ACTIVATED( TreeCtrl_Event, Playlist::OnActivateItem )
EVT_TREE_KEY_DOWN( -1, Playlist::OnKeyDown )
public:
PlaylistItem( playlist_item_t *p_item ) : wxTreeItemData()
{
- i_id = p_item->input.i_id;
+ i_id = p_item->i_id;
+ i_input_id = p_item->p_input->i_id;
}
protected:
+ int i_input_id;
int i_id;
friend class Playlist;
friend class PlaylistFileDropTarget;
pp_sds = NULL;
i_update_counter = 0;
i_sort_mode = MODE_NONE;
- b_need_update = VLC_FALSE;
+ b_need_update = false;
i_items_to_append = 0;
- p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
+ p_playlist = pl_Yield( p_intf );
if( p_playlist == NULL ) return;
SetIcon( *p_intf->p_sys->p_icon );
p_view_menu = NULL;
p_sd_menu = SDMenu();
- i_current_view = VIEW_CATEGORY;
- b_changed_view = VLC_FALSE;
+ p_current_viewroot = p_playlist->p_root_category;
+ p_current_treeroot = NULL;
i_title_sorted = 0;
i_group_sorted = 0;
wxMenu *manage_menu = new wxMenu;
manage_menu->Append( AddFile_Event, wxU(_("&Simple Add File...")) );
manage_menu->Append( AddDir_Event, wxU(_("Add &Directory...")) );
- manage_menu->Append( AddMRL_Event, wxU(_("&Add MRL...")) );
+ manage_menu->Append( AddMRL_Event, wxU(_("&Add URL...")) );
manage_menu->AppendSeparator();
- manage_menu->Append( MenuDummy_Event, wxU(_("Services discovery")),
+ manage_menu->Append( MenuDummy_Event, wxU(_("Services Discovery")),
p_sd_menu );
manage_menu->AppendSeparator();
manage_menu->Append( Open_Event, wxU(_("&Open Playlist...")) );
/* Create our "Sort" menu */
wxMenu *sort_menu = new wxMenu;
- sort_menu->Append( SortTitle_Event, wxU(_("Sort by &title")) );
- sort_menu->Append( RSortTitle_Event, wxU(_("&Reverse sort by title")) );
+ 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( Randomize_Event, wxU(_("&Shuffle Playlist")) );
+ sort_menu->Append( Randomize_Event, wxU(_("&Shuffle")) );
/* Create our "Selection" menu */
wxMenu *selection_menu = new wxMenu;
/* Create the popup menu */
node_popup = new wxMenu;
node_popup->Append( PopupPlay_Event, wxU(_("Play")) );
- node_popup->Append( PopupPlayThis_Event, wxU(_("Play this branch")) );
+ node_popup->Append( PopupPlayThis_Event, wxU(_("Play this Branch")) );
node_popup->Append( PopupPreparse_Event, wxU(_("Preparse")) );
- node_popup->Append( PopupSort_Event, wxU(_("Sort this branch")) );
+ node_popup->Append( PopupSort_Event, wxU(_("Sort this Branch")) );
node_popup->Append( PopupDel_Event, wxU(_("Delete")) );
node_popup->Append( PopupInfo_Event, wxU(_("Info")) );
- node_popup->Append( PopupAddNode_Event, wxU(_("Add node")) );
+ node_popup->Append( PopupAddNode_Event, wxU(_("Add Node")) );
item_popup = new wxMenu;
item_popup->Append( PopupPlay_Event, wxU(_("Play")) );
search_button->SetDefault();
toolbar->Realize();
+ /* Create teh source selector */
+ source_sel = new wxListView( playlist_panel, Source_Event,
+ wxDefaultPosition, wxDefaultSize,
+ wxLC_AUTOARRANGE|wxLC_SINGLE_SEL );
+
/* Create the tree */
treectrl = new wxTreeCtrl( playlist_panel, TreeCtrl_Event,
wxDefaultPosition, wxDefaultSize,
p_images->Add( wxIcon( type_node_xpm ) );
treectrl->AssignImageList( p_images );
- treectrl->AddRoot( wxU(_("root" )), -1, -1, NULL );
-
/* Reduce font size */
wxFont font= treectrl->GetFont();
font.SetPointSize(9);
treectrl->SetFont( font );
- wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
+ wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
+ panel_sizer->Add( source_sel, 0, wxALL | wxEXPAND, 5 );
panel_sizer->Add( treectrl, 1, wxEXPAND | wxALL, 5 );
panel_sizer->Layout();
#if wxUSE_DRAG_AND_DROP
/* Associate drop targets with the playlist */
SetDropTarget( new PlaylistFileDropTarget( this ) );
+ menubar->SetDropTarget( new PlaylistFileDropTarget( this ) );
+ toolbar->SetDropTarget( new PlaylistFileDropTarget( this ) );
#endif
i_saved_id = -1;
-
-
- /* We want to be noticed of playlist changes */
+ i_saved_input_id = -1;
/* Some global changes happened -> Rebuild all */
var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
var_AddCallback( p_playlist, "item-deleted", ItemDeleted, this );
/* Update the playlist */
- Rebuild( VLC_TRUE );
-
+ p_current_treeroot = p_playlist->p_local_category;
+ Rebuild( true );
}
Playlist::~Playlist()
{
- if( pp_sds != NULL ) free( pp_sds );
+ if( pp_sds != NULL )
+ {
+ char **pp_sd = pp_sds;
+ for( ; *pp_sd; pp_sd++ ) free( *pp_sd );
+ free( pp_sds );
+ }
if( p_playlist == NULL ) return;
child = treectrl->GetNextChild( node, cookie );
}
}
- treectrl->SetItemImage( node, p_node->input.i_type );
+ treectrl->SetItemImage( node, p_node->p_input->i_type );
}
void Playlist::CreateNode( playlist_item_t *p_node, wxTreeItemId parent )
{
wxTreeItemId node =
- treectrl->AppendItem( parent, wxL2U( p_node->input.psz_name ),
+ treectrl->AppendItem( parent, wxL2U( p_node->p_input->psz_name ),
-1,-1, new PlaylistItem( p_node ) );
- treectrl->SetItemImage( node, p_node->input.i_type );
+ treectrl->SetItemImage( node, p_node->p_input->i_type );
UpdateNodeChildren( p_node, node );
}
void Playlist::UpdateNodeChildren( playlist_item_t *p_node,
wxTreeItemId node )
{
-
for( int i = 0; i< p_node->i_children ; i++ )
{
/* Append the item */
if( p_node->pp_children[i]->i_children == -1 )
{
- wxTreeItemId item =
- treectrl->AppendItem( node,
- wxL2U( p_node->pp_children[i]->input.psz_name ), -1,-1,
+ if( !(p_node->pp_children[i]->i_flags & PLAYLIST_DBL_FLAG) )
+ {
+ wxTreeItemId item =
+ treectrl->AppendItem( node,
+ wxL2U( p_node->pp_children[i]->p_input->psz_name ), -1,-1,
new PlaylistItem( p_node->pp_children[i]) );
- UpdateTreeItem( item );
+ UpdateTreeItem( item );
+ }
}
else
{
/* Update an item in the tree */
void Playlist::UpdateTreeItem( wxTreeItemId item )
{
+ LockPlaylist( p_intf->p_sys, p_playlist );
if( ! item.IsOk() ) return;
wxTreeItemData *p_data = treectrl->GetItemData( item );
if( !p_data ) return;
- LockPlaylist( p_intf->p_sys, p_playlist );
playlist_item_t *p_item = playlist_ItemGetById( p_playlist,
- ((PlaylistItem *)p_data)->i_id );
+ ((PlaylistItem *)p_data)->i_id, true );
if( !p_item )
{
UnlockPlaylist( p_intf->p_sys, p_playlist );
wxString msg;
wxString duration = wxU( "" );
- char *psz_author = vlc_input_item_GetInfo( &p_item->input,
- _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
- if( !psz_author )
- {
- UnlockPlaylist( p_intf->p_sys, p_playlist );
- return;
- }
+
+ char *psz_artist = input_item_GetArtist( p_item->p_input );
+ char *psz_name = input_item_GetName( p_item->p_input );
char psz_duration[MSTRTIME_MAX_SIZE];
- mtime_t dur = p_item->input.i_duration;
+ mtime_t dur = input_item_GetDuration( p_item->p_input );
if( dur != -1 )
{
wxU( " )" ) );
}
- if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE )
+ if( !psz_artist || !strcmp( psz_artist, "" ) || p_item->p_input->b_fixed_name == true )
{
- msg = wxString( wxU( p_item->input.psz_name ) ) + duration;
+ msg = wxString( wxU( psz_name ) ) + duration;
}
else
{
- msg = wxString(wxU( psz_author )) + wxT(" - ") +
- wxString(wxU(p_item->input.psz_name)) + duration;
+ msg = wxString(wxU( psz_artist )) + wxT(" - ") +
+ wxString(wxU(psz_name)) + duration;
}
- free( psz_author );
+ free( psz_artist );
+ free( psz_name );
treectrl->SetItemText( item , msg );
- treectrl->SetItemImage( item, p_item->input.i_type );
+ treectrl->SetItemImage( item, p_item->p_input->i_type );
if( p_playlist->status.p_item == p_item )
{
while( treectrl->GetItemParent( item ).IsOk() )
{
item = treectrl->GetItemParent( item );
- treectrl->Expand( item );
+ if( ! (item == treectrl->GetRootItem() &&
+ treectrl->HasFlag( wxTR_HIDE_ROOT ) ) )
+ treectrl->Expand( item );
}
}
else
/* No need to do anything if the playlist is going to be rebuilt */
if( b_need_update ) return;
- if( p_add->i_view != i_current_view ) goto update;
-
node = FindItem( treectrl->GetRootItem(), p_add->i_node );
if( !node.IsOk() ) goto update;
- p_item = playlist_ItemGetById( p_playlist, p_add->i_item );
+ p_item = playlist_ItemGetById( p_playlist, p_add->i_item, true );
if( !p_item ) goto update;
+ if( (p_item->i_flags & PLAYLIST_DBL_FLAG ) ) goto update;
item = FindItem( treectrl->GetRootItem(), p_add->i_item );
if( item.IsOk() ) goto update;
item = treectrl->AppendItem( node,
- wxL2U( p_item->input.psz_name ), -1,-1,
+ wxL2U( p_item->p_input->psz_name ), -1,-1,
new PlaylistItem( p_item ) );
- treectrl->SetItemImage( item, p_item->input.i_type );
+ treectrl->SetItemImage( item, p_item->p_input->i_type );
if( item.IsOk() && p_item->i_children == -1 )
{
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 );
- }
-
+ statusbar->SetStatusText( wxString::Format( wxU(_(
+ "%i items in playlist" ) ), i_count ) );
return;
}
void Playlist::UpdateItem( int i )
{
if( i < 0 ) return; /* Sanity check */
-
- wxTreeItemId item = FindItem( treectrl->GetRootItem(), i );
-
+ wxTreeItemId item = FindItemByInput( treectrl->GetRootItem(), i );
if( item.IsOk() )
{
UpdateTreeItem( item );
if( i <= 0 ) return; /* Sanity check */
if( i == i_saved_id ) i_saved_id = -1;
+ /* Hack: always invalidate input item cache */
+ i_saved_input_id = -1;
+
+ /// \todo Check if it is in the source selector */
+
wxTreeItemId item = FindItem( treectrl->GetRootItem(), i );
if( item.IsOk() )
/* Find a wxItem from a playlist id */
wxTreeItemId Playlist::FindItem( wxTreeItemId root, int i_id )
+{
+ return FindItemInner( root, i_id, false );
+}
+
+wxTreeItemId Playlist::FindItemByInput( wxTreeItemId root, int i_input_id )
+{
+ return FindItemInner( root, i_input_id, true );
+}
+
+wxTreeItemId Playlist::FindItemInner( wxTreeItemId root, int i_id, bool b_byinput )
{
wxTreeItemIdValue cookie;
PlaylistItem *p_wxcurrent;
if( i_id < 0 )
{
- wxTreeItemId dummy;
- return dummy;
+ wxTreeItemId dummy; dummy.Unset(); return dummy;
}
- if( i_saved_id == i_id )
- {
+ if( b_byinput && i_saved_input_id == i_id )
+ return saved_input_tree_item;
+ if( !b_byinput && i_saved_id == i_id)
return saved_tree_item;
- }
if( !p_wxcurrent )
{
- wxTreeItemId dummy;
- return dummy;
+ wxTreeItemId dummy; dummy.Unset(); return dummy;
}
- if( p_wxcurrent->i_id == i_id )
+ if( !b_byinput && p_wxcurrent->i_id == i_id )
{
i_saved_id = i_id;
saved_tree_item = root;
return root;
}
+ if( b_byinput && p_wxcurrent->i_input_id == i_id )
+ {
+ i_saved_input_id = i_id;
+ saved_input_tree_item = root;
+ return root;
+ }
while( item.IsOk() )
{
p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( item );
- if( p_wxcurrent->i_id == i_id )
+ if( !b_byinput && p_wxcurrent->i_id == i_id )
{
i_saved_id = i_id;
saved_tree_item = item;
return item;
}
+ else if( b_byinput && p_wxcurrent->i_input_id == i_id )
+ {
+ i_saved_input_id = i_id;
+ saved_input_tree_item = item;
+ return item;
+ }
if( treectrl->ItemHasChildren( item ) )
{
- wxTreeItemId search = FindItem( item, i_id );
+ wxTreeItemId search = FindItemInner( item, i_id, b_byinput );
if( search.IsOk() )
{
- i_saved_id = i_id;
- saved_tree_item = search;
- return search;
+ if( !b_byinput )
+ {
+ i_saved_id = i_id;
+ saved_tree_item = search;
+ return search;
+ }
+ else
+ {
+ i_saved_input_id = i_id;
+ saved_input_tree_item = search;
+ return search;
+
+ }
}
}
item = treectrl->GetNextChild( root, cookie );
}
/* Not found */
- wxTreeItemId dummy;
- return dummy;
+ wxTreeItemId dummy; dummy.Unset(); return dummy;
}
int Playlist::CountItems( wxTreeItemId root )
{
playlist_item_t *p_item;
LockPlaylist( p_intf->p_sys, p_playlist );
- p_item = playlist_ItemGetById( p_playlist, ((PlaylistItem *)treectrl->GetItemData( item ))->i_id );
+ p_item = playlist_ItemGetById( p_playlist, ((PlaylistItem *)treectrl->GetItemData( item ))->i_id, true );
if( p_item && p_item->i_children == -1 )
count++;
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
/* Find a wxItem from a name (from current) */
-wxTreeItemId Playlist::FindItemByName( wxTreeItemId root, wxString search_string, wxTreeItemId current, vlc_bool_t *pb_current_found )
+wxTreeItemId Playlist::FindItemByName( wxTreeItemId root, wxString search_string, wxTreeItemId current, bool *pb_current_found )
{
wxTreeItemIdValue cookie;
wxTreeItemId search;
if( treectrl->GetItemText( item).Lower().Contains(
search_string.Lower() ) )
{
- if( !current.IsOk() || *pb_current_found == VLC_TRUE )
+ if( !current.IsOk() || *pb_current_found == true )
{
return item;
}
else if( current.IsOk() && item == current )
{
- *pb_current_found = VLC_TRUE;
+ *pb_current_found = true;
}
}
if( treectrl->ItemHasChildren( item ) )
item = treectrl->GetNextChild( root, cookie);
}
/* Not found */
- wxTreeItemId dummy;
+ wxTreeItemId dummy; dummy.Unset();
return dummy;
}
/**********************************************************************
* Rebuild the playlist
**********************************************************************/
-void Playlist::Rebuild( vlc_bool_t b_root )
+void Playlist::Rebuild( bool b_root )
{
- playlist_view_t *p_view;
-
i_items_to_append = 0;
- /* We can remove the callbacks before locking, anyway, we won't
- * miss anything */
- if( b_root )
- {
- var_DelCallback( p_playlist, "item-change", ItemChanged, this );
- var_DelCallback( p_playlist, "playlist-current", PlaylistNext, this );
- var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this );
- var_DelCallback( p_playlist, "item-append", ItemAppended, this );
- var_DelCallback( p_playlist, "item-deleted", ItemDeleted, this );
+ LockPlaylist( p_intf->p_sys, p_playlist );
- /* ...and rebuild it */
- LockPlaylist( p_intf->p_sys, p_playlist );
- }
+ /* Invalidate cache */
i_saved_id = -1;
+ i_saved_input_id = -1;
- p_view = playlist_ViewFind( p_playlist, i_current_view ); /* FIXME */
+ /* Rebuild the list */
+ source_sel->ClearAll();
+ for( int i = 0 ; i< p_current_viewroot->i_children ; i++ )
+ {
+ source_sel->InsertItem( i,
+ wxL2U( p_current_viewroot->pp_children[i]->p_input->psz_name) );
+ source_sel->SetItemData( i,
+ p_current_viewroot->pp_children[i]->i_id );
+ if( p_current_viewroot->pp_children[i] == p_current_treeroot )
+ source_sel->Select( i );
+ }
/* HACK we should really get new*/
treectrl->DeleteAllItems();
treectrl->AddRoot( wxU(_("root" )), -1, -1,
- new PlaylistItem( p_view->p_root) );
+ new PlaylistItem( p_current_treeroot ) );
wxTreeItemId root = treectrl->GetRootItem();
- UpdateNode( p_view->p_root, root );
+ UpdateNodeChildren( p_current_treeroot, root );
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;
- Rebuild( VLC_FALSE );
- }
- else 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 ) );
- }
- else
- {
- statusbar->SetStatusText( wxString::Format( wxU(_(
- "%i items in playlist")),
- p_playlist->i_size ), 0 );
- }
-
- if( b_root )
- {
- /* Put callbacks back online */
- var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
- var_AddCallback( p_playlist, "playlist-current", PlaylistNext, this );
- var_AddCallback( p_playlist, "item-change", ItemChanged, this );
- var_AddCallback( p_playlist, "item-append", ItemAppended, this );
- var_AddCallback( p_playlist, "item-deleted", ItemDeleted, this );
+ statusbar->SetStatusText( wxString::Format( wxU(_(
+ "%i items in playlist")), i_count ), 0 );
- UnlockPlaylist( p_intf->p_sys, p_playlist );
- }
+ UnlockPlaylist( p_intf->p_sys, p_playlist );
}
-
-
void Playlist::ShowPlaylist( bool show )
{
- if( show ) Rebuild( VLC_TRUE );
+ if( show ) Rebuild( true );
Show( show );
}
if( this->b_need_update )
{
- this->b_need_update = VLC_FALSE;
- Rebuild( VLC_TRUE );
+ this->b_need_update = false;
+ Rebuild( true );
}
/* Updating the playing status every 0.5s is enough */
p_wxitem = (PlaylistItem *)treectrl->GetItemData( item );
LockPlaylist( p_intf->p_sys, p_playlist );
- p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
+ p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, true );
if( !p_item )
{
return;
}
- if( p_item->i_children == -1 ) DeleteItem( p_item->input.i_id );
+ if( p_item->i_children == -1 ) DeleteItem( p_item->p_input->i_id );
else DeleteNode( p_item );
- RemoveItem( item );
+ RemoveItem( p_item->i_id );
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
void Playlist::DeleteItem( int item_id )
{
- playlist_Delete( p_playlist, item_id );
+ playlist_DeleteFromInput( p_playlist, item_id, true );
}
void Playlist::DeleteNode( playlist_item_t *p_item )
{
- playlist_NodeDelete( p_playlist, p_item, VLC_TRUE , VLC_FALSE );
+ playlist_NodeDelete( p_playlist, p_item, true , false );
}
void Playlist::OnMenuClose( wxCommandEvent& event )
char *psz_desc;
char *psz_filter;
char *psz_module;
- } formats[] = {{ _("M3U file"), "*.m3u", "export-m3u" }};
+ } formats[] = {//{ _("M3U file"), "*.m3u", "export-m3u" },
+ { _("XSPF playlist"), "*.xspf", "export-xspf"}
+ };
wxString filter = wxT("");
- if( p_playlist->i_size == 0 )
+ if( playlist_IsEmpty( p_playlist ) )
{
wxMessageBox( wxU(_("Playlist is empty") ), wxU(_("Can't save")),
wxICON_WARNING | wxOK, this );
if( dialog.ShowModal() == wxID_OK )
{
- if( dialog.GetPath().mb_str() )
+ if( dialog.GetPath().mb_str(wxConvUTF8) )
{
- playlist_Export( p_playlist, dialog.GetPath().mb_str(),
- formats[dialog.GetFilterIndex()].psz_module );
+ /* what root should we export? */
+ if( p_playlist->p_root_category->i_children > 0 )
+ {
+ playlist_Export( p_playlist, dialog.GetPath().mb_str(wxConvUTF8),
+ p_playlist->p_root_category->pp_children[0],
+ formats[dialog.GetFilterIndex()].psz_module );
+ }
}
}
void Playlist::OnOpen( wxCommandEvent& WXUNUSED(event) )
{
wxFileDialog dialog( this, wxU(_("Open playlist")), wxT(""), wxT(""),
- wxT("All playlists|*.pls;*.m3u;*.asx;*.b4s|M3U files|*.m3u"), wxOPEN );
+ wxT("All playlists|" EXTENSIONS_PLAYLIST "|XSPF playlist|*.xspf|M3U files|*.m3u"), wxOPEN );
if( dialog.ShowModal() == wxID_OK )
{
- playlist_Import( p_playlist, dialog.GetPath().mb_str() );
+ playlist_Import( p_playlist, dialog.GetPath().mb_str(wxConvUTF8) );
}
}
{
case SortTitle_Event:
playlist_RecursiveNodeSort( p_playlist,
- playlist_ItemGetById( p_playlist, p_wxitem->i_id ),
+ playlist_ItemGetById( p_playlist, p_wxitem->i_id,
+ true ),
SORT_TITLE_NODES_FIRST, ORDER_NORMAL );
break;
case RSortTitle_Event:
playlist_RecursiveNodeSort( p_playlist,
- playlist_ItemGetById( p_playlist, p_wxitem->i_id ),
+ playlist_ItemGetById( p_playlist, p_wxitem->i_id,
+ true ),
SORT_TITLE_NODES_FIRST, ORDER_REVERSE );
}
UnlockPlaylist( p_intf->p_sys, p_playlist );
- Rebuild( VLC_TRUE );
+ Rebuild( true );
}
/**********************************************************************
void Playlist::OnSearch( wxCommandEvent& WXUNUSED(event) )
{
wxString search_string = search_text->GetValue();
+ PlaylistItem *p_wxroot;
+ p_wxroot = (PlaylistItem *)treectrl->GetItemData( treectrl->GetRootItem() );
+ playlist_item_t *p_root = playlist_ItemGetById( p_playlist, p_wxroot->i_id,
+ true );
- vlc_bool_t pb_found = VLC_FALSE;
+ assert( p_root );
+ char *psz_name = wxFromLocale( search_string );
+ playlist_LiveSearchUpdate( p_playlist, p_root, psz_name );
+ Rebuild( true );
- wxTreeItemId found =
- FindItemByName( treectrl->GetRootItem(), search_string,
- search_current, &pb_found );
-
- if( !found.IsOk() )
- {
- wxTreeItemId dummy;
- search_current = dummy;
- found = FindItemByName( treectrl->GetRootItem(), search_string,
- search_current, &pb_found );
- }
-
- if( found.IsOk() )
- {
- search_current = found;
- treectrl->EnsureVisible( found );
- treectrl->UnselectAll();
- treectrl->SelectItem( found, true );
- }
+ wxLocaleFree( psz_name );
}
/**********************************************************************
{
wxTreeItemIdValue cookie;
wxTreeItemId child = treectrl->GetFirstChild( root, cookie );
+ wxTreeItemId nextchild;
+ bool childIsSelected = FALSE;
+ bool nextchildIsSelected = FALSE;
+
+ if( child.IsOk() ) childIsSelected = treectrl->IsSelected( child );
+
while( child.IsOk() )
{
- if( treectrl->ItemHasChildren( child ) )
- {
- RecursiveDeleteSelection( child );
- if( treectrl->IsSelected(child ) ) DeleteTreeItem( child );
- }
- else if( treectrl->IsSelected( child ) )
+ nextchild = treectrl->GetNextChild( root, cookie );
+ if( nextchild.IsOk() )
+ nextchildIsSelected = treectrl->IsSelected( nextchild );
+ if( childIsSelected )
DeleteTreeItem( child );
- child = treectrl->GetNextChild( root, cookie );
+ else if( treectrl->ItemHasChildren( child ) )
+ RecursiveDeleteSelection( child );
+ child = nextchild;
+ childIsSelected = nextchildIsSelected;
}
}
********************************************************************/
void Playlist::OnActivateItem( wxTreeEvent& event )
{
- playlist_item_t *p_item,*p_node,*p_item2,*p_node2;
+ playlist_item_t *p_item, *p_parent;
PlaylistItem *p_wxitem = (PlaylistItem *)treectrl->GetItemData(
event.GetItem() );
- wxTreeItemId parent = treectrl->GetItemParent( event.GetItem() );
-
- PlaylistItem *p_wxparent = (PlaylistItem *)treectrl->GetItemData( parent );
LockPlaylist( p_intf->p_sys, p_playlist );
- if( !( p_wxitem && p_wxparent ) )
+ if( !( p_wxitem ) )
{
UnlockPlaylist( p_intf->p_sys, p_playlist );
return;
}
+ p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, true );
- p_item2 = playlist_ItemGetById(p_playlist, p_wxitem->i_id);
- p_node2 = playlist_ItemGetById(p_playlist, p_wxparent->i_id);
- if( p_item2 && p_item2->i_children == -1 )
+ p_parent = p_item;
+ while( p_parent )
{
- p_node = p_node2;
- p_item = p_item2;
+ if( p_parent == p_current_treeroot )
+ break;
+ p_parent = p_parent->p_parent;
}
- else
+
+ if( p_parent )
{
- p_node = p_item2;
- p_item = NULL;
-/* if( p_node && p_node->i_children > 0 &&
- p_node->pp_children[0]->i_children == -1)
- {
- p_item = p_node->pp_children[0];
- }
- else
- {
- p_item = NULL;
- }*/
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, true, p_parent, p_item );
}
-
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, i_current_view,
- p_node, p_item );
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
{
long keycode = event.GetKeyCode();
/* Delete selected items */
- if( keycode == WXK_BACK || keycode == WXK_DELETE )
+ if( keycode == WXK_BACK || keycode == WXK_DELETE || keycode == WXK_NUMPAD_DELETE )
{
/* We send a dummy event */
OnDeleteSelection( event );
}
+ /* Work around wxWin32 bug */
+ else if( keycode == WXK_RETURN )
+ {
+ wxArrayTreeItemIds items;
+ if( treectrl->GetSelections( items ) > 0 )
+ {
+ wxTreeEvent event;
+ event.SetItem( items.Item( 0 ) );
+ OnActivateItem( event );
+ }
+ }
else
{
event.Skip();
}
}
-void Playlist::OnEnDis( wxCommandEvent& event )
-{
- msg_Warn( p_intf, "not implemented" );
-}
-
void Playlist::OnDragItemBegin( wxTreeEvent& event )
{
event.Allow();
if( !dest_tree_item.IsOk() ) return;
- /* check that we're not trying to move a node into one of it's children */
+ /* check that we're not trying to move a node into one of its children */
wxTreeItemId parent = dest_tree_item;
while( parent != treectrl->GetRootItem() )
{
}
playlist_item_t *p_drageditem =
- playlist_ItemGetById(p_playlist, p_wxdrageditem->i_id );
+ playlist_ItemGetById(p_playlist, p_wxdrageditem->i_id, true );
playlist_item_t *p_destitem =
- playlist_ItemGetById(p_playlist, p_wxdestitem->i_id );
+ playlist_ItemGetById(p_playlist, p_wxdestitem->i_id, true );
if( !p_drageditem || !p_destitem )
{
UnlockPlaylist( p_intf->p_sys, p_playlist );
return;
}
playlist_item_t *p_destitem2 =
- playlist_ItemGetById( p_playlist, p_parent->i_id );
+ playlist_ItemGetById( p_playlist, p_parent->i_id, true );
if( !p_destitem2 )
{
UnlockPlaylist( p_intf->p_sys, p_playlist );
{
if( p_destitem2->pp_children[i] == p_destitem ) break;
}
- playlist_TreeMove( p_playlist, p_drageditem, p_destitem2,
- i, i_current_view );
+ playlist_TreeMove( p_playlist, p_drageditem, p_destitem2, i );
}
else
/* this is a node */
{
- playlist_TreeMove( p_playlist, p_drageditem, p_destitem,
- 0, i_current_view );
+ playlist_TreeMove( p_playlist, p_drageditem, p_destitem, 0 );
}
UnlockPlaylist( p_intf->p_sys, p_playlist );
/* FIXME: having this Rebuild() is dirty */
- Rebuild( VLC_TRUE );
+ Rebuild( true );
}
#if wxUSE_DRAG_AND_DROP
/* find the destination node and position in that node */
const wxPoint pt( x, y );
- int flags = 0;
- wxTreeItemId item = p->treectrl->HitTest( pt, flags );
+ wxTreeItemId item = p->treectrl->HitTest( pt );
- if( flags & wxTREE_HITTEST_NOWHERE )
+ if( !item.IsOk() )
{
/* We were droped below the last item so we append to the
* general node */
- p_dest = p->p_playlist->p_general;
+ msg_Err( p->p_playlist, "USE OF P_GENERAL" );
+ p_dest = p->p_playlist->p_local_category;
i_pos = PLAYLIST_END;
}
else
{
- /* We were droped on an item */
- if( !item.IsOk() )
- {
- printf("Arf ....\n" );
- UnlockPlaylist( p->p_intf->p_sys, p->p_playlist );
- return FALSE;
- }
-
PlaylistItem *p_plitem =
(PlaylistItem *)p->treectrl->GetItemData( item );
- p_dest = playlist_ItemGetById( p->p_playlist, p_plitem->i_id );
+ p_dest = playlist_ItemGetById( p->p_playlist, p_plitem->i_id, true );
if( p_dest->i_children == -1 )
{
/* This is a leaf. Append right after it
* We thus need to find the parrent node and the position of the
- * leaf in it's children list */
+ * leaf in its children list */
wxTreeItemId parent = p->treectrl->GetItemParent( item );
PlaylistItem *p_parent =
(PlaylistItem *)p->treectrl->GetItemData( parent );
return FALSE;
}
playlist_item_t *p_node =
- playlist_ItemGetById( p->p_playlist, p_parent->i_id );
+ playlist_ItemGetById( p->p_playlist, p_parent->i_id, true );
if( !p_node )
{
UnlockPlaylist( p->p_intf->p_sys, p->p_playlist );
/* Put the items in the playlist node */
for( size_t i = 0; i < filenames.GetCount(); i++ )
{
- const char *psz_utf8 = wxDnDFromLocale( filenames[i] );
- playlist_item_t *p_item =
- playlist_ItemNew( p->p_playlist, psz_utf8, psz_utf8 );
- playlist_NodeAddItem( p->p_playlist, p_item, p->i_current_view,
- p_dest, PLAYLIST_PREPARSE, i_pos );
+ char *psz_utf8 = wxDnDFromLocale( filenames[i] );
+ input_item_t *p_input = input_ItemNew( p->p_playlist,
+ psz_utf8, psz_utf8 );
+ int i_ret = ( playlist_BothAddInput( p->p_playlist, p_input, p_dest,
+ PLAYLIST_PREPARSE, i_pos, NULL, NULL, pl_Unlocked ) != VLC_SUCCESS );
+ vlc_gc_decref( p_input );
wxDnDLocaleFree( psz_utf8 );
+ if( i_ret != VLC_SUCCESS )
+ return FALSE;
}
/* FIXME: having this Rebuild() is dirty */
- p->Rebuild( VLC_TRUE );
+ p->Rebuild( true );
return TRUE;
}
}
else if( event.GetId() < LastView_Event )
{
-
- int i_new_view = event.GetId() - FirstView_Event;
-
- playlist_view_t *p_view = playlist_ViewFind( p_playlist, i_new_view );
-
- if( p_view != NULL )
+ if( event.GetId() == CategoryView_Event )
{
- b_changed_view = VLC_TRUE;
- i_current_view = i_new_view;
- playlist_ViewUpdate( p_playlist, i_new_view );
- Rebuild( VLC_TRUE );
- return;
+ p_current_viewroot = p_playlist->p_root_category;
+ if( p_current_treeroot == p_playlist->p_local_category ||
+ p_current_treeroot == p_playlist->p_local_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_local_category;
+ }
+ else if( p_current_treeroot == p_playlist->p_ml_category ||
+ p_current_treeroot == p_playlist->p_ml_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_ml_category;
+ }
}
- else if( i_new_view >= VIEW_FIRST_SORTED &&
- i_new_view <= VIEW_LAST_SORTED )
+ else if( event.GetId() == OneLevelView_Event )
{
- b_changed_view = VLC_TRUE;
- playlist_ViewInsert( p_playlist, i_new_view, "View" );
- playlist_ViewUpdate( p_playlist, i_new_view );
-
- i_current_view = i_new_view;
-
- Rebuild( VLC_TRUE );
+ p_current_viewroot = p_playlist->p_root_onelevel;
+ if( p_current_treeroot == p_playlist->p_local_category ||
+ p_current_treeroot == p_playlist->p_local_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_local_onelevel;
+ }
+ else if( p_current_treeroot == p_playlist->p_ml_category ||
+ p_current_treeroot == p_playlist->p_ml_onelevel )
+ {
+ p_current_treeroot = p_playlist->p_ml_onelevel;
+ }
}
+ wxCommandEvent event;
+ OnSearch( event );
+ return;
}
else if( event.GetId() >= FirstSD_Event && event.GetId() < LastSD_Event )
{
}
}
- /* FIXME : have a list of "should have" views */
- p_view_menu->Append( FirstView_Event + VIEW_CATEGORY,
- wxU(_("Normal") ) );
- p_view_menu->Append( FirstView_Event + VIEW_S_AUTHOR,
- wxU(_("Sorted by artist") ) );
- p_view_menu->Append( FirstView_Event + VIEW_S_ALBUM,
- wxU(_("Sorted by Album") ) );
-
+ p_view_menu->Append( CategoryView_Event, wxU(_("Normal") ) );
+ p_view_menu->Append( OneLevelView_Event, wxU(_("One level") ) );
return p_view_menu;
}
{
p_sd_menu = new wxMenu;
- vlc_list_t *p_list = vlc_list_find( p_playlist, VLC_OBJECT_MODULE,
- FIND_ANYWHERE );
+ char **ppsz_longnames;
+ char **ppsz_names = services_discovery_GetServicesNames( p_playlist,
+ &ppsz_longnames );
+ if( !ppsz_names )
+ return p_sd_menu;
- int i_number = 0;
- for( int i_index = 0; i_index < p_list->i_count; i_index++ )
- {
- module_t * p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+ char **ppsz_name = ppsz_names, **ppsz_longname = ppsz_longnames;
- if( !strcmp( p_parser->psz_capability, "services_discovery" ) )
- i_number++;
- }
- if( i_number ) pp_sds = (char **)calloc( i_number, sizeof(void *) );
+ int i_number = 0;
- i_number = 0;
- for( int i_index = 0; i_index < p_list->i_count; i_index++ )
+ for( ; *ppsz_name; ppsz_name++, ppsz_longname++ )
{
- module_t * p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+ p_sd_menu->AppendCheckItem( FirstSD_Event + i_number++ ,
+ wxU( *ppsz_longname ) );
- if( !strcmp( p_parser->psz_capability, "services_discovery" ) )
- {
- p_sd_menu->AppendCheckItem( FirstSD_Event + i_number ,
- wxU( p_parser->psz_longname ? p_parser->psz_longname :
- (p_parser->psz_shortname ?
- p_parser->psz_shortname : p_parser->psz_object_name) ) );
+ if( playlist_IsServicesDiscoveryLoaded( p_playlist, *ppsz_name ) )
+ p_sd_menu->Check( FirstSD_Event + i_number, TRUE );
- if( playlist_IsServicesDiscoveryLoaded( p_playlist,
- p_parser->psz_object_name ) )
- {
- p_sd_menu->Check( FirstSD_Event + i_number, TRUE );
- }
-
- pp_sds[i_number++] = p_parser->psz_object_name;
- }
+ free( *ppsz_longname );
}
- vlc_list_release( p_list );
+ pp_sds = ppsz_names;
+ free( ppsz_longnames );
return p_sd_menu;
}
treectrl->SelectItem( i_wx_popup_item );
LockPlaylist( p_intf->p_sys, p_playlist );
- p_item = playlist_ItemGetById( p_playlist, i_popup_item );
+ p_item = playlist_ItemGetById( p_playlist, i_popup_item, true );
if( !p_item )
{
{
playlist_item_t *p_popup_item, *p_popup_parent;
LockPlaylist( p_intf->p_sys, p_playlist );
- p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
- p_popup_parent = playlist_ItemGetById( p_playlist, i_popup_parent );
- if( p_popup_item != NULL )
+ p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item, true );
+
+ p_popup_parent = p_popup_item;
+ while( p_popup_parent )
{
- if( p_popup_item->i_children > -1 )
- {
- if( event.GetId() == PopupPlay_Event &&
- p_popup_item->i_children > 0 )
- {
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- i_current_view, p_popup_item,
- p_popup_item->pp_children[0] );
- }
- else
- {
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- i_current_view, p_popup_item, NULL );
- }
- }
- else
- {
- if( event.GetId() == PopupPlay_Event )
- {
- playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
- i_current_view, p_popup_parent,
- p_popup_item );
- }
- }
+ if( p_popup_parent == p_current_treeroot )
+ break;
+ p_popup_parent = p_popup_parent->p_parent;
+ }
+
+ if( p_popup_parent )
+ {
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, true, p_popup_parent,
+ p_popup_item );
}
UnlockPlaylist( p_intf->p_sys, p_playlist );
}
{
playlist_item_t *p_popup_item;
LockPlaylist( p_intf->p_sys, p_playlist );
- p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
+ p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item, true );
if( p_popup_item != NULL )
{
if( p_popup_item->i_children == -1 )
{
- playlist_PreparseEnqueue( p_playlist, &p_popup_item->input );
+ playlist_PreparseEnqueue( p_playlist, p_popup_item->p_input );
}
else
{
{
wxMenuEvent dummy;
i_wx_popup_item = FindItem( treectrl->GetRootItem(),
- p_parent->pp_children[i]->input.i_id );
- i_popup_item = p_parent->pp_children[i]->input.i_id;
+ p_parent->pp_children[i]->i_id );
+ i_popup_item = p_parent->pp_children[i]->i_id;
Preparse();
}
}
p_wxitem = (PlaylistItem *)treectrl->GetItemData( i_wx_popup_item );
LockPlaylist( p_intf->p_sys, p_playlist );
- p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
+ p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, true );
if( p_item->i_children >= 0 )
{
playlist_RecursiveNodeSort( p_playlist, p_item,
SORT_TITLE_NODES_FIRST, ORDER_NORMAL );
treectrl->DeleteChildren( i_wx_popup_item );
- i_saved_id = -1;
+ i_saved_id = -1; i_saved_input_id = -1;
UpdateNodeChildren( p_item, i_wx_popup_item );
}
void Playlist::OnPopupInfo( wxCommandEvent& event )
{
LockPlaylist( p_intf->p_sys, p_playlist );
- playlist_item_t *p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
+ playlist_item_t *p_popup_item = playlist_ItemGetById( p_playlist,
+ i_popup_item,
+ true );
if( p_popup_item )
{
iteminfo_dialog = new ItemInfoDialog( p_intf, p_popup_item, this );
p_wxitem = (PlaylistItem *)treectrl->GetItemData( i_wx_popup_item );
- p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
+ p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, true );
- playlist_NodeCreate( p_playlist, i_current_view, psz_name, p_item );
+ playlist_NodeCreate( p_playlist, psz_name, p_item, 0, NULL );
UnlockPlaylist( p_intf->p_sys, p_playlist );
- Rebuild( VLC_TRUE );
+ Rebuild( true );
wxLocaleFree( psz_name );
}
+void Playlist::OnSourceSelected( wxListEvent &event )
+{
+ int i_id = event.GetData();
+
+ if( !p_current_treeroot || i_id != p_current_treeroot->i_id )
+ {
+ playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id,
+ true );
+ if( p_item ) p_current_treeroot = p_item;
+ Rebuild( true );
+ }
+}
/*****************************************************************************
* Custom events management
vlc_value_t oval, vlc_value_t nval, void *param )
{
Playlist *p_playlist_dialog = (Playlist *)param;
- p_playlist_dialog->b_need_update = VLC_TRUE;
+ p_playlist_dialog->b_need_update = true;
return VLC_SUCCESS;
}
{
/* Too many items waiting to be added, it will be quicker to rebuild
* the whole playlist */
- p_playlist_dialog->b_need_update = VLC_TRUE;
+ p_playlist_dialog->b_need_update = true;
return VLC_SUCCESS;
}