Commit a80da5c3 authored by Antoine Cellerier's avatar Antoine Cellerier

playlist.cpp, playlist.hpp: fix segfault when destroying playlist drop target...

playlist.cpp, playlist.hpp: fix segfault when destroying playlist drop target (and use the wxDnD*Locale functions).
interface.cpp, wxwidgets.hpp: put courmisch's fixes to the DnD encoding issue in wx into wxDnDFromLocale and wxDnDFreeLocale
parent 9a5cf69b
...@@ -193,6 +193,7 @@ public: ...@@ -193,6 +193,7 @@ public:
protected: protected:
int i_id; int i_id;
friend class Playlist; friend class Playlist;
friend class PlaylistFileDropTarget;
}; };
/***************************************************************************** /*****************************************************************************
...@@ -374,7 +375,7 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ): ...@@ -374,7 +375,7 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
/* Associate drop targets with the playlist */ /* Associate drop targets with the playlist */
SetDropTarget( this ); SetDropTarget( new PlaylistFileDropTarget( this ) );
#endif #endif
i_saved_id = -1; i_saved_id = -1;
...@@ -1227,27 +1228,29 @@ void Playlist::OnDragItemEnd( wxTreeEvent& event ) ...@@ -1227,27 +1228,29 @@ void Playlist::OnDragItemEnd( wxTreeEvent& event )
} }
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
PlaylistFileDropTarget::PlaylistFileDropTarget( Playlist *p ):p( p ){}
/******************************************************************** /********************************************************************
* File Drag And Drop handling * File Drag And Drop handling
********************************************************************/ ********************************************************************/
bool Playlist::OnDropFiles( wxCoord x, wxCoord y, bool PlaylistFileDropTarget::OnDropFiles( wxCoord x, wxCoord y,
const wxArrayString& filenames ) const wxArrayString& filenames )
{ {
int i_pos = 0; int i_pos = 0;
playlist_item_t *p_dest; playlist_item_t *p_dest;
LockPlaylist( p_intf->p_sys, p_playlist ); LockPlaylist( p->p_intf->p_sys, p->p_playlist );
/* find the destination node and position in that node */ /* find the destination node and position in that node */
const wxPoint p( x, y ); const wxPoint pt( x, y );
int flags = 0; int flags = 0;
wxTreeItemId item = treectrl->HitTest( p, flags ); wxTreeItemId item = p->treectrl->HitTest( pt, flags );
if( flags & wxTREE_HITTEST_NOWHERE ) if( flags & wxTREE_HITTEST_NOWHERE )
{ {
/* We were droped below the last item so we append to the /* We were droped below the last item so we append to the
* general node */ * general node */
p_dest = p_playlist->p_general; p_dest = p->p_playlist->p_general;
i_pos = PLAYLIST_END; i_pos = PLAYLIST_END;
} }
else else
...@@ -1256,32 +1259,32 @@ bool Playlist::OnDropFiles( wxCoord x, wxCoord y, ...@@ -1256,32 +1259,32 @@ bool Playlist::OnDropFiles( wxCoord x, wxCoord y,
if( !item.IsOk() ) if( !item.IsOk() )
{ {
printf("Arf ....\n" ); printf("Arf ....\n" );
UnlockPlaylist( p_intf->p_sys, p_playlist ); UnlockPlaylist( p->p_intf->p_sys, p->p_playlist );
return FALSE; return FALSE;
} }
PlaylistItem *p_plitem = PlaylistItem *p_plitem =
(PlaylistItem *)treectrl->GetItemData( item ); (PlaylistItem *)p->treectrl->GetItemData( item );
p_dest = playlist_ItemGetById(p_playlist, p_plitem->i_id ); p_dest = playlist_ItemGetById( p->p_playlist, p_plitem->i_id );
if( p_dest->i_children == -1 ) if( p_dest->i_children == -1 )
{ {
/* This is a leaf. Append right after it /* This is a leaf. Append right after it
* We thus need to find the parrent node and the position of the * We thus need to find the parrent node and the position of the
* leaf in it's children list */ * leaf in it's children list */
wxTreeItemId parent = treectrl->GetItemParent( item ); wxTreeItemId parent = p->treectrl->GetItemParent( item );
PlaylistItem *p_parent = PlaylistItem *p_parent =
(PlaylistItem *)treectrl->GetItemData( parent ); (PlaylistItem *)p->treectrl->GetItemData( parent );
if( !p_parent ) if( !p_parent )
{ {
UnlockPlaylist( p_intf->p_sys, p_playlist ); UnlockPlaylist( p->p_intf->p_sys, p->p_playlist );
return FALSE; return FALSE;
} }
playlist_item_t *p_node = playlist_item_t *p_node =
playlist_ItemGetById( p_playlist, p_parent->i_id ); playlist_ItemGetById( p->p_playlist, p_parent->i_id );
if( !p_node ) if( !p_node )
{ {
UnlockPlaylist( p_intf->p_sys, p_playlist ); UnlockPlaylist( p->p_intf->p_sys, p->p_playlist );
return FALSE; return FALSE;
} }
for( i_pos = 0; i_pos < p_node->i_children; i_pos++ ) for( i_pos = 0; i_pos < p_node->i_children; i_pos++ )
...@@ -1292,21 +1295,21 @@ bool Playlist::OnDropFiles( wxCoord x, wxCoord y, ...@@ -1292,21 +1295,21 @@ bool Playlist::OnDropFiles( wxCoord x, wxCoord y,
} }
} }
UnlockPlaylist( p_intf->p_sys, p_playlist ); UnlockPlaylist( p->p_intf->p_sys, p->p_playlist );
/* Put the items in the playlist node */ /* Put the items in the playlist node */
for( size_t i = 0; i < filenames.GetCount(); i++ ) for( size_t i = 0; i < filenames.GetCount(); i++ )
{ {
char *psz_utf8 = wxFromLocale( filenames[i] ); const char *psz_utf8 = wxDnDFromLocale( filenames[i] );
playlist_item_t *p_item = playlist_item_t *p_item =
playlist_ItemNew( p_playlist, psz_utf8, psz_utf8 ); playlist_ItemNew( p->p_playlist, psz_utf8, psz_utf8 );
playlist_NodeAddItem( p_playlist, p_item, i_current_view, playlist_NodeAddItem( p->p_playlist, p_item, p->i_current_view,
p_dest, PLAYLIST_PREPARSE, i_pos ); p_dest, PLAYLIST_PREPARSE, i_pos );
wxLocaleFree( psz_utf8 ); wxDnDLocaleFree( psz_utf8 );
} }
/* FIXME: having this Rebuild() is dirty */ /* FIXME: having this Rebuild() is dirty */
Rebuild( VLC_TRUE ); p->Rebuild( VLC_TRUE );
return TRUE; return TRUE;
} }
......
...@@ -45,9 +45,6 @@ class ExportPlaylist; ...@@ -45,9 +45,6 @@ class ExportPlaylist;
/* Playlist */ /* Playlist */
class Playlist: public wxFrame class Playlist: public wxFrame
#if wxUSE_DRAG_AND_DROP
, public wxFileDropTarget
#endif
{ {
public: public:
/* Constructor */ /* Constructor */
...@@ -61,10 +58,8 @@ public: ...@@ -61,10 +58,8 @@ public:
bool b_need_update; bool b_need_update;
int i_items_to_append; int i_items_to_append;
#if wxUSE_DRAG_AND_DROP
virtual bool OnDropFiles( wxCoord x, wxCoord y, int GetCurrentView( ){ return i_current_view; };
const wxArrayString& filenames );
#endif
private: private:
void RemoveItem( int ); void RemoveItem( int );
...@@ -141,7 +136,9 @@ private: ...@@ -141,7 +136,9 @@ private:
void OnPopupEna( wxCommandEvent& event ); void OnPopupEna( wxCommandEvent& event );
void OnPopupInfo( wxCommandEvent& event ); void OnPopupInfo( wxCommandEvent& event );
void OnPopupAddNode( wxCommandEvent& event ); void OnPopupAddNode( wxCommandEvent& event );
protected:
void Rebuild( vlc_bool_t ); void Rebuild( vlc_bool_t );
private:
void Preparse(); void Preparse();
...@@ -160,9 +157,10 @@ private: ...@@ -160,9 +157,10 @@ private:
wxTreeItemId saved_tree_item; wxTreeItemId saved_tree_item;
int i_saved_id; int i_saved_id;
protected:
playlist_t *p_playlist; playlist_t *p_playlist;
private:
/* Custom events */ /* Custom events */
void OnPlaylistEvent( wxCommandEvent& event ); void OnPlaylistEvent( wxCommandEvent& event );
...@@ -175,14 +173,29 @@ private: ...@@ -175,14 +173,29 @@ private:
int i_update_counter; int i_update_counter;
vlc_bool_t b_changed_view;
char **pp_sds;
protected:
intf_thread_t *p_intf; intf_thread_t *p_intf;
wxTreeCtrl *treectrl; wxTreeCtrl *treectrl;
int i_current_view; int i_current_view;
vlc_bool_t b_changed_view;
char **pp_sds;
friend class PlaylistFileDropTarget;
};
#if wxUSE_DRAG_AND_DROP
/* Playlist file drop target */
class PlaylistFileDropTarget: public wxFileDropTarget
{
public:
PlaylistFileDropTarget( Playlist * );
virtual bool OnDropFiles( wxCoord x, wxCoord y,
const wxArrayString& filenames );
private:
Playlist *p;
}; };
#endif
} // end of wxvlc namespace } // end of wxvlc namespace
......
...@@ -1261,47 +1261,13 @@ bool DragAndDrop::OnDropFiles( wxCoord, wxCoord, ...@@ -1261,47 +1261,13 @@ bool DragAndDrop::OnDropFiles( wxCoord, wxCoord,
for( size_t i = 0; i < filenames.GetCount(); i++ ) for( size_t i = 0; i < filenames.GetCount(); i++ )
{ {
#ifdef wxUSE_UNICODE char *psz_utf8 = wxDnDFromLocale( filenames[i] );
/*
* FIXME: this is yet another awful and ugly bug-to-bug work-around
* for the painfully broken and brain-dead wxWidgets character
* encoding internals. Maybe, one day the wxWidgets team will find out
* and we will have to remove (phew) this kludge or autodetect whether
* to trigger it (damn).
*
* In Unicode mode, wxWidgets will encode file names in the locale
* encoding with each **bytes** (rather than characters) represented
* by a 32 bits unsigned integer. If you are lucky enough to be using
* ISO-8859-1 as your local character encoding, that lame encoding
* scheme happens to be identical to UTF-32 with your arch native
* byte-endianess. If you are using anything else, including not only
* UTF-8 but also Windows-1252(!) and ISO-8859-15(!) or any
* non-western encoding, it obviously fails.
*/
const wxChar *stupid = filenames[i];
for (const wxChar *braindead = stupid; *braindead; braindead++);
size_t i = (braindead - stupid);
char *psz_local = (char *)malloc( i + 1 );
do
psz_local[i] = (char)stupid[i];
while (i--);
const char *psz_utf8 = FromLocale( psz_local );
#else
char *psz_utf8 = wxFromLocale( filenames[i] );
#endif
playlist_Add( p_playlist, psz_utf8, psz_utf8, playlist_Add( p_playlist, psz_utf8, psz_utf8,
PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO), PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO),
PLAYLIST_END ); PLAYLIST_END );
#ifdef wxUSE_UNICODE
LocaleFree( psz_utf8 ); wxDnDLocaleFree( psz_utf8 );
free( psz_local );
#else
wxLocaleFree( psz_utf8 );
#endif
} }
vlc_object_release( p_playlist ); vlc_object_release( p_playlist );
......
...@@ -95,6 +95,43 @@ DECLARE_LOCAL_EVENT_TYPE( wxEVT_INTF, 1 ); ...@@ -95,6 +95,43 @@ DECLARE_LOCAL_EVENT_TYPE( wxEVT_INTF, 1 );
# define wxLocaleFree(string) LocaleFree(string) # define wxLocaleFree(string) LocaleFree(string)
#endif #endif
/* From Locale functions to use for File Drop targets ... go figure */
#ifdef wxUSE_UNICODE
inline const char *wxDnDFromLocale( const wxChar *stupid )
{
/*
* FIXME: this is yet another awful and ugly bug-to-bug work-around
* for the painfully broken and brain-dead wxWidgets character
* encoding internals. Maybe, one day the wxWidgets team will find out
* and we will have to remove (phew) this kludge or autodetect whether
* to trigger it (damn).
*
* In Unicode mode, wxWidgets will encode file names in the locale
* encoding with each **bytes** (rather than characters) represented
* by a 32 bits unsigned integer. If you are lucky enough to be using
* ISO-8859-1 as your local character encoding, that lame encoding
* scheme happens to be identical to UTF-32 with your arch native
* byte-endianess. If you are using anything else, including not only
* UTF-8 but also Windows-1252(!) and ISO-8859-15(!) or any
* non-western encoding, it obviously fails.
*/
const wxChar *braindead;
for (braindead = stupid; *braindead; braindead++);
size_t i = (braindead - stupid);
char *psz_local = (char *)malloc( i + 1 );
do
psz_local[i] = (char)stupid[i];
while (i--);
const char *psz_utf8 = FromLocale( psz_local );
free( psz_local );
return psz_utf8;
}
#else
# define wxDnDFromLocale( string ) wxFromLocale( string )
#endif
#define wxDnDLocaleFree(string) LocaleFree( string )
#define WRAPCOUNT 80 #define WRAPCOUNT 80
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment