]> git.sesse.net Git - vlc/blob - modules/gui/win32/mainframe.cpp
130a7bfc4e7c6c4b5559bc1c92225a616e513da9
[vlc] / modules / gui / win32 / mainframe.cpp
1 /*****************************************************************************\r
2  * mainframe.cpp: Win32 interface plugin for vlc\r
3  *****************************************************************************\r
4  * Copyright (C) 2002 VideoLAN\r
5  *\r
6  * Authors: Olivier Teulière <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 <vlc/vlc.h>\r
27 #include <vlc/intf.h>\r
28 #include <vlc/vout.h>\r
29 \r
30 #include "dragdrop.h"\r
31 #include "mainframe.h"\r
32 #include "menu.h"\r
33 #include "disc.h"\r
34 #include "network.h"\r
35 #include "about.h"\r
36 #include "preferences.h"\r
37 #include "messages.h"\r
38 #include "playlist.h"\r
39 #include "misc.h"\r
40 #include "win32_common.h"\r
41 \r
42 #include "netutils.h"\r
43 \r
44 //---------------------------------------------------------------------------\r
45 #pragma link "CSPIN"\r
46 #pragma resource "*.dfm"\r
47 \r
48 extern int Win32Manage( intf_thread_t *p_intf );\r
49 \r
50 //---------------------------------------------------------------------------\r
51 __fastcall TMainFrameDlg::TMainFrameDlg(\r
52     TComponent* Owner, intf_thread_t *_p_intf ) : TForm( Owner )\r
53 {\r
54     p_intf = _p_intf;\r
55 \r
56     Application->ShowHint = true;\r
57     Application->OnHint = DisplayHint;\r
58 \r
59     TimerManage->Interval = INTF_IDLE_SLEEP / 1000;\r
60 \r
61     TrackBar->Max = SLIDER_MAX_VALUE;\r
62 \r
63     /* default height and caption */\r
64     ClientHeight = 37 + ToolBar->Height;\r
65     Caption = VOUT_TITLE " (Win32 interface)";\r
66 \r
67     StringListPref = new TStringList();\r
68 \r
69     Translate( this );\r
70 \r
71     /* drag and drop stuff */\r
72 \r
73     /* initialize the OLE library */\r
74     OleInitialize( NULL );\r
75     /* TDropTarget will send the WM_OLEDROP message to the form */\r
76     lpDropTarget = (LPDROPTARGET)new TDropTarget( this->Handle );\r
77     CoLockObjectExternal( lpDropTarget, true, true );\r
78     /* register the form as a drop target */\r
79     RegisterDragDrop( this->Handle, lpDropTarget );\r
80 }\r
81 //---------------------------------------------------------------------------\r
82 __fastcall TMainFrameDlg::~TMainFrameDlg()\r
83 {\r
84     delete StringListPref;\r
85 }\r
86 //---------------------------------------------------------------------------\r
87 \r
88 \r
89 /*****************************************************************************\r
90  * Event handlers\r
91  ****************************************************************************/\r
92 void __fastcall TMainFrameDlg::TimerManageTimer( TObject *Sender )\r
93 {\r
94     Win32Manage( p_intf );\r
95 }\r
96 //---------------------------------------------------------------------------\r
97 void __fastcall TMainFrameDlg::DisplayHint( TObject *Sender )\r
98 {\r
99     StatusBar->SimpleText = GetLongHint( Application->Hint );\r
100 }\r
101 //---------------------------------------------------------------------------\r
102 void __fastcall TMainFrameDlg::TrackBarChange( TObject *Sender )\r
103 {\r
104     /* This function displays the current date related to the position in\r
105      * the stream. It is called whenever the slider changes its value.\r
106      * The lock has to be taken before the function is called */\r
107 \r
108     if( p_intf->p_sys->p_input != NULL )\r
109     {\r
110 #define p_area p_intf->p_sys->p_input->stream.p_selected_area\r
111         char psz_time[ OFFSETTOTIME_MAX_SIZE ];\r
112         off_t Value = TrackBar->Position;\r
113 \r
114         GroupBoxSlider->Caption =\r
115                 input_OffsetToTime( p_intf->p_sys->p_input, psz_time,\r
116                         ( p_area->i_size * Value ) / (off_t)SLIDER_MAX_VALUE );\r
117 #undef p_area\r
118      }\r
119 }\r
120 //---------------------------------------------------------------------------\r
121 void __fastcall TMainFrameDlg::FormClose( TObject *Sender,\r
122       TCloseAction &Action )\r
123 {\r
124     vlc_mutex_lock( &p_intf->change_lock );\r
125     p_intf->p_vlc->b_die = VLC_TRUE;\r
126     vlc_mutex_unlock( &p_intf->change_lock );\r
127 \r
128     /* remove the form from the list of drop targets */\r
129     RevokeDragDrop( this->Handle );\r
130     lpDropTarget->Release();\r
131     CoLockObjectExternal( lpDropTarget, false, true );\r
132 \r
133     /* uninitialize the OLE library */\r
134     OleUninitialize();\r
135 \r
136     /* we don't destroy the form immediatly */\r
137     Action = caHide;\r
138 }\r
139 //---------------------------------------------------------------------------\r
140 \r
141 \r
142 /*****************************************************************************\r
143  * Main callbacks\r
144  ****************************************************************************/\r
145 void __fastcall TMainFrameDlg::OpenFileActionExecute( TObject *Sender )\r
146 {\r
147     if( OpenDialog1->Execute() )\r
148     {\r
149         /* add the new file to the interface playlist */\r
150          p_intf->p_sys->p_playwin->Add( OpenDialog1->FileName,\r
151                                         PLAYLIST_APPEND | PLAYLIST_GO,\r
152                                         PLAYLIST_END );\r
153     };\r
154 }\r
155 //---------------------------------------------------------------------------\r
156 void __fastcall TMainFrameDlg::OpenDiscActionExecute( TObject *Sender )\r
157 {\r
158     TDiscDlg *p_disc = p_intf->p_sys->p_disc;\r
159     if( p_disc == NULL )\r
160     {\r
161         p_disc = new TDiscDlg( this, p_intf );\r
162         p_intf->p_sys->p_disc = p_disc;\r
163     }\r
164     p_disc->Show();\r
165 }\r
166 //---------------------------------------------------------------------------\r
167 void __fastcall TMainFrameDlg::NetworkStreamActionExecute( TObject *Sender )\r
168 {\r
169     TNetworkDlg *p_network = p_intf->p_sys->p_network;\r
170     if( p_network == NULL )\r
171     {\r
172         p_network = new TNetworkDlg( this, p_intf );\r
173         p_intf->p_sys->p_network = p_network;\r
174     }\r
175     p_network->Show();\r
176 }\r
177 //---------------------------------------------------------------------------\r
178 void __fastcall TMainFrameDlg::ExitActionExecute( TObject *Sender )\r
179 {\r
180     Close();\r
181 }\r
182 //---------------------------------------------------------------------------\r
183 void __fastcall TMainFrameDlg::FullscreenActionExecute( TObject *Sender )\r
184 {\r
185     vout_thread_t *p_vout;\r
186 \r
187     p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,\r
188                                                VLC_OBJECT_VOUT, FIND_CHILD );\r
189     if( p_vout == NULL )\r
190     {\r
191         return;\r
192     }\r
193 \r
194     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;\r
195     vlc_object_release( p_vout );\r
196 }\r
197 //---------------------------------------------------------------------------\r
198 void __fastcall TMainFrameDlg::PlaylistActionExecute( TObject *Sender )\r
199 {\r
200     TPlaylistDlg *p_playwin = p_intf->p_sys->p_playwin;\r
201     if( p_playwin->Visible )\r
202     {\r
203         p_playwin->Hide();\r
204     }\r
205     else\r
206     {\r
207         p_playwin->UpdateGrid();\r
208         p_playwin->Show();\r
209     }\r
210 }\r
211 //---------------------------------------------------------------------------\r
212 void __fastcall TMainFrameDlg::MessagesActionExecute( TObject *Sender )\r
213 {\r
214      p_intf->p_sys->p_messages->Show();\r
215 }\r
216 //---------------------------------------------------------------------------\r
217 void __fastcall TMainFrameDlg::PreferencesActionExecute( TObject *Sender )\r
218 {\r
219     CreatePreferences( "main" );\r
220 }\r
221 //---------------------------------------------------------------------------\r
222 void __fastcall TMainFrameDlg::AboutActionExecute( TObject *Sender )\r
223 {\r
224     TAboutDlg *AboutDlg = new TAboutDlg( this, p_intf );\r
225     AboutDlg->ShowModal();\r
226     delete AboutDlg;\r
227 }\r
228 //---------------------------------------------------------------------------\r
229 void __fastcall TMainFrameDlg::BackActionExecute( TObject *Sender )\r
230 {\r
231     /* TODO */\r
232 }\r
233 //---------------------------------------------------------------------------\r
234 void __fastcall TMainFrameDlg::PlayActionExecute( TObject *Sender )\r
235 {\r
236     p_intf->p_sys->p_playwin->Play();\r
237 }\r
238 //---------------------------------------------------------------------------\r
239 void __fastcall TMainFrameDlg::PauseActionExecute( TObject *Sender )\r
240 {\r
241     p_intf->p_sys->p_playwin->Pause();\r
242 }\r
243 //---------------------------------------------------------------------------\r
244 void __fastcall TMainFrameDlg::StopActionExecute( TObject *Sender )\r
245 {\r
246     p_intf->p_sys->p_playwin->Stop();\r
247 }\r
248 //---------------------------------------------------------------------------\r
249 void __fastcall TMainFrameDlg::SlowActionExecute( TObject *Sender )\r
250 {\r
251     p_intf->p_sys->p_playwin->Slow();\r
252 }\r
253 //---------------------------------------------------------------------------\r
254 void __fastcall TMainFrameDlg::FastActionExecute( TObject *Sender )\r
255 {\r
256     p_intf->p_sys->p_playwin->Fast();\r
257 }\r
258 //---------------------------------------------------------------------------\r
259 void __fastcall TMainFrameDlg::PreviousActionExecute(TObject *Sender)\r
260 {\r
261     p_intf->p_sys->p_playwin->Previous();\r
262 }\r
263 //---------------------------------------------------------------------------\r
264 void __fastcall TMainFrameDlg::NextActionExecute(TObject *Sender)\r
265 {\r
266     p_intf->p_sys->p_playwin->Next();\r
267 }\r
268 //---------------------------------------------------------------------------\r
269 void __fastcall TMainFrameDlg::EjectActionExecute( TObject *Sender )\r
270 {\r
271     AnsiString Device = "";\r
272     char * psz_current;\r
273     playlist_t * p_playlist;\r
274 \r
275     p_playlist = (playlist_t *)vlc_object_find( p_intf,\r
276                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );\r
277     if( p_playlist == NULL )\r
278     {\r
279         return;\r
280     }\r
281 \r
282     /*\r
283      * Get the active input\r
284      * Determine whether we can eject a media, ie it's a VCD or DVD\r
285      * If it's neither a VCD nor a DVD, then return\r
286      */\r
287 \r
288     vlc_mutex_lock( &p_playlist->object_lock );\r
289     psz_current = p_playlist->pp_items[ p_playlist->i_index ]->psz_name;\r
290 \r
291     if( psz_current != NULL )\r
292     {\r
293         if( strncmp( psz_current, "dvd", 3 )\r
294             || strncmp( psz_current, "vcd", 3 ) )\r
295         {\r
296             /* Determine the device name by omitting the first 4 characters\r
297              * and keeping 3 characters */\r
298             Device = strdup( ( psz_current + 4 ) );\r
299             Device = Device.SubString( 1, 2 );\r
300         }\r
301     }\r
302 \r
303     vlc_mutex_unlock( &p_playlist->object_lock );\r
304     vlc_object_release( p_playlist );\r
305 \r
306     if( Device == "" )\r
307     {\r
308         return;\r
309     }\r
310 \r
311     /* If there's a stream playing, we aren't allowed to eject ! */\r
312     if( p_intf->p_sys->p_input == NULL )\r
313     {\r
314         msg_Dbg( p_intf, "ejecting %s", Device.c_str() );\r
315 \r
316         intf_Eject( p_intf, Device.c_str() );\r
317     }\r
318 }\r
319 //--------------------------------------------------------------------------\r
320 \r
321 \r
322 /*****************************************************************************\r
323  * External drop handling\r
324  *****************************************************************************/\r
325 void __fastcall TMainFrameDlg::OnDrop( TMessage &Msg )\r
326 {\r
327     /* find the number of files dropped */\r
328     int num_files = DragQueryFile( (HDROP)Msg.WParam, 0xFFFFFFFF,\r
329                                    (LPSTR)NULL, NULL );\r
330 \r
331     /* append each file to the playlist */\r
332     for( int i = 0; i < num_files; i++ )\r
333     {\r
334         /* find the length of the filename */\r
335         int name_length = DragQueryFile( (HDROP)Msg.WParam, i, NULL, NULL ) + 1;\r
336 \r
337         /* get the filename */\r
338         char *FileName = new char[name_length];\r
339         DragQueryFile( (HDROP)Msg.WParam, i, FileName, name_length );\r
340 \r
341         /* add the new file to the playlist */\r
342         p_intf->p_sys->p_playwin->Add( FileName, PLAYLIST_APPEND | PLAYLIST_GO,\r
343                                        PLAYLIST_END );\r
344 \r
345         delete[] FileName;\r
346     }\r
347 \r
348     DragFinish( (HDROP)Msg.WParam );\r
349     Msg.Result = 0;\r
350 }\r
351 //--------------------------------------------------------------------------\r
352 \r
353 \r
354 /*****************************************************************************\r
355  * Menu and popup callbacks\r
356  *****************************************************************************/\r
357 void __fastcall TMainFrameDlg::MenuHideinterfaceClick( TObject *Sender )\r
358 {\r
359      this->SendToBack();\r
360 }\r
361 //---------------------------------------------------------------------------\r
362 void __fastcall TMainFrameDlg::PopupToggleInterfaceClick( TObject *Sender )\r
363 {\r
364     this->BringToFront();\r
365 }\r
366 //---------------------------------------------------------------------------\r
367 void __fastcall TMainFrameDlg::PopupCloseClick( TObject *Sender )\r
368 {\r
369     /* We do nothing, we just need a click on a menu item\r
370      * to close the popup. Don't ask me why... */\r
371     return;\r
372 }\r
373 //---------------------------------------------------------------------------\r
374 void __fastcall TMainFrameDlg::PopupJumpClick( TObject *Sender )\r
375 {\r
376     // TODO\r
377 }\r
378 //---------------------------------------------------------------------------\r
379 \r
380 \r
381 /*****************************************************************************\r
382  * Callbacks for DVD/VCD navigation\r
383  ****************************************************************************/\r
384 void __fastcall TMainFrameDlg::PrevTitleActionExecute( TObject *Sender )\r
385 {\r
386     input_area_t  * p_area;\r
387     int             i_id;\r
388 \r
389     i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;\r
390 \r
391     /* Disallow area 0 since it is used for video_ts.vob */\r
392     if( i_id > 0 )\r
393     {\r
394         p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];\r
395         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );\r
396 \r
397         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
398 \r
399         p_intf->p_sys->b_title_update = 1;\r
400         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
401         p_intf->p_sys->p_menus->SetupMenus();\r
402         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
403     }\r
404 }\r
405 //---------------------------------------------------------------------------\r
406 void __fastcall TMainFrameDlg::NextTitleActionExecute( TObject *Sender )\r
407 {\r
408     input_area_t  * p_area;\r
409     int             i_id;\r
410 \r
411     i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;\r
412 \r
413     if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )\r
414     {\r
415         p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];\r
416         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );\r
417 \r
418         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
419 \r
420         p_intf->p_sys->b_title_update = 1;\r
421         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
422         p_intf->p_sys->p_menus->SetupMenus();\r
423         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
424     }\r
425 }\r
426 //---------------------------------------------------------------------------\r
427 void __fastcall TMainFrameDlg::PrevChapterActionExecute( TObject *Sender )\r
428 {\r
429     input_area_t  * p_area;\r
430 \r
431     p_area = p_intf->p_sys->p_input->stream.p_selected_area;\r
432 \r
433     if( p_area->i_part > 0 )\r
434     {\r
435         p_area->i_part--;\r
436         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );\r
437 \r
438         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
439 \r
440         p_intf->p_sys->b_chapter_update = 1;\r
441         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
442         p_intf->p_sys->p_menus->SetupMenus();\r
443         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
444     }\r
445 }\r
446 //---------------------------------------------------------------------------\r
447 void __fastcall TMainFrameDlg::NextChapterActionExecute( TObject *Sender )\r
448 {\r
449     input_area_t  * p_area;\r
450 \r
451     p_area = p_intf->p_sys->p_input->stream.p_selected_area;\r
452 \r
453     if( p_area->i_part < p_area->i_part_nb )\r
454     {\r
455         p_area->i_part++;\r
456         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );\r
457 \r
458         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
459 \r
460         p_intf->p_sys->b_chapter_update = 1;\r
461         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
462         p_intf->p_sys->p_menus->SetupMenus();\r
463         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
464     }\r
465 }\r
466 //---------------------------------------------------------------------------\r
467 \r
468 \r
469 /*****************************************************************************\r
470  * Callback for the 'go!' button\r
471  ****************************************************************************/\r
472 void __fastcall TMainFrameDlg::ButtonGoClick( TObject *Sender )\r
473 {\r
474     int i_channel;\r
475 \r
476     i_channel = SpinEditChannel->Value;\r
477     msg_Dbg( p_intf, "joining channel %d", i_channel );\r
478 \r
479     vlc_mutex_lock( &p_intf->change_lock );\r
480     network_ChannelJoin( p_intf, i_channel );\r
481     vlc_mutex_unlock( &p_intf->change_lock );\r
482 \r
483 //    input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
484 }\r
485 //---------------------------------------------------------------------------\r
486 \r
487 \r
488 /*****************************************************************************\r
489  * ModeManage: actualise the aspect of the interface whenever the input\r
490  *             changes.\r
491  *****************************************************************************\r
492  * The lock has to be taken before you call the function.\r
493  *****************************************************************************/\r
494 void __fastcall TMainFrameDlg::ModeManage()\r
495 {\r
496     TGroupBox     * ActiveGB;\r
497     int             i_Height;\r
498     bool            b_control;\r
499 \r
500     /* hide all boxes */\r
501     GroupBoxFile->Visible = false;\r
502     GroupBoxNetwork->Visible = false;\r
503     GroupBoxDisc->Visible = false;\r
504 \r
505     /* hide slider */\r
506     GroupBoxSlider->Hide();\r
507 \r
508     /* controls unavailable */\r
509     b_control = 0;\r
510 \r
511     /* show the box related to current input mode */\r
512     if( p_intf->p_sys->p_input != NULL )\r
513     {\r
514         switch( p_intf->p_sys->p_input->stream.i_method & 0xf0 )\r
515         {\r
516             case INPUT_METHOD_FILE:\r
517                 GroupBoxFile->Visible = true;\r
518                 ActiveGB = GroupBoxFile;\r
519                 LabelFileName->Caption = p_intf->p_sys->p_input->psz_source;\r
520                 break;\r
521             case INPUT_METHOD_DISC:\r
522                 GroupBoxDisc->Visible = true;\r
523                 ActiveGB = GroupBoxDisc;\r
524                 break;\r
525             case INPUT_METHOD_NETWORK:\r
526                 GroupBoxNetwork->Visible = true;\r
527                 ActiveGB = GroupBoxNetwork;\r
528                 LabelServer->Caption = p_intf->p_sys->p_input->psz_source;\r
529                 if( config_GetInt( p_intf, "network-channel" ) )\r
530                 {\r
531                     LabelChannel->Visible = true;\r
532                 }\r
533                 else\r
534                 {\r
535                     LabelChannel->Visible = false;\r
536                 }\r
537                 break;\r
538             default:\r
539                 msg_Warn( p_intf, "cannot determine input method" );\r
540                 GroupBoxFile->Visible = true;\r
541                 ActiveGB = GroupBoxFile;\r
542                 LabelFileName->Caption = p_intf->p_sys->p_input->psz_source;\r
543                 break;\r
544         }\r
545 \r
546         i_Height = StatusBar->Height + ActiveGB->Height + ToolBar->Height + 54;\r
547 \r
548         /* initialize and show slider for seekable streams */\r
549         if( p_intf->p_sys->p_input->stream.b_seekable )\r
550         {\r
551             TrackBar->Position = p_intf->p_sys->OldValue = 0;\r
552             GroupBoxSlider->Show();\r
553             i_Height += GroupBoxSlider->Height;\r
554         }\r
555 \r
556         /* control buttons for free pace streams */\r
557         b_control = p_intf->p_sys->p_input->stream.b_pace_control;\r
558 \r
559         /* get ready for menu regeneration */\r
560         p_intf->p_sys->b_program_update = 1;\r
561         p_intf->p_sys->b_title_update = 1;\r
562         p_intf->p_sys->b_chapter_update = 1;\r
563         p_intf->p_sys->b_audio_update = 1;\r
564         p_intf->p_sys->b_spu_update = 1;\r
565         p_intf->p_sys->i_part = 0;\r
566 \r
567         p_intf->p_sys->p_input->stream.b_changed = 0;\r
568         msg_Dbg( p_intf, "stream has changed, refreshing interface" );\r
569     }\r
570     else\r
571     {\r
572         i_Height = StatusBar->Height + ToolBar->Height + 47;\r
573 \r
574         if( config_GetInt( p_intf, "network-channel" ) )\r
575         {\r
576             GroupBoxNetwork->Visible = true;\r
577             LabelChannel->Visible = true;\r
578             i_Height += GroupBoxNetwork->Height + 7;\r
579         }\r
580         else\r
581         {\r
582             /* add space between tolbar and statusbar when\r
583              * nothing is displayed; isn't it nicer ? :) */\r
584             i_Height += 17;\r
585         }\r
586 \r
587         /* unsensitize menus */\r
588         MenuProgram->Enabled = false;\r
589         MenuTitle->Enabled = false;\r
590         MenuChapter->Enabled = false;\r
591         MenuAudio->Enabled = false;\r
592         MenuSubtitles->Enabled = false;\r
593         PopupNavigation->Enabled = false;\r
594         PopupAudio->Enabled = false;\r
595         PopupSubtitles->Enabled = false;\r
596     }\r
597 \r
598     /* resize main window */\r
599     this->Height = i_Height;\r
600 \r
601     /* set control items */\r
602     ToolButtonBack->Enabled = false;\r
603     ToolButtonEject->Enabled = !b_control;\r
604     StopAction->Enabled = true;\r
605     PauseAction->Enabled = b_control;\r
606     SlowAction->Enabled = b_control;\r
607     FastAction->Enabled = b_control;\r
608     PopupBack->Enabled = false;\r
609 }\r
610 //---------------------------------------------------------------------------\r
611 \r
612 \r
613 /*****************************************************************************\r
614  * CreateConfig: create a configuration dialog and save it for further use\r
615  *****************************************************************************\r
616  * Check if the dialog box is already opened, if so this will save us\r
617  * quite a bit of work. (the interface will be destroyed when you actually\r
618  * close the main window, but remember that it is only hidden if you\r
619  * clicked on the action buttons). This trick also allows us not to\r
620  * duplicate identical dialog windows.\r
621  *****************************************************************************/\r
622 void __fastcall TMainFrameDlg::CreatePreferences( AnsiString Name )\r
623 {\r
624     TPreferencesDlg *Preferences;\r
625     int i_index, i_pos;\r
626 \r
627     i_index = StringListPref->IndexOf( Name );\r
628     if( i_index != -1 )\r
629     {\r
630         /* config dialog already exists */\r
631         Preferences = (TPreferencesDlg *)StringListPref->Objects[i_index];\r
632     }\r
633     else\r
634     {\r
635         /* create the config dialog */\r
636         Preferences = new TPreferencesDlg( this, p_intf );\r
637         Preferences->CreateConfigDialog( Name.c_str() );\r
638 \r
639         /* save it */\r
640         i_pos = StringListPref->Add( Name );\r
641         StringListPref->Objects[i_pos] = Preferences;\r
642     }\r
643 \r
644     /* display the dialog */\r
645     Preferences->Show();\r
646 }\r
647 //---------------------------------------------------------------------------\r
648 \r