]> git.sesse.net Git - vlc/blob - plugins/win32/playlist.cpp
aa90ac75b91db1f5634e113c0da2eee882174656
[vlc] / plugins / win32 / playlist.cpp
1 /*****************************************************************************\r
2  * playlist.cpp: Interface for the playlist dialog\r
3  *****************************************************************************\r
4  * Copyright (C) 2002 VideoLAN\r
5  *\r
6  * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>\r
7  *\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
12  * \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
17  *\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
22 \r
23 #include <vcl.h>\r
24 #pragma hdrstop\r
25 \r
26 #include <videolan/vlc.h>\r
27 \r
28 #include "stream_control.h"\r
29 #include "input_ext-intf.h"\r
30 \r
31 #include "interface.h"\r
32 #include "intf_playlist.h"\r
33 \r
34 #include "playlist.h"\r
35 #include "win32_common.h"\r
36 \r
37 //---------------------------------------------------------------------------\r
38 //#pragma package(smart_init)\r
39 #pragma resource "*.dfm"\r
40 \r
41 extern  struct intf_thread_s *p_intfGlobal;\r
42 \r
43 //---------------------------------------------------------------------------\r
44 __fastcall TPlaylistDlg::TPlaylistDlg( TComponent* Owner )\r
45         : TForm( Owner )\r
46 {\r
47     Icon = p_intfGlobal->p_sys->p_window->Icon;\r
48 }\r
49 //---------------------------------------------------------------------------\r
50 char * __fastcall TPlaylistDlg::rindex( char *s, char c )\r
51 {\r
52     char *ref = s;\r
53 \r
54     s = s + strlen( s ) - 2;\r
55     while( ( s > ref ) && ( *s != c ) )\r
56     {\r
57         s--;\r
58     }\r
59     if( *s == c )\r
60     {\r
61         return( s );\r
62     }\r
63     else\r
64     {\r
65         return( NULL );\r
66     }\r
67 }\r
68 //---------------------------------------------------------------------------\r
69 \r
70 \r
71 /*****************************************************************************\r
72  * Event handlers\r
73  ****************************************************************************/\r
74 void __fastcall TPlaylistDlg::FormShow( TObject *Sender )\r
75 {\r
76     p_intfGlobal->p_sys->p_window->MenuPlaylist->Checked = true;\r
77     p_intfGlobal->p_sys->p_window->PopupPlaylist->Checked = true;\r
78     p_intfGlobal->p_sys->p_window->ToolButtonPlaylist->Down = true;\r
79 }\r
80 //---------------------------------------------------------------------------\r
81 void __fastcall TPlaylistDlg::FormHide( TObject *Sender )\r
82 {\r
83     p_intfGlobal->p_sys->p_window->MenuPlaylist->Checked = false;\r
84     p_intfGlobal->p_sys->p_window->PopupPlaylist->Checked = false;\r
85     p_intfGlobal->p_sys->p_window->ToolButtonPlaylist->Down = false;\r
86 }\r
87 //---------------------------------------------------------------------------\r
88 void __fastcall TPlaylistDlg::BitBtnOkClick( TObject *Sender )\r
89 {\r
90     Hide();\r
91 }\r
92 //---------------------------------------------------------------------------\r
93 void __fastcall TPlaylistDlg::ListViewPlaylistDblClick( TObject *Sender )\r
94 {\r
95     TListItem *Item;\r
96     TListItem *ItemStart;\r
97     TItemStates Focused;\r
98 \r
99     /* search the selected item */\r
100     if( ListViewPlaylist->SelCount > 0 )\r
101     {\r
102         if( ListViewPlaylist->SelCount == 1 )\r
103         {\r
104             Item = ListViewPlaylist->Selected;\r
105         }\r
106         else\r
107         {\r
108             Focused << isFocused;\r
109             ItemStart = ListViewPlaylist->Items->Item[0];\r
110 \r
111             Item = ListViewPlaylist->GetNextItem( ItemStart, sdAll, Focused );\r
112         }\r
113 \r
114         /* stop current item, select the good one */\r
115         if( ( p_input_bank->pp_input[0] != NULL ) &&\r
116             ( Item->Index != p_intfGlobal->p_sys->i_playing ) )\r
117         {\r
118             /* FIXME: temporary hack */\r
119             p_input_bank->pp_input[0]->b_eof = 1;\r
120         }\r
121         intf_PlaylistJumpto( p_main->p_playlist, Item->Index - 1 );\r
122     }\r
123 }\r
124 //---------------------------------------------------------------------------\r
125 void __fastcall TPlaylistDlg::ListViewPlaylistKeyDown( TObject *Sender,\r
126         WORD &Key, TShiftState Shift )\r
127 {\r
128     /* 'suppr' or 'backspace' */\r
129     if( ( Key == VK_DELETE ) || ( Key == VK_BACK ) )\r
130     {\r
131         MenuDeleteSelectedClick( Sender );\r
132     }\r
133 \r
134     /* 'enter' */\r
135     if( Key == VK_RETURN )\r
136     {\r
137         PopupPlayClick( Sender );\r
138     }\r
139 }\r
140 //---------------------------------------------------------------------------\r
141 void __fastcall TPlaylistDlg::ListViewPlaylistCustomDrawItem(\r
142         TCustomListView *Sender, TListItem *Item, TCustomDrawState State,\r
143         bool &DefaultDraw)\r
144 {\r
145     TRect Rect = Item->DisplayRect( drBounds );\r
146 \r
147     /* set the background color */\r
148     if( Item->Index == p_intfGlobal->p_sys->i_playing )\r
149     {\r
150         Sender->Canvas->Brush->Color = clRed;\r
151     }\r
152     else\r
153     {\r
154         Sender->Canvas->Brush->Color = clWhite;\r
155     }\r
156 \r
157     Sender->Canvas->FillRect( Rect );\r
158 }\r
159 //---------------------------------------------------------------------------\r
160 \r
161 \r
162 /*****************************************************************************\r
163  * Menu callbacks\r
164  ****************************************************************************/\r
165 void __fastcall TPlaylistDlg::MenuAddFileClick( TObject *Sender )\r
166 {\r
167     p_intfGlobal->p_sys->p_window->MenuOpenFileClick( Sender );\r
168 }\r
169 //---------------------------------------------------------------------------\r
170 void __fastcall TPlaylistDlg::MenuAddDiscClick( TObject *Sender )\r
171 {\r
172     p_intfGlobal->p_sys->p_window->MenuOpenDiscClick( Sender );\r
173 }\r
174 //---------------------------------------------------------------------------\r
175 void __fastcall TPlaylistDlg::MenuAddNetClick( TObject *Sender )\r
176 {\r
177     p_intfGlobal->p_sys->p_window->MenuNetworkStreamClick( Sender );\r
178 }\r
179 //---------------------------------------------------------------------------\r
180 void __fastcall TPlaylistDlg::MenuAddUrlClick( TObject *Sender )\r
181 {\r
182     /* TODO */\r
183 }\r
184 //---------------------------------------------------------------------------\r
185 void __fastcall TPlaylistDlg::MenuDeleteSelectedClick( TObject *Sender )\r
186 {\r
187     /* user wants to delete a file in the queue */\r
188     int         i_pos;\r
189     playlist_t *p_playlist = p_main->p_playlist;\r
190 \r
191     /* lock the struct */\r
192     vlc_mutex_lock( &p_intfGlobal->change_lock );\r
193 \r
194     /* delete the items from the last to the first */\r
195     for( i_pos = p_playlist->i_size - 1; i_pos >= 0; i_pos-- )\r
196     {\r
197         if( ListViewPlaylist->Items->Item[i_pos]->Selected )\r
198         {\r
199             DeleteItem( i_pos );\r
200         }\r
201     }\r
202 \r
203     /* Rebuild the ListView */\r
204     UpdateGrid( p_playlist );\r
205 \r
206     vlc_mutex_unlock( &p_intfGlobal->change_lock );\r
207 }\r
208 //---------------------------------------------------------------------------\r
209 void __fastcall TPlaylistDlg::MenuDeleteAllClick( TObject *Sender )\r
210 {\r
211     int         i_pos;\r
212     playlist_t *p_playlist = p_main->p_playlist;\r
213 \r
214     /* lock the struct */\r
215     vlc_mutex_lock( &p_intfGlobal->change_lock );\r
216 \r
217     /* delete the items from the last to the first */\r
218     for( i_pos = p_playlist->i_size - 1; i_pos >= 0; i_pos-- )\r
219     {\r
220         DeleteItem( i_pos );\r
221     }\r
222 \r
223     /* Rebuild the ListView */\r
224     UpdateGrid( p_playlist );\r
225 \r
226     vlc_mutex_unlock( &p_intfGlobal->change_lock );\r
227 }\r
228 //---------------------------------------------------------------------------\r
229 void __fastcall TPlaylistDlg::MenuSelectionInvertClick( TObject *Sender )\r
230 {\r
231 #define NOT( var ) ( (var) ? false : true )\r
232     int         i_pos;\r
233     playlist_t *p_playlist = p_main->p_playlist;\r
234     TListItems *Items = ListViewPlaylist->Items;\r
235 \r
236     /* delete the items from the last to the first */\r
237     for( i_pos = p_playlist->i_size - 1; i_pos >= 0; i_pos-- )\r
238     {\r
239         Items->Item[i_pos]->Selected = NOT( Items->Item[i_pos]->Selected );\r
240     }\r
241 #undef NOT\r
242 }\r
243 //---------------------------------------------------------------------------\r
244 void __fastcall TPlaylistDlg::MenuSelectionCropClick( TObject *Sender )\r
245 {\r
246     MenuSelectionInvertClick( Sender );\r
247     MenuDeleteSelectedClick( Sender );\r
248 }\r
249 //---------------------------------------------------------------------------\r
250 \r
251 \r
252 /*****************************************************************************\r
253  * Popup callbacks\r
254  ****************************************************************************/\r
255 void __fastcall TPlaylistDlg::PopupPlayClick( TObject *Sender )\r
256 {\r
257     ListViewPlaylistDblClick( Sender );\r
258 }\r
259 //---------------------------------------------------------------------------\r
260 void __fastcall TPlaylistDlg::PopupInvertSelectionClick( TObject *Sender )\r
261 {\r
262     MenuSelectionInvertClick( Sender );\r
263 }\r
264 //---------------------------------------------------------------------------\r
265 void __fastcall TPlaylistDlg::PopupCropSelectionClick( TObject *Sender )\r
266 {\r
267     MenuSelectionCropClick( Sender );\r
268 }\r
269 //---------------------------------------------------------------------------\r
270 void __fastcall TPlaylistDlg::PopupDeleteSelectedClick( TObject *Sender )\r
271 {\r
272     MenuDeleteSelectedClick( Sender );\r
273 }\r
274 //---------------------------------------------------------------------------\r
275 void __fastcall TPlaylistDlg::PopupDeleteAllClick( TObject *Sender )\r
276 {\r
277     MenuDeleteAllClick( Sender );\r
278 }\r
279 //---------------------------------------------------------------------------\r
280 \r
281 \r
282 /*****************************************************************************\r
283  * Useful functions, needed by the event handlers\r
284  ****************************************************************************/\r
285 void __fastcall TPlaylistDlg::UpdateGrid( playlist_t * p_playlist )\r
286 {\r
287     int i_dummy;\r
288     char *FileName;\r
289     TListItem *Item;\r
290 \r
291     ListViewPlaylist->Items->BeginUpdate();\r
292 \r
293     /* Clear the list... */\r
294     ListViewPlaylist->Items->Clear();\r
295 \r
296     /* ...and rebuild it */\r
297     for( i_dummy = 0; i_dummy < p_playlist->i_size; i_dummy++ )\r
298     {\r
299 #ifdef WIN32\r
300         /* Position of the last '\' in the string */\r
301         FileName = rindex( p_playlist->p_item[i_dummy].psz_name, '\\' );\r
302 #else\r
303         /* Position of the last '/' in the string */\r
304         FileName = rindex( p_playlist->p_item[i_dummy].psz_name, '/' );\r
305 #endif\r
306         if( ( FileName == NULL ) || ( *(FileName + 1) == '\0' ) )\r
307         {\r
308             FileName = p_playlist->p_item[i_dummy].psz_name;\r
309         }\r
310         else\r
311         {\r
312             /* Skip leading '\' or '/' */\r
313             FileName++;\r
314         }\r
315 \r
316         Item = ListViewPlaylist->Items->Add();\r
317         Item->Caption = FileName;\r
318         Item->SubItems->Add( "no info" );\r
319     }\r
320     /* TODO: Set background color ? */\r
321 \r
322     ListViewPlaylist->Items->EndUpdate();\r
323 }\r
324 //---------------------------------------------------------------------------\r
325 void __fastcall TPlaylistDlg::Manage( intf_thread_t * p_intf )\r
326 {\r
327     playlist_t *p_playlist = p_main->p_playlist ;\r
328 \r
329     vlc_mutex_lock( &p_playlist->change_lock );\r
330 \r
331     if( p_intf->p_sys->i_playing != p_playlist->i_index )\r
332     {\r
333         p_intf->p_sys->i_playing = p_playlist->i_index;\r
334 \r
335         /* update the background color */\r
336         UpdateGrid( p_playlist );\r
337     }\r
338 \r
339     vlc_mutex_unlock( &p_playlist->change_lock );\r
340 }\r
341 //---------------------------------------------------------------------------\r
342 void __fastcall TPlaylistDlg::DeleteItem( int i_pos )\r
343 {\r
344     intf_PlaylistDelete( p_main->p_playlist, i_pos );\r
345 \r
346     /* are we deleting the current played stream */\r
347     if( p_intfGlobal->p_sys->i_playing == i_pos )\r
348     {\r
349         /* next ! */\r
350         p_input_bank->pp_input[0]->b_eof = 1;\r
351         /* this has to set the slider to 0 */\r
352         \r
353         /* step minus one */\r
354         p_intfGlobal->p_sys->i_playing-- ;\r
355 \r
356         vlc_mutex_lock( &p_main->p_playlist->change_lock );\r
357         p_main->p_playlist->i_index-- ;\r
358         vlc_mutex_unlock( &p_main->p_playlist->change_lock );\r
359     }\r
360 }\r
361 //---------------------------------------------------------------------------\r
362 void __fastcall TPlaylistDlg::Previous()\r
363 {\r
364     if( p_input_bank->pp_input[0] != NULL )\r
365     {\r
366         /* FIXME: temporary hack */\r
367         intf_PlaylistPrev( p_main->p_playlist );\r
368         intf_PlaylistPrev( p_main->p_playlist );\r
369         p_input_bank->pp_input[0]->b_eof = 1;\r
370     }\r
371 }\r
372 //---------------------------------------------------------------------------\r
373 void __fastcall TPlaylistDlg::Next()\r
374 {\r
375     if( p_input_bank->pp_input[0] != NULL )\r
376     {\r
377         /* FIXME: temporary hack */\r
378         p_input_bank->pp_input[0]->b_eof = 1;\r
379     }\r
380 }\r
381 //---------------------------------------------------------------------------\r
382 \r