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