1 /*****************************************************************************
2 * profile_selector.cpp : A small profile selector and editor
3 ****************************************************************************
4 * Copyright (C) 2009 the VideoLAN team
7 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
25 #include "components/sout/profile_selector.hpp"
26 #include "components/sout/profiles.hpp"
27 #include "dialogs/sout.hpp"
29 #include <QHBoxLayout>
30 #include <QToolButton>
33 #include <QMessageBox>
34 #include <QRadioButton>
36 #include <QButtonGroup>
39 #include <QListWidgetItem>
40 #include <QFontMetrics>
43 #include <vlc_modules.h>
45 #define CATPROP2NAME( val ) QString("valueholder_%1").arg( val )
46 #define CATANDPROP( cat, prop ) QString("%1_%2").arg( cat ).arg( prop )
47 #define OLDFORMAT "^\\w+;\\d+;\\d+;\\d+;"
49 VLCProfileSelector::VLCProfileSelector( QWidget
*_parent
): QWidget( _parent
)
51 QHBoxLayout
*layout
= new QHBoxLayout( this );
53 QLabel
*prLabel
= new QLabel( qtr( "Profile"), this );
54 layout
->addWidget( prLabel
);
56 profileBox
= new QComboBox( this );
57 layout
->addWidget( profileBox
);
59 QToolButton
*editButton
= new QToolButton( this );
60 editButton
->setIcon( QIcon( ":/menu/preferences.svg" ) );
61 editButton
->setToolTip( qtr( "Edit selected profile" ) );
62 layout
->addWidget( editButton
);
64 QToolButton
*deleteButton
= new QToolButton( this );
65 deleteButton
->setIcon( QIcon( ":/toolbar/clear.svg" ) );
66 deleteButton
->setToolTip( qtr( "Delete selected profile" ) );
67 layout
->addWidget( deleteButton
);
69 QToolButton
*newButton
= new QToolButton( this );
70 newButton
->setIcon( QIcon( ":/new.svg" ) );
71 newButton
->setToolTip( qtr( "Create a new profile" ) );
72 layout
->addWidget(newButton
);
74 BUTTONACT( newButton
, newProfile() );
75 BUTTONACT( editButton
, editProfile() );
76 BUTTONACT( deleteButton
, deleteProfile() );
79 CONNECT( profileBox
, activated( int ),
80 this, updateOptions( int ) );
81 updateOptions( qMax(profileBox
->currentIndex(), 0) );
84 VLCProfileSelector::~VLCProfileSelector()
90 QSettings::NativeFormat
,
92 QSettings::UserScope
, "vlc", "vlc-qt-interface" );
94 settings
.setValue( "codecs-profiles-selected", profileBox
->currentText() );
97 inline void VLCProfileSelector::fillProfilesCombo()
101 QSettings::IniFormat
,
103 QSettings::NativeFormat
,
105 QSettings::UserScope
, "vlc", "vlc-qt-interface" );
107 int i_size
= settings
.beginReadArray( "codecs-profiles" );
109 for( int i
= 0; i
< i_size
; i
++ )
111 settings
.setArrayIndex( i
);
112 if( settings
.value( "Profile-Name" ).toString().isEmpty() ) continue;
113 profileBox
->addItem( settings
.value( "Profile-Name" ).toString(),
114 settings
.value( "Profile-Value" ) );
118 for( size_t i
= 0; i
< NB_PROFILE
; i
++ )
120 profileBox
->addItem( video_profile_name_list
[i
],
121 video_profile_value_list
[i
] );
126 profileBox
->setCurrentIndex(
127 profileBox
->findText(
128 settings
.value( "codecs-profiles-selected" ).toString() ));
132 void VLCProfileSelector::newProfile()
134 editProfile( "", "" );
137 void VLCProfileSelector::editProfile()
139 editProfile( profileBox
->currentText(),
140 profileBox
->itemData( profileBox
->currentIndex() ).toString() );
143 void VLCProfileSelector::editProfile( const QString
& qs
, const QString
& value
)
145 /* Create the Profile Editor */
146 VLCProfileEditor
*editor
= new VLCProfileEditor( qs
, value
, this );
149 if( QDialog::Accepted
== editor
->exec() )
153 profileBox
->addItem( editor
->name
, QVariant( editor
->transcodeValue() ) );
154 /* Update old profile */
157 /* Look for the profile */
158 int i_profile
= profileBox
->findText( qs
);
159 assert( i_profile
!= -1 );
160 profileBox
->setItemText( i_profile
, editor
->name
);
161 profileBox
->setItemData( i_profile
, editor
->transcodeValue() );
162 /* Force mrl recreation */
163 updateOptions( i_profile
);
169 emit
optionsChanged();
172 void VLCProfileSelector::deleteProfile()
174 profileBox
->removeItem( profileBox
->currentIndex() );
178 void VLCProfileSelector::saveProfiles()
182 QSettings::IniFormat
,
184 QSettings::NativeFormat
,
186 QSettings::UserScope
, "vlc", "vlc-qt-interface" );
188 settings
.remove( "codecs-profiles" ); /* Erase old profiles to be rewritten */
189 settings
.beginWriteArray( "codecs-profiles" );
190 for( int i
= 0; i
< profileBox
->count(); i
++ )
192 settings
.setArrayIndex( i
);
193 settings
.setValue( "Profile-Name", profileBox
->itemText( i
) );
194 settings
.setValue( "Profile-Value", profileBox
->itemData( i
).toString() );
199 void VLCProfileSelector::updateOptions( int i
)
201 QString options
= profileBox
->itemData( i
).toString();
202 QRegExp
rx(OLDFORMAT
);
203 if ( !options
.contains( ";" ) ) return;
204 if ( rx
.indexIn( options
) != -1 )
205 return updateOptionsOldFormat( i
);
209 QStringList tuples
= options
.split( ";" );
210 typedef QHash
<QString
, QString
> proptovalueHashType
;
211 QHash
<QString
, proptovalueHashType
*> categtopropHash
;
212 proptovalueHashType
*proptovalueHash
;
215 /* Build a double hash structure because we need to make ordered lookups */
216 foreach ( const QString
&tuple
, tuples
)
218 QStringList keyvalue
= tuple
.split( "=" );
219 if ( keyvalue
.count() != 2 ) continue;
220 QString key
= keyvalue
[0];
222 keyvalue
= key
.split( "_" );
223 if ( keyvalue
.count() != 2 ) continue;
224 QString categ
= keyvalue
[0];
225 QString prop
= keyvalue
[1];
227 if ( ! categtopropHash
.contains( categ
) )
229 proptovalueHash
= new proptovalueHashType();
230 categtopropHash
.insert( categ
, proptovalueHash
);
232 proptovalueHash
= categtopropHash
.value( categ
);
234 proptovalueHash
->insert( prop
, value
);
237 /* Now we can build the/translate into MRL */
238 #define HASHPICK( categ, prop ) \
239 if ( categtopropHash.contains( categ ) ) \
241 proptovalueHash = categtopropHash.value( categ );\
242 value = proptovalueHash->take( prop );\
244 else value = QString()
247 smrl
.begin( "transcode" );
249 /* First muxer options */
250 HASHPICK( "muxer", "mux" );
251 if ( value
.isEmpty() ) goto cleanup
;
254 HASHPICK( "video", "enable" );
255 if ( !value
.isEmpty() )
257 HASHPICK( "video", "codec" );
259 if ( !value
.isEmpty() )
261 smrl
.option( "vcodec", value
);
263 HASHPICK( "vcodec", "bitrate" );
264 if ( value
.toInt() > 0 )
266 smrl
.option( "vb", value
.toInt() );
269 HASHPICK( "video", "filters" );
270 if ( !value
.isEmpty() )
272 QStringList valuesList
= QUrl::fromPercentEncoding( value
.toLatin1() ).split( ";" );
273 smrl
.option( "vfilter", valuesList
.join( ":" ) );
276 /*if ( codec is h264 )*/
278 /* special handling */
279 QStringList codecoptions
;
281 HASHPICK( "vcodec", "qp" );
282 if( value
.toInt() > 0 )
283 codecoptions
<< QString( "qp=%1" ).arg( value
);
285 HASHPICK( "vcodec", "custom" );
286 if( !value
.isEmpty() )
287 codecoptions
<< QUrl::fromPercentEncoding( value
.toLatin1() );
289 if ( codecoptions
.count() )
291 QString("x264{%1}").arg( codecoptions
.join(",") ) );
294 HASHPICK( "vcodec", "framerate" );
295 if ( !value
.isEmpty() && value
.toInt() > 0 )
296 smrl
.option( "fps", value
);
298 HASHPICK( "vcodec", "scale" );
299 if ( !value
.isEmpty() )
300 smrl
.option( "scale", value
);
302 HASHPICK( "vcodec", "width" );
303 if ( !value
.isEmpty() && value
.toInt() > 0 )
304 smrl
.option( "width", value
);
306 HASHPICK( "vcodec", "height" );
307 if ( !value
.isEmpty() && value
.toInt() > 0 )
308 smrl
.option( "height", value
);
311 smrl
.option( "vcodec", "none" );
314 HASHPICK( "audio", "enable" );
315 if ( !value
.isEmpty() )
317 HASHPICK( "audio", "codec" );
318 if ( !value
.isEmpty() )
320 smrl
.option( "acodec", value
);
322 HASHPICK( "acodec", "bitrate" );
323 smrl
.option( "ab", value
.toInt() );
325 HASHPICK( "acodec", "channels" );
326 smrl
.option( "channels", value
.toInt() );
328 HASHPICK( "acodec", "samplerate" );
329 smrl
.option( "samplerate", value
.toInt() );
331 HASHPICK( "audio", "filters" );
332 if ( !value
.isEmpty() )
334 QStringList valuesList
= QUrl::fromPercentEncoding( value
.toLatin1() ).split( ";" );
335 smrl
.option( "afilter", valuesList
.join( ":" ) );
340 smrl
.option( "acodec", "none" );
343 HASHPICK( "subtitles", "enable" );
344 if( !value
.isEmpty() )
346 HASHPICK( "subtitles", "overlay" );
347 if ( value
.isEmpty() )
349 HASHPICK( "subtitles", "codec" );
350 smrl
.option( "scodec", value
);
354 smrl
.option( "soverlay" );
357 smrl
.option( "scodec", "none" );
362 transcode
= smrl
.getMrl();
365 /* Temp hash tables cleanup */
366 foreach( proptovalueHashType
*hash
, categtopropHash
)
369 emit
optionsChanged();
372 void VLCProfileSelector::updateOptionsOldFormat( int i
)
374 QStringList options
= profileBox
->itemData( i
).toString().split( ";" );
375 if( options
.count() < 16 )
381 if( options
[1].toInt() || options
[2].toInt() || options
[3].toInt() )
383 smrl
.begin( "transcode" );
385 if( options
[1].toInt() )
387 smrl
.option( "vcodec", options
[4] );
388 if( options
[4] != "none" )
390 smrl
.option( "vb", options
[5].toInt() );
391 if( !options
[7].isEmpty() && options
[7].toInt() > 0 )
392 smrl
.option( "fps", options
[7] );
393 if( !options
[6].isEmpty() )
394 smrl
.option( "scale", options
[6] );
395 if( !options
[8].isEmpty() && options
[8].toInt() > 0 )
396 smrl
.option( "width", options
[8].toInt() );
397 if( !options
[9].isEmpty() && options
[9].toInt() > 0 )
398 smrl
.option( "height", options
[9].toInt() );
402 if( options
[2].toInt() )
404 smrl
.option( "acodec", options
[10] );
405 if( options
[10] != "none" )
407 smrl
.option( "ab", options
[11].toInt() );
408 smrl
.option( "channels", options
[12].toInt() );
409 smrl
.option( "samplerate", options
[13].toInt() );
413 if( options
[3].toInt() )
415 smrl
.option( "scodec", options
[14] );
416 if( options
[15].toInt() )
417 smrl
.option( "soverlay" );
422 transcode
= smrl
.getMrl();
426 emit
optionsChanged();
433 VLCProfileEditor::VLCProfileEditor( const QString
& qs_name
, const QString
& value
,
435 : QVLCDialog( _parent
, NULL
)
438 ui
.buttonGroup
->setObjectName( CATPROP2NAME( CATANDPROP( "muxer", "mux" ) ) );
439 if( !qs_name
.isEmpty() )
441 ui
.profileLine
->setText( qs_name
);
442 ui
.profileLine
->setReadOnly( true );
448 QPushButton
*saveButton
= new QPushButton(
449 ( qs_name
.isEmpty() ) ? qtr( "Create" ) : qtr( "Save" ) );
450 ui
.buttonBox
->addButton( saveButton
, QDialogButtonBox::AcceptRole
);
451 BUTTONACT( saveButton
, close() );
452 QPushButton
*cancelButton
= new QPushButton( qtr( "Cancel" ) );
453 ui
.buttonBox
->addButton( cancelButton
, QDialogButtonBox::RejectRole
);
454 BUTTONACT( cancelButton
, reject() );
456 CONNECT( ui
.valueholder_video_copy
, stateChanged( int ),
457 this, activatePanels() );
458 CONNECT( ui
.valueholder_audio_copy
, stateChanged( int ),
459 this, activatePanels() );
460 CONNECT( ui
.valueholder_subtitles_overlay
, stateChanged( int ),
461 this, activatePanels() );
462 CONNECT( ui
.valueholder_vcodec_bitrate
, editingFinished( ),
463 this, fixBirateState() );
464 CONNECT( ui
.valueholder_vcodec_qp
, editingFinished( ),
465 this, fixQPState() );
466 CONNECT( ui
.valueholder_video_codec
, currentIndexChanged( int ),
467 this, codecSelected() );
470 fillProfile( value
);
475 void VLCProfileEditor::loadCapabilities()
478 module_t
**p_all
= module_list_get (&count
);
480 /* Parse the module list for capabilities and probe each of them */
481 for (size_t i
= 0; i
< count
; i
++)
483 module_t
*p_module
= p_all
[i
];
485 if( module_provides( p_module
, "sout mux" ) )
486 caps
["muxers"].insert( module_get_object( p_module
) );
487 // else if ( module_provides( p_module, "encoder" ) )
488 // caps["encoders"].insert( module_get_object( p_module ) );
490 module_list_free (p_all
);
493 inline void VLCProfileEditor::registerFilters()
496 module_t
**p_all
= module_list_get (&count
);
498 for (size_t i
= 0; i
< count
; i
++)
500 module_t
*p_module
= p_all
[i
];
501 if ( module_get_score( p_module
) > 0 ) continue;
503 QString capability
= module_get_capability( p_module
);
504 QListWidget
*listWidget
= NULL
;
505 QListWidgetItem
*item
;
507 if ( capability
== "video filter" )
508 listWidget
= ui
.valueholder_video_filters
;
509 else if ( capability
== "audio filter" )
510 listWidget
= ui
.valueholder_audio_filters
;
512 if ( !listWidget
) continue;
514 item
= new QListWidgetItem( module_get_name( p_module
, true ) );
515 item
->setCheckState( Qt::Unchecked
);
516 item
->setToolTip( QString( module_get_help( p_module
) ) );
517 item
->setData( Qt::UserRole
, QString( module_get_object( p_module
) ) );
518 listWidget
->addItem( item
);
520 module_list_free (p_all
);
522 ui
.valueholder_video_filters
->sortItems();
523 ui
.valueholder_audio_filters
->sortItems();
526 inline void VLCProfileEditor::registerCodecs()
528 #define SETMUX( button, val, mod, vid, aud, men, sub, stream, chaps ) \
529 ui.button->setProperty( "sout", val );\
530 ui.button->setProperty( "module", mod );\
531 ui.button->setProperty( "capvideo", vid );\
532 ui.button->setProperty( "capaudio", aud );\
533 ui.button->setProperty( "capmenu", men );\
534 ui.button->setProperty( "capsubs", sub );\
535 ui.button->setProperty( "capstream", stream );\
536 ui.button->setProperty( "capchaps", chaps );\
537 CONNECT( ui.button, clicked(bool), this, muxSelected() );
538 SETMUX( PSMux
, "ps", "ps", true, true, false, true, false, true )
539 SETMUX( TSMux
, "ts", "ts", true, true, false, true, true, false )
540 SETMUX( WEBMux
, "webm", "avformat", true, true, false, false, true, false )
541 SETMUX( MPEG1Mux
, "mpeg1", "ps", true, true, false, false, false, false )
542 SETMUX( OggMux
, "ogg", "ogg", true, true, false, false, true, true )
543 SETMUX( ASFMux
, "asf", "asf", true, true, false, true, true, true )
544 SETMUX( MOVMux
, "mp4", "mp4", true, true, true, true, true, false )
545 SETMUX( WAVMux
, "wav", "wav", false, true, false, false, false, false )
546 SETMUX( FLACMux
, "flac", "dummy", false, true, false, false, false, false )
547 SETMUX( MP3Mux
, "mp3", "dummy", false, true, false, false, false, false )
548 SETMUX( RAWMux
, "raw", "dummy", true, true, false, false, false, false )
549 SETMUX( FLVMux
, "flv", "avformat", true, true, false, false, true, false )
550 SETMUX( MKVMux
, "mkv", "avformat", true, true, true, true, true, true )
551 SETMUX( AVIMux
, "avi", "avi", true, true, false, false, false, false )
552 SETMUX( MJPEGMux
, "mpjpeg", "mpjpeg", true, false, false, false, false, false )
555 #define ADD_VCODEC( name, fourcc ) \
556 ui.valueholder_video_codec->addItem( name, QVariant( fourcc ) );
557 ADD_VCODEC( "MPEG-1", "mp1v" )
558 ADD_VCODEC( "MPEG-2", "mp2v" )
559 ADD_VCODEC( "MPEG-4", "mp4v" )
560 ADD_VCODEC( "DIVX 1" , "DIV1" )
561 ADD_VCODEC( "DIVX 2" , "DIV2" )
562 ADD_VCODEC( "DIVX 3" , "DIV3" )
563 ADD_VCODEC( "H-263", "H263" )
564 ADD_VCODEC( "H-264 (AVC)", "h264" )
565 ADD_VCODEC( "H-265 (HEVC)", "hevc" )
566 ADD_VCODEC( "AV1", "av01" )
567 ADD_VCODEC( "VP8", "VP80" )
568 ADD_VCODEC( "WMV1", "WMV1" )
569 ADD_VCODEC( "WMV2" , "WMV2" )
570 ADD_VCODEC( "M-JPEG", "MJPG" )
571 ADD_VCODEC( "Theora", "theo" )
574 qpcodecsList
<< "h264";
576 #define ADD_ACODEC( name, fourcc ) ui.valueholder_audio_codec->addItem( name, QVariant( fourcc ) );
577 ADD_ACODEC( "MPEG Audio", "mpga" )
578 ADD_ACODEC( "MP3", "mp3" )
579 ADD_ACODEC( "MPEG 4 Audio ( AAC )", "mp4a" )
580 ADD_ACODEC( "A52/AC-3", "a52" )
581 ADD_ACODEC( "Vorbis", "vorb" )
582 ADD_ACODEC( "Flac", "flac" )
583 ADD_ACODEC( "Opus", "opus" )
584 ADD_ACODEC( "Speex", "spx" )
585 ADD_ACODEC( "WAV", "s16l" )
586 ADD_ACODEC( "WMA2", "wma2" )
589 #define ADD_SCALING( factor ) ui.valueholder_vcodec_scale->addItem( factor );
590 ADD_SCALING( qtr("Auto") );
592 ADD_SCALING( "0.25" )
594 ADD_SCALING( "0.75" )
595 ADD_SCALING( "1.25" )
597 ADD_SCALING( "1.75" )
601 #define ADD_SAMPLERATE( sample, val ) ui.valueholder_acodec_samplerate->addItem( sample, val );
602 ADD_SAMPLERATE( "8000 Hz", 8000 )
603 ADD_SAMPLERATE( "11025 Hz", 11025 )
604 ADD_SAMPLERATE( "22050 Hz", 22050 )
605 ADD_SAMPLERATE( "44100 Hz", 44100 )
606 ADD_SAMPLERATE( "48000 Hz", 48000 )
607 #undef ADD_SAMPLERATE
609 #define ADD_SCODEC( name, fourcc ) ui.valueholder_subtitles_codec->addItem( name, QVariant( fourcc ) );
610 ADD_SCODEC( "DVBS (DVB subtitles)", "dvbs" )
611 ADD_SCODEC( "tx3g (MPEG-4 timed text)", "tx3g" )
612 ADD_SCODEC( "T-REC 140 (for rtp)", "t140" )
616 void VLCProfileEditor::muxSelected()
618 QRadioButton
*current
=
619 qobject_cast
<QRadioButton
*>( ui
.buttonGroup
->checkedButton() );
621 #define SETYESNOSTATE( name, prop ) \
622 ui.name->setChecked( current->property( prop ).toBool() )
625 SETYESNOSTATE( capvideo
, "capvideo" );
626 SETYESNOSTATE( capaudio
, "capaudio" );
627 SETYESNOSTATE( capmenu
, "capmenu" );
628 SETYESNOSTATE( capsubs
, "capsubs" );
629 SETYESNOSTATE( capstream
, "capstream" );
630 SETYESNOSTATE( capchaps
, "capchaps" );
632 int textsize
= QFontMetrics(ui
.muxerwarning
->font()).ascent();
633 if( current
->property("module").toString() == "avformat" )
634 ui
.muxerwarning
->setText(
635 QString( "<img src=\":/menu/info.svg\" width=%2 height=%2/> %1" )
636 .arg( qtr( "This muxer is not provided directly by VLC: It could be missing." ) )
639 else if ( !caps
["muxers"].contains( current
->property("module").toString() ) &&
640 !caps
["muxers"].contains( "mux_" + current
->property("module").toString() ) )
641 ui
.muxerwarning
->setText(
642 QString( "<img src=\":/toobar/clear.svg\" width=%2 height=%2/> %1" )
643 .arg( qtr( "This muxer is missing. Using this profile will fail" ) )
647 ui
.muxerwarning
->setText("");
653 void VLCProfileEditor::codecSelected()
655 /* Enable quality preset */
656 QString currentcodec
= ui
.valueholder_video_codec
->
657 itemData(ui
.valueholder_video_codec
->currentIndex() ).toString();
658 ui
.valueholder_vcodec_qp
->setEnabled( qpcodecsList
.contains( currentcodec
) );
661 void VLCProfileEditor::fillProfile( const QString
& qs
)
663 QRegExp
rx(OLDFORMAT
);
664 if ( rx
.indexIn( qs
) != -1 ) return fillProfileOldFormat( qs
);
666 QStringList tuples
= qs
.split( ";" );
667 foreach ( const QString
&tuple
, tuples
)
669 QStringList keyvalue
= tuple
.split( "=" );
670 if ( keyvalue
.count() != 2 ) continue;
671 QString key
= keyvalue
[0];
672 QString value
= keyvalue
[1];
673 QObject
*object
= findChild
<QObject
*>( CATPROP2NAME( key
) );
676 if( object
->inherits( "QButtonGroup" ) )
677 { /* Buttongroup for Radios */
678 const QButtonGroup
*group
= qobject_cast
<const QButtonGroup
*>( object
);
679 foreach( QAbstractButton
*button
, group
->buttons() )
681 if ( button
->property("sout").toString() == value
)
683 button
->setChecked( true );
684 break;/* radios are exclusive */
688 else if( object
->inherits( "QCheckBox" ) )
690 QCheckBox
*box
= qobject_cast
<QCheckBox
*>( object
);
691 box
->setChecked( ! value
.isEmpty() );
693 else if( object
->inherits( "QGroupBox" ) )
695 QGroupBox
*box
= qobject_cast
<QGroupBox
*>( object
);
696 box
->setChecked( ! value
.isEmpty() );
698 else if( object
->inherits( "QSpinBox" ) )
700 QSpinBox
*box
= qobject_cast
<QSpinBox
*>( object
);
701 box
->setValue( value
.toInt() );
703 else if( object
->inherits( "QDoubleSpinBox" ) )
705 QDoubleSpinBox
*box
= qobject_cast
<QDoubleSpinBox
*>( object
);
706 box
->setValue( value
.toDouble() );
708 else if( object
->inherits( "QComboBox" ) )
710 QComboBox
*box
= qobject_cast
<QComboBox
*>( object
);
711 box
->setCurrentIndex( box
->findData( value
) );
712 if ( box
->lineEdit() && box
->currentIndex() == -1 )
713 box
->lineEdit()->setText( value
);
715 else if( object
->inherits( "QLineEdit" ) )
717 QLineEdit
*box
= qobject_cast
<QLineEdit
*>( object
);
718 box
->setText( QUrl::fromPercentEncoding( value
.toLatin1() ) );
720 else if ( object
->inherits( "QListWidget" ) )
722 QStringList valuesList
= QUrl::fromPercentEncoding( value
.toLatin1() ).split( ";" );
723 const QListWidget
*list
= qobject_cast
<const QListWidget
*>( object
);
724 for( int i
=0; i
< list
->count(); i
++ )
726 QListWidgetItem
*item
= list
->item( i
);
727 if ( valuesList
.contains( item
->data( Qt::UserRole
).toString() ) )
728 item
->setCheckState( Qt::Checked
);
730 item
->setCheckState( Qt::Unchecked
);
737 void VLCProfileEditor::fillProfileOldFormat( const QString
& qs
)
739 QStringList options
= qs
.split( ";" );
740 if( options
.count() < 16 )
743 const QString mux
= options
[0];
744 for ( int i
=0; i
< ui
.muxer
->layout()->count(); i
++ )
746 QRadioButton
*current
=
747 qobject_cast
<QRadioButton
*>(ui
.muxer
->layout()->itemAt(i
)->widget());
748 if ( unlikely( !current
) ) continue;/* someone is messing up with ui */
749 if ( current
->property("sout").toString() == mux
)
751 current
->setChecked( true );
752 break;/* radios are exclusive */
756 ui
.valueholder_video_copy
->setChecked( !options
[1].toInt() );
757 ui
.valueholder_video_enable
->setChecked( ( options
[4] != "none" ) );
758 ui
.valueholder_audio_copy
->setChecked( !options
[2].toInt() );
759 ui
.valueholder_audio_enable
->setChecked( ( options
[10] != "none" ) );
760 ui
.valueholder_subtitles_enable
->setChecked( options
[3].toInt() );
762 ui
.valueholder_video_codec
->setCurrentIndex( ui
.valueholder_video_codec
->findData( options
[4] ) );
763 ui
.valueholder_vcodec_bitrate
->setValue( options
[5].toInt() );
764 if ( options
[6].toInt() > 0 )
765 ui
.valueholder_vcodec_scale
->setEditText( options
[6] );
767 ui
.valueholder_vcodec_scale
->setCurrentIndex( 0 );
768 ui
.valueholder_vcodec_framerate
->setValue( options
[7].toDouble() );
769 ui
.valueholder_vcodec_width
->setValue( options
[8].toInt() );
770 ui
.valueholder_vcodec_height
->setValue( options
[9].toInt() );
772 ui
.valueholder_audio_codec
->setCurrentIndex( ui
.valueholder_audio_codec
->findData( options
[10] ) );
773 ui
.valueholder_acodec_bitrate
->setValue( options
[11].toInt() );
774 ui
.valueholder_acodec_channels
->setValue( options
[12].toInt() );
776 int index
= ui
.valueholder_acodec_samplerate
->findData( options
[13] );
777 if ( index
== -1 ) index
= ui
.valueholder_acodec_samplerate
->findData( 44100 );
778 ui
.valueholder_acodec_samplerate
->setCurrentIndex( index
);
780 ui
.valueholder_subtitles_codec
->setCurrentIndex( ui
.valueholder_subtitles_codec
->findData( options
[14] ) );
781 ui
.valueholder_subtitles_overlay
->setChecked( options
[15].toInt() );
784 void VLCProfileEditor::close()
786 if( ui
.profileLine
->text().isEmpty() )
788 QMessageBox::warning( this, qtr(" Profile Name Missing" ),
789 qtr( "You must set a name for the profile." ) );
790 ui
.profileLine
->setFocus();
793 name
= ui
.profileLine
->text();
798 #define currentData( box ) box->itemData( box->currentIndex() )
800 QString
VLCProfileEditor::transcodeValue()
802 QList
<QObject
*> allwidgets
= findChildren
<QObject
*>();
803 QStringList configuration
;
805 foreach( const QObject
*object
, allwidgets
)
807 if ( ! object
->objectName().startsWith( CATPROP2NAME( "" ) ) )
809 if ( object
->inherits( "QWidget" ) &&
810 ! qobject_cast
<const QWidget
*>(object
)->isEnabled() ) continue;
812 QString name
= object
->objectName();
813 QStringList vals
= object
->objectName().split( "_" );
814 if ( vals
.count() != 3 ) continue;
815 QString
&categ
= vals
[1];
816 QString
&prop
= vals
[2];
819 if( object
->inherits( "QButtonGroup" ) )
821 const QButtonGroup
*group
= qobject_cast
<const QButtonGroup
*>( object
);
822 value
= group
->checkedButton()->property( "sout" ).toString();
824 else if( object
->inherits( "QCheckBox" ) )
826 const QCheckBox
*box
= qobject_cast
<const QCheckBox
*>( object
);
827 value
= box
->isChecked() ? "yes" : "";
829 else if( object
->inherits( "QGroupBox" ) )
831 const QGroupBox
*box
= qobject_cast
<const QGroupBox
*>( object
);
832 value
= box
->isChecked() ? "yes" : "";
834 else if( object
->inherits( "QSpinBox" ) )
836 const QSpinBox
*box
= qobject_cast
<const QSpinBox
*>( object
);
837 value
= QString::number( box
->value() );
839 else if( object
->inherits( "QDoubleSpinBox" ) )
841 const QDoubleSpinBox
*box
= qobject_cast
<const QDoubleSpinBox
*>( object
);
842 value
= QString::number( box
->value() );
844 else if( object
->inherits( "QComboBox" ) )
846 const QComboBox
*box
= qobject_cast
<const QComboBox
*>( object
);
847 value
= currentData( box
).toString();
848 if ( value
.isEmpty() && box
->lineEdit() ) value
= box
->lineEdit()->text();
850 else if( object
->inherits( "QLineEdit" ) )
852 const QLineEdit
*box
= qobject_cast
<const QLineEdit
*>( object
);
853 value
= QUrl::toPercentEncoding( box
->text(), "", "_;" );
855 else if ( object
->inherits( "QListWidget" ) )
857 const QListWidget
*list
= qobject_cast
<const QListWidget
*>( object
);
858 QStringList valuesList
;
859 for( int i
=0; i
< list
->count(); i
++ )
861 const QListWidgetItem
*item
= list
->item( i
);
862 if ( item
->checkState() == Qt::Checked
)
863 valuesList
.append( item
->data( Qt::UserRole
).toString() );
865 value
= QUrl::toPercentEncoding( valuesList
.join( ";" ), "", "_;" );
868 if ( !value
.isEmpty() )
869 configuration
<< QString( "%1_%2=%3" )
870 .arg( categ
).arg( prop
).arg( value
);
873 return configuration
.join( ";" );
876 void VLCProfileEditor::reset()
878 /* reset to default state as we can only check/enable existing values */
879 ui
.valueholder_video_copy
->setChecked( false );
880 ui
.valueholder_audio_copy
->setChecked( false );
882 fixBirateState(); /* defaults to bitrate, not qp */
883 /* end with top level ones for cascaded setEnabled() */
884 ui
.valueholder_video_enable
->setChecked( false );
885 ui
.valueholder_audio_enable
->setChecked( false );
886 ui
.valueholder_subtitles_enable
->setChecked( false );
889 void VLCProfileEditor::activatePanels()
891 ui
.transcodevideo
->setEnabled( ! ui
.valueholder_video_copy
->isChecked() );
892 ui
.transcodeaudio
->setEnabled( ! ui
.valueholder_audio_copy
->isChecked() );
893 ui
.valueholder_subtitles_codec
->setEnabled( ! ui
.valueholder_subtitles_overlay
->isChecked() );
896 void VLCProfileEditor::fixBirateState()
898 /* exclusive bitrate choice */
899 ui
.valueholder_vcodec_qp
->setValue( 0 );
902 void VLCProfileEditor::fixQPState()
904 /* exclusive bitrate choice */
905 ui
.valueholder_vcodec_bitrate
->setValue( 0 );