164e5da49bfeb37d288653ebe72ad74bb93c7172
[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     /*******
479      * V4L *
480      *******/
481     addModuleAndLayouts( V4L_DEVICE, v4l, "Video for Linux" );
482
483     /* V4l Main panel */
484     QLabel *v4lVideoDeviceLabel = new QLabel( qtr( "Video device name" ) );
485     v4lDevLayout->addWidget( v4lVideoDeviceLabel, 0, 0 );
486
487     v4lVideoDevice = new QLineEdit;
488     v4lDevLayout->addWidget( v4lVideoDevice, 0, 1 );
489
490     QLabel *v4lAudioDeviceLabel = new QLabel( qtr( "Audio device name" ) );
491     v4lDevLayout->addWidget( v4lAudioDeviceLabel, 1, 0 );
492
493     v4lAudioDevice = new QLineEdit;
494     v4lDevLayout->addWidget( v4lAudioDevice, 1, 1 );
495
496     /* V4l Props panel */
497     QLabel *v4lNormLabel = new QLabel( qtr( "Norm" ) );
498     v4lPropLayout->addWidget( v4lNormLabel, 0 , 0 );
499
500     v4lNormBox = new QComboBox;
501     setfillVLCConfigCombo( "v4l-norm", p_intf, v4lNormBox );
502     v4lPropLayout->addWidget( v4lNormBox, 0 , 1 );
503
504     QLabel *v4lFreqLabel = new QLabel( qtr( "Frequency" ) );
505     v4lPropLayout->addWidget( v4lFreqLabel, 1 , 0 );
506
507     v4lFreq = new QSpinBox;
508     v4lFreq->setAlignment( Qt::AlignRight );
509     v4lFreq->setSuffix(" kHz");
510     setSpinBoxFreq( v4lFreq );
511     v4lPropLayout->addWidget( v4lFreq, 1 , 1 );
512
513     /* v4l CONNECTs */
514     CuMRL( v4lVideoDevice, textChanged( QString ) );
515     CuMRL( v4lAudioDevice, textChanged( QString ) );
516     CuMRL( v4lFreq, valueChanged ( int ) );
517     CuMRL( v4lNormBox,  currentIndexChanged ( int ) );
518
519     /************
520      * PVR      *
521      ************/
522     addModuleAndLayouts( PVR_DEVICE, pvr, "PVR" );
523
524     /* PVR Main panel */
525     QLabel *pvrDeviceLabel = new QLabel( qtr( "Device name" ) );
526     pvrDevLayout->addWidget( pvrDeviceLabel, 0, 0 );
527
528     pvrDevice = new QLineEdit;
529     pvrDevLayout->addWidget( pvrDevice, 0, 1 );
530
531     QLabel *pvrRadioDeviceLabel = new QLabel( qtr( "Radio device name" ) );
532     pvrDevLayout->addWidget( pvrRadioDeviceLabel, 1, 0 );
533
534     pvrRadioDevice = new QLineEdit;
535     pvrDevLayout->addWidget( pvrRadioDevice, 1, 1 );
536
537     /* PVR props panel */
538     QLabel *pvrNormLabel = new QLabel( qtr( "Norm" ) );
539     pvrPropLayout->addWidget( pvrNormLabel, 0, 0 );
540
541     pvrNormBox = new QComboBox;
542     setfillVLCConfigCombo( "pvr-norm", p_intf, pvrNormBox );
543     pvrPropLayout->addWidget( pvrNormBox, 0, 1 );
544
545     QLabel *pvrFreqLabel = new QLabel( qtr( "Frequency" ) );
546     pvrPropLayout->addWidget( pvrFreqLabel, 1, 0 );
547
548     pvrFreq = new QSpinBox;
549     pvrFreq->setAlignment( Qt::AlignRight );
550     pvrFreq->setSuffix(" kHz");
551     setSpinBoxFreq( pvrFreq );
552     pvrPropLayout->addWidget( pvrFreq, 1, 1 );
553
554     QLabel *pvrBitrLabel = new QLabel( qtr( "Bitrate" ) );
555     pvrPropLayout->addWidget( pvrBitrLabel, 2, 0 );
556
557     pvrBitr = new QSpinBox;
558     pvrBitr->setAlignment( Qt::AlignRight );
559     pvrBitr->setSuffix(" kHz");
560     setSpinBoxFreq( pvrBitr );
561     pvrPropLayout->addWidget( pvrBitr, 2, 1 );
562
563     /* PVR CONNECTs */
564     CuMRL( pvrDevice, textChanged( QString ) );
565     CuMRL( pvrRadioDevice, textChanged( QString ) );
566
567     CuMRL( pvrFreq, valueChanged ( int ) );
568     CuMRL( pvrBitr, valueChanged ( int ) );
569     CuMRL( pvrNormBox,  currentIndexChanged ( int ) );
570
571     /*********************
572      * DirectShow Stuffs *
573      *********************/
574     addModuleAndLayouts( DSHOW_DEVICE, dshow, "DirectShow" );
575
576     /* dshow Main */
577
578     QLabel *dshowVDeviceLabel = new QLabel( qtr( "Video Device Name " ) );
579     dshowDevLayout->addWidget( dshowVDeviceLabel, 0, 0 );
580
581     QLabel *dshowADeviceLabel = new QLabel( qtr( "Audio Device Name " ) );
582     dshowDevLayout->addWidget( dshowADeviceLabel, 1, 0 );
583
584     QComboBox *dshowVDevice = new QComboBox;
585     dshowDevLayout->addWidget( dshowVDevice, 0, 1 );
586
587     QComboBox *dshowADevice = new QComboBox;
588     dshowDevLayout->addWidget( dshowADevice, 1, 1 );
589
590     QPushButton *dshowVRefresh = new QPushButton( qtr( "Update List" ) );
591     dshowDevLayout->addWidget( dshowVRefresh, 0, 2 );
592
593     QPushButton *dshowARefresh = new QPushButton( qtr( "Update List" ) );
594     dshowDevLayout->addWidget( dshowARefresh, 1, 2 );
595
596     QPushButton *dshowVConfig = new QPushButton( qtr( "Configure" ) );
597     dshowDevLayout->addWidget( dshowVConfig, 0, 3 );
598
599     QPushButton *dshowAConfig = new QPushButton( qtr( "Configure" ) );
600     dshowDevLayout->addWidget( dshowAConfig, 1, 3 );
601
602     /* dshow Properties */
603
604     QLabel *dshowVSizeLabel = new QLabel( qtr( "Video size" ) );
605     dshowPropLayout->addWidget( dshowVSizeLabel, 0, 0 );
606
607     QLineEdit *dshowVSizeLine = new QLineEdit;
608     dshowPropLayout->addWidget( dshowVSizeLine, 0, 1);
609
610     /* dshow CONNECTs */
611     CuMRL( dshowVDevice, currentIndexChanged ( int ) );
612     CuMRL( dshowADevice, currentIndexChanged ( int ) );
613     CuMRL( dshowVSizeLine, textChanged( QString ) );
614
615     /**************
616      * BDA Stuffs *
617      **************/
618     addModuleAndLayouts( BDA_DEVICE, bda, "DVB DirectShow" );
619
620     /* bda Main */
621     QLabel *bdaTypeLabel = new QLabel( qtr( "DVB Type:" ) );
622
623     bdas = new QRadioButton( "DVB-S" );
624     bdas->setChecked( true );
625     bdac = new QRadioButton( "DVB-C" );
626     bdat = new QRadioButton( "DVB-T" );
627
628     bdaDevLayout->addWidget( bdaTypeLabel, 0, 0 );
629     bdaDevLayout->addWidget( bdas, 0, 1 );
630     bdaDevLayout->addWidget( bdac, 0, 2 );
631     bdaDevLayout->addWidget( bdat, 0, 3 );
632
633     /* bda Props */
634     QLabel *bdaFreqLabel =
635                     new QLabel( qtr( "Transponder/multiplex frequency" ) );
636     bdaPropLayout->addWidget( bdaFreqLabel, 0, 0 );
637
638     bdaFreq = new QSpinBox;
639     bdaFreq->setAlignment( Qt::AlignRight );
640     bdaFreq->setSuffix(" kHz");
641     bdaFreq->setSingleStep( 1000 );
642     setSpinBoxFreq( bdaFreq )
643     bdaPropLayout->addWidget( bdaFreq, 0, 1 );
644
645     bdaSrateLabel = new QLabel( qtr( "Transponder symbol rate" ) );
646     bdaPropLayout->addWidget( bdaSrateLabel, 1, 0 );
647
648     bdaSrate = new QSpinBox;
649     bdaSrate->setAlignment( Qt::AlignRight );
650     bdaSrate->setSuffix(" kHz");
651     setSpinBoxFreq( bdaSrate );
652     bdaPropLayout->addWidget( bdaSrate, 1, 1 );
653
654     bdaBandLabel = new QLabel( qtr( "Bandwidth" ) );
655     bdaPropLayout->addWidget( bdaBandLabel, 2, 0 );
656
657     bdaBandBox = new QComboBox;
658     setfillVLCConfigCombo( "dvb-bandwidth", p_intf, bdaBandBox );
659     bdaPropLayout->addWidget( bdaBandBox, 2, 1 );
660
661     bdaBandLabel->hide();
662     bdaBandBox->hide();
663
664     /* bda CONNECTs */
665     CuMRL( bdaFreq, valueChanged ( int ) );
666     CuMRL( bdaSrate, valueChanged ( int ) );
667     CuMRL( bdaBandBox,  currentIndexChanged ( int ) );
668     BUTTONACT( bdas, updateButtons() );
669     BUTTONACT( bdat, updateButtons() );
670     BUTTONACT( bdac, updateButtons() );
671     BUTTONACT( bdas, updateMRL() );
672     BUTTONACT( bdat, updateMRL() );
673     BUTTONACT( bdac, updateMRL() );
674
675     /**************
676      * DVB Stuffs *
677      **************/
678     addModuleAndLayouts( DVB_DEVICE, dvb, "DVB" );
679
680     /* DVB Main */
681     QLabel *dvbDeviceLabel = new QLabel( qtr( "Adapter card to tune" ) );
682     QLabel *dvbTypeLabel = new QLabel( qtr( "DVB Type:" ) );
683
684     dvbCard = new QSpinBox;
685     dvbCard->setAlignment( Qt::AlignRight );
686     dvbCard->setPrefix( "/dev/dvb/adapter" );
687
688     dvbDevLayout->addWidget( dvbDeviceLabel, 0, 0 );
689     dvbDevLayout->addWidget( dvbCard, 0, 2, 1, 2 );
690
691     dvbs = new QRadioButton( "DVB-S" );
692     dvbs->setChecked( true );
693     dvbc = new QRadioButton( "DVB-C" );
694     dvbt = new QRadioButton( "DVB-T" );
695
696     dvbDevLayout->addWidget( dvbTypeLabel, 1, 0 );
697     dvbDevLayout->addWidget( dvbs, 1, 1 );
698     dvbDevLayout->addWidget( dvbc, 1, 2 );
699     dvbDevLayout->addWidget( dvbt, 1, 3 );
700
701     /* DVB Props panel */
702     QLabel *dvbFreqLabel =
703                     new QLabel( qtr( "Transponder/multiplex frequency" ) );
704     dvbPropLayout->addWidget( dvbFreqLabel, 0, 0 );
705
706     dvbFreq = new QSpinBox;
707     dvbFreq->setAlignment( Qt::AlignRight );
708     dvbFreq->setSuffix(" kHz");
709     setSpinBoxFreq( dvbFreq  );
710     dvbPropLayout->addWidget( dvbFreq, 0, 1 );
711
712     QLabel *dvbSrateLabel = new QLabel( qtr( "Transponder symbol rate" ) );
713     dvbPropLayout->addWidget( dvbSrateLabel, 1, 0 );
714
715     dvbSrate = new QSpinBox;
716     dvbSrate->setAlignment( Qt::AlignRight );
717     dvbSrate->setSuffix(" kHz");
718     setSpinBoxFreq( dvbSrate );
719     dvbPropLayout->addWidget( dvbSrate, 1, 1 );
720
721     /* DVB CONNECTs */
722     CuMRL( dvbCard, valueChanged ( int ) );
723     CuMRL( dvbFreq, valueChanged ( int ) );
724     CuMRL( dvbSrate, valueChanged ( int ) );
725
726     BUTTONACT( dvbs, updateButtons() );
727     BUTTONACT( dvbt, updateButtons() );
728     BUTTONACT( dvbc, updateButtons() );
729
730     /* General connects */
731     connect( ui.deviceCombo, SIGNAL( activated( int ) ),
732                      stackedDevLayout, SLOT( setCurrentIndex( int ) ) );
733     connect( ui.deviceCombo, SIGNAL( activated( int ) ),
734                      stackedPropLayout, SLOT( setCurrentIndex( int ) ) );
735     CONNECT( ui.deviceCombo, activated( int ), this, updateMRL() );
736
737 #undef addModule
738 }
739
740 CaptureOpenPanel::~CaptureOpenPanel()
741 {}
742
743 void CaptureOpenPanel::clear()
744 {}
745
746 void CaptureOpenPanel::updateMRL()
747 {
748     QString mrl = "";
749     int i_devicetype = ui.deviceCombo->itemData(
750             ui.deviceCombo->currentIndex() ).toInt();
751     msg_Dbg( p_intf, "Capture Type: %i", i_devicetype );
752     switch( i_devicetype )
753     {
754     case V4L_DEVICE:
755         mrl = "v4l://";
756         mrl += " :v4l-vdev=" + v4lVideoDevice->text();
757         mrl += " :v4l-adev=" + v4lAudioDevice->text();
758         mrl += " :v4l-norm=" + QString("%1").arg( v4lNormBox->currentIndex() );
759         mrl += " :v4l-frequency=" + QString("%1").arg( v4lFreq->value() );
760         break;
761     case PVR_DEVICE:
762         mrl = "pvr://";
763         mrl += " :pvr-device=" + pvrDevice->text();
764         mrl += " :pvr-radio-device=" + pvrRadioDevice->text();
765         mrl += " :pvr-norm=" + QString("%1").arg( pvrNormBox->currentIndex() );
766         if( pvrFreq->value() )
767             mrl += " :pvr-frequency=" + QString("%1").arg( pvrFreq->value() );
768         if( pvrBitr->value() )
769             mrl += " :pvr-bitrate=" + QString("%1").arg( pvrBitr->value() );
770         break;
771     case DVB_DEVICE:
772         mrl = "dvb://";
773         mrl += " :dvb-adapter=" + QString("%1").arg( dvbCard->value() );
774         mrl += " :dvb-frequency=" + QString("%1").arg( dvbFreq->value() );
775         mrl += " :dvb-srate=" + QString("%1").arg( dvbSrate->value() );
776         break;
777     case BDA_DEVICE:
778         if( bdas->isChecked() ) mrl = "dvb-s://";
779         else if(  bdat->isChecked() ) mrl = "dvb-t://";
780         else if(  bdac->isChecked() ) mrl = "dvb-c://";
781         else return;
782         mrl += " :dvb-frequency=" + QString("%1").arg( bdaFreq->value() );
783         if( bdas->isChecked() || bdac->isChecked() )
784             mrl += " :dvb-srate=" + QString("%1").arg( bdaSrate->value() );
785         else
786             mrl += " :dvb-bandwidth=" +
787                 QString("%1").arg( bdaBandBox->itemData(
788                     bdaBandBox->currentIndex() ).toInt() );
789         break;
790   case DSHOW_DEVICE:
791         break;
792     }
793     emit mrlUpdated( mrl );
794 }
795
796 void CaptureOpenPanel::updateButtons()
797 {
798     int i_devicetype = ui.deviceCombo->itemData(
799             ui.deviceCombo->currentIndex() ).toInt();
800     msg_Dbg( p_intf, "Capture Type: %i", i_devicetype );
801     switch( i_devicetype )
802     {
803     case DVB_DEVICE:
804         if( dvbs->isChecked() ) dvbFreq->setSuffix(" kHz");
805         if( dvbc->isChecked() || dvbt->isChecked() ) dvbFreq->setSuffix(" Hz");
806         break;
807     case BDA_DEVICE:
808         if( bdas->isChecked() || bdac->isChecked() )
809         {
810             bdaSrate->show();
811             bdaSrateLabel->show();
812             bdaBandBox->hide();
813             bdaBandLabel->hide();
814         }
815         else
816         {
817             bdaSrate->hide();
818             bdaSrateLabel->hide();
819             bdaBandBox->show();
820             bdaBandLabel->show();
821         }
822         break;
823     }
824 }