Add MYOB to thanks file...
[vlc.git] / modules / gui / qt4 / components / open.cpp
1 /*****************************************************************************
2  * open.cpp : Panels for the open dialogs
3  ****************************************************************************
4  * Copyright (C) 2006-2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *          Jean-Baptiste Kempf <jb@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25
26 #include "qt4.hpp"
27 #include "components/open.hpp"
28 #include "dialogs/open.hpp"
29 #include "dialogs_provider.hpp"
30 #include "util/customwidgets.hpp"
31
32 #include <QFileDialog>
33 #include <QDialogButtonBox>
34 #include <QLineEdit>
35 #include <QStackedLayout>
36 #include <QListView>
37
38 /**************************************************************************
39  * Open Files and subtitles                                               *
40  **************************************************************************/
41 FileOpenPanel::FileOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
42                                 OpenPanel( _parent, _p_intf )
43 {
44     /* Classic UI Setup */
45     ui.setupUi( this );
46
47     /* Use a QFileDialog and customize it because we don't want to
48        rewrite it all. Be careful to your eyes cause there are a few hacks.
49        Be very careful and test correctly when you modify this. */
50
51     /* Set Filters for file selection */
52     QString fileTypes = "";
53     ADD_FILTER_MEDIA( fileTypes );
54     ADD_FILTER_VIDEO( fileTypes );
55     ADD_FILTER_AUDIO( fileTypes );
56     ADD_FILTER_PLAYLIST( fileTypes );
57     ADD_FILTER_ALL( fileTypes );
58     fileTypes.replace( QString(";*"), QString(" *"));
59
60     // Make this QFileDialog a child of tempWidget from the ui.
61     dialogBox = new FileOpenBox( ui.tempWidget, NULL,
62             qfu( p_intf->p_libvlc->psz_homedir ), fileTypes );
63     dialogBox->setFileMode( QFileDialog::ExistingFiles );
64     dialogBox->setAcceptMode( QFileDialog::AcceptOpen );
65
66     /* retrieve last known path used in file browsing */
67     char *psz_filepath = config_GetPsz( p_intf, "qt-filedialog-path" );
68     if( psz_filepath )
69     {
70         dialogBox->setDirectory( QString::fromUtf8( psz_filepath ) );
71         delete psz_filepath;
72     }
73
74     /* We don't want to see a grip in the middle of the window, do we? */
75     dialogBox->setSizeGripEnabled( false );
76
77     /* Add a tooltip */
78     dialogBox->setToolTip( qtr( "Select one or multiple files, or a folder" ) );
79
80     // Add it to the layout
81     ui.gridLayout->addWidget( dialogBox, 0, 0, 1, 3 );
82
83     // But hide the two OK/Cancel buttons. Enable them for debug.
84     QDialogButtonBox *fileDialogAcceptBox =
85                                         findChildren<QDialogButtonBox*>()[0];
86     fileDialogAcceptBox->hide();
87
88     /* Ugly hacks to get the good Widget */
89     //This lineEdit is the normal line in the fileDialog.
90     lineFileEdit = findChildren<QLineEdit*>()[3];
91     lineFileEdit->hide();
92
93     /* Make a list of QLabel inside the QFileDialog to access the good ones */
94     QList<QLabel *> listLabel = findChildren<QLabel*>();
95
96     /* Hide the FileNames one. Enable it for debug */
97     listLabel[4]->hide();
98     /* Change the text that was uncool in the usual box */
99     listLabel[5]->setText( qtr( "Filter:" ) );
100
101 #if WIN32
102     /* QFileDialog is quite buggy make it brerable on win32 by tweaking 
103        the followin */
104     QListView *fileListView = findChildren<QListView*>().first();
105     fileListView->setLayoutMode(QListView::Batched);
106     fileListView->setViewMode(QListView::ListMode);
107     fileListView->setResizeMode(QListView::Adjust);
108     fileListView->setUniformItemSizes(false);
109     fileListView->setFlow(QListView::TopToBottom);
110     fileListView->setWrapping(true);
111 #endif
112
113     // Hide the subtitles control by default.
114     ui.subFrame->hide();
115
116     /* Build the subs size combo box */
117     setfillVLCConfigCombo( "freetype-rel-fontsize" , p_intf,
118                             ui.sizeSubComboBox );
119
120     /* Build the subs align combo box */
121     setfillVLCConfigCombo( "subsdec-align", p_intf, ui.alignSubComboBox );
122
123     /* Connects  */
124     BUTTONACT( ui.subBrowseButton, browseFileSub() );
125     BUTTONACT( ui.subCheckBox, toggleSubtitleFrame());
126
127     CONNECT( ui.fileInput, editTextChanged( QString ), this, updateMRL() );
128     CONNECT( ui.subInput, editTextChanged( QString ), this, updateMRL() );
129     CONNECT( ui.alignSubComboBox, currentIndexChanged( int ), this,
130                                                             updateMRL() );
131     CONNECT( ui.sizeSubComboBox, currentIndexChanged( int ), this,
132                                                             updateMRL() );
133
134     CONNECT( lineFileEdit, textChanged( QString ), this, browseFile() );
135 }
136
137 FileOpenPanel::~FileOpenPanel()
138 {}
139
140 QStringList FileOpenPanel::browse( QString help )
141 {
142     return THEDP->showSimpleOpen( help );
143 }
144
145 void FileOpenPanel::browseFile()
146 {
147     QString fileString = "";
148     foreach( QString file, dialogBox->selectedFiles() ) {
149          fileString += "\"" + file + "\" ";
150     }
151     ui.fileInput->setEditText( fileString );
152     updateMRL();
153 }
154
155 void FileOpenPanel::browseFileSub()
156 {
157     // FIXME Handle selection of more than one subtitles file
158     QStringList files = THEDP->showSimpleOpen( qtr("Open subtitles file"),
159                             EXT_FILTER_SUBTITLE,
160                             dialogBox->directory().absolutePath() );
161     if( files.isEmpty() ) return;
162     ui.subInput->setEditText( files.join(" ") );
163     updateMRL();
164 }
165
166 void FileOpenPanel::updateMRL()
167 {
168     QString mrl = ui.fileInput->currentText();
169
170     if( ui.subCheckBox->isChecked() ) {
171         mrl.append( " :sub-file=" + ui.subInput->currentText() );
172         int align = ui.alignSubComboBox->itemData(
173                     ui.alignSubComboBox->currentIndex() ).toInt();
174         mrl.append( " :subsdec-align=" + QString().setNum( align ) );
175         int size = ui.sizeSubComboBox->itemData(
176                    ui.sizeSubComboBox->currentIndex() ).toInt();
177         mrl.append( " :freetype-rel-fontsize=" + QString().setNum( size ) );
178     }
179
180     const char *psz_filepath = config_GetPsz( p_intf, "qt-filedialog-path" );
181     if( ( NULL == psz_filepath )
182       || strcmp( psz_filepath, qtu( dialogBox->directory().absolutePath() )) )
183     {
184         /* set dialog box current directory as last known path */
185         config_PutPsz( p_intf, "qt-filedialog-path",
186                        qtu( dialogBox->directory().absolutePath() ) );
187     }
188     delete psz_filepath;
189
190     emit mrlUpdated( mrl );
191     emit methodChanged( "file-caching" );
192 }
193
194
195 /* Function called by Open Dialog when clicke on Play/Enqueue */
196 void FileOpenPanel::accept()
197 {
198     ui.fileInput->addItem( ui.fileInput->currentText());
199     if ( ui.fileInput->count() > 8 ) ui.fileInput->removeItem( 0 );
200 }
201
202 void FileOpenBox::accept()
203 {
204     OpenDialog::getInstance( NULL, NULL )->play();
205 }
206
207 /* Function called by Open Dialog when clicked on cancel */
208 void FileOpenPanel::clear()
209 {
210     ui.fileInput->setEditText( "" );
211     ui.subInput->setEditText( "" );
212 }
213
214 void FileOpenPanel::toggleSubtitleFrame()
215 {
216     if ( ui.subFrame->isVisible() )
217     {
218         ui.subFrame->hide();
219         updateGeometry();
220     /* FiXME Size */
221     }
222     else
223     {
224         ui.subFrame->show();
225     }
226
227     /* Update the MRL */
228     updateMRL();
229 }
230
231 /**************************************************************************
232  * Open Discs ( DVD, CD, VCD and similar devices )                        *
233  **************************************************************************/
234 DiscOpenPanel::DiscOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
235                                 OpenPanel( _parent, _p_intf )
236 {
237     ui.setupUi( this );
238
239     /*Win 32 Probe  as in WX ? */
240
241     /* CONNECTs */
242     BUTTONACT( ui.dvdRadioButton, updateButtons());
243     BUTTONACT( ui.vcdRadioButton, updateButtons());
244     BUTTONACT( ui.audioCDRadioButton, updateButtons());
245     BUTTONACT( ui.dvdsimple,  updateButtons());
246
247     CONNECT( ui.deviceCombo, editTextChanged( QString ), this, updateMRL());
248     CONNECT( ui.titleSpin, valueChanged( int ), this, updateMRL());
249     CONNECT( ui.chapterSpin, valueChanged( int ), this, updateMRL());
250     CONNECT( ui.audioSpin, valueChanged( int ), this, updateMRL());
251     CONNECT( ui.subtitlesSpin, valueChanged( int ), this, updateMRL());
252 }
253
254 DiscOpenPanel::~DiscOpenPanel()
255 {}
256
257 void DiscOpenPanel::clear()
258 {
259     ui.titleSpin->setValue( 0 );
260     ui.chapterSpin->setValue( 0 );
261 }
262
263 void DiscOpenPanel::updateButtons()
264 {
265     if ( ui.dvdRadioButton->isChecked() )
266     {
267         ui.titleLabel->setText( qtr("Title") );
268         ui.chapterLabel->show();
269         ui.chapterSpin->show();
270         ui.diskOptionBox_2->show();
271     }
272     else if ( ui.vcdRadioButton->isChecked() )
273     {
274         ui.titleLabel->setText( qtr("Entry") );
275         ui.chapterLabel->hide();
276         ui.chapterSpin->hide();
277         ui.diskOptionBox_2->show();
278     }
279     else
280     {
281         ui.titleLabel->setText( qtr("Track") );
282         ui.chapterLabel->hide();
283         ui.chapterSpin->hide();
284         ui.diskOptionBox_2->hide();
285     }
286
287     updateMRL();
288 }
289
290
291 void DiscOpenPanel::updateMRL()
292 {
293     QString mrl = "";
294
295     /* CDDAX and VCDX not implemented. FIXME ? */
296     /* DVD */
297     if( ui.dvdRadioButton->isChecked() ) {
298         if( !ui.dvdsimple->isChecked() )
299             mrl = "dvd://";
300         else
301             mrl = "dvdsimple://";
302         mrl += ui.deviceCombo->currentText();
303         emit methodChanged( "dvdnav-caching" );
304
305         if ( ui.titleSpin->value() > 0 ) {
306             mrl += QString("@%1").arg( ui.titleSpin->value() );
307             if ( ui.chapterSpin->value() > 0 ) {
308                 mrl+= QString(":%1").arg( ui.chapterSpin->value() );
309             }
310         }
311
312     /* VCD */
313     } else if ( ui.vcdRadioButton->isChecked() ) {
314         mrl = "vcd://" + ui.deviceCombo->currentText();
315         emit methodChanged( "vcd-caching" );
316
317         if( ui.titleSpin->value() > 0 ) {
318             mrl += QString("@E%1").arg( ui.titleSpin->value() );
319         }
320
321     /* CDDA */
322     } else {
323         mrl = "cdda://" + ui.deviceCombo->currentText();
324         if( ui.titleSpin->value() > 0 ) {
325             QString("@%1").arg( ui.titleSpin->value() );
326         }
327     }
328
329     if ( ui.dvdRadioButton->isChecked() || ui.vcdRadioButton->isChecked() )
330     {
331         if ( ui.audioSpin->value() >= 0 ) {
332             mrl += " :audio-track=" +
333                 QString("%1").arg( ui.audioSpin->value() );
334         }
335         if ( ui.subtitlesSpin->value() >= 0 ) {
336             mrl += " :sub-track=" +
337                 QString("%1").arg( ui.subtitlesSpin->value() );
338         }
339     }
340     emit mrlUpdated( mrl );
341 }
342
343
344
345 /**************************************************************************
346  * Open Network streams and URL pages                                     *
347  **************************************************************************/
348 NetOpenPanel::NetOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
349                                 OpenPanel( _parent, _p_intf )
350 {
351     ui.setupUi( this );
352
353     /* CONNECTs */
354     CONNECT( ui.protocolCombo, currentIndexChanged( int ),
355              this, updateProtocol( int ) );
356     CONNECT( ui.portSpin, valueChanged( int ), this, updateMRL() );
357     CONNECT( ui.addressText, textChanged( QString ), this, updateAddress());
358     CONNECT( ui.timeShift, clicked(), this, updateMRL());
359     CONNECT( ui.ipv6, clicked(), this, updateMRL());
360
361     ui.protocolCombo->addItem("HTTP", QVariant("http"));
362     ui.protocolCombo->addItem("HTTPS", QVariant("https"));
363     ui.protocolCombo->addItem("FTP", QVariant("ftp"));
364     ui.protocolCombo->addItem("MMS", QVariant("mms"));
365     ui.protocolCombo->addItem("RTSP", QVariant("rtsp"));
366     ui.protocolCombo->addItem("UDP/RTP (unicast)", QVariant("udp"));
367     ui.protocolCombo->addItem("UDP/RTP (multicast)", QVariant("udp"));
368 }
369
370 NetOpenPanel::~NetOpenPanel()
371 {}
372
373 void NetOpenPanel::clear()
374 {}
375
376 void NetOpenPanel::updateProtocol( int idx ) {
377     QString addr = ui.addressText->text();
378     QString proto = ui.protocolCombo->itemData( idx ).toString();
379
380     ui.timeShift->setEnabled( idx >= 4 );
381     ui.ipv6->setEnabled( idx == 4 );
382     ui.addressText->setEnabled( idx != 4 );
383     ui.portSpin->setEnabled( idx >= 4 );
384
385     /* If we already have a protocol in the address, replace it */
386     if( addr.contains( "://")) {
387         msg_Err( p_intf, "replace");
388         addr.replace( QRegExp("^.*://"), proto + "://");
389         ui.addressText->setText( addr );
390     }
391     updateMRL();
392 }
393
394 void NetOpenPanel::updateAddress() {
395     updateMRL();
396 }
397
398 void NetOpenPanel::updateMRL() {
399     QString mrl = "";
400     QString addr = ui.addressText->text();
401     int proto = ui.protocolCombo->currentIndex();
402
403     if( addr.contains( "://") && proto != 4 ) {
404         mrl = addr;
405     } else {
406         switch( proto ) {
407         case 0:
408         case 1:
409             mrl = "http://" + addr;
410             emit methodChanged("http-caching");
411             break;
412         case 3:
413             mrl = "mms://" + addr;
414             emit methodChanged("mms-caching");
415             break;
416         case 2:
417             mrl = "ftp://" + addr;
418             emit methodChanged("ftp-caching");
419             break;
420         case 4: /* RTSP */
421             mrl = "rtsp://" + addr;
422             emit methodChanged("rtsp-caching");
423             break;
424         case 5:
425             mrl = "udp://@";
426             if( ui.ipv6->isEnabled() && ui.ipv6->isChecked() ) {
427                 mrl += "[::]";
428             }
429             mrl += QString(":%1").arg( ui.portSpin->value() );
430             emit methodChanged("udp-caching");
431             break;
432         case 6: /* UDP multicast */
433             mrl = "udp://@";
434             /* Add [] to IPv6 */
435             if ( addr.contains(':') && !addr.contains('[') ) {
436                 mrl += "[" + addr + "]";
437             } else mrl += addr;
438             mrl += QString(":%1").arg( ui.portSpin->value() );
439             emit methodChanged("udp-caching");
440         }
441     }
442     if( ui.timeShift->isEnabled() && ui.timeShift->isChecked() ) {
443         mrl += " :access-filter=timeshift";
444     }
445     emit mrlUpdated( mrl );
446 }
447
448 /**************************************************************************
449  * Open Capture device ( DVB, PVR, V4L, and similar )                     *
450  **************************************************************************/
451 CaptureOpenPanel::CaptureOpenPanel( QWidget *_parent, intf_thread_t *_p_intf ) :
452                                 OpenPanel( _parent, _p_intf )
453 {
454     ui.setupUi( this );
455
456     /* Create two stacked layouts in the main comboBoxes */
457     QStackedLayout *stackedDevLayout = new QStackedLayout;
458     ui.cardBox->setLayout( stackedDevLayout );
459
460     QStackedLayout *stackedPropLayout = new QStackedLayout;
461     ui.optionsBox->setLayout( stackedPropLayout );
462
463     /* Creation and connections of the WIdgets in the stacked layout */
464 #define addModuleAndLayouts( number, name, label )                    \
465     QWidget * name ## DevPage = new QWidget( this );                  \
466     QWidget * name ## PropPage = new QWidget( this );                 \
467     stackedDevLayout->addWidget( name ## DevPage );        \
468     stackedPropLayout->addWidget( name ## PropPage );      \
469     QGridLayout * name ## DevLayout = new QGridLayout;                \
470     QGridLayout * name ## PropLayout = new QGridLayout;               \
471     name ## DevPage->setLayout( name ## DevLayout );                  \
472     name ## PropPage->setLayout( name ## PropLayout );                \
473     ui.deviceCombo->addItem( qtr( label ), QVariant( number ) );
474
475 #define CuMRL( widget, slot ) CONNECT( widget , slot , this, updateMRL() );
476
477     /*******
478      * V4L *
479      *******/
480     addModuleAndLayouts( V4L_DEVICE, v4l, "Video for Linux" );
481
482     /* V4l Main panel */
483     QLabel *v4lVideoDeviceLabel = new QLabel( qtr( "Video device name" ) );
484     v4lDevLayout->addWidget( v4lVideoDeviceLabel, 0, 0 );
485
486     v4lVideoDevice = new QLineEdit;
487     v4lDevLayout->addWidget( v4lVideoDevice, 0, 1 );
488
489     QLabel *v4lAudioDeviceLabel = new QLabel( qtr( "Audio device name" ) );
490     v4lDevLayout->addWidget( v4lAudioDeviceLabel, 1, 0 );
491
492     v4lAudioDevice = new QLineEdit;
493     v4lDevLayout->addWidget( v4lAudioDevice, 1, 1 );
494
495     /* V4l Props panel */
496     QLabel *v4lNormLabel = new QLabel( qtr( "Norm" ) );
497     v4lPropLayout->addWidget( v4lNormLabel, 0 , 0 );
498
499     v4lNormBox = new QComboBox;
500     setfillVLCConfigCombo( "v4l-norm", p_intf, v4lNormBox );
501     v4lPropLayout->addWidget( v4lNormBox, 0 , 1 );
502
503     QLabel *v4lFreqLabel = new QLabel( qtr( "Frequency" ) );
504     v4lPropLayout->addWidget( v4lFreqLabel, 1 , 0 );
505
506     v4lFreq = new QSpinBox;
507     v4lFreq->setAlignment( Qt::AlignRight );
508     v4lFreq->setSuffix(" kHz");
509     setSpinBoxFreq( v4lFreq );
510     v4lPropLayout->addWidget( v4lFreq, 1 , 1 );
511
512     /* v4l CONNECTs */
513     CuMRL( v4lVideoDevice, textChanged( QString ) );
514     CuMRL( v4lAudioDevice, textChanged( QString ) );
515     CuMRL( v4lFreq, valueChanged ( int ) );
516     CuMRL( v4lNormBox,  currentIndexChanged ( int ) );
517
518     /************
519      * PVR      *
520      ************/
521     addModuleAndLayouts( PVR_DEVICE, pvr, "PVR" );
522
523     /* PVR Main panel */
524     QLabel *pvrDeviceLabel = new QLabel( qtr( "Device name" ) );
525     pvrDevLayout->addWidget( pvrDeviceLabel, 0, 0 );
526
527     pvrDevice = new QLineEdit;
528     pvrDevLayout->addWidget( pvrDevice, 0, 1 );
529
530     QLabel *pvrRadioDeviceLabel = new QLabel( qtr( "Radio device name" ) );
531     pvrDevLayout->addWidget( pvrRadioDeviceLabel, 1, 0 );
532
533     pvrRadioDevice = new QLineEdit;
534     pvrDevLayout->addWidget( pvrRadioDevice, 1, 1 );
535
536     /* PVR props panel */
537     QLabel *pvrNormLabel = new QLabel( qtr( "Norm" ) );
538     pvrPropLayout->addWidget( pvrNormLabel, 0, 0 );
539
540     pvrNormBox = new QComboBox;
541     setfillVLCConfigCombo( "pvr-norm", p_intf, pvrNormBox );
542     pvrPropLayout->addWidget( pvrNormBox, 0, 1 );
543
544     QLabel *pvrFreqLabel = new QLabel( qtr( "Frequency" ) );
545     pvrPropLayout->addWidget( pvrFreqLabel, 1, 0 );
546
547     pvrFreq = new QSpinBox;
548     pvrFreq->setAlignment( Qt::AlignRight );
549     pvrFreq->setSuffix(" kHz");
550     setSpinBoxFreq( pvrFreq );
551     pvrPropLayout->addWidget( pvrFreq, 1, 1 );
552
553     QLabel *pvrBitrLabel = new QLabel( qtr( "Bitrate" ) );
554     pvrPropLayout->addWidget( pvrBitrLabel, 2, 0 );
555
556     pvrBitr = new QSpinBox;
557     pvrBitr->setAlignment( Qt::AlignRight );
558     pvrBitr->setSuffix(" kHz");
559     setSpinBoxFreq( pvrBitr );
560     pvrPropLayout->addWidget( pvrBitr, 2, 1 );
561
562     /* PVR CONNECTs */
563     CuMRL( pvrDevice, textChanged( QString ) );
564     CuMRL( pvrRadioDevice, textChanged( QString ) );
565
566     CuMRL( pvrFreq, valueChanged ( int ) );
567     CuMRL( pvrBitr, valueChanged ( int ) );
568     CuMRL( pvrNormBox,  currentIndexChanged ( int ) );
569
570     /*********************
571      * DirectShow Stuffs *
572      *********************/
573     addModuleAndLayouts( DSHOW_DEVICE, dshow, "DirectShow" );
574
575     /* dshow Main */
576
577     QLabel *dshowVDeviceLabel = new QLabel( qtr( "Video Device Name " ) );
578     dshowDevLayout->addWidget( dshowVDeviceLabel, 0, 0 );
579
580     QLabel *dshowADeviceLabel = new QLabel( qtr( "Audio Device Name " ) );
581     dshowDevLayout->addWidget( dshowADeviceLabel, 1, 0 );
582
583     QComboBox *dshowVDevice = new QComboBox;
584     dshowDevLayout->addWidget( dshowVDevice, 0, 1 );
585
586     QComboBox *dshowADevice = new QComboBox;
587     dshowDevLayout->addWidget( dshowADevice, 1, 1 );
588
589     QPushButton *dshowVRefresh = new QPushButton( qtr( "Update List" ) );
590     dshowDevLayout->addWidget( dshowVRefresh, 0, 2 );
591
592     QPushButton *dshowARefresh = new QPushButton( qtr( "Update List" ) );
593     dshowDevLayout->addWidget( dshowARefresh, 1, 2 );
594
595     QPushButton *dshowVConfig = new QPushButton( qtr( "Configure" ) );
596     dshowDevLayout->addWidget( dshowVConfig, 0, 3 );
597
598     QPushButton *dshowAConfig = new QPushButton( qtr( "Configure" ) );
599     dshowDevLayout->addWidget( dshowAConfig, 1, 3 );
600
601     /* dshow Properties */
602
603     QLabel *dshowVSizeLabel = new QLabel( qtr( "Video size" ) );
604     dshowPropLayout->addWidget( dshowVSizeLabel, 0, 0 );
605
606     QLineEdit *dshowVSizeLine = new QLineEdit;
607     dshowPropLayout->addWidget( dshowVSizeLine, 0, 1);
608
609     /* dshow CONNECTs */
610     CuMRL( dshowVDevice, currentIndexChanged ( int ) );
611     CuMRL( dshowADevice, currentIndexChanged ( int ) );
612     CuMRL( dshowVSizeLine, textChanged( QString ) );
613
614     /**************
615      * BDA Stuffs *
616      **************/
617     addModuleAndLayouts( BDA_DEVICE, bda, "DVB DirectShow" );
618
619     /* bda Main */
620     QLabel *bdaTypeLabel = new QLabel( qtr( "DVB Type:" ) );
621
622     bdas = new QRadioButton( "DVB-S" );
623     bdas->setChecked( true );
624     bdac = new QRadioButton( "DVB-C" );
625     bdat = new QRadioButton( "DVB-T" );
626
627     bdaDevLayout->addWidget( bdaTypeLabel, 0, 0 );
628     bdaDevLayout->addWidget( bdas, 0, 1 );
629     bdaDevLayout->addWidget( bdac, 0, 2 );
630     bdaDevLayout->addWidget( bdat, 0, 3 );
631
632     /* bda Props */
633     QLabel *bdaFreqLabel =
634                     new QLabel( qtr( "Transponder/multiplex frequency" ) );
635     bdaPropLayout->addWidget( bdaFreqLabel, 0, 0 );
636
637     bdaFreq = new QSpinBox;
638     bdaFreq->setAlignment( Qt::AlignRight );
639     bdaFreq->setSuffix(" kHz");
640     bdaFreq->setSingleStep( 1000 );
641     setSpinBoxFreq( bdaFreq )
642     bdaPropLayout->addWidget( bdaFreq, 0, 1 );
643
644     bdaSrateLabel = new QLabel( qtr( "Transponder symbol rate" ) );
645     bdaPropLayout->addWidget( bdaSrateLabel, 1, 0 );
646
647     bdaSrate = new QSpinBox;
648     bdaSrate->setAlignment( Qt::AlignRight );
649     bdaSrate->setSuffix(" kHz");
650     setSpinBoxFreq( bdaSrate );
651     bdaPropLayout->addWidget( bdaSrate, 1, 1 );
652
653     bdaBandLabel = new QLabel( qtr( "Bandwidth" ) );
654     bdaPropLayout->addWidget( bdaBandLabel, 2, 0 );
655
656     bdaBandBox = new QComboBox;
657     setfillVLCConfigCombo( "dvb-bandwidth", p_intf, bdaBandBox );
658     bdaPropLayout->addWidget( bdaBandBox, 2, 1 );
659
660     bdaBandLabel->hide();
661     bdaBandBox->hide();
662
663     /* bda CONNECTs */
664     CuMRL( bdaFreq, valueChanged ( int ) );
665     CuMRL( bdaSrate, valueChanged ( int ) );
666     CuMRL( bdaBandBox,  currentIndexChanged ( int ) );
667     BUTTONACT( bdas, updateButtons() );
668     BUTTONACT( bdat, updateButtons() );
669     BUTTONACT( bdac, updateButtons() );
670     BUTTONACT( bdas, updateMRL() );
671     BUTTONACT( bdat, updateMRL() );
672     BUTTONACT( bdac, updateMRL() );
673
674     /**************
675      * DVB Stuffs *
676      **************/
677     addModuleAndLayouts( DVB_DEVICE, dvb, "DVB" );
678
679     /* DVB Main */
680     QLabel *dvbDeviceLabel = new QLabel( qtr( "Adapter card to tune" ) );
681     QLabel *dvbTypeLabel = new QLabel( qtr( "DVB Type:" ) );
682
683     dvbCard = new QSpinBox;
684     dvbCard->setAlignment( Qt::AlignRight );
685     dvbCard->setPrefix( "/dev/dvb/adapter" );
686
687     dvbDevLayout->addWidget( dvbDeviceLabel, 0, 0 );
688     dvbDevLayout->addWidget( dvbCard, 0, 2, 1, 2 );
689
690     dvbs = new QRadioButton( "DVB-S" );
691     dvbs->setChecked( true );
692     dvbc = new QRadioButton( "DVB-C" );
693     dvbt = new QRadioButton( "DVB-T" );
694
695     dvbDevLayout->addWidget( dvbTypeLabel, 1, 0 );
696     dvbDevLayout->addWidget( dvbs, 1, 1 );
697     dvbDevLayout->addWidget( dvbc, 1, 2 );
698     dvbDevLayout->addWidget( dvbt, 1, 3 );
699
700     /* DVB Props panel */
701     QLabel *dvbFreqLabel =
702                     new QLabel( qtr( "Transponder/multiplex frequency" ) );
703     dvbPropLayout->addWidget( dvbFreqLabel, 0, 0 );
704
705     dvbFreq = new QSpinBox;
706     dvbFreq->setAlignment( Qt::AlignRight );
707     dvbFreq->setSuffix(" kHz");
708     setSpinBoxFreq( dvbFreq  );
709     dvbPropLayout->addWidget( dvbFreq, 0, 1 );
710
711     QLabel *dvbSrateLabel = new QLabel( qtr( "Transponder symbol rate" ) );
712     dvbPropLayout->addWidget( dvbSrateLabel, 1, 0 );
713
714     dvbSrate = new QSpinBox;
715     dvbSrate->setAlignment( Qt::AlignRight );
716     dvbSrate->setSuffix(" kHz");
717     setSpinBoxFreq( dvbSrate );
718     dvbPropLayout->addWidget( dvbSrate, 1, 1 );
719
720     /* DVB CONNECTs */
721     CuMRL( dvbCard, valueChanged ( int ) );
722     CuMRL( dvbFreq, valueChanged ( int ) );
723     CuMRL( dvbSrate, valueChanged ( int ) );
724
725     BUTTONACT( dvbs, updateButtons() );
726     BUTTONACT( dvbt, updateButtons() );
727     BUTTONACT( dvbc, updateButtons() );
728
729     /**********
730      * Screen *
731      **********/
732
733     addModuleAndLayouts( SCREEN_DEVICE, screen, "Desktop" );
734     QLabel *screenLabel = new QLabel( "This option will open your own "
735             "desktop in order to save or stream it.");
736     screenLabel->setWordWrap( true );
737     screenDevLayout->addWidget( screenLabel, 0, 0 );
738
739
740     /* General connects */
741     connect( ui.deviceCombo, SIGNAL( activated( int ) ),
742                      stackedDevLayout, SLOT( setCurrentIndex( int ) ) );
743     connect( ui.deviceCombo, SIGNAL( activated( int ) ),
744                      stackedPropLayout, SLOT( setCurrentIndex( int ) ) );
745     CONNECT( ui.deviceCombo, activated( int ), this, updateMRL() );
746     CONNECT( ui.deviceCombo, activated( int ), this, updateButtons() );
747
748 #undef addModule
749 }
750
751 CaptureOpenPanel::~CaptureOpenPanel()
752 {}
753
754 void CaptureOpenPanel::clear()
755 {}
756
757 void CaptureOpenPanel::updateMRL()
758 {
759     QString mrl = "";
760     int i_devicetype = ui.deviceCombo->itemData(
761             ui.deviceCombo->currentIndex() ).toInt();
762     msg_Dbg( p_intf, "Capture Type: %i", i_devicetype );
763     switch( i_devicetype )
764     {
765     case V4L_DEVICE:
766         mrl = "v4l://";
767         mrl += " :v4l-vdev=" + v4lVideoDevice->text();
768         mrl += " :v4l-adev=" + v4lAudioDevice->text();
769         mrl += " :v4l-norm=" + QString("%1").arg( v4lNormBox->currentIndex() );
770         mrl += " :v4l-frequency=" + QString("%1").arg( v4lFreq->value() );
771         break;
772     case PVR_DEVICE:
773         mrl = "pvr://";
774         mrl += " :pvr-device=" + pvrDevice->text();
775         mrl += " :pvr-radio-device=" + pvrRadioDevice->text();
776         mrl += " :pvr-norm=" + QString("%1").arg( pvrNormBox->currentIndex() );
777         if( pvrFreq->value() )
778             mrl += " :pvr-frequency=" + QString("%1").arg( pvrFreq->value() );
779         if( pvrBitr->value() )
780             mrl += " :pvr-bitrate=" + QString("%1").arg( pvrBitr->value() );
781         break;
782     case DVB_DEVICE:
783         mrl = "dvb://";
784         mrl += " :dvb-adapter=" + QString("%1").arg( dvbCard->value() );
785         mrl += " :dvb-frequency=" + QString("%1").arg( dvbFreq->value() );
786         mrl += " :dvb-srate=" + QString("%1").arg( dvbSrate->value() );
787         break;
788     case BDA_DEVICE:
789         if( bdas->isChecked() ) mrl = "dvb-s://";
790         else if(  bdat->isChecked() ) mrl = "dvb-t://";
791         else if(  bdac->isChecked() ) mrl = "dvb-c://";
792         else return;
793         mrl += " :dvb-frequency=" + QString("%1").arg( bdaFreq->value() );
794         if( bdas->isChecked() || bdac->isChecked() )
795             mrl += " :dvb-srate=" + QString("%1").arg( bdaSrate->value() );
796         else
797             mrl += " :dvb-bandwidth=" +
798                 QString("%1").arg( bdaBandBox->itemData(
799                     bdaBandBox->currentIndex() ).toInt() );
800         break;
801     case DSHOW_DEVICE:
802         break;
803     case SCREEN_DEVICE:
804         mrl = "screen://";
805         updateButtons();
806         break;
807     }
808     emit mrlUpdated( mrl );
809 }
810
811 /**
812  * Update the Buttons (show/hide) for the GUI as all device type don't 
813  * use the same ui. elements.
814  **/
815 void CaptureOpenPanel::updateButtons()
816 {
817     /*  Be sure to display the ui Elements in case they were hidden by
818      *  some Device Type (like Screen://) */
819     ui.optionsBox->show();
820     ui.advancedButton->show();
821     /* Get the current Device Number */
822     int i_devicetype = ui.deviceCombo->itemData(
823                                 ui.deviceCombo->currentIndex() ).toInt();
824     msg_Dbg( p_intf, "Capture Type: %i", i_devicetype );
825     switch( i_devicetype )
826     {
827     case DVB_DEVICE:
828         if( dvbs->isChecked() ) dvbFreq->setSuffix(" kHz");
829         if( dvbc->isChecked() || dvbt->isChecked() ) dvbFreq->setSuffix(" Hz");
830         break;
831     case BDA_DEVICE:
832         if( bdas->isChecked() || bdac->isChecked() )
833         {
834             bdaSrate->show();
835             bdaSrateLabel->show();
836             bdaBandBox->hide();
837             bdaBandLabel->hide();
838         }
839         else
840         {
841             bdaSrate->hide();
842             bdaSrateLabel->hide();
843             bdaBandBox->show();
844             bdaBandLabel->show();
845         }
846         break;
847     case SCREEN_DEVICE:
848         ui.optionsBox->hide();
849         ui.advancedButton->hide();
850         break;
851     }
852 }