]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs/open.cpp
Qt4 - Open Dialog: Make Slave text open only when needed. Fix a bit the subtitles...
[vlc] / modules / gui / qt4 / dialogs / open.cpp
1 /*****************************************************************************
2  * open.cpp : Advanced open dialog
3  *****************************************************************************
4  * Copyright (C) 2006-2007 the VideoLAN team
5  * $Id: streaminfo.cpp 16816 2006-09-23 20:56:52Z jb $
6  *
7  * Authors: Jean-Baptiste Kempf <jb@videolan.org>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 #include <QTabWidget>
25 #include <QGridLayout>
26 #include <QFileDialog>
27 #include <QRegExp>
28 #include <QMenu>
29 #include "dialogs/open.hpp"
30 #include "components/open.hpp"
31
32 #include "qt4.hpp"
33 #include "util/qvlcframe.hpp"
34
35 #include "input_manager.hpp"
36
37 OpenDialog *OpenDialog::instance = NULL;
38
39 OpenDialog::OpenDialog( QWidget *parent, intf_thread_t *_p_intf, bool modal,
40                         int _action_flag )  :  QVLCDialog( parent, _p_intf )
41 {
42     setModal( modal );
43     i_action_flag = _action_flag;
44
45     /* Basic Creation of the Window */
46     ui.setupUi( this );
47     setWindowTitle( qtr("Open" ) );
48     resize( 410, 300);
49
50     /* Tab definition and creation */
51     fileOpenPanel = new FileOpenPanel( ui.Tab, p_intf );
52     discOpenPanel = new DiscOpenPanel( ui.Tab, p_intf );
53     netOpenPanel = new NetOpenPanel( ui.Tab, p_intf );
54     captureOpenPanel = new CaptureOpenPanel( ui.Tab, p_intf );
55
56     /* Insert the tabs */
57     ui.Tab->insertTab( OPEN_FILE_TAB, fileOpenPanel, qtr( "&File" ) );
58     ui.Tab->insertTab( OPEN_DISC_TAB, discOpenPanel, qtr( "&Disc" ) );
59     ui.Tab->insertTab( OPEN_NETWORK_TAB, netOpenPanel, qtr( "&Network" ) );
60     ui.Tab->insertTab( OPEN_CAPTURE_TAB, captureOpenPanel,
61                                 qtr( "Capture &Device" ) );
62
63     /* Hide the advancedPanel */
64     if(! config_GetInt( p_intf, "qt-adv-options") )
65     {
66         ui.advancedFrame->hide();
67     }
68
69     ui.slaveLabel->hide();
70     ui.slaveText->hide();
71     ui.slaveBrowseButton->hide();
72
73     /* Buttons Creation */
74     QSizePolicy buttonSizePolicy( static_cast<QSizePolicy::Policy>(7),
75                                   static_cast<QSizePolicy::Policy>(1) );
76     buttonSizePolicy.setHorizontalStretch(0);
77     buttonSizePolicy.setVerticalStretch(0);
78
79     playButton = new QToolButton( this );
80     playButton->setText( qtr( "&Play" ) );
81     playButton->setSizePolicy( buttonSizePolicy );
82     playButton->setMinimumSize( QSize(90, 0) );
83     playButton->setPopupMode( QToolButton::MenuButtonPopup );
84     playButton->setToolButtonStyle( Qt::ToolButtonTextOnly );
85
86     cancelButton = new QPushButton();
87     cancelButton->setText( qtr( "&Cancel" ) );
88     cancelButton->setSizePolicy( buttonSizePolicy );
89
90     QMenu * openButtonMenu = new QMenu( "Open" );
91     openButtonMenu->addAction( qtr("&Enqueue"), this, SLOT( enqueue() ),
92                                     QKeySequence( "Alt+E") );
93     openButtonMenu->addAction( qtr("&Play"), this, SLOT( play() ),
94                                     QKeySequence( "Alt+P" ) );
95     openButtonMenu->addAction( qtr("&Stream"), this, SLOT( stream() ) ,
96                                     QKeySequence( "Alt+S" ) );
97     openButtonMenu->addAction( qtr("&Convert"), this, SLOT( transcode( ) ) ,
98                                     QKeySequence( "Alt+C" ) );
99
100     playButton->setMenu( openButtonMenu );
101
102     ui.buttonsBox->addButton( playButton, QDialogButtonBox::AcceptRole );
103     ui.buttonsBox->addButton( cancelButton, QDialogButtonBox::RejectRole );
104
105     /* Force MRL update on tab change */
106     CONNECT( ui.Tab, currentChanged(int), this, signalCurrent());
107
108     CONNECT( fileOpenPanel, mrlUpdated( QString ), this, updateMRL(QString) );
109     CONNECT( netOpenPanel, mrlUpdated( QString ), this, updateMRL(QString) );
110     CONNECT( discOpenPanel, mrlUpdated( QString ), this, updateMRL(QString) );
111     CONNECT( captureOpenPanel, mrlUpdated( QString ), this,
112                                                          updateMRL(QString) );
113
114     CONNECT( fileOpenPanel, methodChanged( QString ),
115                                                  this, newMethod(QString) );
116     CONNECT( netOpenPanel, methodChanged( QString ),
117                                                  this, newMethod(QString) );
118     CONNECT( discOpenPanel, methodChanged( QString ),
119                                                  this, newMethod(QString) );
120     CONNECT( captureOpenPanel, methodChanged( QString ),
121                                                  this, newMethod(QString) );
122
123     /* Advanced frame Connects */
124     CONNECT( ui.slaveText, textChanged(QString), this, updateMRL());
125     CONNECT( ui.cacheSpinBox, valueChanged(int), this, updateMRL());
126     CONNECT( ui.startTimeSpinBox, valueChanged(int), this, updateMRL());
127     BUTTONACT( ui.advancedCheckBox , toggleAdvancedPanel() );
128
129     /* Buttons action */
130     BUTTONACT( playButton, play());
131     BUTTONACT( cancelButton, cancel());
132
133     /* At creation time, modify the default buttons */
134     if ( i_action_flag ) setMenuAction();
135
136
137     /* Initialize caching */
138     storedMethod = "";
139     newMethod("file-caching");
140
141     mainHeight = advHeight = 0;
142 }
143
144 OpenDialog::~OpenDialog()
145 {
146 }
147
148 /* Finish the dialog and decide if you open another one after */
149 void OpenDialog::setMenuAction()
150 {
151     switch ( i_action_flag )
152     {
153         case OPEN_AND_STREAM:
154             playButton->setText( qtr("&Stream") );
155             BUTTONACT( playButton, stream() );
156             break;
157         case OPEN_AND_SAVE:
158             playButton->setText( qtr("&Convert / Save") );
159             BUTTONACT( playButton, stream( true ) );
160             break;
161         case ENQUEUE:
162             playButton->setText( qtr("&Enqueue") );
163             BUTTONACT( playButton, enqueue() );
164             break;
165         case OPEN_AND_PLAY:
166         default:
167             playButton->setText( qtr("&Play") );
168             BUTTONACT( playButton, play() );
169    }
170 }
171
172 void OpenDialog::showTab(int i_tab=0)
173 {
174     this->show();
175     ui.Tab->setCurrentIndex(i_tab);
176 }
177
178 void OpenDialog::signalCurrent() {
179     if (ui.Tab->currentWidget() != NULL) {
180         (dynamic_cast<OpenPanel*>(ui.Tab->currentWidget()))->updateMRL();
181     }
182 }
183
184 /***********
185  * Actions *
186  ***********/
187
188 /* If Cancel is pressed or escaped */
189 void OpenDialog::cancel()
190 {
191     fileOpenPanel->clear();
192     this->toggleVisible();
193     if( isModal() )
194         reject();
195 }
196
197 /* If EnterKey is pressed */
198 void OpenDialog::close()
199 {
200     /* FIXME */
201     if ( !i_action_flag )
202     {
203         play();
204     }
205     else
206     {
207         stream();
208     }
209 }
210
211 /* Play button */
212 void OpenDialog::play()
213 {
214     finish( false );
215 }
216
217 void OpenDialog::enqueue()
218 {
219     finish( true );
220 }
221
222 void OpenDialog::transcode()
223 {
224     stream( true );
225 }
226
227 void OpenDialog::stream( bool b_transcode_only )
228 {
229     /* not finished FIXME */
230     /* Should go through the finish function */
231     THEDP->streamingDialog( mrl, b_transcode_only );
232 }
233
234 void OpenDialog::finish( bool b_enqueue = false )
235 {
236     this->toggleVisible();
237     mrl = ui.advancedLineInput->text();
238
239     if( !isModal() )
240     {
241         QStringList tempMRL = SeparateEntries( mrl );
242         for( size_t i = 0; i < tempMRL.size(); i++ )
243         {
244             bool b_start = !i && !b_enqueue;
245             input_item_t *p_input;
246             const char *psz_utf8 = qtu( tempMRL[i] );
247
248             p_input = input_ItemNew( p_intf, psz_utf8, NULL );
249
250             /* Insert options */
251             while( i + 1 < tempMRL.size() && tempMRL[i + 1].startsWith( ":" ) )
252             {
253                 i++;
254                 psz_utf8 = qtu( tempMRL[i] );
255                 input_ItemAddOption( p_input, psz_utf8 );
256             }
257
258             if( b_start )
259             {
260                 playlist_AddInput( THEPL, p_input,
261                                    PLAYLIST_APPEND | PLAYLIST_GO,
262                                    PLAYLIST_END, VLC_TRUE, VLC_FALSE );
263             }
264             else
265             {
266                 playlist_AddInput( THEPL, p_input,
267                                    PLAYLIST_APPEND|PLAYLIST_PREPARSE,
268                                    PLAYLIST_END, VLC_TRUE, VLC_FALSE );
269             }
270         }
271     }
272     else
273         accept();
274 }
275
276 void OpenDialog::toggleAdvancedPanel()
277 {
278     //FIXME does not work under Windows
279     if (ui.advancedFrame->isVisible()) {
280         ui.advancedFrame->hide();
281         setMinimumHeight(1);
282         resize( width(), mainHeight );
283
284     } else {
285         if( mainHeight == 0 )
286             mainHeight = height();
287
288         ui.advancedFrame->show();
289         if( advHeight == 0 ) {
290             advHeight = height() - mainHeight;
291         }
292         resize( width(), mainHeight + advHeight );
293     }
294 }
295
296 void OpenDialog::updateMRL() {
297     mrl = mainMRL;
298     if( ui.slaveCheckbox->isChecked() ) {
299         mrl += " :input-slave=" + ui.slaveText->text();
300     }
301     int i_cache = config_GetInt( p_intf, qta(storedMethod) );
302     if( i_cache != ui.cacheSpinBox->value() ) {
303         mrl += QString(" :%1=%2").arg(storedMethod).
304                                   arg(ui.cacheSpinBox->value());
305     }
306     if( ui.startTimeSpinBox->value()) {
307         mrl += " :start-time=" + QString("%1").
308             arg(ui.startTimeSpinBox->value());
309     }
310     ui.advancedLineInput->setText(mrl);
311 }
312
313 void OpenDialog::updateMRL(QString tempMRL)
314 {
315     mainMRL = tempMRL;
316     updateMRL();
317 }
318
319 void OpenDialog::newMethod(QString method)
320 {
321     if( method != storedMethod ) {
322         storedMethod = method;
323         int i_value = config_GetInt( p_intf, qta(storedMethod) );
324         ui.cacheSpinBox->setValue(i_value);
325     }
326 }
327
328 QStringList OpenDialog::SeparateEntries( QString entries )
329 {
330     bool b_quotes_mode = false;
331
332     QStringList entries_array;
333     QString entry;
334
335     int index = 0;
336     while( index < entries.size() )
337     {
338         int delim_pos = entries.indexOf( QRegExp( "\\s+|\"" ), index );
339         if( delim_pos < 0 ) delim_pos = entries.size() - 1;
340         entry += entries.mid( index, delim_pos - index + 1 );
341         index = delim_pos + 1;
342
343         if( entry.isEmpty() ) continue;
344
345         if( !b_quotes_mode && entry.endsWith( "\"" ) )
346         {
347             /* Enters quotes mode */
348             entry.truncate( entry.size() - 1 );
349             b_quotes_mode = true;
350         }
351         else if( b_quotes_mode && entry.endsWith( "\"" ) )
352         {
353             /* Finished the quotes mode */
354             entry.truncate( entry.size() - 1 );
355             b_quotes_mode = false;
356         }
357         else if( !b_quotes_mode && !entry.endsWith( "\"" ) )
358         {
359             /* we found a non-quoted standalone string */
360             if( index < entries.size() ||
361                 entry.endsWith( " " ) || entry.endsWith( "\t" ) ||
362                 entry.endsWith( "\r" ) || entry.endsWith( "\n" ) )
363                 entry.truncate( entry.size() - 1 );
364             if( !entry.isEmpty() ) entries_array.append( entry );
365             entry.clear();
366         }
367         else
368         {;}
369     }
370
371     if( !entry.isEmpty() ) entries_array.append( entry );
372
373     return entries_array;
374 }