1 /*****************************************************************************
2 * open.cpp : Advanced open dialog
3 *****************************************************************************
4 * Copyright © 2006-2011 the VideoLAN team
6 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
27 #include "dialogs/open.hpp"
28 #include "dialogs_provider.hpp"
29 #include "recents.hpp"
30 #include "util/qt_dirs.hpp"
33 #include <QGridLayout>
41 OpenDialog
*OpenDialog::instance
= NULL
;
43 OpenDialog
* OpenDialog::getInstance( QWidget
*parent
, intf_thread_t
*p_intf
,
44 bool b_rawInstance
, int _action_flag
, bool b_selectMode
, bool _b_pl
)
48 instance
= new OpenDialog( parent
, p_intf
, b_selectMode
,
49 _action_flag
, _b_pl
);
50 else if( !b_rawInstance
)
52 /* Request the instance but change small details:
55 _action_flag
= SELECT
; /* This should be useless, but we never know
56 if the call is correct */
57 instance
->setWindowModality( Qt::WindowModal
);
58 instance
->i_action_flag
= _action_flag
;
59 instance
->b_pl
= _b_pl
;
60 instance
->setMenuAction();
65 OpenDialog::OpenDialog( QWidget
*parent
,
66 intf_thread_t
*_p_intf
,
69 bool _b_pl
) : QVLCDialog( parent
, _p_intf
)
71 i_action_flag
= _action_flag
;
74 if( b_selectMode
) /* Select mode */
75 i_action_flag
= SELECT
;
77 /* Basic Creation of the Window */
79 setWindowTitle( qtr( "Open Media" ) );
80 setWindowRole( "vlc-open-media" );
81 setWindowModality( Qt::WindowModal
);
83 /* Tab definition and creation */
84 fileOpenPanel
= new FileOpenPanel( this, p_intf
);
85 discOpenPanel
= new DiscOpenPanel( this, p_intf
);
86 netOpenPanel
= new NetOpenPanel( this, p_intf
);
87 captureOpenPanel
= new CaptureOpenPanel( this, p_intf
);
90 ui
.Tab
->insertTab( OPEN_FILE_TAB
, fileOpenPanel
, QIcon( ":/type/folder-grey" ),
92 ui
.Tab
->insertTab( OPEN_DISC_TAB
, discOpenPanel
, QIcon( ":/type/disc" ),
94 ui
.Tab
->insertTab( OPEN_NETWORK_TAB
, netOpenPanel
, QIcon( ":/type/network" ),
96 ui
.Tab
->insertTab( OPEN_CAPTURE_TAB
, captureOpenPanel
,
97 QIcon( ":/type/capture-card" ), qtr( "Capture &Device" ) );
99 /* Hide the Slave input widgets */
100 ui
.slaveLabel
->hide();
101 ui
.slaveText
->hide();
102 ui
.slaveBrowseButton
->hide();
104 /* Buttons Creation */
106 playButton
= ui
.playButton
;
109 cancelButton
= new QPushButton( qtr( "&Cancel" ) );
112 selectButton
= new QPushButton( qtr( "&Select" ) );
114 /* Menu for the Play button */
115 QMenu
* openButtonMenu
= new QMenu( "Open" );
116 openButtonMenu
->addAction( qtr( "&Enqueue" ), this, SLOT( enqueue() ),
117 QKeySequence( "Alt+E" ) );
118 openButtonMenu
->addAction( qtr( "&Play" ), this, SLOT( play() ),
119 QKeySequence( "Alt+P" ) );
120 openButtonMenu
->addAction( qtr( "&Stream" ), this, SLOT( stream() ) ,
121 QKeySequence( "Alt+S" ) );
122 openButtonMenu
->addAction( qtr( "&Convert" ), this, SLOT( transcode() ) ,
123 QKeySequence( "Alt+C" ) );
125 playButton
->setMenu( openButtonMenu
);
127 /* Add the three Buttons */
128 ui
.buttonsBox
->addButton( selectButton
, QDialogButtonBox::AcceptRole
);
129 ui
.buttonsBox
->addButton( cancelButton
, QDialogButtonBox::RejectRole
);
131 /* At creation time, modify the default buttons */
134 /* Force MRL update on tab change */
135 CONNECT( ui
.Tab
, currentChanged( int ), this, signalCurrent( int ) );
137 CONNECT( fileOpenPanel
, mrlUpdated( const QStringList
&, const QString
& ),
138 this, updateMRL( const QStringList
&, const QString
& ) );
139 CONNECT( netOpenPanel
, mrlUpdated( const QStringList
&, const QString
& ),
140 this, updateMRL( const QStringList
&, const QString
& ) );
141 CONNECT( discOpenPanel
, mrlUpdated( const QStringList
&, const QString
& ),
142 this, updateMRL( const QStringList
&, const QString
& ) );
143 CONNECT( captureOpenPanel
, mrlUpdated( const QStringList
&, const QString
& ),
144 this, updateMRL( const QStringList
&, const QString
& ) );
146 CONNECT( fileOpenPanel
, methodChanged( const QString
& ),
147 this, newCachingMethod( const QString
& ) );
148 CONNECT( netOpenPanel
, methodChanged( const QString
& ),
149 this, newCachingMethod( const QString
& ) );
150 CONNECT( discOpenPanel
, methodChanged( const QString
& ),
151 this, newCachingMethod( const QString
& ) );
152 CONNECT( captureOpenPanel
, methodChanged( const QString
& ),
153 this, newCachingMethod( const QString
& ) );
155 /* Advanced frame Connects */
156 CONNECT( ui
.slaveCheckbox
, toggled( bool ), this, updateMRL() );
157 CONNECT( ui
.slaveText
, textChanged( const QString
& ), this, updateMRL() );
158 CONNECT( ui
.cacheSpinBox
, valueChanged( int ), this, updateMRL() );
159 CONNECT( ui
.startTimeTimeEdit
, timeChanged ( const QTime
& ), this, updateMRL() );
160 BUTTONACT( ui
.advancedCheckBox
, toggleAdvancedPanel() );
161 BUTTONACT( ui
.slaveBrowseButton
, browseInputSlave() );
164 BUTTONACT( playButton
, selectSlots() );
165 BUTTONACT( selectButton
, close() );
166 BUTTONACT( cancelButton
, cancel() );
168 /* Hide the advancedPanel */
169 if( !getSettings()->value( "opendialog-advanced", false ).toBool())
171 ui
.advancedFrame
->hide();
172 ui
.advancedFrame
->setEnabled( false );
175 ui
.advancedCheckBox
->setChecked( true );
177 /* Initialize caching */
179 newCachingMethod( "file-caching" );
181 /* enforce section due to .ui bug */
182 ui
.startTimeTimeEdit
->setCurrentSection( QDateTimeEdit::SecondSection
);
184 setMinimumSize( sizeHint() );
185 setMaximumWidth( 900 );
186 resize( getSettings()->value( "opendialog-size", QSize( 500, 400 ) ).toSize() );
189 /* Finish the dialog and decide if you open another one after */
190 void OpenDialog::setMenuAction()
192 if( i_action_flag
== SELECT
)
195 selectButton
->show();
196 selectButton
->setDefault( true );
200 switch ( i_action_flag
)
202 case OPEN_AND_STREAM
:
203 playButton
->setText( qtr( "&Stream" ) );
206 playButton
->setText( qtr( "&Convert / Save" ) );
208 case OPEN_AND_ENQUEUE
:
209 playButton
->setText( qtr( "&Enqueue" ) );
213 playButton
->setText( qtr( "&Play" ) );
216 selectButton
->hide();
220 OpenDialog::~OpenDialog()
222 getSettings()->setValue( "opendialog-size", size() -
223 ( ui
.advancedFrame
->isEnabled() ?
224 QSize(0, ui
.advancedFrame
->height()) : QSize(0, 0) ) );
225 getSettings()->setValue( "opendialog-advanced", ui
.advancedFrame
->isVisible() );
228 /* Used by VLM dialog and inputSlave selection */
229 QString
OpenDialog::getMRL( bool b_all
)
231 if( itemsMRL
.count() == 0 ) return "";
232 return b_all
? itemsMRL
[0] + ui
.advancedLineInput
->text()
236 QString
OpenDialog::getOptions()
238 return ui
.advancedLineInput
->text();
241 void OpenDialog::showTab( int i_tab
)
243 if( i_tab
== OPEN_CAPTURE_TAB
) captureOpenPanel
->initialize();
244 ui
.Tab
->setCurrentIndex( i_tab
);
246 if( ui
.Tab
->currentWidget() != NULL
)
248 OpenPanel
*panel
= qobject_cast
<OpenPanel
*>( ui
.Tab
->currentWidget() );
254 void OpenDialog::toggleAdvancedPanel()
256 if( ui
.advancedFrame
->isVisible() )
258 ui
.advancedFrame
->hide();
259 ui
.advancedFrame
->setEnabled( false );
260 if( size().isValid() )
261 resize( size().width(), size().height()
262 - ui
.advancedFrame
->height() );
266 ui
.advancedFrame
->show();
267 ui
.advancedFrame
->setEnabled( true );
268 if( size().isValid() )
269 resize( size().width(), size().height()
270 + ui
.advancedFrame
->height() );
274 void OpenDialog::browseInputSlave()
276 OpenDialog
*od
= new OpenDialog( this, p_intf
, true, SELECT
);
278 ui
.slaveText
->setText( od
->getMRL( false ) );
282 /* Function called on signal currentChanged triggered */
283 void OpenDialog::signalCurrent( int i_tab
)
285 if( i_tab
== OPEN_CAPTURE_TAB
) captureOpenPanel
->initialize();
286 if( ui
.Tab
->currentWidget() != NULL
)
288 OpenPanel
*panel
= qobject_cast
<OpenPanel
*>( ui
.Tab
->currentWidget() );
298 /* If Cancel is pressed or escaped */
299 void OpenDialog::cancel()
301 /* Clear the panels */
302 for( int i
= 0; i
< OPEN_TAB_MAX
; i
++ )
303 qobject_cast
<OpenPanel
*>( ui
.Tab
->widget( i
) )->clear();
305 /* Clear the variables */
309 /* If in Select Mode, reject instead of hiding */
310 if( i_action_flag
== SELECT
) reject();
314 /* If EnterKey is pressed */
315 void OpenDialog::close()
317 /* If in Select Mode, accept instead of selecting a Slot */
318 if( i_action_flag
== SELECT
)
325 void OpenDialog::selectSlots()
327 switch ( i_action_flag
)
329 case OPEN_AND_STREAM
:
335 case OPEN_AND_ENQUEUE
:
344 /* Play Action, called from selectSlots or play Menu */
345 void OpenDialog::play()
350 /* Enqueue Action, called from selectSlots or enqueue Menu */
351 void OpenDialog::enqueue( bool b_enqueue
)
355 if( i_action_flag
== SELECT
)
361 for( int i
= 0; i
< OPEN_TAB_MAX
; i
++ )
362 qobject_cast
<OpenPanel
*>( ui
.Tab
->widget( i
) )->onAccept();
364 /* Sort alphabetically */
367 /* Go through the item list */
368 for( int i
= 0; i
< itemsMRL
.count(); i
++ )
370 bool b_start
= !i
&& !b_enqueue
;
372 input_item_t
*p_input
;
373 p_input
= input_item_New( qtu( itemsMRL
[i
] ), NULL
);
375 /* Insert options only for the first element.
376 We don't know how to edit that anyway. */
379 /* Take options from the UI, not from what we stored */
380 QStringList optionsList
= ui
.advancedLineInput
->text().split( " :" );
383 for( int j
= 0; j
< optionsList
.count(); j
++ )
385 QString qs
= colon_unescape( optionsList
[j
] );
388 input_item_AddOption( p_input
, qtu( qs
),
389 VLC_INPUT_OPTION_TRUSTED
);
391 msg_Warn( p_intf
, "Input option: %s", qtu( qs
) );
397 /* Switch between enqueuing and starting the item */
398 /* FIXME: playlist_AddInput() can fail */
399 playlist_AddInput( THEPL
, p_input
,
400 PLAYLIST_APPEND
| ( b_start
? PLAYLIST_GO
: PLAYLIST_PREPARSE
),
401 PLAYLIST_END
, b_pl
? true : false, pl_Unlocked
);
402 vlc_gc_decref( p_input
);
404 /* Do not add the current MRL if playlist_AddInput fail */
405 RecentsMRL::getInstance( p_intf
)->addRecent( itemsMRL
[i
] );
409 void OpenDialog::transcode()
414 void OpenDialog::stream( bool b_transcode_only
)
416 QString soutMRL
= getMRL( false );
417 if( soutMRL
.isEmpty() ) return;
420 /* Dbg and send :D */
421 msg_Dbg( p_intf
, "MRL passed to the Sout: %s", qtu( soutMRL
) );
422 THEDP
->streamingDialog( this, soutMRL
, b_transcode_only
,
423 ui
.advancedLineInput
->text().split( " :" ) );
426 /* Update the MRL items from the panels */
427 void OpenDialog::updateMRL( const QStringList
& item
, const QString
& tempMRL
)
429 optionsMRL
= tempMRL
;
434 /* Update the complete MRL */
435 void OpenDialog::updateMRL() {
436 QString mrl
= optionsMRL
;
437 if( ui
.slaveCheckbox
->isChecked() ) {
438 mrl
+= " :input-slave=" + ui
.slaveText
->text();
440 mrl
+= QString( " :%1=%2" ).arg( storedMethod
).
441 arg( ui
.cacheSpinBox
->value() );
442 if( ui
.startTimeTimeEdit
->time() != ui
.startTimeTimeEdit
->minimumTime() ) {
443 mrl
+= QString( " :start-time=%1.%2" )
444 .arg( QString::number(
445 ui
.startTimeTimeEdit
->minimumTime().secsTo(
446 ui
.startTimeTimeEdit
->time()
448 .arg( ui
.startTimeTimeEdit
->time().msec(), 3, 10, QChar('0') );
450 ui
.advancedLineInput
->setText( mrl
);
451 ui
.mrlLine
->setText( itemsMRL
.join( " " ) );
454 /* Change the caching combobox */
455 void OpenDialog::newCachingMethod( const QString
& method
)
457 if( method
!= storedMethod
) {
458 storedMethod
= method
;
459 int i_value
= var_InheritInteger( p_intf
, qtu( storedMethod
) );
460 ui
.cacheSpinBox
->setValue( i_value
);
466 QStringList
OpenDialog::SeparateEntries( const QString
& entries
)
468 bool b_quotes_mode
= false;
470 QStringList entries_array
;
474 while( index
< entries
.count() )
476 int delim_pos
= entries
.indexOf( QRegExp( "\\s+|\"" ), index
);
477 if( delim_pos
< 0 ) delim_pos
= entries
.count() - 1;
478 entry
+= entries
.mid( index
, delim_pos
- index
+ 1 );
479 index
= delim_pos
+ 1;
481 if( entry
.isEmpty() ) continue;
483 if( !b_quotes_mode
&& entry
.endsWith( "\"" ) )
485 /* Enters quotes mode */
486 entry
.truncate( entry
.count() - 1 );
487 b_quotes_mode
= true;
489 else if( b_quotes_mode
&& entry
.endsWith( "\"" ) )
491 /* Finished the quotes mode */
492 entry
.truncate( entry
.count() - 1 );
493 b_quotes_mode
= false;
495 else if( !b_quotes_mode
&& !entry
.endsWith( "\"" ) )
497 /* we found a non-quoted standalone string */
498 if( index
< entries
.count() ||
499 entry
.endsWith( " " ) || entry
.endsWith( "\t" ) ||
500 entry
.endsWith( "\r" ) || entry
.endsWith( "\n" ) )
501 entry
.truncate( entry
.count() - 1 );
502 if( !entry
.isEmpty() ) entries_array
.append( entry
);
509 if( !entry
.isEmpty() ) entries_array
.append( entry
);
511 return entries_array
;