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
10 * Authors: Clément Stenac <zorglub@videolan.org>
11 * Jean-Baptiste Kempf <jb@videolan.org>
12 * Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27 *****************************************************************************/
34 #include "components/open_panels.hpp"
35 #include "dialogs/open.hpp"
36 #include "dialogs_provider.hpp"
38 #include <QFileDialog>
39 #include <QDialogButtonBox>
41 #include <QStackedLayout>
45 #include <QScrollArea>
48 /**************************************************************************
49 * Open Files and subtitles *
50 **************************************************************************/
51 FileOpenPanel::FileOpenPanel( QWidget
*_parent
, intf_thread_t
*_p_intf
) :
52 OpenPanel( _parent
, _p_intf
)
54 /* Classic UI Setup */
57 /** BEGIN QFileDialog tweaking **/
58 /* Use a QFileDialog and customize it because we don't want to
59 rewrite it all. Be careful to your eyes cause there are a few hacks.
60 Be very careful and test correctly when you modify this. */
62 /* Set Filters for file selection */
63 QString fileTypes
= "";
64 ADD_FILTER_MEDIA( fileTypes
);
65 ADD_FILTER_VIDEO( fileTypes
);
66 ADD_FILTER_AUDIO( fileTypes
);
67 ADD_FILTER_PLAYLIST( fileTypes
);
68 ADD_FILTER_ALL( fileTypes
);
69 fileTypes
.replace( QString(";*"), QString(" *"));
71 // Make this QFileDialog a child of tempWidget from the ui.
72 dialogBox
= new FileOpenBox( ui
.tempWidget
, NULL
,
73 qfu( p_intf
->p_sys
->psz_filepath
), fileTypes
);
75 dialogBox
->setFileMode( QFileDialog::ExistingFiles
);
76 dialogBox
->setAcceptMode( QFileDialog::AcceptOpen
);
77 dialogBox
->setViewMode( config_GetInt( p_intf
, "qt-open-detail" ) ?
78 QFileDialog::Detail
: QFileDialog::List
);
80 /* We don't want to see a grip in the middle of the window, do we? */
81 dialogBox
->setSizeGripEnabled( false );
84 dialogBox
->setToolTip( qtr( "Select one or multiple files" ) );
86 // But hide the two OK/Cancel buttons. Enable them for debug.
87 QDialogButtonBox
*fileDialogAcceptBox
=
88 dialogBox
->findChildren
<QDialogButtonBox
*>()[0];
89 fileDialogAcceptBox
->hide();
91 /* Ugly hacks to get the good Widget */
92 //This lineEdit is the normal line in the fileDialog.
94 lineFileEdit
= dialogBox
->findChildren
<QLineEdit
*>()[0];
96 lineFileEdit
= dialogBox
->findChildren
<QLineEdit
*>()[1];
98 /* Make a list of QLabel inside the QFileDialog to access the good ones */
99 QList
<QLabel
*> listLabel
= dialogBox
->findChildren
<QLabel
*>();
101 /* Hide the FileNames one. Enable it for debug */
102 listLabel
[1]->setText( qtr( "File names:" ) );
103 /* Change the text that was uncool in the usual box */
104 listLabel
[2]->setText( qtr( "Filter:" ) );
106 dialogBox
->layout()->setMargin( 0 );
107 dialogBox
->layout()->setSizeConstraint( QLayout::SetNoConstraint
);
109 /** END of QFileDialog tweaking **/
111 // Add the DialogBox to the layout
112 ui
.gridLayout
->addWidget( dialogBox
, 0, 0, 1, 3 );
114 //TODO later: fill the fileCompleteList with previous items played.
115 QCompleter
*fileCompleter
= new QCompleter( fileCompleteList
, this );
116 fileCompleter
->setModel( new QDirModel( fileCompleter
) );
117 lineFileEdit
->setCompleter( fileCompleter
);
119 // Hide the subtitles control by default.
122 /* Build the subs size combo box */
123 setfillVLCConfigCombo( "freetype-rel-fontsize" , p_intf
,
124 ui
.sizeSubComboBox
);
126 /* Build the subs align combo box */
127 setfillVLCConfigCombo( "subsdec-align", p_intf
, ui
.alignSubComboBox
);
130 BUTTONACT( ui
.subBrowseButton
, browseFileSub() );
131 BUTTONACT( ui
.subCheckBox
, toggleSubtitleFrame());
133 CONNECT( lineFileEdit
, textChanged( QString
), this, updateMRL() );
134 CONNECT( ui
.subInput
, textChanged( QString
), this, updateMRL() );
135 CONNECT( ui
.alignSubComboBox
, currentIndexChanged( int ), this, updateMRL() );
136 CONNECT( ui
.sizeSubComboBox
, currentIndexChanged( int ), this, updateMRL() );
139 FileOpenPanel::~FileOpenPanel()
143 /* Show a fileBrowser to select a subtitle */
144 void FileOpenPanel::browseFileSub()
146 // TODO Handle selection of more than one subtitles file
147 QStringList files
= THEDP
->showSimpleOpen( qtr("Open subtitles file"),
149 dialogBox
->directory().absolutePath() );
150 if( files
.isEmpty() ) return;
151 ui
.subInput
->setText( files
.join(" ") );
155 /* Update the current MRL */
156 void FileOpenPanel::updateMRL()
159 foreach( QString file
, dialogBox
->selectedFiles() ) {
160 mrl
+= "\"" + file
+ "\" ";
163 if( ui
.subCheckBox
->isChecked() ) {
164 mrl
.append( " :sub-file=\"" + ui
.subInput
->text() + "\"" );
165 int align
= ui
.alignSubComboBox
->itemData(
166 ui
.alignSubComboBox
->currentIndex() ).toInt();
167 mrl
.append( " :subsdec-align=" + QString().setNum( align
) );
168 int size
= ui
.sizeSubComboBox
->itemData(
169 ui
.sizeSubComboBox
->currentIndex() ).toInt();
170 mrl
.append( " :freetype-rel-fontsize=" + QString().setNum( size
) );
173 emit
mrlUpdated( mrl
);
174 emit
methodChanged( "file-caching" );
177 /* Function called by Open Dialog when clicke on Play/Enqueue */
178 void FileOpenPanel::accept()
180 //TODO set the completer
181 p_intf
->p_sys
->psz_filepath
= qtu( dialogBox
->directory().absolutePath() );
184 void FileOpenBox::accept()
186 OpenDialog::getInstance( NULL
, NULL
)->play();
189 /* Function called by Open Dialog when clicked on cancel */
190 void FileOpenPanel::clear()
192 lineFileEdit
->clear();
193 ui
.subInput
->clear();
196 void FileOpenPanel::toggleSubtitleFrame()
198 TOGGLEV( ui
.subFrame
);
204 /**************************************************************************
205 * Open Discs ( DVD, CD, VCD and similar devices ) *
206 **************************************************************************/
207 DiscOpenPanel::DiscOpenPanel( QWidget
*_parent
, intf_thread_t
*_p_intf
) :
208 OpenPanel( _parent
, _p_intf
)
212 /* Get the default configuration path for the devices */
213 psz_dvddiscpath
= config_GetPsz( p_intf
, "dvd" );
214 psz_vcddiscpath
= config_GetPsz( p_intf
, "vcd" );
215 psz_cddadiscpath
= config_GetPsz( p_intf
, "cd-audio" );
217 /* State to avoid overwritting the users changes with the configuration */
222 #if WIN32 /* Disc drives probing for Windows */
225 if( GetLogicalDriveStringsA( sizeof( szDrives
) - 1, szDrives
) )
227 char *drive
= szDrives
;
228 UINT oldMode
= SetErrorMode( SEM_FAILCRITICALERRORS
);
231 if( GetDriveTypeA(drive
) == DRIVE_CDROM
)
232 ui
.deviceCombo
->addItem( drive
);
234 /* go to next drive */
237 SetErrorMode(oldMode
);
239 #else /* Use a Completer under Linux */
240 QCompleter
*discCompleter
= new QCompleter( this );
241 discCompleter
->setModel( new QDirModel( discCompleter
) );
242 ui
.deviceCombo
->setCompleter( discCompleter
);
246 BUTTONACT( ui
.dvdRadioButton
, updateButtons() );
247 BUTTONACT( ui
.vcdRadioButton
, updateButtons() );
248 BUTTONACT( ui
.audioCDRadioButton
, updateButtons() );
249 BUTTONACT( ui
.dvdsimple
, updateButtons() );
250 BUTTONACT( ui
.browseDiscButton
, browseDevice() );
251 BUTTONACT( ui
.ejectButton
, eject() );
253 CONNECT( ui
.deviceCombo
, editTextChanged( QString
), this, updateMRL());
254 CONNECT( ui
.titleSpin
, valueChanged( int ), this, updateMRL());
255 CONNECT( ui
.chapterSpin
, valueChanged( int ), this, updateMRL());
256 CONNECT( ui
.audioSpin
, valueChanged( int ), this, updateMRL());
257 CONNECT( ui
.subtitlesSpin
, valueChanged( int ), this, updateMRL());
259 /* Run once the updateButtons function in order to fill correctly the comboBoxes */
263 DiscOpenPanel::~DiscOpenPanel()
265 delete psz_dvddiscpath
;
266 delete psz_vcddiscpath
;
267 delete psz_cddadiscpath
;
270 void DiscOpenPanel::clear()
272 ui
.titleSpin
->setValue( 0 );
273 ui
.chapterSpin
->setValue( 0 );
280 #define setDrive( psz_name ) {\
281 int index = ui.deviceCombo->findText( qfu( psz_name ) ); \
282 if( index != -1 ) ui.deviceCombo->setCurrentIndex( index );}
284 #define setDrive( psz_name ) {\
285 ui.deviceCombo->setEditText( qfu( psz_name ) ); }
288 /* update the buttons according the type of device */
289 void DiscOpenPanel::updateButtons()
291 if ( ui
.dvdRadioButton
->isChecked() )
295 setDrive( psz_dvddiscpath
);
298 ui
.titleLabel
->setText( qtr("Title") );
299 ui
.chapterLabel
->show();
300 ui
.chapterSpin
->show();
301 ui
.diskOptionBox_2
->show();
303 else if ( ui
.vcdRadioButton
->isChecked() )
307 setDrive( psz_vcddiscpath
);
310 ui
.titleLabel
->setText( qtr("Entry") );
311 ui
.chapterLabel
->hide();
312 ui
.chapterSpin
->hide();
313 ui
.diskOptionBox_2
->show();
319 setDrive( psz_cddadiscpath
);
322 ui
.titleLabel
->setText( qtr("Track") );
323 ui
.chapterLabel
->hide();
324 ui
.chapterSpin
->hide();
325 ui
.diskOptionBox_2
->hide();
331 /* Update the current MRL */
332 void DiscOpenPanel::updateMRL()
336 /* CDDAX and VCDX not implemented. TODO ? */
338 if( ui
.dvdRadioButton
->isChecked() ) {
339 if( !ui
.dvdsimple
->isChecked() )
342 mrl
= "\"dvdsimple://";
343 mrl
+= ui
.deviceCombo
->currentText();
344 emit
methodChanged( "dvdnav-caching" );
346 if ( ui
.titleSpin
->value() > 0 ) {
347 mrl
+= QString("@%1").arg( ui
.titleSpin
->value() );
348 if ( ui
.chapterSpin
->value() > 0 ) {
349 mrl
+= QString(":%1").arg( ui
.chapterSpin
->value() );
354 } else if ( ui
.vcdRadioButton
->isChecked() ) {
355 mrl
= "\"vcd://" + ui
.deviceCombo
->currentText();
356 emit
methodChanged( "vcd-caching" );
358 if( ui
.titleSpin
->value() > 0 ) {
359 mrl
+= QString("@E%1").arg( ui
.titleSpin
->value() );
364 mrl
= "\"cdda://" + ui
.deviceCombo
->currentText();
365 if( ui
.titleSpin
->value() > 0 ) {
366 QString("@%1").arg( ui
.titleSpin
->value() );
372 if ( ui
.dvdRadioButton
->isChecked() || ui
.vcdRadioButton
->isChecked() )
374 if ( ui
.audioSpin
->value() >= 0 ) {
375 mrl
+= " :audio-track=" +
376 QString("%1").arg( ui
.audioSpin
->value() );
378 if ( ui
.subtitlesSpin
->value() >= 0 ) {
379 mrl
+= " :sub-track=" +
380 QString("%1").arg( ui
.subtitlesSpin
->value() );
383 emit
mrlUpdated( mrl
);
386 void DiscOpenPanel::browseDevice()
388 QString dir
= QFileDialog::getExistingDirectory( 0,
389 qtr("Open a device or a VIDEO_TS directory") );
390 if (!dir
.isEmpty()) {
391 ui
.deviceCombo
->setEditText( dir
);
396 void DiscOpenPanel::eject()
398 intf_Eject( p_intf
, qtu( ui
.deviceCombo
->currentText() ) );
401 void DiscOpenPanel::accept()
404 /**************************************************************************
405 * Open Network streams and URL pages *
406 **************************************************************************/
407 NetOpenPanel::NetOpenPanel( QWidget
*_parent
, intf_thread_t
*_p_intf
) :
408 OpenPanel( _parent
, _p_intf
)
413 CONNECT( ui
.protocolCombo
, activated( int ),
414 this, updateProtocol( int ) );
415 CONNECT( ui
.portSpin
, valueChanged( int ), this, updateMRL() );
416 CONNECT( ui
.addressText
, textChanged( QString
), this, updateMRL());
417 CONNECT( ui
.timeShift
, clicked(), this, updateMRL());
418 CONNECT( ui
.ipv6
, clicked(), this, updateMRL());
420 ui
.protocolCombo
->addItem( "" );
421 ui
.protocolCombo
->addItem("HTTP", QVariant("http"));
422 ui
.protocolCombo
->addItem("HTTPS", QVariant("https"));
423 ui
.protocolCombo
->addItem("FTP", QVariant("ftp"));
424 ui
.protocolCombo
->addItem("MMS", QVariant("mms"));
425 ui
.protocolCombo
->addItem("RTSP", QVariant("rtsp"));
426 ui
.protocolCombo
->addItem("UDP/RTP (unicast)", QVariant("udp"));
427 ui
.protocolCombo
->addItem("UDP/RTP (multicast)", QVariant("udp"));
428 ui
.protocolCombo
->addItem("RTMP", QVariant("rtmp"));
431 NetOpenPanel::~NetOpenPanel()
434 void NetOpenPanel::clear()
437 /* update the widgets according the type of protocol */
438 void NetOpenPanel::updateProtocol( int idx_proto
) {
439 QString addr
= ui
.addressText
->text();
440 QString proto
= ui
.protocolCombo
->itemData( idx_proto
).toString();
442 ui
.timeShift
->setEnabled( idx_proto
== UDP_PROTO
||
443 idx_proto
== UDPM_PROTO
);
444 ui
.ipv6
->setEnabled( idx_proto
== UDP_PROTO
);
445 ui
.addressText
->setEnabled( idx_proto
!= UDP_PROTO
);
446 ui
.portSpin
->setEnabled( idx_proto
== UDP_PROTO
||
447 idx_proto
== UDPM_PROTO
);
449 if( idx_proto
== NO_PROTO
) return;
451 /* If we already have a protocol in the address, replace it */
452 if( addr
.contains( "://"))
454 if( idx_proto
!= UDPM_PROTO
)
455 addr
.replace( QRegExp("^.*://@*"), proto
+ "://");
457 addr
.replace( QRegExp("^.*://"), proto
+ "://@");
458 ui
.addressText
->setText( addr
);
463 void NetOpenPanel::updateMRL() {
465 QString addr
= ui
.addressText
->text();
466 addr
= QUrl::toPercentEncoding( addr
, ":/?#@!$&'()*+,;=" );
467 int idx_proto
= ui
.protocolCombo
->currentIndex();
469 if( addr
.contains( "://"))
471 /* Match the correct item in the comboBox */
472 ui
.protocolCombo
->setCurrentIndex(
473 ui
.protocolCombo
->findData( addr
.section( ':', 0, 0 ) ) );
475 if( idx_proto
!= UDP_PROTO
|| idx_proto
!= UDPM_PROTO
)
480 switch( idx_proto
) {
482 mrl
= "http://" + addr
;
483 emit
methodChanged("http-caching");
486 mrl
= "https://" + addr
;
487 emit
methodChanged("http-caching");
490 mrl
= "mms://" + addr
;
491 emit
methodChanged("mms-caching");
494 mrl
= "ftp://" + addr
;
495 emit
methodChanged("ftp-caching");
498 mrl
= "rtsp://" + addr
;
499 emit
methodChanged("rtsp-caching");
503 if( ui
.ipv6
->isEnabled() && ui
.ipv6
->isChecked() )
507 mrl
+= QString(":%1").arg( ui
.portSpin
->value() );
508 emit
methodChanged("udp-caching");
510 case UDPM_PROTO
: /* UDP multicast */
513 if ( addr
.contains(':') && !addr
.contains('[') )
515 mrl
+= "[" + addr
+ "]";
518 mrl
+= QString(":%1").arg( ui
.portSpin
->value() );
519 emit
methodChanged("udp-caching");
521 mrl
= "rtmp://" + addr
;
522 emit
methodChanged("rtmp-caching");
528 // Encode the boring stuffs
530 if( ui
.timeShift
->isEnabled() && ui
.timeShift
->isChecked() ) {
531 mrl
+= " :access-filter=timeshift";
533 emit
mrlUpdated( mrl
);
536 /**************************************************************************
537 * Open Capture device ( DVB, PVR, V4L, and similar ) *
538 **************************************************************************/
539 CaptureOpenPanel::CaptureOpenPanel( QWidget
*_parent
, intf_thread_t
*_p_intf
) :
540 OpenPanel( _parent
, _p_intf
)
544 BUTTONACT( ui
.advancedButton
, advancedDialog() );
546 /* Create two stacked layouts in the main comboBoxes */
547 QStackedLayout
*stackedDevLayout
= new QStackedLayout
;
548 ui
.cardBox
->setLayout( stackedDevLayout
);
550 QStackedLayout
*stackedPropLayout
= new QStackedLayout
;
551 ui
.optionsBox
->setLayout( stackedPropLayout
);
553 /* Creation and connections of the WIdgets in the stacked layout */
554 #define addModuleAndLayouts( number, name, label ) \
555 QWidget * name ## DevPage = new QWidget( this ); \
556 QWidget * name ## PropPage = new QWidget( this ); \
557 stackedDevLayout->addWidget( name ## DevPage ); \
558 stackedPropLayout->addWidget( name ## PropPage ); \
559 QGridLayout * name ## DevLayout = new QGridLayout; \
560 QGridLayout * name ## PropLayout = new QGridLayout; \
561 name ## DevPage->setLayout( name ## DevLayout ); \
562 name ## PropPage->setLayout( name ## PropLayout ); \
563 ui.deviceCombo->addItem( qtr( label ), QVariant( number ) );
565 #define CuMRL( widget, slot ) CONNECT( widget , slot , this, updateMRL() );
568 /*********************
569 * DirectShow Stuffs *
570 *********************/
571 if( module_Exists( p_intf
, "dshow" ) ){
572 addModuleAndLayouts( DSHOW_DEVICE
, dshow
, "DirectShow" );
576 module_config_t
*p_config
=
577 config_FindConfig( VLC_OBJECT(p_intf
), "dshow-vdev" );
578 vdevDshowW
= new StringListConfigControl(
579 VLC_OBJECT(p_intf
), p_config
, this, false, dshowDevLayout
, line
);
582 p_config
= config_FindConfig( VLC_OBJECT(p_intf
), "dshow-adev" );
583 adevDshowW
= new StringListConfigControl(
584 VLC_OBJECT(p_intf
), p_config
, this, false, dshowDevLayout
, line
);
587 /* dshow Properties */
588 QLabel
*dshowVSizeLabel
= new QLabel( qtr( "Video size" ) );
589 dshowPropLayout
->addWidget( dshowVSizeLabel
, 0, 0 );
591 dshowVSizeLine
= new QLineEdit
;
592 dshowPropLayout
->addWidget( dshowVSizeLine
, 0, 1);
593 dshowPropLayout
->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding
),
597 CuMRL( vdevDshowW
->combo
, currentIndexChanged ( int ) );
598 CuMRL( adevDshowW
->combo
, currentIndexChanged ( int ) );
599 CuMRL( dshowVSizeLine
, textChanged( QString
) );
605 if( module_Exists( p_intf
, "bda" ) ){
606 addModuleAndLayouts( BDA_DEVICE
, bda
, "DVB DirectShow" );
609 QLabel
*bdaTypeLabel
= new QLabel( qtr( "DVB Type:" ) );
611 bdas
= new QRadioButton( "DVB-S" );
612 bdas
->setChecked( true );
613 bdac
= new QRadioButton( "DVB-C" );
614 bdat
= new QRadioButton( "DVB-T" );
616 bdaDevLayout
->addWidget( bdaTypeLabel
, 0, 0 );
617 bdaDevLayout
->addWidget( bdas
, 0, 1 );
618 bdaDevLayout
->addWidget( bdac
, 0, 2 );
619 bdaDevLayout
->addWidget( bdat
, 0, 3 );
622 QLabel
*bdaFreqLabel
=
623 new QLabel( qtr( "Transponder/multiplex frequency" ) );
624 bdaPropLayout
->addWidget( bdaFreqLabel
, 0, 0 );
626 bdaFreq
= new QSpinBox
;
627 bdaFreq
->setAlignment( Qt::AlignRight
);
628 bdaFreq
->setSuffix(" kHz");
629 bdaFreq
->setSingleStep( 1000 );
630 setSpinBoxFreq( bdaFreq
)
631 bdaPropLayout
->addWidget( bdaFreq
, 0, 1 );
633 bdaSrateLabel
= new QLabel( qtr( "Transponder symbol rate" ) );
634 bdaPropLayout
->addWidget( bdaSrateLabel
, 1, 0 );
636 bdaSrate
= new QSpinBox
;
637 bdaSrate
->setAlignment( Qt::AlignRight
);
638 bdaSrate
->setSuffix(" kHz");
639 setSpinBoxFreq( bdaSrate
);
640 bdaPropLayout
->addWidget( bdaSrate
, 1, 1 );
642 bdaBandLabel
= new QLabel( qtr( "Bandwidth" ) );
643 bdaPropLayout
->addWidget( bdaBandLabel
, 2, 0 );
645 bdaBandBox
= new QComboBox
;
646 setfillVLCConfigCombo( "dvb-bandwidth", p_intf
, bdaBandBox
);
647 bdaPropLayout
->addWidget( bdaBandBox
, 2, 1 );
649 bdaBandLabel
->hide();
651 bdaPropLayout
->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding
),
655 CuMRL( bdaFreq
, valueChanged ( int ) );
656 CuMRL( bdaSrate
, valueChanged ( int ) );
657 CuMRL( bdaBandBox
, currentIndexChanged ( int ) );
658 BUTTONACT( bdas
, updateButtons() );
659 BUTTONACT( bdat
, updateButtons() );
660 BUTTONACT( bdac
, updateButtons() );
661 BUTTONACT( bdas
, updateMRL() );
662 BUTTONACT( bdat
, updateMRL() );
663 BUTTONACT( bdac
, updateMRL() );
670 if( module_Exists( p_intf
, "v4l2" ) ){
671 addModuleAndLayouts( V4L2_DEVICE
, v4l2
, "Video for Linux 2" );
674 QLabel
*v4l2VideoDeviceLabel
= new QLabel( qtr( "Video device name" ) );
675 v4l2DevLayout
->addWidget( v4l2VideoDeviceLabel
, 0, 0 );
677 v4l2VideoDevice
= new QLineEdit
;
678 v4l2DevLayout
->addWidget( v4l2VideoDevice
, 0, 1 );
680 QLabel
*v4l2AudioDeviceLabel
= new QLabel( qtr( "Audio device name" ) );
681 v4l2DevLayout
->addWidget( v4l2AudioDeviceLabel
, 1, 0 );
683 v4l2AudioDevice
= new QLineEdit
;
684 v4l2DevLayout
->addWidget( v4l2AudioDevice
, 1, 1 );
686 /* v4l2 Props panel */
687 QLabel
*v4l2StdLabel
= new QLabel( qtr( "Standard" ) );
688 v4l2PropLayout
->addWidget( v4l2StdLabel
, 0 , 0 );
690 v4l2StdBox
= new QComboBox
;
691 setfillVLCConfigCombo( "v4l2-standard", p_intf
, v4l2StdBox
);
692 v4l2PropLayout
->addWidget( v4l2StdBox
, 0 , 1 );
693 v4l2PropLayout
->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding
),
697 CuMRL( v4l2VideoDevice
, textChanged( QString
) );
698 CuMRL( v4l2AudioDevice
, textChanged( QString
) );
699 CuMRL( v4l2StdBox
, currentIndexChanged ( int ) );
705 if( module_Exists( p_intf
, "v4l" ) ){
706 addModuleAndLayouts( V4L_DEVICE
, v4l
, "Video for Linux" );
709 QLabel
*v4lVideoDeviceLabel
= new QLabel( qtr( "Video device name" ) );
710 v4lDevLayout
->addWidget( v4lVideoDeviceLabel
, 0, 0 );
712 v4lVideoDevice
= new QLineEdit
;
713 v4lDevLayout
->addWidget( v4lVideoDevice
, 0, 1 );
715 QLabel
*v4lAudioDeviceLabel
= new QLabel( qtr( "Audio device name" ) );
716 v4lDevLayout
->addWidget( v4lAudioDeviceLabel
, 1, 0 );
718 v4lAudioDevice
= new QLineEdit
;
719 v4lDevLayout
->addWidget( v4lAudioDevice
, 1, 1 );
721 /* V4l Props panel */
722 QLabel
*v4lNormLabel
= new QLabel( qtr( "Norm" ) );
723 v4lPropLayout
->addWidget( v4lNormLabel
, 0 , 0 );
725 v4lNormBox
= new QComboBox
;
726 setfillVLCConfigCombo( "v4l-norm", p_intf
, v4lNormBox
);
727 v4lPropLayout
->addWidget( v4lNormBox
, 0 , 1 );
729 QLabel
*v4lFreqLabel
= new QLabel( qtr( "Frequency" ) );
730 v4lPropLayout
->addWidget( v4lFreqLabel
, 1 , 0 );
732 v4lFreq
= new QSpinBox
;
733 v4lFreq
->setAlignment( Qt::AlignRight
);
734 v4lFreq
->setSuffix(" kHz");
735 setSpinBoxFreq( v4lFreq
);
736 v4lPropLayout
->addWidget( v4lFreq
, 1 , 1 );
737 v4lPropLayout
->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding
),
741 CuMRL( v4lVideoDevice
, textChanged( QString
) );
742 CuMRL( v4lAudioDevice
, textChanged( QString
) );
743 CuMRL( v4lFreq
, valueChanged ( int ) );
744 CuMRL( v4lNormBox
, currentIndexChanged ( int ) );
750 if( module_Exists( p_intf
, "jack" ) ){
751 addModuleAndLayouts( JACK_DEVICE
, jack
, "JACK Audio Connection Kit" );
753 /* Jack Main panel */
755 QLabel
*jackChannelsLabel
= new QLabel( qtr( "Channels:" ) );
756 jackDevLayout
->addWidget( jackChannelsLabel
, 1, 0 );
758 jackChannels
= new QSpinBox
;
759 setSpinBoxFreq( jackChannels
);
760 jackChannels
->setMaximum(255);
761 jackChannels
->setValue(2);
762 jackChannels
->setAlignment( Qt::AlignRight
);
763 jackDevLayout
->addWidget( jackChannels
, 1, 1 );
765 /* Jack Props panel */
768 QLabel
*jackPortsLabel
= new QLabel( qtr( "Selected ports:" ) );
769 jackPropLayout
->addWidget( jackPortsLabel
, 0 , 0 );
771 jackPortsSelected
= new QLineEdit( qtr( ".*") );
772 jackPortsSelected
->setAlignment( Qt::AlignRight
);
773 jackPropLayout
->addWidget( jackPortsSelected
, 0, 1 );
776 QLabel
*jackCachingLabel
= new QLabel( qtr( "Input caching:" ) );
777 jackPropLayout
->addWidget( jackCachingLabel
, 1 , 0 );
778 jackCaching
= new QSpinBox
;
779 setSpinBoxFreq( jackCaching
);
780 jackCaching
->setSuffix( " ms" );
781 jackCaching
->setValue(1000);
782 jackCaching
->setAlignment( Qt::AlignRight
);
783 jackPropLayout
->addWidget( jackCaching
, 1 , 1 );
786 jackPace
= new QCheckBox(qtr( "Use VLC pace" ));
787 jackPropLayout
->addWidget( jackPace
, 2, 1 );
790 jackConnect
= new QCheckBox( qtr( "Auto connnection" ));
791 jackPropLayout
->addWidget( jackConnect
, 3, 1 );
794 CuMRL( jackChannels
, valueChanged( int ) );
795 CuMRL( jackCaching
, valueChanged( int ) );
796 CuMRL( jackPace
, stateChanged( int ) );
797 CuMRL( jackConnect
, stateChanged( int ) );
798 CuMRL( jackPortsSelected
, textChanged( QString
) );
804 if( module_Exists( p_intf
, "pvr" ) ){
805 addModuleAndLayouts( PVR_DEVICE
, pvr
, "PVR" );
808 QLabel
*pvrDeviceLabel
= new QLabel( qtr( "Device name" ) );
809 pvrDevLayout
->addWidget( pvrDeviceLabel
, 0, 0 );
811 pvrDevice
= new QLineEdit
;
812 pvrDevLayout
->addWidget( pvrDevice
, 0, 1 );
814 QLabel
*pvrRadioDeviceLabel
= new QLabel( qtr( "Radio device name" ) );
815 pvrDevLayout
->addWidget( pvrRadioDeviceLabel
, 1, 0 );
817 pvrRadioDevice
= new QLineEdit
;
818 pvrDevLayout
->addWidget( pvrRadioDevice
, 1, 1 );
820 /* PVR props panel */
821 QLabel
*pvrNormLabel
= new QLabel( qtr( "Norm" ) );
822 pvrPropLayout
->addWidget( pvrNormLabel
, 0, 0 );
824 pvrNormBox
= new QComboBox
;
825 setfillVLCConfigCombo( "pvr-norm", p_intf
, pvrNormBox
);
826 pvrPropLayout
->addWidget( pvrNormBox
, 0, 1 );
828 QLabel
*pvrFreqLabel
= new QLabel( qtr( "Frequency" ) );
829 pvrPropLayout
->addWidget( pvrFreqLabel
, 1, 0 );
831 pvrFreq
= new QSpinBox
;
832 pvrFreq
->setAlignment( Qt::AlignRight
);
833 pvrFreq
->setSuffix(" kHz");
834 setSpinBoxFreq( pvrFreq
);
835 pvrPropLayout
->addWidget( pvrFreq
, 1, 1 );
837 QLabel
*pvrBitrLabel
= new QLabel( qtr( "Bitrate" ) );
838 pvrPropLayout
->addWidget( pvrBitrLabel
, 2, 0 );
840 pvrBitr
= new QSpinBox
;
841 pvrBitr
->setAlignment( Qt::AlignRight
);
842 pvrBitr
->setSuffix(" kHz");
843 setSpinBoxFreq( pvrBitr
);
844 pvrPropLayout
->addWidget( pvrBitr
, 2, 1 );
845 pvrPropLayout
->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding
),
849 CuMRL( pvrDevice
, textChanged( QString
) );
850 CuMRL( pvrRadioDevice
, textChanged( QString
) );
852 CuMRL( pvrFreq
, valueChanged ( int ) );
853 CuMRL( pvrBitr
, valueChanged ( int ) );
854 CuMRL( pvrNormBox
, currentIndexChanged ( int ) );
860 if( module_Exists( p_intf
, "dvb" ) ){
861 addModuleAndLayouts( DVB_DEVICE
, dvb
, "DVB" );
864 QLabel
*dvbDeviceLabel
= new QLabel( qtr( "Adapter card to tune" ) );
865 QLabel
*dvbTypeLabel
= new QLabel( qtr( "DVB Type:" ) );
867 dvbCard
= new QSpinBox
;
868 dvbCard
->setAlignment( Qt::AlignRight
);
869 dvbCard
->setPrefix( "/dev/dvb/adapter" );
871 dvbDevLayout
->addWidget( dvbDeviceLabel
, 0, 0 );
872 dvbDevLayout
->addWidget( dvbCard
, 0, 2, 1, 2 );
874 dvbs
= new QRadioButton( "DVB-S" );
875 dvbs
->setChecked( true );
876 dvbc
= new QRadioButton( "DVB-C" );
877 dvbt
= new QRadioButton( "DVB-T" );
879 dvbDevLayout
->addWidget( dvbTypeLabel
, 1, 0 );
880 dvbDevLayout
->addWidget( dvbs
, 1, 1 );
881 dvbDevLayout
->addWidget( dvbc
, 1, 2 );
882 dvbDevLayout
->addWidget( dvbt
, 1, 3 );
884 /* DVB Props panel */
885 QLabel
*dvbFreqLabel
=
886 new QLabel( qtr( "Transponder/multiplex frequency" ) );
887 dvbPropLayout
->addWidget( dvbFreqLabel
, 0, 0 );
889 dvbFreq
= new QSpinBox
;
890 dvbFreq
->setAlignment( Qt::AlignRight
);
891 dvbFreq
->setSuffix(" kHz");
892 setSpinBoxFreq( dvbFreq
);
893 dvbPropLayout
->addWidget( dvbFreq
, 0, 1 );
895 QLabel
*dvbSrateLabel
= new QLabel( qtr( "Transponder symbol rate" ) );
896 dvbPropLayout
->addWidget( dvbSrateLabel
, 1, 0 );
898 dvbSrate
= new QSpinBox
;
899 dvbSrate
->setAlignment( Qt::AlignRight
);
900 dvbSrate
->setSuffix(" kHz");
901 setSpinBoxFreq( dvbSrate
);
902 dvbPropLayout
->addWidget( dvbSrate
, 1, 1 );
903 dvbPropLayout
->addItem( new QSpacerItem( 20, 20, QSizePolicy::Expanding
),
907 CuMRL( dvbCard
, valueChanged ( int ) );
908 CuMRL( dvbFreq
, valueChanged ( int ) );
909 CuMRL( dvbSrate
, valueChanged ( int ) );
911 BUTTONACT( dvbs
, updateButtons() );
912 BUTTONACT( dvbt
, updateButtons() );
913 BUTTONACT( dvbc
, updateButtons() );
922 addModuleAndLayouts( SCREEN_DEVICE
, screen
, "Desktop" );
923 QLabel
*screenLabel
= new QLabel( "This option will open your own "
924 "desktop in order to save or stream it.");
925 screenLabel
->setWordWrap( true );
926 screenDevLayout
->addWidget( screenLabel
, 0, 0 );
928 /* General connects */
929 connect( ui
.deviceCombo
, SIGNAL( activated( int ) ),
930 stackedDevLayout
, SLOT( setCurrentIndex( int ) ) );
931 connect( ui
.deviceCombo
, SIGNAL( activated( int ) ),
932 stackedPropLayout
, SLOT( setCurrentIndex( int ) ) );
933 CONNECT( ui
.deviceCombo
, activated( int ), this, updateMRL() );
934 CONNECT( ui
.deviceCombo
, activated( int ), this, updateButtons() );
939 CaptureOpenPanel::~CaptureOpenPanel()
943 void CaptureOpenPanel::clear()
948 void CaptureOpenPanel::updateMRL()
951 int i_devicetype
= ui
.deviceCombo
->itemData(
952 ui
.deviceCombo
->currentIndex() ).toInt();
953 switch( i_devicetype
)
957 if( bdas
->isChecked() ) mrl
= "dvb-s://";
958 else if( bdat
->isChecked() ) mrl
= "dvb-t://";
959 else if( bdac
->isChecked() ) mrl
= "dvb-c://";
961 mrl
+= " :dvb-frequency=" + QString("%1").arg( bdaFreq
->value() );
962 if( bdas
->isChecked() || bdac
->isChecked() )
963 mrl
+= " :dvb-srate=" + QString("%1").arg( bdaSrate
->value() );
965 mrl
+= " :dvb-bandwidth=" +
966 QString("%1").arg( bdaBandBox
->itemData(
967 bdaBandBox
->currentIndex() ).toInt() );
971 mrl
+= " :dshow-vdev=" + QString("\"%1\"").arg( vdevDshowW
->getValue() );
972 mrl
+= " :dshow-adev=" + QString("\"%1\"").arg( adevDshowW
->getValue() );
973 if( dshowVSizeLine
->isModified() )
974 mrl
+= " :dshow-size=" + dshowVSizeLine
->text();
979 mrl
+= " :v4l-vdev=" + v4lVideoDevice
->text();
980 mrl
+= " :v4l-adev=" + v4lAudioDevice
->text();
981 mrl
+= " :v4l-norm=" + QString("%1").arg( v4lNormBox
->currentIndex() );
982 mrl
+= " :v4l-frequency=" + QString("%1").arg( v4lFreq
->value() );
986 mrl
+= " :v4l2-dev=" + v4l2VideoDevice
->text();
987 mrl
+= " :v4l2-adev=" + v4l2AudioDevice
->text();
988 mrl
+= " :v4l2-standard=" + QString("%1").arg( v4l2StdBox
->currentIndex() );
992 mrl
+= "channels=" + QString("%1").arg( jackChannels
->value() );
993 mrl
+= ":ports=" + jackPortsSelected
->text();
994 mrl
+= " --jack-input-caching=" + QString("%1").arg( jackCaching
->value() );
995 if ( jackPace
->isChecked() )
997 mrl
+= " --jack-input-use-vlc-pace";
999 if ( jackConnect
->isChecked() )
1001 mrl
+= " --jack-input-auto-connect";
1006 mrl
+= " :pvr-device=" + pvrDevice
->text();
1007 mrl
+= " :pvr-radio-device=" + pvrRadioDevice
->text();
1008 mrl
+= " :pvr-norm=" + QString("%1").arg( pvrNormBox
->currentIndex() );
1009 if( pvrFreq
->value() )
1010 mrl
+= " :pvr-frequency=" + QString("%1").arg( pvrFreq
->value() );
1011 if( pvrBitr
->value() )
1012 mrl
+= " :pvr-bitrate=" + QString("%1").arg( pvrBitr
->value() );
1016 mrl
+= " :dvb-adapter=" + QString("%1").arg( dvbCard
->value() );
1017 mrl
+= " :dvb-frequency=" + QString("%1").arg( dvbFreq
->value() );
1018 mrl
+= " :dvb-srate=" + QString("%1").arg( dvbSrate
->value() );
1027 if( !advMRL
.isEmpty() ) mrl
+= advMRL
;
1029 emit
mrlUpdated( mrl
);
1033 * Update the Buttons (show/hide) for the GUI as all device type don't
1034 * use the same ui. elements.
1036 void CaptureOpenPanel::updateButtons()
1038 /* Be sure to display the ui Elements in case they were hidden by
1039 * some Device Type (like Screen://) */
1040 ui
.optionsBox
->show();
1041 ui
.advancedButton
->show();
1042 /* Get the current Device Number */
1043 int i_devicetype
= ui
.deviceCombo
->itemData(
1044 ui
.deviceCombo
->currentIndex() ).toInt();
1045 switch( i_devicetype
)
1049 if( bdas
->isChecked() || bdac
->isChecked() )
1052 bdaSrateLabel
->show();
1054 bdaBandLabel
->hide();
1059 bdaSrateLabel
->hide();
1061 bdaBandLabel
->show();
1066 if( dvbs
->isChecked() ) dvbFreq
->setSuffix(" kHz");
1067 if( dvbc
->isChecked() || dvbt
->isChecked() ) dvbFreq
->setSuffix(" Hz");
1071 ui
.optionsBox
->hide();
1072 ui
.advancedButton
->hide();
1079 void CaptureOpenPanel::advancedDialog()
1081 /* Get selected device type */
1082 int i_devicetype
= ui
.deviceCombo
->itemData(
1083 ui
.deviceCombo
->currentIndex() ).toInt();
1085 /* Get the corresponding module */
1086 module_t
*p_module
=
1087 module_Find( VLC_OBJECT(p_intf
), psz_devModule
[i_devicetype
] );
1088 if( NULL
== p_module
) return;
1091 QList
<ConfigControl
*> controls
;
1093 /* Get the confsize */
1094 unsigned int i_confsize
;
1095 module_config_t
*p_config
;
1096 p_config
= module_GetConfig( p_module
, &i_confsize
);
1098 /* New Adv Prop dialog */
1099 adv
= new QDialog( this );
1100 adv
->setWindowTitle( qtr( "Advanced options..." ) );
1102 /* A main Layout with a Frame */
1103 QVBoxLayout
*mainLayout
= new QVBoxLayout( adv
);
1104 QFrame
*advFrame
= new QFrame
;
1105 QScrollArea
*scroll
= new QScrollArea
;
1106 mainLayout
->addWidget( scroll
);
1108 /* GridLayout inside the Frame */
1109 QGridLayout
*gLayout
= new QGridLayout( advFrame
);
1110 gLayout
->setSizeConstraint( QLayout::SetFixedSize
);
1112 scroll
->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff
);
1113 scroll
->setWidgetResizable( true );
1114 scroll
->setWidget( advFrame
);
1116 /* Create the options inside the FrameLayout */
1117 for( int n
= 0; n
< i_confsize
; n
++ )
1119 module_config_t
*p_item
= p_config
+ n
;
1120 ConfigControl
*config
= ConfigControl::createControl(
1121 VLC_OBJECT( p_intf
), p_item
, advFrame
, gLayout
, n
);
1122 controls
.append( config
);
1126 QDialogButtonBox
*advButtonBox
= new QDialogButtonBox( adv
);
1127 QPushButton
*closeButton
= new QPushButton( qtr( "Ok" ) );
1128 QPushButton
*cancelButton
= new QPushButton( qtr( "Cancel" ) );
1130 CONNECT( closeButton
, clicked(), adv
, accept() );
1131 CONNECT( cancelButton
, clicked(), adv
, reject() );
1133 advButtonBox
->addButton( closeButton
, QDialogButtonBox::AcceptRole
);
1134 advButtonBox
->addButton( cancelButton
, QDialogButtonBox::RejectRole
);
1136 gLayout
->addWidget( advButtonBox
, i_confsize
+ 1, 0, 1, -1 );
1138 /* Creation of the MRL */
1141 QString tempMRL
= "";
1142 for( int i
= 0; i
< controls
.size(); i
++ )
1144 ConfigControl
*control
= controls
[i
];
1147 msg_Dbg( p_intf
, "This shouldn't happen, please report" );
1151 tempMRL
+= (i
? " :" : ":");
1153 if( control
->getType() == CONFIG_ITEM_BOOL
)
1154 if( !(qobject_cast
<VIntConfigControl
*>(control
)->getValue() ) )
1157 tempMRL
+= control
->getName();
1159 switch( control
->getType() )
1161 case CONFIG_ITEM_STRING
:
1162 case CONFIG_ITEM_FILE
:
1163 case CONFIG_ITEM_DIRECTORY
:
1164 case CONFIG_ITEM_MODULE
:
1165 tempMRL
+= QString("=\"%1\"").arg( qobject_cast
<VStringConfigControl
*>(control
)->getValue() );
1167 case CONFIG_ITEM_INTEGER
:
1168 tempMRL
+= QString("=%1").arg( qobject_cast
<VIntConfigControl
*>(control
)->getValue() );
1170 case CONFIG_ITEM_FLOAT
:
1171 tempMRL
+= QString("=%1").arg( qobject_cast
<VFloatConfigControl
*>(control
)->getValue() );
1177 msg_Dbg( p_intf
, "%s", qtu( advMRL
) );