]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs/sout.cpp
Qt/Sout: pass the ttl from the UI to the MRL
[vlc] / modules / gui / qt4 / dialogs / sout.cpp
1 /*****************************************************************************
2  * sout.cpp : Stream output dialog ( old-style )
3  ****************************************************************************
4  * Copyright (C) 2007-2009 the VideoLAN team
5  *
6  * $Id$
7  *
8  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
9  *          Jean-Baptiste Kempf <jb@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * ( at your option ) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include "dialogs/sout.hpp"
31 #include "util/qt_dirs.hpp"
32 #include "components/sout/sout_widgets.hpp"
33
34 #include <QString>
35 #include <QFileDialog>
36 #include <QToolButton>
37 #include <QSpinBox>
38 #include <assert.h>
39
40 SoutDialog::SoutDialog( QWidget *parent, intf_thread_t *_p_intf, const QString& inputMRL )
41            : QVLCDialog( parent,  _p_intf )
42 {
43     setWindowTitle( qtr( "Stream Output" ) );
44     setWindowRole( "vlc-stream-output" );
45
46     /* UI stuff */
47     ui.setupUi( this );
48     ui.inputBox->setMRL( inputMRL );
49     ui.helpEdit->setPlainText( qtr("This dialog will allow you to stream or "
50             "convert your media for use locally, on your private network, "
51             "or on the Internet.\n"
52             "You should start by checking that source matches what you want "
53             "your input to be and then press the \"Next\" "
54             "button to continue.\n") );
55
56     ui.mrlEdit->setToolTip ( qtr( "Stream output string.\n"
57                 "This is automatically generated "
58                  "when you change the above settings,\n"
59                  "but you can change it manually." ) ) ;
60
61 #if 0
62     /* This needs Qt4.5 to be cool */
63     ui.destTab->setTabsClosable( true );
64 #else
65     closeTabButton = new QToolButton( this );
66     ui.destTab->setCornerWidget( closeTabButton );
67     closeTabButton->hide();
68     closeTabButton->setAutoRaise( true );
69     closeTabButton->setIcon( QIcon( ":/toolbar/clear" ) );
70     BUTTONACT( closeTabButton, closeTab() );
71 #endif
72     CONNECT( ui.destTab, currentChanged( int ), this, tabChanged( int ) );
73     ui.destTab->setTabIcon( 0, QIcon( ":/buttons/playlist/playlist_add" ) );
74
75     ui.destBox->addItem( qtr( "File" ) );
76     ui.destBox->addItem( "HTTP" );
77     ui.destBox->addItem( "MS-WMSP (MMSH)" );
78     ui.destBox->addItem( "RTSP" );
79     ui.destBox->addItem( "RTP / MPEG Transport Stream" );
80     ui.destBox->addItem( "RTP Audio/Video Profile" );
81     ui.destBox->addItem( "UDP (legacy)" );
82     ui.destBox->addItem( "IceCast" );
83
84     BUTTONACT( ui.addButton, addDest() );
85
86 //     /* Connect everything to the updateMRL function */
87 #define CB( x ) CONNECT( ui.x, toggled( bool ), this, updateMRL() );
88 #define CT( x ) CONNECT( ui.x, textChanged( const QString& ), this, updateMRL() );
89 #define CS( x ) CONNECT( ui.x, valueChanged( int ), this, updateMRL() );
90 #define CC( x ) CONNECT( ui.x, currentIndexChanged( int ), this, updateMRL() );
91
92     /* Misc */
93     CB( soutAll );  CS( ttl ); CT( sapName ); CT( sapGroup );
94     CB( localOutput ); CB( transcodeBox );
95     CONNECT( ui.profileSelect, optionsChanged(), this, updateMRL() );
96
97     okButton = new QPushButton( qtr( "&Stream" ) );
98     QPushButton *cancelButton = new QPushButton( qtr( "&Cancel" ) );
99
100     okButton->setDefault( true );
101     ui.acceptButtonBox->addButton( okButton, QDialogButtonBox::AcceptRole );
102     ui.acceptButtonBox->addButton( cancelButton, QDialogButtonBox::RejectRole );
103
104     BUTTONACT( okButton, ok() );
105     BUTTONACT( cancelButton, cancel() );
106
107     BUTTONACT( ui.nextButton, next() );
108     BUTTONACT( ui.nextButton2, next() );
109     BUTTONACT( ui.prevButton, prev() );
110     BUTTONACT( ui.prevButton2, prev() );
111
112 #undef CC
113 #undef CS
114 #undef CT
115 #undef CB
116 }
117
118 void SoutDialog::next()
119 {
120     ui.toolBox->setCurrentIndex( ui.toolBox->currentIndex() + 1 );
121 }
122
123 void SoutDialog::prev()
124 {
125     ui.toolBox->setCurrentIndex( ui.toolBox->currentIndex() - 1 );
126 }
127
128 void SoutDialog::tabChanged( int i )
129 {
130     closeTabButton->setVisible( (i != 0) );
131 }
132
133 void SoutDialog::closeTab()
134 {
135     int i = ui.destTab->currentIndex();
136     if( i == 0 ) return;
137
138     QWidget *temp = ui.destTab->currentWidget();
139     ui.destTab->removeTab( i );
140     delete temp;
141     updateMRL();
142 }
143
144 void SoutDialog::addDest( )
145 {
146     VirtualDestBox *db;
147     QString caption;
148
149     switch( ui.destBox->currentIndex() )
150     {
151         case 0:
152             db = new FileDestBox( this );
153             caption = qtr( "File" );
154             break;
155         case 1:
156             db = new HTTPDestBox( this );
157             caption = qfu( "HTTP" );
158             break;
159         case 2:
160             db = new MMSHDestBox( this );
161             caption = qfu( "WMSP" );
162             break;
163         case 3:
164             db = new RTSPDestBox( this );
165             caption = qfu( "RTSP" );
166             break;
167         case 4:
168             db = new RTPDestBox( this, "ts" );
169             caption = "RTP/TS";
170             break;
171         case 5:
172             db = new RTPDestBox( this );
173             caption = "RTP/AVP";
174             break;
175         case 6:
176             db = new UDPDestBox( this );
177             caption = "UDP";
178             break;
179         case 7:
180             db = new ICEDestBox( this );
181             caption = "Icecast";
182             break;
183         default:
184             assert(0);
185     }
186
187     int index = ui.destTab->addTab( db, caption );
188     CONNECT( db, mrlUpdated(), this, updateMRL() );
189     ui.destTab->setCurrentIndex( index );
190     updateMRL();
191 }
192
193 void SoutDialog::ok()
194 {
195     mrl = ui.mrlEdit->toPlainText();
196     accept();
197 }
198
199 void SoutDialog::cancel()
200 {
201     mrl.clear();
202     reject();
203 }
204
205 void SoutDialog::updateMRL()
206 {
207     QString qs_mux = ui.profileSelect->getMux();
208
209     SoutMrl smrl( ":sout=#" );
210     if( !ui.profileSelect->getTranscode().isEmpty() && ui.transcodeBox->isChecked() )
211     {
212         smrl.begin( ui.profileSelect->getTranscode() );
213         smrl.end();
214     }
215
216     bool multi = false;
217
218     if( ui.destTab->count() >= 3 ||
219         ( ui.destTab->count() == 2 && ui.localOutput->isChecked() ) )
220         multi = true;
221
222     if( multi )
223         smrl.begin( "duplicate" );
224
225     for( int i = 1; i < ui.destTab->count(); i++ )
226     {
227         VirtualDestBox *vdb = qobject_cast<VirtualDestBox *>(ui.destTab->widget( i ));
228         if( !vdb )
229             continue;
230
231         QString tempMRL = vdb->getMRL( qs_mux );
232         if( tempMRL.isEmpty() ) continue;
233
234         if( multi )
235             smrl.option( "dst", tempMRL );
236         else
237         {
238             smrl.begin( tempMRL);
239             smrl.end();
240         }
241     }
242     if( ui.localOutput->isChecked() )
243     {
244         if( multi )
245             smrl.option( "dst", "display" );
246         else
247         {
248             smrl.begin( "display" );
249             smrl.end();
250         }
251     }
252
253     if ( multi ) smrl.end();
254
255     mrl = smrl.getMrl();
256
257     if( ui.sap->isChecked() )
258     {
259         QString group = ui.sapGroup->text();
260         QString name = ui.sapName->text();
261
262         /* FIXME: This sucks. We should really return a QStringList instead of
263          * (mis)quoting, concatainating and split input item paramters. */
264         name = name.replace( " ", " " );
265         group = group.replace( " ", " " );
266
267         /* We need to add options for both standard and rtp targets */
268         /* This is inelegant but simple and functional */
269         mrl.append( qfu( " :sout-rtp-sap" ) );
270         mrl.append( qfu( " :sout-rtp-name=" ) + name );
271         mrl.append( qfu( " :sout-standard-sap" ) );
272         mrl.append( qfu( " :sout-standard-name=" ) + name );
273         mrl.append( qfu( " :sout-standard-group=" ) + group );
274     }
275     else
276     {
277         mrl.append( qfu( " :no-sout-rtp-sap" ) );
278         mrl.append( qfu( " :no-sout-standard-sap" ) );
279     }
280
281     if( ui.soutAll->isChecked() ) mrl.append( " :sout-all" );
282
283     if( ui.ttl->value() != 1 ) mrl.append( " :ttl=" + ui.ttl->value() );
284
285     mrl.append( " :sout-keep" );
286
287     ui.mrlEdit->setPlainText( mrl );
288 }
289