Qt: Profiles Editor for the transcoding.
[vlc.git] / modules / gui / qt4 / components / sout / profile_selector.cpp
1
2 #include "components/sout/profile_selector.hpp"
3 #include "dialogs/sout.hpp"
4
5 #include <QHBoxLayout>
6 #include <QToolButton>
7 #include <QComboBox>
8 #include <QLabel>
9 #include <QMessageBox>
10
11 VLCProfileSelector::VLCProfileSelector( QWidget *_parent ): QWidget( _parent )
12 {
13     QHBoxLayout *layout = new QHBoxLayout( this );
14
15     QLabel *prLabel = new QLabel( qtr( "Profile"), this );
16     layout->addWidget( prLabel );
17
18     profileBox = new QComboBox( this );
19     layout->addWidget( profileBox );
20
21     QToolButton *editButton = new QToolButton( this );
22     editButton->setIcon( QIcon( ":/preferences" ) );
23     editButton->setToolTip( qtr( "Edit selected profile" ) );
24     layout->addWidget( editButton );
25
26     QToolButton *deleteButton = new QToolButton( this );
27     deleteButton->setIcon( QIcon( ":/clear" ) );
28     deleteButton->setToolTip( qtr( "Delete selected profile" ) );
29     layout->addWidget( deleteButton );
30
31     QToolButton *newButton = new QToolButton( this );
32 //    newButton->setIcon( QIcon( ":/clear" ) );
33     newButton->setToolTip( qtr( "Create a new profile" ) );
34     layout->addWidget(newButton);
35
36     BUTTONACT( newButton, newProfile() );
37     BUTTONACT( editButton, editProfile() );
38     BUTTONACT( deleteButton, deleteProfile() );
39     fillProfilesCombo();
40
41     CONNECT( profileBox, activated( int ),
42              this, updateOptions( int ) );
43
44 }
45
46 inline void VLCProfileSelector::fillProfilesCombo()
47 {
48     QSettings settings(
49 #ifdef WIN32
50             QSettings::IniFormat,
51 #else
52             QSettings::NativeFormat,
53 #endif
54             QSettings::UserScope, "vlc", "vlc-qt-interface" );
55
56     int i_size = settings.beginReadArray( "codecs-profiles" );
57
58     for( int i = 0; i < i_size; i++ )
59     {
60         settings.setArrayIndex( i );
61         profileBox->addItem( settings.value( "Profile-Name" ).toString(),
62                 settings.value( "Profile-Value" ) );
63     }
64     settings.endArray();
65 }
66
67 void VLCProfileSelector::newProfile()
68 {
69     editProfile( "", "" );
70 }
71
72 void VLCProfileSelector::editProfile()
73 {
74     editProfile( profileBox->currentText(),
75                  profileBox->itemData( profileBox->currentIndex() ).toString() );
76 }
77
78 void VLCProfileSelector::editProfile( QString qs, QString value )
79 {
80     VLCProfileEditor *editor = new VLCProfileEditor( qs, value, this );
81
82     if( QDialog::Accepted == editor->exec() )
83     {
84         if( qs.isEmpty() )
85             profileBox->addItem( editor->name, QVariant( editor->transcodeValue() ) );
86         else
87         {
88             int i_profile = profileBox->findText( qs );
89             profileBox->setItemText( i_profile, editor->name );
90             profileBox->setItemData( i_profile, QVariant( editor->transcodeValue() ) );
91         }
92     }
93     delete editor;
94
95     saveProfiles();
96     emit optionsChanged();
97 }
98
99 void VLCProfileSelector::deleteProfile()
100 {
101     profileBox->removeItem( profileBox->currentIndex() );
102 }
103
104 void VLCProfileSelector::saveProfiles()
105 {
106     QSettings settings(
107 #ifdef WIN32
108             QSettings::IniFormat,
109 #else
110             QSettings::NativeFormat,
111 #endif
112             QSettings::UserScope, "vlc", "vlc-qt-interface" );
113
114     settings.beginWriteArray( "codecs-profiles" );
115     for( int i = 0; i < profileBox->count(); i++ )
116     {
117         settings.setArrayIndex( i );
118         settings.setValue( "Profile-Name", profileBox->itemText( i ) );
119         settings.setValue( "Profile-Value", profileBox->itemData( i ).toString() );
120     }
121     settings.endArray();
122 }
123
124 void VLCProfileSelector::updateOptions( int i )
125 {
126     QStringList options = profileBox->itemData( i ).toString().split( ";" );
127     if( options.size() < 16 )
128         return;
129
130     mux = options[0];
131
132     SoutMrl smrl;
133     if( options[1].toInt() || options[2].toInt() )
134     {
135         smrl.begin( "transcode" );
136
137         if( options[1].toInt() )
138         {
139             smrl.option( "vcodec", options[4] );
140             smrl.option( "vb", options[5].toInt() );
141             smrl.option( "scale", options[6] );
142             smrl.option( "fps", options[7] );
143             smrl.option( "width", options[8].toInt() );
144             smrl.option( "height", options[9].toInt() );
145         }
146
147         if( options[2].toInt() )
148         {
149             smrl.option( "acodec", options[10] );
150             smrl.option( "ab", options[11].toInt() );
151             smrl.option( "channels", options[12].toInt() );
152             smrl.option( "samplerate", options[13].toInt() );
153         }
154
155         if( options[3].toInt() )
156         {
157             smrl.option( "scodec", options[14] );
158             if( options[15].toInt() )
159                 smrl.option( "soverlay" );
160         }
161
162         smrl.end();
163
164         transcode = smrl.getMrl();
165     }
166     else
167         transcode = "";
168 }
169
170
171 /**
172  * VLCProfileEditor
173  **/
174 VLCProfileEditor::VLCProfileEditor( QString qs_name, QString value,
175         QWidget *_parent )
176                  : QVLCDialog( _parent, NULL )
177 {
178     ui.setupUi( this );
179     if( !qs_name.isEmpty() )
180     {
181         ui.profileLine->setText( qs_name );
182         ui.profileLine->setReadOnly( true );
183     }
184     registerCodecs();
185     CONNECT( ui.transcodeVideo, toggled( bool ),
186             this, setVTranscodeOptions( bool ) );
187     CONNECT( ui.transcodeAudio, toggled( bool ),
188             this, setATranscodeOptions( bool ) );
189     CONNECT( ui.transcodeSubs, toggled( bool ),
190             this, setSTranscodeOptions( bool ) );
191     setVTranscodeOptions( false );
192     setATranscodeOptions( false );
193     setSTranscodeOptions( false );
194
195     QPushButton *saveButton = new QPushButton( qtr( "Save" ) );
196     ui.buttonBox->addButton( saveButton, QDialogButtonBox::AcceptRole );
197     BUTTONACT( saveButton, close() );
198     QPushButton *cancelButton = new QPushButton( qtr( "Cancel" ) );
199     ui.buttonBox->addButton( cancelButton, QDialogButtonBox::RejectRole );
200     BUTTONACT( cancelButton, reject() );
201
202     fillProfile( value );
203 }
204
205 inline void VLCProfileEditor::registerCodecs()
206 {
207  
208 #define ADD_VCODEC( name, fourcc ) ui.vCodecBox->addItem( name, QVariant( fourcc ) );
209     ADD_VCODEC( "MPEG-1", "mp1v" )
210     ADD_VCODEC( "MPEG-2", "mp2v" )
211     ADD_VCODEC( "MPEG-4", "mp4v" )
212     ADD_VCODEC( "DIVX 1" , "DIV1" )
213     ADD_VCODEC( "DIVX 2" , "DIV2" )
214     ADD_VCODEC( "DIVX 3" , "DIV3" )
215     ADD_VCODEC( "H-263", "H263" )
216     ADD_VCODEC( "H-264", "h264" )
217     ADD_VCODEC( "WMV1", "WMV1" )
218     ADD_VCODEC( "WMV2" , "WMV2" )
219     ADD_VCODEC( "M-JPEG", "MJPG" )
220     ADD_VCODEC( "Theora", "theo" )
221     ADD_VCODEC( "Dirac", "drac" )
222
223 #define ADD_ACODEC( name, fourcc ) ui.aCodecBox->addItem( name, QVariant( fourcc ) );
224     ADD_ACODEC( "MPEG Audio", "mpga" )
225     ADD_ACODEC( "MP3", "mp3" )
226     ADD_ACODEC( "MPEG 4 Audio ( AAC )", "mp4a" )
227     ADD_ACODEC( "A52/AC-3", "a52" )
228     ADD_ACODEC( "Vorbis", "vorb" )
229     ADD_ACODEC( "Flac", "flac" )
230     ADD_ACODEC( "Speex", "spx" )
231     ADD_ACODEC( "WAV", "s16l" )
232     ADD_ACODEC( "WMA", "wma" )
233
234 #define ADD_SCALING( factor ) ui.vScaleBox->addItem( factor );
235     ADD_SCALING( "1" )
236     ADD_SCALING( "0.25" )
237     ADD_SCALING( "0.5" )
238     ADD_SCALING( "0.75" )
239     ADD_SCALING( "1.25" )
240     ADD_SCALING( "1.5" )
241     ADD_SCALING( "1.75" )
242     ADD_SCALING( "2" )
243
244 #define ADD_SAMPLERATE( sample ) ui.aSampleBox->addItem( sample );
245     ADD_SAMPLERATE( "11250" )
246     ADD_SAMPLERATE( "22500" )
247     ADD_SAMPLERATE( "41000" )
248     ADD_SAMPLERATE( "48000" )
249
250 #define ADD_SCODEC( name, fourcc ) ui.subsCodecBox->addItem( name, QVariant( fourcc ) );
251     ADD_SCODEC( "DVB subtitle", "dvbs" )
252     ADD_SCODEC( "T.140", "t140" )
253 }
254
255 void VLCProfileEditor::fillProfile( QString qs )
256 {
257     QStringList options = qs.split( ";" );
258     if( options.size() < 16 )
259         return;
260
261     ui.transcodeVideo->setChecked( options[1].toInt() );
262     ui.transcodeAudio->setChecked( options[2].toInt() );
263     ui.transcodeSubs->setChecked( options[3].toInt() );
264
265     ui.vCodecBox->setCurrentIndex( ui.vCodecBox->findData( options[4] ) );
266     ui.vBitrateSpin->setValue( options[5].toInt() );
267     ui.vScaleBox->setEditText( options[6] );
268     ui.vFrameBox->setValue( options[7].toDouble() );
269     ui.widthBox->setValue( options[8].toInt() );
270     ui.heightBox->setValue( options[9].toInt() );
271
272     ui.aCodecBox->setCurrentIndex( ui.aCodecBox->findData( options[10] ) );
273     ui.aBitrateSpin->setValue( options[11].toInt() );
274     ui.aChannelsSpin->setValue( options[12].toInt() );
275     ui.aSampleBox->setCurrentIndex( ui.aSampleBox->findData( options[13] ) );
276
277     ui.subsCodecBox->setCurrentIndex( ui.subsCodecBox->findData( options[14] ) );
278     ui.subsOverlay->setChecked( options[15].toInt() );
279 }
280
281 void VLCProfileEditor::setVTranscodeOptions( bool b_trans )
282 {
283     ui.vCodecLabel->setEnabled( b_trans );
284     ui.vCodecBox->setEnabled( b_trans );
285     ui.vBitrateLabel->setEnabled( b_trans );
286     ui.vBitrateSpin->setEnabled( b_trans );
287     ui.vScaleLabel->setEnabled( b_trans );
288     ui.vScaleBox->setEnabled( b_trans );
289     ui.heightBox->setEnabled( b_trans );
290     ui.heightLabel->setEnabled( b_trans );
291     ui.widthBox->setEnabled( b_trans );
292     ui.widthLabel->setEnabled( b_trans );
293     ui.vFrameBox->setEnabled( b_trans );
294     ui.vFrameLabel->setEnabled( b_trans );
295 }
296
297 void VLCProfileEditor::setATranscodeOptions( bool b_trans )
298 {
299     ui.aCodecLabel->setEnabled( b_trans );
300     ui.aCodecBox->setEnabled( b_trans );
301     ui.aBitrateLabel->setEnabled( b_trans );
302     ui.aBitrateSpin->setEnabled( b_trans );
303     ui.aChannelsLabel->setEnabled( b_trans );
304     ui.aChannelsSpin->setEnabled( b_trans );
305     ui.aSampleLabel->setEnabled( b_trans );
306     ui.aSampleBox->setEnabled( b_trans );
307 }
308
309 void VLCProfileEditor::setSTranscodeOptions( bool b_trans )
310 {
311     ui.subsCodecBox->setEnabled( b_trans );
312     ui.subsOverlay->setEnabled( b_trans );
313 }
314
315 void VLCProfileEditor::close()
316 {
317     if( ui.profileLine->text().isEmpty() )
318     {
319         QMessageBox::warning( this, qtr(" Profile Name Missing" ),
320                 qtr( "You must set a name for the profile." ) );
321         ui.profileLine->setFocus();
322         return;
323     }
324     name = ui.profileLine->text();
325
326     accept();
327 }
328
329 QString VLCProfileEditor::transcodeValue()
330 {
331 #define SMUX( x, txt ) if( ui.x->isChecked() ) muxValue =  txt; else
332     SMUX( PSMux, "ps" )
333     SMUX( TSMux, "ts" )
334     SMUX( MPEG1Mux, "mpeg1" )
335     SMUX( OggMux, "ogg" )
336     SMUX( ASFMux, "asf" )
337     SMUX( MOVMux, "mp4" )
338     SMUX( WAVMux, "wav" )
339     SMUX( RAWMux, "raw" )
340     SMUX( FLVMux, "flv" )
341     SMUX( MKVMux, "mkv" )
342     SMUX( AVIMux, "avi" )
343     SMUX( MJPEGMux, "mjpg" );
344
345 #define currentData( box ) box->itemData( box->currentIndex() )
346     QStringList transcodeMRL;
347     transcodeMRL
348             << muxValue
349
350             << QString::number( ui.transcodeVideo->isChecked() )
351             << QString::number( ui.transcodeAudio->isChecked() )
352             << QString::number( ui.transcodeSubs->isChecked() )
353
354             << currentData( ui.vCodecBox ).toString()
355             << QString::number( ui.vBitrateSpin->value() )
356             << ui.vScaleBox->currentText() 
357             << QString::number( ui.vFrameBox->value() )
358             << QString::number( ui.widthBox->value() )
359             << QString::number( ui.heightBox->value() )
360
361             << currentData( ui.aCodecBox ).toString()
362             << QString::number( ui.aBitrateSpin->value() )
363             << QString::number( ui.aChannelsSpin->value() )
364             << ui.aSampleBox->currentText()
365
366             << currentData( ui.subsCodecBox ).toString()
367             << QString::number( ui.subsOverlay->isChecked() );
368
369     return transcodeMRL.join( ";" );
370 }
371