1 /*****************************************************************************
\r
2 * playlist.cpp: Interface for the playlist dialog
\r
3 *****************************************************************************
\r
4 * Copyright (C) 2002 VideoLAN
\r
6 * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
\r
8 * This program is free software; you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation; either version 2 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License
\r
19 * along with this program; if not, write to the Free Software
\r
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
\r
21 *****************************************************************************/
\r
26 #include <vlc/vlc.h>
\r
27 #include <vlc/intf.h>
\r
29 #include "playlist.h"
\r
30 #include "dragdrop.h"
\r
32 #include "win32_common.h"
\r
34 //---------------------------------------------------------------------------
\r
35 #pragma resource "*.dfm"
\r
37 //---------------------------------------------------------------------------
\r
38 _fastcall TPlaylistDlg::TPlaylistDlg(
\r
39 TComponent* Owner, intf_thread_t *_p_intf ) : TForm( Owner )
\r
42 Icon = p_intf->p_sys->p_window->Icon;
\r
45 /* store a pointer to the core playlist */
\r
46 p_playlist = (playlist_t *)
\r
47 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
\r
48 if( p_playlist == NULL )
\r
50 msg_Err( p_intf, "cannot find a playlist object" );
\r
53 /* drag and drop stuff */
\r
55 /* initialize the OLE library */
\r
56 OleInitialize( NULL );
\r
57 /* TDropTarget will send the WM_OLEDROP message to the form */
\r
58 lpDropTarget = (LPDROPTARGET)new TDropTarget( this->Handle );
\r
59 CoLockObjectExternal( lpDropTarget, true, true );
\r
60 /* register the listview as a drop target */
\r
61 RegisterDragDrop( ListViewPlaylist->Handle, lpDropTarget );
\r
63 //---------------------------------------------------------------------------
\r
64 __fastcall TPlaylistDlg::~TPlaylistDlg()
\r
66 /* release the core playlist */
\r
67 vlc_object_release( p_playlist );
\r
69 /* remove the listview from the list of drop targets */
\r
70 RevokeDragDrop( ListViewPlaylist->Handle );
\r
71 lpDropTarget->Release();
\r
72 CoLockObjectExternal( lpDropTarget, false, true );
\r
73 /* uninitialize the OLE library */
\r
76 //---------------------------------------------------------------------------
\r
77 char * __fastcall TPlaylistDlg::rindex( char *s, char c )
\r
81 s = s + strlen( s ) - 2;
\r
82 while( ( s > ref ) && ( *s != c ) )
\r
95 //---------------------------------------------------------------------------
\r
98 /*****************************************************************************
\r
99 * External drop handling
\r
100 *****************************************************************************/
\r
101 void __fastcall TPlaylistDlg::OnDrop( TMessage &Msg )
\r
103 p_intf->p_sys->p_window->OnDrop( Msg );
\r
105 //--------------------------------------------------------------------------
\r
108 /*****************************************************************************
\r
110 ****************************************************************************/
\r
111 void __fastcall TPlaylistDlg::FormShow( TObject *Sender )
\r
113 p_intf->p_sys->p_window->PlaylistAction->Checked = true;
\r
115 //---------------------------------------------------------------------------
\r
116 void __fastcall TPlaylistDlg::FormHide( TObject *Sender )
\r
118 p_intf->p_sys->p_window->PlaylistAction->Checked = false;
\r
120 //---------------------------------------------------------------------------
\r
121 void __fastcall TPlaylistDlg::BitBtnOkClick( TObject *Sender )
\r
125 //---------------------------------------------------------------------------
\r
126 void __fastcall TPlaylistDlg::PlayStreamActionExecute( TObject *Sender )
\r
129 TListItem *ItemStart;
\r
130 TItemStates Focused;
\r
132 if( p_playlist == NULL )
\r
135 /* search the selected item */
\r
136 if( ListViewPlaylist->SelCount > 0 )
\r
138 if( ListViewPlaylist->SelCount == 1 )
\r
140 Item = ListViewPlaylist->Selected;
\r
144 Focused << isFocused;
\r
145 ItemStart = ListViewPlaylist->Items->Item[0];
\r
147 Item = ListViewPlaylist->GetNextItem( ItemStart, sdAll, Focused );
\r
150 playlist_Goto( p_playlist, Item->Index );
\r
153 //---------------------------------------------------------------------------
\r
154 void __fastcall TPlaylistDlg::ListViewPlaylistKeyDown( TObject *Sender,
\r
155 WORD &Key, TShiftState Shift )
\r
157 /* 'suppr' or 'backspace' */
\r
158 if( ( Key == VK_DELETE ) || ( Key == VK_BACK ) )
\r
160 DeleteSelectionActionExecute( Sender );
\r
164 if( Key == VK_RETURN )
\r
166 PlayStreamActionExecute( Sender );
\r
169 //---------------------------------------------------------------------------
\r
170 void __fastcall TPlaylistDlg::ListViewPlaylistCustomDrawItem(
\r
171 TCustomListView *Sender, TListItem *Item, TCustomDrawState State,
\r
174 TRect Rect = Item->DisplayRect( drBounds );
\r
176 /* set the background color */
\r
177 if( Item->Index == p_intf->p_sys->i_playing )
\r
178 Sender->Canvas->Brush->Color = clRed;
\r
180 Sender->Canvas->Brush->Color = clWhite;
\r
182 Sender->Canvas->FillRect( Rect );
\r
184 //---------------------------------------------------------------------------
\r
187 /*****************************************************************************
\r
188 * Menu and popup callbacks
\r
189 ****************************************************************************/
\r
190 void __fastcall TPlaylistDlg::MenuAddFileClick( TObject *Sender )
\r
192 p_intf->p_sys->b_play_when_adding = false;
\r
193 p_intf->p_sys->p_window->OpenFileActionExecute( Sender );
\r
194 p_intf->p_sys->b_play_when_adding = true;
\r
196 //---------------------------------------------------------------------------
\r
197 void __fastcall TPlaylistDlg::MenuAddDiscClick( TObject *Sender )
\r
199 p_intf->p_sys->b_play_when_adding = false;
\r
200 p_intf->p_sys->p_window->OpenDiscActionExecute( Sender );
\r
201 p_intf->p_sys->b_play_when_adding = true;
\r
203 //---------------------------------------------------------------------------
\r
204 void __fastcall TPlaylistDlg::MenuAddNetClick( TObject *Sender )
\r
206 p_intf->p_sys->b_play_when_adding = false;
\r
207 p_intf->p_sys->p_window->NetworkStreamActionExecute( Sender );
\r
208 p_intf->p_sys->b_play_when_adding = true;
\r
210 //---------------------------------------------------------------------------
\r
211 void __fastcall TPlaylistDlg::MenuAddUrlClick( TObject *Sender )
\r
215 //---------------------------------------------------------------------------
\r
216 void __fastcall TPlaylistDlg::DeleteSelectionActionExecute( TObject *Sender )
\r
218 /* user wants to delete a file in the queue */
\r
221 /* lock the struct */
\r
222 vlc_mutex_lock( &p_intf->change_lock );
\r
224 /* delete the items from the last to the first */
\r
225 for( i_pos = p_playlist->i_size - 1; i_pos >= 0; i_pos-- )
\r
227 if( ListViewPlaylist->Items->Item[i_pos]->Selected )
\r
229 DeleteItem( i_pos );
\r
233 /* rebuild the ListView */
\r
236 vlc_mutex_unlock( &p_intf->change_lock );
\r
238 //---------------------------------------------------------------------------
\r
239 void __fastcall TPlaylistDlg::DeleteAllActionExecute( TObject *Sender )
\r
243 /* lock the struct */
\r
244 vlc_mutex_lock( &p_intf->change_lock );
\r
246 /* delete the items from the last to the first */
\r
247 for( i_pos = p_playlist->i_size - 1; i_pos >= 0; i_pos-- )
\r
249 DeleteItem( i_pos );
\r
252 /* Rebuild the ListView */
\r
255 vlc_mutex_unlock( &p_intf->change_lock );
\r
257 //---------------------------------------------------------------------------
\r
258 void __fastcall TPlaylistDlg::InvertSelectionActionExecute( TObject *Sender )
\r
260 #define NOT( var ) ( (var) ? false : true )
\r
262 TListItems *Items = ListViewPlaylist->Items;
\r
264 /* delete the items from the last to the first */
\r
265 for( i_pos = p_playlist->i_size - 1; i_pos >= 0; i_pos-- )
\r
267 Items->Item[i_pos]->Selected = NOT( Items->Item[i_pos]->Selected );
\r
271 //---------------------------------------------------------------------------
\r
272 void __fastcall TPlaylistDlg::CropSelectionActionExecute( TObject *Sender )
\r
274 InvertSelectionActionExecute( Sender );
\r
275 DeleteSelectionActionExecute( Sender );
\r
277 //---------------------------------------------------------------------------
\r
280 /*****************************************************************************
\r
281 * Useful functions, needed by the event handlers or by other windows
\r
282 ****************************************************************************/
\r
283 void __fastcall TPlaylistDlg::Add( AnsiString FileName, int i_mode, int i_pos )
\r
285 if( p_playlist == NULL )
\r
288 playlist_Add( p_playlist, FileName.c_str(), i_mode, i_pos );
\r
290 /* refresh the display */
\r
293 //---------------------------------------------------------------------------
\r
294 void __fastcall TPlaylistDlg::Stop()
\r
296 if( p_playlist == NULL )
\r
299 playlist_Stop( p_playlist );
\r
301 //---------------------------------------------------------------------------
\r
302 void __fastcall TPlaylistDlg::Play()
\r
304 if( p_playlist == NULL )
\r
307 if ( p_playlist->i_size )
\r
308 playlist_Play( p_playlist );
\r
312 //---------------------------------------------------------------------------
\r
313 void __fastcall TPlaylistDlg::Pause()
\r
315 if( p_intf->p_sys->p_input != NULL )
\r
317 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
\r
320 //---------------------------------------------------------------------------
\r
321 void __fastcall TPlaylistDlg::Slow()
\r
323 if( p_intf->p_sys->p_input != NULL )
\r
325 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
\r
328 //---------------------------------------------------------------------------
\r
329 void __fastcall TPlaylistDlg::Fast()
\r
331 if( p_intf->p_sys->p_input != NULL )
\r
333 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
\r
336 //---------------------------------------------------------------------------
\r
337 void __fastcall TPlaylistDlg::UpdateGrid()
\r
343 ListViewPlaylist->Items->BeginUpdate();
\r
345 /* Clear the list... */
\r
346 ListViewPlaylist->Items->Clear();
\r
348 /* ...and rebuild it */
\r
349 for( i_dummy = 0; i_dummy < p_playlist->i_size; i_dummy++ )
\r
352 /* Position of the last '\' in the string */
\r
353 FileName = rindex( p_playlist->pp_items[i_dummy]->psz_name, '\\' );
\r
355 /* Position of the last '/' in the string */
\r
356 FileName = rindex( p_playlist->pp_items[i_dummy]->psz_name, '/' );
\r
358 if( ( FileName == NULL ) || ( *(FileName + 1) == '\0' ) )
\r
360 FileName = p_playlist->pp_items[i_dummy]->psz_name;
\r
364 /* Skip leading '\' or '/' */
\r
368 Item = ListViewPlaylist->Items->Add();
\r
369 Item->Caption = FileName;
\r
370 Item->SubItems->Add( "no info" );
\r
372 /* TODO: Set background color ? */
\r
374 ListViewPlaylist->Items->EndUpdate();
\r
376 //---------------------------------------------------------------------------
\r
377 void __fastcall TPlaylistDlg::Manage()
\r
379 if( p_playlist == NULL )
\r
382 vlc_mutex_lock( &p_playlist->object_lock );
\r
384 if( p_intf->p_sys->i_playing != p_playlist->i_index )
\r
386 p_intf->p_sys->i_playing = p_playlist->i_index;
\r
388 /* update the background color */
\r
392 vlc_mutex_unlock( &p_playlist->object_lock );
\r
394 //---------------------------------------------------------------------------
\r
395 void __fastcall TPlaylistDlg::DeleteItem( int i_pos )
\r
397 if( p_playlist == NULL )
\r
400 playlist_Delete( p_playlist, i_pos );
\r
402 //---------------------------------------------------------------------------
\r
403 void __fastcall TPlaylistDlg::Previous()
\r
405 if( p_playlist == NULL )
\r
408 playlist_Prev( p_playlist );
\r
410 //---------------------------------------------------------------------------
\r
411 void __fastcall TPlaylistDlg::Next()
\r
413 if( p_playlist == NULL )
\r
416 playlist_Next( p_playlist );
\r
418 //---------------------------------------------------------------------------
\r
421 void __fastcall TPlaylistDlg::MenuFileCloseClick(TObject *Sender)
\r
425 //---------------------------------------------------------------------------
\r
427 void __fastcall TPlaylistDlg::MenuFileOpenClick(TObject *Sender)
\r
429 if ( PlaylistOpenDlg->Execute() )
\r
431 playlist_LoadFile ( p_playlist , PlaylistOpenDlg->FileName.c_str() );
\r
435 //---------------------------------------------------------------------------
\r
437 void __fastcall TPlaylistDlg::MenuFileSaveClick(TObject *Sender)
\r
439 if ( PlaylistSaveDlg->Execute() )
\r
441 playlist_SaveFile ( p_playlist , PlaylistSaveDlg->FileName.c_str() );
\r
444 //---------------------------------------------------------------------------
\r