]> git.sesse.net Git - vlc/blob - modules/gui/qt4/components/open_panels.cpp
Use _WIN32 rather than WIN32 (same for WIN64)
[vlc] / modules / gui / qt4 / components / open_panels.cpp
1 /*****************************************************************************
2  * open_panels.cpp : Panels for the open dialogs
3  ****************************************************************************
4  * Copyright (C) 2006-2009 the VideoLAN team
5  * Copyright (C) 2007 Société des arts technologiques
6  * Copyright (C) 2007 Savoir-faire Linux
7  *
8  * $Id$
9  *
10  * Authors: Clément Stenac <zorglub@videolan.org>
11  *          Jean-Baptiste Kempf <jb@videolan.org>
12  *          Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include "qt4.hpp"
34 #include "components/open_panels.hpp"
35 #include "dialogs/open.hpp"
36 #include "dialogs_provider.hpp" /* Open Subtitle file */
37 #include "util/qt_dirs.hpp"
38 #include <vlc_intf_strings.h>
39 #include <vlc_modules.h>
40 #include <vlc_plugin.h>
41 #ifdef _WIN32
42   #include <vlc_charset.h> /* FromWide for Win32 */
43 #endif
44
45 #include <QFileDialog>
46 #include <QDialogButtonBox>
47 #include <QLineEdit>
48 #include <QStackedLayout>
49 #include <QCompleter>
50 #include <QDirModel>
51 #include <QScrollArea>
52 #include <QUrl>
53 #include <QMimeData>
54 #include <QDropEvent>
55
56 #define I_DEVICE_TOOLTIP \
57     I_DIR_OR_FOLDER( N_("Select a device or a VIDEO_TS directory"), \
58                      N_("Select a device or a VIDEO_TS folder") )
59
60 #include "../../eject.c"
61
62 /* Populate a combobox with the devices matching a pattern.
63    Combobox will automatically do autocompletion on the edit zone */
64 #define POPULATE_WITH_DEVS(ppsz_devlist, targetCombo) \
65     QStringList targetCombo ## StringList = QStringList(); \
66     for ( size_t i = 0; i< sizeof(ppsz_devlist) / sizeof(*ppsz_devlist); i++ ) \
67         targetCombo ## StringList << QString( ppsz_devlist[ i ] ); \
68     targetCombo->addItems( QDir( "/dev/" )\
69         .entryList( targetCombo ## StringList, QDir::System )\
70         .replaceInStrings( QRegExp("^"), "/dev/" ) \
71     );
72
73 static const char psz_devModule[][8] = { "v4l2", "pvr", "dtv",
74                                        "dshow", "screen", "jack" };
75
76 /**************************************************************************
77  * Open Files and subtitles                                               *
78  **************************************************************************/
79 FileOpenPanel::FileOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
80                                 OpenPanel( _parent, _p_intf ), dialogBox( NULL )
81 {
82     /* Classic UI Setup */
83     ui.setupUi( this );
84
85     setAcceptDrops( true );
86
87     /* Set Filters for file selection */
88 /*    QString fileTypes = "";
89     ADD_FILTER_MEDIA( fileTypes );
90     ADD_FILTER_VIDEO( fileTypes );
91     ADD_FILTER_AUDIO( fileTypes );
92     ADD_FILTER_PLAYLIST( fileTypes );
93     ADD_FILTER_ALL( fileTypes );
94     fileTypes.replace( QString(";*"), QString(" *")); */
95
96
97 /*    lineFileEdit = ui.fileEdit;
98     //TODO later: fill the fileCompleteList with previous items played.
99     QCompleter *fileCompleter = new QCompleter( fileCompleteList, this );
100     fileCompleter->setModel( new QDirModel( fileCompleter ) );
101     lineFileEdit->setCompleter( fileCompleter );*/
102     if( var_InheritBool( p_intf, "qt-embedded-open" ) )
103     {
104         ui.tempWidget->hide();
105         BuildOldPanel();
106     }
107
108     /* Subtitles */
109     /* Deactivate the subtitles control by default. */
110     ui.subFrame->setEnabled( false );
111
112     /* Connects  */
113     BUTTONACT( ui.fileBrowseButton, browseFile() );
114     BUTTONACT( ui.removeFileButton, removeFile() );
115
116     BUTTONACT( ui.subBrowseButton, browseFileSub() );
117     CONNECT( ui.subCheckBox, toggled( bool ), this, toggleSubtitleFrame( bool ) );
118
119     CONNECT( ui.fileListWidg, itemChanged( QListWidgetItem * ), this, updateMRL() );
120     CONNECT( ui.subInput, textChanged( const QString& ), this, updateMRL() );
121     updateButtons();
122 }
123
124 inline void FileOpenPanel::BuildOldPanel()
125 {
126     /** BEGIN QFileDialog tweaking **/
127     /* Use a QFileDialog and customize it because we don't want to
128        rewrite it all. Be careful to your eyes cause there are a few hacks.
129        Be very careful and test correctly when you modify this. */
130
131     /* Make this QFileDialog a child of tempWidget from the ui. */
132     dialogBox = new FileOpenBox( ui.tempWidget, NULL,
133                                  p_intf->p_sys->filepath, "" );
134
135     dialogBox->setFileMode( QFileDialog::ExistingFiles );
136     dialogBox->setAcceptMode( QFileDialog::AcceptOpen );
137     dialogBox->restoreState(
138             getSettings()->value( "file-dialog-state" ).toByteArray() );
139
140     /* We don't want to see a grip in the middle of the window, do we? */
141     dialogBox->setSizeGripEnabled( false );
142
143     /* Add a tooltip */
144     dialogBox->setToolTip( qtr( "Select one or multiple files" ) );
145     dialogBox->setMinimumHeight( 250 );
146
147     // But hide the two OK/Cancel buttons. Enable them for debug.
148     QDialogButtonBox *fileDialogAcceptBox =
149                       dialogBox->findChildren<QDialogButtonBox*>()[0];
150     fileDialogAcceptBox->hide();
151
152     /* Ugly hacks to get the good Widget */
153     //This lineEdit is the normal line in the fileDialog.
154     QLineEdit *lineFileEdit = dialogBox->findChildren<QLineEdit*>()[0];
155     /* Make a list of QLabel inside the QFileDialog to access the good ones */
156     QList<QLabel *> listLabel = dialogBox->findChildren<QLabel*>();
157
158     /* Hide the FileNames one. Enable it for debug */
159     listLabel[1]->setText( qtr( "File names:" ) );
160     /* Change the text that was uncool in the usual box */
161     listLabel[2]->setText( qtr( "Filter:" ) );
162
163     dialogBox->layout()->setMargin( 0 );
164     dialogBox->layout()->setSizeConstraint( QLayout::SetNoConstraint );
165
166     /** END of QFileDialog tweaking **/
167
168     // Add the DialogBox to the layout
169     ui.gridLayout->addWidget( dialogBox, 0, 0, 1, 3 );
170
171     CONNECT( lineFileEdit, textChanged( const QString& ), this, updateMRL() );
172     dialogBox->installEventFilter( this );
173 }
174
175 FileOpenPanel::~FileOpenPanel()
176 {
177     if( dialogBox )
178         getSettings()->setValue( "file-dialog-state", dialogBox->saveState() );
179 }
180
181 void FileOpenPanel::dragEnterEvent( QDragEnterEvent *event )
182 {
183     event->acceptProposedAction();
184 }
185
186 void FileOpenPanel::dragMoveEvent( QDragMoveEvent *event )
187 {
188     event->acceptProposedAction();
189 }
190
191 void FileOpenPanel::dragLeaveEvent( QDragLeaveEvent *event )
192 {
193     event->accept();
194 }
195
196 void FileOpenPanel::dropEvent( QDropEvent *event )
197 {
198     if( event->possibleActions() & Qt::CopyAction )
199        event->setDropAction( Qt::CopyAction );
200     else
201         return;
202
203     const QMimeData *mimeData = event->mimeData();
204     foreach( const QUrl &url, mimeData->urls() )
205     {
206         if( url.isValid() )
207         {
208             QListWidgetItem *item = new QListWidgetItem(
209                                          toNativeSeparators( url.toLocalFile() ),
210                                          ui.fileListWidg );
211             item->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled );
212             ui.fileListWidg->addItem( item );
213         }
214     }
215     updateMRL();
216     updateButtons();
217     event->accept();
218 }
219
220 void FileOpenPanel::browseFile()
221 {
222     QStringList files = QFileDialog::getOpenFileNames( this, qtr( "Select one or multiple files" ), p_intf->p_sys->filepath) ;
223     foreach( const QString &file, files )
224     {
225         QListWidgetItem *item =
226             new QListWidgetItem( toNativeSeparators( file ), ui.fileListWidg );
227         item->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled );
228         ui.fileListWidg->addItem( item );
229         savedirpathFromFile( file );
230     }
231     updateButtons();
232     updateMRL();
233 }
234
235 void FileOpenPanel::removeFile()
236 {
237     int i = ui.fileListWidg->currentRow();
238     if( i != -1 )
239     {
240         QListWidgetItem *temp = ui.fileListWidg->takeItem( i );
241         delete temp;
242     }
243
244     updateMRL();
245     updateButtons();
246 }
247
248 /* Show a fileBrowser to select a subtitle */
249 void FileOpenPanel::browseFileSub()
250 {
251     // TODO Handle selection of more than one subtitles file
252     QStringList files = THEDP->showSimpleOpen( qtr("Open subtitle file"),
253                            EXT_FILTER_SUBTITLE, p_intf->p_sys->filepath );
254
255     if( files.isEmpty() ) return;
256     ui.subInput->setText( toNativeSeparators( files.join(" ") ) );
257     updateMRL();
258 }
259
260 void FileOpenPanel::toggleSubtitleFrame( bool b )
261 {
262     ui.subFrame->setEnabled( b );
263
264     /* Update the MRL */
265     updateMRL();
266 }
267
268
269 /* Update the current MRL */
270 void FileOpenPanel::updateMRL()
271 {
272     QStringList fileList;
273     QString mrl;
274
275     /* File Listing */
276     if( dialogBox == NULL )
277         for( int i = 0; i < ui.fileListWidg->count(); i++ )
278         {
279             if( !ui.fileListWidg->item( i )->text().isEmpty() )
280                 fileList << toURI(ui.fileListWidg->item( i )->text());
281         }
282     else
283     {
284         fileList = dialogBox->selectedFiles();
285         for( int i = 0; i < fileList.count(); i++ )
286             fileList[i] = toURI( fileList[i] );
287     }
288
289     /* Options */
290     if( ui.subCheckBox->isChecked() &&  !ui.subInput->text().isEmpty() ) {
291         mrl.append( " :sub-file=" + colon_escape( ui.subInput->text() ) );
292     }
293
294     emit methodChanged( "file-caching" );
295     emit mrlUpdated( fileList, mrl );
296 }
297
298 /* Function called by Open Dialog when clicke on Play/Enqueue */
299 void FileOpenPanel::accept()
300 {
301     if( dialogBox )
302         p_intf->p_sys->filepath = dialogBox->directory().absolutePath();
303     ui.fileListWidg->clear();
304 }
305
306 /* Function called by Open Dialog when clicked on cancel */
307 void FileOpenPanel::clear()
308 {
309     ui.fileListWidg->clear();
310     ui.subInput->clear();
311 }
312
313 /* Update buttons depending on current selection */
314 void FileOpenPanel::updateButtons()
315 {
316     bool b_has_files = ( ui.fileListWidg->count() > 0 );
317     ui.removeFileButton->setEnabled( b_has_files );
318     ui.subCheckBox->setEnabled( b_has_files );
319 }
320
321 /**************************************************************************
322  * Open Discs ( DVD, CD, VCD and similar devices )                        *
323  **************************************************************************/
324 DiscOpenPanel::DiscOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
325                                 OpenPanel( _parent, _p_intf )
326 {
327     ui.setupUi( this );
328
329     /* Get the default configuration path for the devices */
330     psz_dvddiscpath = var_InheritString( p_intf, "dvd" );
331     psz_vcddiscpath = var_InheritString( p_intf, "vcd" );
332     psz_cddadiscpath = var_InheritString( p_intf, "cd-audio" );
333
334     /* State to avoid overwritting the users changes with the configuration */
335     m_discType = None;
336
337     ui.browseDiscButton->setToolTip( qtr( I_DEVICE_TOOLTIP ));
338     ui.deviceCombo->setToolTip( qtr(I_DEVICE_TOOLTIP) );
339     ui.deviceCombo->setInsertPolicy( QComboBox::InsertAtTop );
340
341 #if !defined( _WIN32 ) && !defined( __OS2__ )
342     char const * const ppsz_discdevices[] = {
343         "sr*",
344         "sg*",
345         "scd*",
346         "dvd*",
347         "cd*"
348     };
349     QComboBox *discCombo = ui.deviceCombo; /* avoid namespacing in macro */
350     POPULATE_WITH_DEVS( ppsz_discdevices, discCombo );
351     int temp = ui.deviceCombo->findData( config_GetPsz( p_intf, "dvd" ), Qt::UserRole, Qt::MatchStartsWith );
352     if( temp != -1 )
353         ui.deviceCombo->setCurrentIndex( temp );
354 #endif
355
356     /* CONNECTs */
357     BUTTONACT( ui.dvdRadioButton,     updateButtons() );
358     BUTTONACT( ui.bdRadioButton,      updateButtons() );
359     BUTTONACT( ui.vcdRadioButton,     updateButtons() );
360     BUTTONACT( ui.audioCDRadioButton, updateButtons() );
361     BUTTONACT( ui.dvdsimple,          updateButtons() );
362     BUTTONACT( ui.browseDiscButton, browseDevice() );
363     BUTTON_SET_ACT_I( ui.ejectButton, "", toolbar/eject, qtr( "Eject the disc" ),
364             eject() );
365
366     CONNECT( ui.deviceCombo, editTextChanged( QString ), this, updateMRL());
367     CONNECT( ui.deviceCombo, currentIndexChanged( QString ), this, updateMRL());
368     CONNECT( ui.titleSpin, valueChanged( int ), this, updateMRL());
369     CONNECT( ui.chapterSpin, valueChanged( int ), this, updateMRL());
370     CONNECT( ui.audioSpin, valueChanged( int ), this, updateMRL());
371     CONNECT( ui.subtitlesSpin, valueChanged( int ), this, updateMRL());
372
373     /* Run once the updateButtons function in order to fill correctly the comboBoxes */
374     updateButtons();
375 }
376
377 #ifdef _WIN32 /* Disc drives probing for Windows */
378 void DiscOpenPanel::onFocus()
379 {
380     ui.deviceCombo->clear();
381     wchar_t szDrives[512];
382     szDrives[0] = '\0';
383     if( GetLogicalDriveStringsW( sizeof( szDrives ) - 1, szDrives ) )
384     {
385         wchar_t *drive = szDrives;
386         UINT oldMode = SetErrorMode( SEM_FAILCRITICALERRORS );
387         while( *drive )
388         {
389             if( GetDriveTypeW(drive) == DRIVE_CDROM )
390             {
391                 wchar_t psz_name[512] = L"";
392                 GetVolumeInformationW( drive, psz_name, 511, NULL, NULL, NULL, NULL, 0 );
393
394                 QString displayName = FromWide( drive );
395                 char *psz_title = FromWide( psz_name );
396                 if( !EMPTY_STR(psz_title)) {
397                     displayName = displayName + " - "  + psz_title;
398                 }
399
400                 ui.deviceCombo->addItem( displayName, FromWide( drive ) );
401                 free( psz_title );
402             }
403
404             /* go to next drive */
405             while( *(drive++) );
406         }
407         SetErrorMode(oldMode);
408     }
409
410     int temp = ui.deviceCombo->findData( config_GetPsz( p_intf, "dvd" ), Qt::UserRole, Qt::MatchStartsWith );
411     if( temp != -1 )
412         ui.deviceCombo->setCurrentIndex( temp );
413 }
414 #elif defined( __OS2__ ) /* Disc drives probing for OS/2 */
415 void DiscOpenPanel::onFocus()
416 {
417
418     ui.deviceCombo->clear();
419
420 #define IOCTL_CDROMDISK2        0x82
421 #define CDROMDISK2_DRIVELETTERS 0x60
422
423     HFILE hcd2;
424     ULONG ulAction;
425     ULONG ulParamLen;
426     ULONG ulData;
427     ULONG ulDataLen;
428
429     if( DosOpen(( PSZ )"CD-ROM2$", ( PHFILE )&hcd2, &ulAction, 0, FILE_NORMAL,
430                 OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
431                 OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE,
432                 NULL ))
433         return;
434
435     if( !DosDevIOCtl( hcd2, IOCTL_CDROMDISK2, CDROMDISK2_DRIVELETTERS,
436                       NULL, 0, &ulParamLen, &ulData, sizeof( ulData ), &ulDataLen ))
437     {
438         char szDriveName[] = "X:\\";
439
440         int count = LOUSHORT( ulData );
441         int drive = HIUSHORT( ulData );
442
443         for( ; count; --count, ++drive )
444         {
445             szDriveName[ 0 ] = 'A' + drive;
446
447             QString name = qfu( szDriveName );
448
449             ui.deviceCombo->addItem( name, name );
450         }
451     }
452
453     DosClose( hcd2 );
454 }
455 #endif
456
457 DiscOpenPanel::~DiscOpenPanel()
458 {
459     free( psz_dvddiscpath );
460     free( psz_vcddiscpath );
461     free( psz_cddadiscpath );
462 }
463
464 void DiscOpenPanel::clear()
465 {
466     ui.titleSpin->setValue( 0 );
467     ui.chapterSpin->setValue( 0 );
468     ui.subtitlesSpin->setValue( -1 );
469     ui.audioSpin->setValue( -1 );
470     m_discType = None;
471 }
472
473 #if defined( _WIN32 ) || defined( __OS2__ )
474     #define setDrive( psz_name ) {\
475     int index = ui.deviceCombo->findText( qfu( psz_name ) ); \
476     if( index != -1 ) ui.deviceCombo->setCurrentIndex( index );}
477 #else
478     #define setDrive( psz_name ) {\
479     ui.deviceCombo->setEditText( qfu( psz_name ) ); }
480 #endif
481
482 /* update the buttons according the type of device */
483 void DiscOpenPanel::updateButtons()
484 {
485     if ( ui.dvdRadioButton->isChecked() )
486     {
487         if( m_discType != Dvd )
488         {
489             setDrive( psz_dvddiscpath );
490             m_discType = Dvd;
491         }
492         ui.titleLabel->setText( qtr("Title") );
493         ui.chapterLabel->show();
494         ui.chapterSpin->show();
495         ui.diskOptionBox_2->show();
496         ui.dvdsimple->setEnabled( true );
497     }
498     else if ( ui.bdRadioButton->isChecked() )
499     {
500         if( m_discType != BRD )
501         {
502             setDrive( psz_dvddiscpath );
503             m_discType = BRD;
504             ui.dvdsimple->setChecked( !var_InheritBool( p_intf, "bluray-menu" ) );
505         }
506         ui.titleLabel->setText( qtr("Title") );
507         ui.chapterLabel->hide();
508         ui.chapterSpin->hide();
509         ui.diskOptionBox_2->hide();
510         ui.dvdsimple->setEnabled( true );
511     }
512     else if ( ui.vcdRadioButton->isChecked() )
513     {
514         if( m_discType != Vcd )
515         {
516             setDrive( psz_vcddiscpath );
517             m_discType = Vcd;
518         }
519         ui.titleLabel->setText( qtr("Entry") );
520         ui.chapterLabel->hide();
521         ui.chapterSpin->hide();
522         ui.diskOptionBox_2->show();
523         ui.dvdsimple->setEnabled( false );
524     }
525     else /* CDDA */
526     {
527         if( m_discType != Cdda )
528         {
529             setDrive( psz_cddadiscpath );
530             m_discType = Cdda;
531         }
532         ui.titleLabel->setText( qtr("Track") );
533         ui.chapterLabel->hide();
534         ui.chapterSpin->hide();
535         ui.diskOptionBox_2->hide();
536         ui.dvdsimple->setEnabled( false );
537     }
538
539     updateMRL();
540 }
541
542 #undef setDrive
543
544 /* Update the current MRL */
545 void DiscOpenPanel::updateMRL()
546 {
547     QString discPath;
548     QStringList fileList;
549
550     discPath = ui.deviceCombo->currentText();
551
552     int tmp = ui.deviceCombo->findText( discPath );
553     if( tmp != -1 &&  ui.deviceCombo->itemData( tmp ) != QVariant::Invalid )
554         discPath = ui.deviceCombo->itemData( tmp ).toString();
555
556     /* MRL scheme */
557     const char *scheme;
558     /* DVD */
559     if( ui.dvdRadioButton->isChecked() ) {
560         if( !ui.dvdsimple->isChecked() )
561             scheme = "dvd";
562         else
563             scheme = "dvdsimple";
564     } else if ( ui.bdRadioButton->isChecked() )
565         scheme = "bluray";
566     /* VCD */
567     else if ( ui.vcdRadioButton->isChecked() )
568         scheme = "vcd";
569     /* CDDA */
570     else
571         scheme = "cdda";
572
573     char *mrl = vlc_path2uri( qtu(discPath), scheme );
574     if( unlikely(mrl == NULL) )
575         return;
576
577     /* Title/chapter encoded in MRL */
578     QString anchor = "";
579     if( ui.titleSpin->value() > 0 ) {
580         if( ui.dvdRadioButton->isChecked() || ui.bdRadioButton->isChecked() ) {
581             anchor = QString("#%1").arg( ui.titleSpin->value() );
582             if ( ui.chapterSpin->value() > 0 )
583                 anchor += QString(":%1").arg( ui.chapterSpin->value() );
584         }
585         else if ( ui.vcdRadioButton->isChecked() )
586             anchor = QString("#%1").arg( ui.titleSpin->value() );
587     }
588
589     emit methodChanged( "disc-caching" );
590
591     fileList << (qfu(mrl) + anchor);
592     free(mrl);
593
594     QString opts = "";
595
596     /* Input item options */
597     if ( ui.dvdRadioButton->isChecked() || ui.vcdRadioButton->isChecked() )
598     {
599         if ( ui.audioSpin->value() >= 0 )
600             opts += " :audio-track=" +
601                 QString("%1").arg( ui.audioSpin->value() );
602         if ( ui.subtitlesSpin->value() >= 0 )
603             opts += " :sub-track=" +
604                 QString("%1").arg( ui.subtitlesSpin->value() );
605     }
606     else if( ui.audioCDRadioButton->isChecked() )
607     {
608         if( ui.titleSpin->value() > 0 )
609             opts += QString(" :cdda-track=%1").arg( ui.titleSpin->value() );
610     }
611     else if ( ui.bdRadioButton->isChecked() )
612     {
613         if ( ui.dvdsimple->isChecked() == false )
614             opts += " :bluray-menu";
615     }
616     emit mrlUpdated( fileList, opts );
617 }
618
619 void DiscOpenPanel::browseDevice()
620 {
621     QString dir = QFileDialog::getExistingDirectory( this,
622             qtr( I_DEVICE_TOOLTIP ), p_intf->p_sys->filepath );
623     if( !dir.isEmpty() )
624     {
625         ui.deviceCombo->addItem( toNativeSepNoSlash( dir ) );
626         ui.deviceCombo->setCurrentIndex( ui.deviceCombo->findText( toNativeSepNoSlash( dir ) ) );
627     }
628
629     updateMRL();
630 }
631
632 void DiscOpenPanel::eject()
633 {
634     intf_Eject( p_intf, qtu( ui.deviceCombo->currentText() ) );
635 }
636
637 void DiscOpenPanel::accept()
638 {}
639
640 /**************************************************************************
641  * Open Network streams and URL pages                                     *
642  **************************************************************************/
643 NetOpenPanel::NetOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
644                                 OpenPanel( _parent, _p_intf )
645 {
646     ui.setupUi( this );
647     CONNECT( ui.urlComboBox, editTextChanged( const QString& ), this, updateMRL());
648
649     /* */
650     if( var_InheritBool( p_intf, "qt-recentplay" ) )
651     {
652         b_recentList = true;
653         ui.urlComboBox->addItems( getSettings()->value( "OpenDialog/netMRL" ).toStringList() );
654         ui.urlComboBox->setMaxCount( 10 );
655     }
656     else
657         b_recentList = false;
658
659     QFont smallFont = QApplication::font();
660     smallFont.setPointSize( smallFont.pointSize() - 1 );
661     ui.examples->setFont( smallFont );
662
663     /* Use a simple validator for URLs */
664     ui.urlComboBox->setValidator( new UrlValidator( this ) );
665     ui.urlComboBox->setFocus();
666 }
667
668 NetOpenPanel::~NetOpenPanel()
669 {
670     if( !b_recentList ) return;
671
672     /* Create the list with the current items */
673     QStringList mrlList;
674     for( int i = 0; i < ui.urlComboBox->count(); i++ )
675         mrlList << ui.urlComboBox->itemText( i );
676
677     if( mrlList.count() > 0 )
678     {
679         /* Clean the list... */
680         mrlList.removeDuplicates();
681         /* ...and save the 8 last entries */
682         getSettings()->setValue( "OpenDialog/netMRL", mrlList );
683     }
684 }
685
686 void NetOpenPanel::clear()
687 {
688     ui.urlComboBox->lineEdit()->clear();
689 }
690
691 void NetOpenPanel::onAccept()
692 {
693     if( ui.urlComboBox->findText( ui.urlComboBox->currentText() ) == -1 )
694         ui.urlComboBox->insertItem( 0, ui.urlComboBox->currentText());
695 }
696
697 void NetOpenPanel::onFocus()
698 {
699     ui.urlComboBox->setFocus();
700     ui.urlComboBox->lineEdit()->selectAll();
701 }
702
703 void NetOpenPanel::updateMRL()
704 {
705     QString url = ui.urlComboBox->lineEdit()->text();
706
707     emit methodChanged( qfu( "network-caching" ) );
708
709     QStringList qsl;
710     if( !url.isEmpty() ) qsl << url;
711     emit mrlUpdated( qsl, "" );
712 }
713
714 QValidator::State UrlValidator::validate( QString& str, int& ) const
715 {
716     if( str.contains( ' ' ) )
717         return QValidator::Invalid;
718     if( !str.contains( "://" ) )
719         return QValidator::Intermediate;
720     return QValidator::Acceptable;
721 }
722
723 void UrlValidator::fixup( QString& str ) const
724 {
725     str = str.trimmed();
726 }
727
728 /**************************************************************************
729  * Open Capture device ( DVB, PVR, V4L, and similar )                     *
730  **************************************************************************/
731 CaptureOpenPanel::CaptureOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
732                                 OpenPanel( _parent, _p_intf )
733 {
734     isInitialized = false;
735 }
736
737 void CaptureOpenPanel::initialize()
738 {
739     if( isInitialized ) return;
740
741     isInitialized = true;
742
743     ui.setupUi( this );
744
745     BUTTONACT( ui.advancedButton, advancedDialog() );
746     CONNECT( ui.deviceCombo, currentIndexChanged(int), this, enableAdvancedDialog(int) );
747
748     /* Create two stacked layouts in the main comboBoxes */
749     QStackedLayout *stackedDevLayout = new QStackedLayout;
750     ui.cardBox->setLayout( stackedDevLayout );
751
752     QStackedLayout *stackedPropLayout = new QStackedLayout;
753     ui.optionsBox->setLayout( stackedPropLayout );
754
755     /* Creation and connections of the WIdgets in the stacked layout */
756 #define addModuleAndLayouts( number, name, label, layout )            \
757     QWidget * name ## DevPage = new QWidget( this );                  \
758     QWidget * name ## PropPage = new QWidget( this );                 \
759     stackedDevLayout->addWidget( name ## DevPage );        \
760     stackedPropLayout->addWidget( name ## PropPage );      \
761     layout * name ## DevLayout = new layout;                \
762     layout * name ## PropLayout = new layout;               \
763     name ## DevPage->setLayout( name ## DevLayout );                  \
764     name ## PropPage->setLayout( name ## PropLayout );                \
765     ui.deviceCombo->addItem( qtr( label ), QVariant( number ) );
766
767 #define CuMRL( widget, slot ) CONNECT( widget , slot , this, updateMRL() );
768
769 #ifdef _WIN32
770     /*********************
771      * DirectShow Stuffs *
772      *********************/
773     if( module_exists( "dshow" ) ){
774     addModuleAndLayouts( DSHOW_DEVICE, dshow, "DirectShow", QGridLayout );
775
776     /* dshow Main */
777     int line = 0;
778     module_config_t *p_config =
779         config_FindConfig( VLC_OBJECT(p_intf), "dshow-vdev" );
780     vdevDshowW = new StringListConfigControl(
781         VLC_OBJECT(p_intf), p_config, this );
782     vdevDshowW->insertIntoExistingGrid( dshowDevLayout, line );
783     line++;
784
785     p_config = config_FindConfig( VLC_OBJECT(p_intf), "dshow-adev" );
786     adevDshowW = new StringListConfigControl(
787         VLC_OBJECT(p_intf), p_config, this );
788     adevDshowW->insertIntoExistingGrid( dshowDevLayout, line );
789     line++;
790
791     /* dshow Properties */
792     QLabel *dshowVSizeLabel = new QLabel( qtr( "Video size" ) );
793     dshowPropLayout->addWidget( dshowVSizeLabel, 0, 0 );
794
795     dshowVSizeLine = new QLineEdit;
796     dshowPropLayout->addWidget( dshowVSizeLine, 0, 1);
797     dshowPropLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding ),
798             1, 0, 3, 1 );
799
800     /* dshow CONNECTs */
801     CuMRL( vdevDshowW, changed() );
802     CuMRL( adevDshowW, changed() );
803     CuMRL( dshowVSizeLine, textChanged( const QString& ) );
804     configList << "dshow-vdev" << "dshow-adev" << "dshow-size";
805     }
806 #else /* _WIN32 */
807     /*******
808      * V4L2*
809      *******/
810     char const * const ppsz_v4lvdevices[] = {
811         "video*"
812     };
813     if( module_exists( "v4l2" ) ){
814     addModuleAndLayouts( V4L2_DEVICE, v4l2, "Video camera", QGridLayout );
815
816     /* V4L2 main panel */
817     QLabel *v4l2VideoDeviceLabel = new QLabel( qtr( "Video device name" ) );
818     v4l2DevLayout->addWidget( v4l2VideoDeviceLabel, 0, 0 );
819
820     v4l2VideoDevice = new QComboBox( this );
821     v4l2VideoDevice->setEditable( true );
822     POPULATE_WITH_DEVS( ppsz_v4lvdevices, v4l2VideoDevice );
823     v4l2DevLayout->addWidget( v4l2VideoDevice, 0, 1 );
824
825     QLabel *v4l2AudioDeviceLabel = new QLabel( qtr( "Audio device name" ) );
826     v4l2DevLayout->addWidget( v4l2AudioDeviceLabel, 1, 0 );
827
828     v4l2AudioDevice = new QComboBox( this );
829     v4l2AudioDevice->setEditable( true );
830     {
831         QStringList patterns = QStringList();
832         patterns << QString( "pcmC*D*c" );
833
834         QStringList nodes = QDir( "/dev/snd" ).entryList( patterns,
835                                                           QDir::System );
836         QStringList names = nodes.replaceInStrings( QRegExp("^pcmC"), "hw:" )
837                                  .replaceInStrings( QRegExp("c$"), "" )
838                                  .replaceInStrings( QRegExp("D"), "," );
839         v4l2AudioDevice->addItems( names );
840     }
841     v4l2AudioDevice->clearEditText();
842     v4l2DevLayout->addWidget( v4l2AudioDevice, 1, 1 );
843
844     /* v4l2 Props panel */
845     QLabel *v4l2StdLabel = new QLabel( qtr( "Video standard" ) );
846     v4l2PropLayout->addWidget( v4l2StdLabel, 0 , 0 );
847
848     v4l2StdBox = new QComboBox;
849     setfillVLCConfigCombo( "v4l2-standard", p_intf, v4l2StdBox );
850     v4l2PropLayout->addWidget( v4l2StdBox, 0 , 1 );
851     v4l2PropLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding ),
852             1, 0, 3, 2 );
853
854     /* v4l2 CONNECTs */
855     CuMRL( v4l2VideoDevice->lineEdit(), textChanged( const QString& ) );
856     CuMRL( v4l2VideoDevice,  currentIndexChanged ( int ) );
857     CuMRL( v4l2AudioDevice->lineEdit(), textChanged( const QString& ) );
858     CuMRL( v4l2AudioDevice,  currentIndexChanged ( int ) );
859     CuMRL( v4l2StdBox,  currentIndexChanged ( int ) );
860     configList << "v4l2-standard";
861     }
862
863     /*******
864      * JACK *
865      *******/
866     if( module_exists( "jack" ) ){
867     addModuleAndLayouts( JACK_DEVICE, jack, "JACK Audio Connection Kit",
868                          QGridLayout);
869
870     /* Jack Main panel */
871     /* Channels */
872     QLabel *jackChannelsLabel = new QLabel( qtr( "Channels:" ) );
873     jackDevLayout->addWidget( jackChannelsLabel, 1, 0 );
874
875     jackChannels = new QSpinBox;
876     setSpinBoxFreq( jackChannels );
877     jackChannels->setMaximum(255);
878     jackChannels->setValue(2);
879     jackChannels->setAlignment( Qt::AlignRight );
880     jackDevLayout->addWidget( jackChannels, 1, 1 );
881
882     /* Selected ports */
883     QLabel *jackPortsLabel = new QLabel( qtr( "Selected ports:" ) );
884     jackDevLayout->addWidget( jackPortsLabel, 0 , 0 );
885
886     jackPortsSelected = new QLineEdit( qtr( ".*") );
887     jackPortsSelected->setAlignment( Qt::AlignRight );
888     jackDevLayout->addWidget( jackPortsSelected, 0, 1 );
889
890     /* Jack Props panel */
891
892     /* Pace */
893     jackPace = new QCheckBox(qtr( "Use VLC pace" ));
894     jackPropLayout->addWidget( jackPace, 1, 1 );
895
896     /* Auto Connect */
897     jackConnect = new QCheckBox( qtr( "Auto connection" ));
898     jackPropLayout->addWidget( jackConnect, 1, 2 );
899
900     /* Jack CONNECTs */
901     CuMRL( jackChannels, valueChanged( int ) );
902     CuMRL( jackPace, stateChanged( int ) );
903     CuMRL( jackConnect, stateChanged( int ) );
904     CuMRL( jackPortsSelected, textChanged( const QString& ) );
905     configList << "jack-input-use-vlc-pace" << "jack-input-auto-connect";
906     }
907 #endif
908
909     /*************
910      * DVB Stuff *
911      *************/
912     if( module_exists( "dtv" ) ){
913     addModuleAndLayouts( DTV_DEVICE, dvb, N_("TV - digital"), QGridLayout );
914
915     /* DVB Main */
916     QLabel *dvbDeviceLabel = new QLabel( qtr( "Tuner card" ) );
917     QLabel *dvbTypeLabel = new QLabel( qtr( "Delivery system" ) );
918
919     dvbCard = new QSpinBox;
920     dvbCard->setAlignment( Qt::AlignRight );
921 #ifdef __unix__
922     dvbCard->setPrefix( "/dev/dvb/adapter" );
923 #endif
924     dvbDevLayout->addWidget( dvbDeviceLabel, 0, 0 );
925     dvbDevLayout->addWidget( dvbCard, 0, 1, 1, 2 );
926
927     dvbc = new QRadioButton( "DVB-C" );
928     dvbs = new QRadioButton( "DVB-S" );
929     dvbs2 = new QRadioButton( "DVB-S2" );
930     dvbt = new QRadioButton( "DVB-T" );
931     dvbt2 = new QRadioButton( "DVB-T2" );
932     atsc = new QRadioButton( "ATSC" );
933     cqam = new QRadioButton( "Clear QAM" );
934     dvbt->setChecked( true );
935
936     dvbDevLayout->addWidget( dvbTypeLabel, 1, 0, 2, 1 );
937     dvbDevLayout->addWidget( dvbc,  1, 1 );
938     dvbDevLayout->addWidget( dvbs,  1, 2 );
939     dvbDevLayout->addWidget( dvbs2, 2, 2 );
940     dvbDevLayout->addWidget( dvbt,  1, 3 );
941     dvbDevLayout->addWidget( dvbt2, 2, 3 );
942     dvbDevLayout->addWidget( atsc,  1, 4 );
943     dvbDevLayout->addWidget( cqam,  2, 4 );
944
945     /* DVB Props panel */
946     QLabel *dvbFreqLabel =
947                     new QLabel( qtr( "Transponder/multiplex frequency" ) );
948     dvbPropLayout->addWidget( dvbFreqLabel, 0, 0 );
949
950     dvbFreq = new QSpinBox;
951     dvbFreq->setAlignment( Qt::AlignRight );
952     dvbFreq->setSuffix(" kHz");
953     dvbFreq->setSingleStep( 1000 );
954     setSpinBoxFreq( dvbFreq  );
955     dvbPropLayout->addWidget( dvbFreq, 0, 1 );
956
957     dvbSrateLabel = new QLabel( qtr( "Transponder symbol rate" ) );
958     dvbPropLayout->addWidget( dvbSrateLabel, 1, 0 );
959
960     dvbSrate = new QSpinBox;
961     dvbSrate->setAlignment( Qt::AlignRight );
962     dvbSrate->setSuffix(" bauds");
963     setSpinBoxFreq( dvbSrate );
964     dvbPropLayout->addWidget( dvbSrate, 1, 1 );
965
966     dvbModLabel = new QLabel( qtr( "Modulation / Constellation" ) );
967     dvbPropLayout->addWidget( dvbModLabel, 2, 0 );
968
969     dvbQamBox = new QComboBox;
970     dvbQamBox->addItem( qtr( "Automatic" ), qfu("QAM") );
971     dvbQamBox->addItem( "256-QAM", qfu("256QAM") );
972     dvbQamBox->addItem( "128-QAM", qfu("128QAM") );
973     dvbQamBox->addItem( "64-QAM", qfu("64QAM") );
974     dvbQamBox->addItem( "32-QAM", qfu("32QAM") );
975     dvbQamBox->addItem( "16-QAM", qfu("16QAM") );
976     dvbPropLayout->addWidget( dvbQamBox, 2, 1 );
977
978     dvbPskBox = new QComboBox;
979     dvbPskBox->addItem( "QPSK", qfu("QPSK") );
980     dvbPskBox->addItem( "DQPSK", qfu("DQPSK") );
981     dvbPskBox->addItem( "8-PSK", qfu("8PSK") );
982     dvbPskBox->addItem( "16-APSK", qfu("16APSK") );
983     dvbPskBox->addItem( "32-APSK", qfu("32APSK") );
984     dvbPropLayout->addWidget( dvbPskBox, 2, 1 );
985
986     dvbModLabel->hide();
987     dvbQamBox->hide();
988     dvbPskBox->hide();
989
990     dvbBandLabel = new QLabel( qtr( "Bandwidth" ) );
991     dvbPropLayout->addWidget( dvbBandLabel, 2, 0 );
992
993     dvbBandBox = new QComboBox;
994     setfillVLCConfigCombo( "dvb-bandwidth", p_intf, dvbBandBox );
995     dvbPropLayout->addWidget( dvbBandBox, 2, 1 );
996
997     dvbBandLabel->hide();
998     dvbBandBox->hide();
999
1000     dvbPropLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding ),
1001             2, 0, 2, 1 );
1002
1003     /* DVB CONNECTs */
1004     CuMRL( dvbCard, valueChanged ( int ) );
1005     CuMRL( dvbFreq, valueChanged ( int ) );
1006     CuMRL( dvbSrate, valueChanged ( int ) );
1007     CuMRL( dvbQamBox, currentIndexChanged ( int ) );
1008     CuMRL( dvbPskBox, currentIndexChanged ( int ) );
1009     CuMRL( dvbBandBox, currentIndexChanged ( int ) );
1010
1011     BUTTONACT( dvbc, updateButtons() );
1012     BUTTONACT( dvbs, updateButtons() );
1013     BUTTONACT( dvbs2, updateButtons() );
1014     BUTTONACT( dvbt, updateButtons() );
1015     BUTTONACT( dvbt2, updateButtons() );
1016     BUTTONACT( atsc, updateButtons() );
1017     BUTTONACT( cqam, updateButtons() );
1018     BUTTONACT( dvbc, updateMRL() );
1019     BUTTONACT( dvbt, updateMRL() );
1020     BUTTONACT( dvbt2, updateMRL() );
1021     BUTTONACT( dvbs, updateMRL() );
1022     BUTTONACT( dvbs2, updateMRL() );
1023     BUTTONACT( atsc, updateMRL() );
1024     BUTTONACT( cqam, updateMRL() );
1025     configList << "dvb-adapter" << "dvb-frequency" << "dvb-modulation"
1026                << "dvb-bandwidth";
1027     }
1028
1029 #ifndef _WIN32
1030     /************
1031      * PVR      *
1032      ************/
1033     if( module_exists( "v4l2" ) ){
1034     addModuleAndLayouts( PVR_DEVICE, pvr, N_("TV - analog"), QGridLayout );
1035
1036     /* PVR Main panel */
1037     QLabel *pvrDeviceLabel = new QLabel( qtr( "Device name" ) );
1038     pvrDevLayout->addWidget( pvrDeviceLabel, 0, 0 );
1039
1040     pvrDevice = new QComboBox;
1041     pvrDevice->setEditable( true );
1042     POPULATE_WITH_DEVS( ppsz_v4lvdevices, pvrDevice );
1043     v4l2VideoDevice->clearEditText();
1044     pvrDevLayout->addWidget( pvrDevice, 0, 1 );
1045
1046     QLabel *pvrAudioDeviceLabel = new QLabel( qtr( "Audio device name" ) );
1047     pvrDevLayout->addWidget( pvrAudioDeviceLabel, 1, 0 );
1048
1049     pvrAudioDevice = new QComboBox( this );
1050     pvrAudioDevice->setEditable( true );
1051     {
1052         QStringList patterns = QStringList();
1053         patterns << QString( "pcmC*D*c" );
1054
1055         QStringList nodes = QDir( "/dev/snd" ).entryList( patterns,
1056                                                           QDir::System );
1057         QStringList names = nodes.replaceInStrings( QRegExp("^pcmC"), "hw:" )
1058                                  .replaceInStrings( QRegExp("c$"), "" )
1059                                  .replaceInStrings( QRegExp("D"), "," );
1060         pvrAudioDevice->addItems( names );
1061     }
1062     pvrAudioDevice->clearEditText();
1063     pvrDevLayout->addWidget( pvrAudioDevice, 1, 1 );
1064
1065     /* PVR props panel */
1066     QLabel *pvrNormLabel = new QLabel( qtr( "Video standard" ) );
1067     pvrPropLayout->addWidget( pvrNormLabel, 0, 0 );
1068
1069     pvrNormBox = new QComboBox;
1070     setfillVLCConfigCombo( "v4l2-standard", p_intf, pvrNormBox );
1071     pvrPropLayout->addWidget( pvrNormBox, 0, 1 );
1072
1073     QLabel *pvrFreqLabel = new QLabel( qtr( "Frequency" ) );
1074     pvrPropLayout->addWidget( pvrFreqLabel, 1, 0 );
1075
1076     pvrFreq = new QSpinBox;
1077     pvrFreq->setAlignment( Qt::AlignRight );
1078     pvrFreq->setSuffix(" kHz");
1079     setSpinBoxFreq( pvrFreq );
1080     pvrPropLayout->addWidget( pvrFreq, 1, 1 );
1081
1082     pvrPropLayout->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding ),
1083                             2, 0, 1, 1 );
1084
1085     /* PVR CONNECTs */
1086     CuMRL( pvrDevice, textChanged( const QString& ) );
1087     CuMRL( pvrAudioDevice, textChanged( const QString& ) );
1088     CuMRL( pvrFreq, valueChanged ( int ) );
1089     CuMRL( pvrNormBox, currentIndexChanged ( int ) );
1090     }
1091 #endif
1092
1093     /**********
1094      * Screen *
1095      **********/
1096     addModuleAndLayouts( SCREEN_DEVICE, screen, "Desktop", QGridLayout );
1097     QLabel *screenLabel = new QLabel( qtr( "Your display will be "
1098             "opened and played in order to stream or save it." ) );
1099     screenLabel->setWordWrap( true );
1100     screenDevLayout->addWidget( screenLabel, 0, 0 );
1101
1102     QLabel *screenFPSLabel = new QLabel(
1103             qtr( "Desired frame rate for the capture." ) );
1104     screenPropLayout->addWidget( screenFPSLabel, 0, 0 );
1105
1106     screenFPS = new QDoubleSpinBox;
1107     screenFPS->setValue( 1. );
1108     screenFPS->setRange( .01, 100. );
1109     screenFPS->setAlignment( Qt::AlignRight );
1110     /* xgettext: frames per second */
1111     screenFPS->setSuffix( qtr( " f/s" ) );
1112     screenPropLayout->addWidget( screenFPS, 0, 1 );
1113
1114     /* Screen connect */
1115     CuMRL( screenFPS, valueChanged( double ) );
1116
1117     /* General connects */
1118     CONNECT( ui.deviceCombo, activated( int ) ,
1119              stackedDevLayout, setCurrentIndex( int ) );
1120     CONNECT( ui.deviceCombo, activated( int ),
1121              stackedPropLayout, setCurrentIndex( int ) );
1122     CONNECT( ui.deviceCombo, activated( int ), this, updateMRL() );
1123     CONNECT( ui.deviceCombo, activated( int ), this, updateButtons() );
1124
1125 #undef CuMRL
1126 #undef addModuleAndLayouts
1127 }
1128
1129 CaptureOpenPanel::~CaptureOpenPanel()
1130 {
1131 }
1132
1133 void CaptureOpenPanel::clear()
1134 {
1135     advMRL.clear();
1136 }
1137
1138 void CaptureOpenPanel::updateMRL()
1139 {
1140     QString mrl = "";
1141     QStringList fileList;
1142     int i_devicetype = ui.deviceCombo->itemData(
1143             ui.deviceCombo->currentIndex() ).toInt();
1144     switch( i_devicetype )
1145     {
1146 #ifdef _WIN32
1147     case DSHOW_DEVICE:
1148         fileList << "dshow://";
1149         mrl+= " :dshow-vdev=" +
1150             colon_escape( QString("%1").arg( vdevDshowW->getValue() ) );
1151         mrl+= " :dshow-adev=" +
1152             colon_escape( QString("%1").arg( adevDshowW->getValue() ) )+" ";
1153         if( dshowVSizeLine->isModified() )
1154             mrl += ":dshow-size=" + dshowVSizeLine->text();
1155         break;
1156 #else
1157     case V4L2_DEVICE:
1158         fileList << "v4l2://" + v4l2VideoDevice->currentText();
1159         mrl += ":v4l2-standard="
1160             + v4l2StdBox->itemData( v4l2StdBox->currentIndex() ).toString();
1161         if( !v4l2AudioDevice->currentText().isEmpty() )
1162             mrl += " :input-slave=alsa://" + v4l2AudioDevice->currentText();
1163         break;
1164     case JACK_DEVICE:
1165         mrl = "jack://";
1166         mrl += "channels=" + QString::number( jackChannels->value() );
1167         mrl += ":ports=" + jackPortsSelected->text();
1168         fileList << mrl; mrl = "";
1169
1170         if ( jackPace->isChecked() )
1171         {
1172                 mrl += " :jack-input-use-vlc-pace";
1173         }
1174         if ( jackConnect->isChecked() )
1175         {
1176                 mrl += " :jack-input-auto-connect";
1177         }
1178         break;
1179     case PVR_DEVICE:
1180         fileList << "v4l2://" + pvrDevice->currentText();
1181         mrl += ":v4l2-standard="
1182             + pvrNormBox->itemData( pvrNormBox->currentIndex() ).toString();
1183         if( pvrFreq->value() )
1184             mrl += ":v4l2-tuner-frequency=" + QString::number( pvrFreq->value() );
1185         if( !pvrAudioDevice->currentText().isEmpty() )
1186             mrl += " :input-slave=" + pvrAudioDevice->currentText();
1187         break;
1188 #endif
1189     case DTV_DEVICE:
1190         if( dvbc->isChecked() ) mrl = "dvb-c://";
1191         else
1192         if( dvbs->isChecked() ) mrl = "dvb-s://";
1193         else
1194         if( dvbs2->isChecked() ) mrl = "dvb-s2://";
1195         else
1196         if( dvbt->isChecked() ) mrl = "dvb-t://";
1197         else
1198         if( dvbt2->isChecked() ) mrl = "dvb-t2://";
1199         else
1200         if( atsc->isChecked() ) mrl = "atsc://";
1201         else
1202         if( cqam->isChecked() ) mrl = "cqam://";
1203
1204         mrl += "frequency=" + QString::number( dvbFreq->value() ) + "000";
1205
1206         if( dvbc->isChecked() || cqam->isChecked() )
1207             mrl += ":modulation="
1208                 + dvbQamBox->itemData( dvbQamBox->currentIndex() ).toString();
1209         if( dvbs2->isChecked() )
1210             mrl += ":modulation="
1211                 + dvbPskBox->itemData( dvbPskBox->currentIndex() ).toString();
1212         if( dvbc->isChecked() || dvbs->isChecked() || dvbs2->isChecked() )
1213             mrl += ":srate=" + QString::number( dvbSrate->value() );
1214         if( dvbt->isChecked() || dvbt2->isChecked() )
1215             mrl += ":bandwidth=" +
1216                 QString::number( dvbBandBox->itemData(
1217                     dvbBandBox->currentIndex() ).toInt() );
1218
1219         fileList << mrl; mrl= "";
1220         mrl += " :dvb-adapter=" + QString::number( dvbCard->value() );
1221         break;
1222     case SCREEN_DEVICE:
1223         fileList << "screen://";
1224         mrl = " :screen-fps=" + QString::number( screenFPS->value(), 'f' );
1225         updateButtons();
1226         break;
1227     }
1228     emit methodChanged( "live-caching" );
1229
1230     if( !advMRL.isEmpty() ) mrl += " " + advMRL;
1231
1232     emit mrlUpdated( fileList, mrl );
1233 }
1234
1235 /**
1236  * Update the Buttons (show/hide) for the GUI as all device type don't
1237  * use the same ui. elements.
1238  **/
1239 void CaptureOpenPanel::updateButtons()
1240 {
1241     /*  Be sure to display the ui Elements in case they were hidden by
1242      *  some Device Type (like Screen://) */
1243     ui.optionsBox->show();
1244     ui.advancedButton->show();
1245     /* Get the current Device Number */
1246     int i_devicetype = ui.deviceCombo->itemData(
1247                                 ui.deviceCombo->currentIndex() ).toInt();
1248     switch( i_devicetype )
1249     {
1250     case DTV_DEVICE:
1251         dvbSrate->hide();
1252         dvbSrateLabel->hide();
1253         dvbQamBox->hide();
1254         dvbPskBox->hide();
1255         dvbModLabel->hide();
1256         dvbBandBox->hide();
1257         dvbBandLabel->hide();
1258
1259         if( dvbc->isChecked() )
1260         {
1261             dvbSrate->show();
1262             dvbSrateLabel->show();
1263             dvbQamBox->show();
1264             dvbModLabel->show();
1265         }
1266         else if( dvbs->isChecked() )
1267         {
1268             dvbSrate->show();
1269             dvbSrateLabel->show();
1270         }
1271         else if( dvbs2->isChecked() )
1272         {
1273             dvbSrate->show();
1274             dvbSrateLabel->show();
1275             dvbPskBox->show();
1276             dvbModLabel->show();
1277         }
1278         else if( dvbt->isChecked() || dvbt2->isChecked() )
1279         {
1280             dvbBandBox->show();
1281             dvbBandLabel->show();
1282         }
1283         break;
1284     case SCREEN_DEVICE:
1285         //ui.optionsBox->hide();
1286         ui.advancedButton->hide();
1287         break;
1288     }
1289
1290     advMRL.clear();
1291 }
1292
1293 void CaptureOpenPanel::enableAdvancedDialog( int i_index )
1294 {
1295     int i_devicetype = ui.deviceCombo->itemData( i_index ).toInt();
1296     module_t *p_module =
1297         module_find( psz_devModule[i_devicetype] );
1298     ui.advancedButton->setEnabled( NULL != p_module );
1299 }
1300
1301 void CaptureOpenPanel::advancedDialog()
1302 {
1303     /* Get selected device type */
1304     int i_devicetype = ui.deviceCombo->itemData(
1305                                 ui.deviceCombo->currentIndex() ).toInt();
1306
1307     /* Get the corresponding module */
1308     module_t *p_module =
1309         module_find( psz_devModule[i_devicetype] );
1310     if( NULL == p_module ) return;
1311
1312     /* Init */
1313     QList<ConfigControl *> controls;
1314
1315     /* Get the confsize  */
1316     unsigned int i_confsize;
1317     module_config_t *p_config;
1318     p_config = module_config_get( p_module, &i_confsize );
1319
1320     /* New Adv Prop dialog */
1321     adv = new QDialog( this );
1322     adv->setWindowTitle( qtr( "Advanced Options" ) );
1323     adv->setWindowRole( "vlc-advanced-options" );
1324
1325     /* A main Layout with a Frame */
1326     QVBoxLayout *mainLayout = new QVBoxLayout( adv );
1327     QScrollArea *scroll = new QScrollArea;
1328     mainLayout->addWidget( scroll );
1329
1330     QFrame *advFrame = new QFrame;
1331     /* GridLayout inside the Frame */
1332     QGridLayout *gLayout = new QGridLayout( advFrame );
1333
1334     scroll->setWidgetResizable( true );
1335     scroll->setWidget( advFrame );
1336
1337     /* Create the options inside the FrameLayout */
1338     for( int n = 0; n < (int)i_confsize; n++ )
1339     {
1340         module_config_t *p_item = p_config + n;
1341         QString name = p_item->psz_name;
1342
1343         if( name.isEmpty() || configList.contains( name ) )
1344             continue;
1345
1346         msg_Dbg( p_intf, "item %s", p_item->psz_name);
1347         ConfigControl *config = ConfigControl::createControl(
1348                         VLC_OBJECT( p_intf ), p_item, advFrame, gLayout, n );
1349         if( config )
1350             controls.append( config );
1351     }
1352
1353     /* Button stuffs */
1354     QDialogButtonBox *advButtonBox = new QDialogButtonBox( adv );
1355     QPushButton *closeButton = new QPushButton( qtr( "OK" ) );
1356     QPushButton *cancelButton = new QPushButton( qtr( "Cancel" ) );
1357
1358     CONNECT( closeButton, clicked(), adv, accept() );
1359     CONNECT( cancelButton, clicked(), adv, reject() );
1360
1361     advButtonBox->addButton( closeButton, QDialogButtonBox::AcceptRole );
1362     advButtonBox->addButton( cancelButton, QDialogButtonBox::RejectRole );
1363
1364     mainLayout->addWidget( advButtonBox );
1365
1366     /* Creation of the MRL */
1367     if( adv->exec() )
1368     {
1369         QString tempMRL = "";
1370         for( int i = 0; i < controls.count(); i++ )
1371         {
1372             ConfigControl *control = controls[i];
1373
1374             tempMRL += (i ? " :" : ":");
1375
1376             if( control->getType() == CONFIG_ITEM_BOOL )
1377                 if( !(qobject_cast<VIntConfigControl *>(control)->getValue() ) )
1378                     tempMRL += "no-";
1379
1380             tempMRL += control->getName();
1381
1382             switch( control->getType() )
1383             {
1384                 case CONFIG_ITEM_STRING:
1385                 case CONFIG_ITEM_LOADFILE:
1386                 case CONFIG_ITEM_SAVEFILE:
1387                 case CONFIG_ITEM_DIRECTORY:
1388                 case CONFIG_ITEM_MODULE:
1389                     tempMRL += colon_escape( QString("=%1").arg( qobject_cast<VStringConfigControl *>(control)->getValue() ) );
1390                     break;
1391                 case CONFIG_ITEM_INTEGER:
1392                     tempMRL += QString("=%1").arg( qobject_cast<VIntConfigControl *>(control)->getValue() );
1393                     break;
1394                 case CONFIG_ITEM_FLOAT:
1395                     tempMRL += QString("=%1").arg( qobject_cast<VFloatConfigControl *>(control)->getValue() );
1396                     break;
1397             }
1398         }
1399         advMRL = tempMRL;
1400         updateMRL();
1401     }
1402     qDeleteAll( controls );
1403     delete adv;
1404     module_config_free( p_config );
1405 }
1406