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