]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs_provider.cpp
* open dialog: look for subtitles in the same directory as the movie
[vlc] / modules / gui / qt4 / dialogs_provider.cpp
1 /*****************************************************************************
2  * main_inteface.cpp : Main interface
3  *****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@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 <QEvent>
25 #include <QApplication>
26 #include <QSignalMapper>
27 #include <QFileDialog>
28
29 #include "qt4.hpp"
30 #include "dialogs_provider.hpp"
31 #include "main_interface.hpp"
32 #include "menus.hpp"
33 #include <vlc_intf_strings.h>
34
35 /* The dialogs */
36 #include "dialogs/playlist.hpp"
37 #include "dialogs/prefs_dialog.hpp"
38 #include "dialogs/mediainfo.hpp"
39 #include "dialogs/messages.hpp"
40 #include "dialogs/extended.hpp"
41 #include "dialogs/sout.hpp"
42 #include "dialogs/open.hpp"
43 #include "dialogs/help.hpp"
44
45 DialogsProvider* DialogsProvider::instance = NULL;
46
47 DialogsProvider::DialogsProvider( intf_thread_t *_p_intf ) :
48                                   QObject( NULL ), p_intf( _p_intf )
49 {
50     fixed_timer = new QTimer( this );
51     fixed_timer->start( 150 /* milliseconds */ );
52
53     menusMapper = new QSignalMapper();
54     CONNECT( menusMapper, mapped(QObject *), this, menuAction( QObject *) );
55
56     menusUpdateMapper = new QSignalMapper();
57     CONNECT( menusUpdateMapper, mapped(QObject *),
58              this, menuUpdateAction( QObject *) );
59
60     SDMapper = new QSignalMapper();
61     CONNECT( SDMapper, mapped (QString), this, SDMenuAction( QString ) );
62 }
63
64 DialogsProvider::~DialogsProvider()
65 {
66     PlaylistDialog::killInstance();
67     MediaInfoDialog::killInstance();
68 }
69
70 void DialogsProvider::quit()
71 {
72     p_intf->b_die = VLC_TRUE;
73     QApplication::quit();
74 }
75
76 void DialogsProvider::customEvent( QEvent *event )
77 {
78     if( event->type() == DialogEvent_Type )
79     {
80         DialogEvent *de = static_cast<DialogEvent*>(event);
81         switch( de->i_dialog )
82         {
83             case INTF_DIALOG_FILE:
84                 openDialog(); break;
85             case INTF_DIALOG_DISC:
86                 openDiscDialog(); break;
87             case INTF_DIALOG_NET:
88                 openNetDialog(); break;
89             case INTF_DIALOG_CAPTURE:
90                 openCaptureDialog(); break;
91             case INTF_DIALOG_PLAYLIST:
92                 playlistDialog(); break;
93             case INTF_DIALOG_MESSAGES:
94                 messagesDialog(); break;
95             case INTF_DIALOG_PREFS:
96                prefsDialog(); break;
97             case INTF_DIALOG_POPUPMENU:
98             case INTF_DIALOG_AUDIOPOPUPMENU:
99             case INTF_DIALOG_VIDEOPOPUPMENU:
100             case INTF_DIALOG_MISCPOPUPMENU:
101                popupMenu( de->i_dialog ); break;
102             case INTF_DIALOG_FILEINFO:
103                mediaInfoDialog(); break;
104             case INTF_DIALOG_INTERACTION:
105                doInteraction( de->p_arg ); break;
106             case INTF_DIALOG_BOOKMARKS:
107                bookmarksDialog(); break;
108             case INTF_DIALOG_VLM:
109             case INTF_DIALOG_WIZARD:
110             default:
111                msg_Warn( p_intf, "unimplemented dialog\n" );
112         }
113     }
114 }
115
116 /****************************************************************************
117  * Individual simple dialogs
118  ****************************************************************************/
119 void DialogsProvider::playlistDialog()
120 {
121     PlaylistDialog::getInstance( p_intf )->toggleVisible();
122 }
123
124 void DialogsProvider::prefsDialog()
125 {
126     PrefsDialog::getInstance( p_intf )->toggleVisible();
127 }
128 void DialogsProvider::extendedDialog()
129 {
130     ExtendedDialog::getInstance( p_intf )->toggleVisible();
131 }
132
133 void DialogsProvider::messagesDialog()
134 {
135     MessagesDialog::getInstance( p_intf )->toggleVisible();
136 }
137
138 void DialogsProvider::helpDialog()
139 {
140     HelpDialog::getInstance( p_intf )->toggleVisible();
141 }
142
143 void DialogsProvider::aboutDialog()
144 {
145     AboutDialog::getInstance( p_intf )->toggleVisible();
146 }
147
148 void DialogsProvider::mediaInfoDialog()
149 {
150     MediaInfoDialog::getInstance( p_intf )->toggleVisible();
151 }
152
153 void DialogsProvider::mediaCodecDialog()
154 {
155     MediaInfoDialog::getInstance( p_intf )->showTab( 1 );
156 }
157
158 void DialogsProvider::bookmarksDialog()
159 {
160 }
161
162 /****************************************************************************
163  * All the open/add stuff
164  ****************************************************************************/
165
166 void DialogsProvider::openDialog()
167 {
168     openDialog( 0 );
169 }
170 void DialogsProvider::openFileDialog()
171 {
172     openDialog( 0 );
173 }
174 void DialogsProvider::openDiscDialog()
175 {
176     openDialog( 1 );
177 }
178 void DialogsProvider::openNetDialog()
179 {
180     openDialog( 2 );
181 }
182 void DialogsProvider::openCaptureDialog()
183 {
184     openDialog( 3 );
185 }
186 void DialogsProvider::openDialog( int i_tab )
187 {
188     OpenDialog::getInstance( p_intf->p_sys->p_mi , p_intf )->showTab( i_tab );
189 }
190
191 void DialogsProvider::PLAppendDialog()
192 {
193 }
194 void DialogsProvider::MLAppendDialog()
195 {
196 }
197
198 /**** Simple open ****/
199 QStringList DialogsProvider::showSimpleOpen( QString help, int filters,
200                                              QString path )
201 {
202     QString fileTypes = "";
203     if( filters & EXT_FILTER_MEDIA ) {
204         ADD_FILTER_MEDIA( fileTypes );
205     }
206     if( filters & EXT_FILTER_VIDEO ) {
207         ADD_FILTER_VIDEO( fileTypes );
208     }
209     if( filters & EXT_FILTER_AUDIO ) {
210         ADD_FILTER_AUDIO( fileTypes );
211     }
212     if( filters & EXT_FILTER_PLAYLIST ) {
213         ADD_FILTER_PLAYLIST( fileTypes );
214     }
215     if( filters & EXT_FILTER_SUBTITLE ) {
216         ADD_FILTER_SUBTITLE( fileTypes );
217     }
218     ADD_FILTER_ALL( fileTypes );
219     fileTypes.replace(QString(";*"), QString(" *"));
220     return QFileDialog::getOpenFileNames( NULL,
221         help.isNull() ? qfu(I_OP_SEL_FILES ) : help,
222         path.isNull() ? qfu( p_intf->p_libvlc->psz_homedir ) : path,
223         fileTypes );
224 }
225
226 void DialogsProvider::addFromSimple( bool pl, bool go)
227 {
228     QStringList files = DialogsProvider::showSimpleOpen();
229     int i = 0;
230     foreach( QString file, files )
231     {
232         const char * psz_utf8 = qtu( file );
233         playlist_Add( THEPL, psz_utf8, NULL,
234                       go ? ( PLAYLIST_APPEND | ( i ? 0 : PLAYLIST_GO ) |
235                                                ( i ? PLAYLIST_PREPARSE : 0 ) )
236                          : ( PLAYLIST_APPEND | PLAYLIST_PREPARSE ),
237                       PLAYLIST_END,
238                       pl ? VLC_TRUE : VLC_FALSE, VLC_FALSE );
239         i++;
240     }
241 }
242
243 void DialogsProvider::simplePLAppendDialog()
244 {
245     addFromSimple( true, false );
246 }
247
248 void DialogsProvider::simpleMLAppendDialog()
249 {
250     addFromSimple( false, false );
251 }
252
253 void DialogsProvider::simpleOpenDialog()
254 {
255     addFromSimple( true, true );
256 }
257
258 void DialogsProvider::openPlaylist()
259 {
260     QStringList files = showSimpleOpen( qtr( "Open playlist file" ),
261                                         EXT_FILTER_PLAYLIST );
262     foreach( QString file, files )
263     {
264         playlist_Import( THEPL, qtu(file) );
265     }
266 }
267
268 void DialogsProvider::savePlaylist()
269 {
270     QFileDialog *qfd = new QFileDialog( NULL,
271                                    qtr("Choose a filename to save playlist"),
272                                    qfu( p_intf->p_libvlc->psz_homedir ),
273                                    qtr("XSPF playlist (*.xspf);; ") +
274                                    qtr("M3U playlist (*.m3u);; Any (*.*) ") );
275     qfd->setFileMode( QFileDialog::AnyFile );
276     qfd->setAcceptMode( QFileDialog::AcceptSave );
277     qfd->setConfirmOverwrite( true );
278
279     if( qfd->exec() == QDialog::Accepted )
280     {
281         if( qfd->selectedFiles().count() > 0 )
282         {
283             char *psz_module, *psz_m3u = "export-m3u",
284                  *psz_xspf = "export-xspf";
285
286             QString file = qfd->selectedFiles().first();
287             QString filter = qfd->selectedFilter();
288
289             if( file.contains(".xsp") ||
290                 ( filter.contains(".xspf") && !file.contains(".m3u") ) )
291             {
292                 psz_module = psz_xspf;
293                 if( !file.contains( ".xsp" ) )
294                     file.append( ".xspf" );
295             }
296             else
297             {
298                 psz_module = psz_m3u;
299                 if( !file.contains( ".m3u" ) )
300                     file.append( ".m3u" );
301             }
302
303             playlist_Export( THEPL, qtu(file), THEPL->p_local_category,
304                              psz_module);
305         }
306     }
307     delete qfd;
308 }
309
310 static void openDirectory( intf_thread_t* p_intf, bool pl, bool go )
311 {
312     QString dir = QFileDialog::getExistingDirectory ( 0,
313                                                      _("Open directory") );
314     input_item_t *p_input = input_ItemNewExt( THEPL, qtu(dir), NULL,
315                                                0, NULL, -1 );
316     playlist_AddInput( THEPL, p_input,
317                        go ? ( PLAYLIST_APPEND | PLAYLIST_GO ) : PLAYLIST_APPEND,
318                        PLAYLIST_END, pl, VLC_FALSE );
319     input_Read( THEPL, p_input, VLC_FALSE );
320 }
321
322 void DialogsProvider::PLAppendDir()
323 {
324     openDirectory( p_intf, true, false );
325 }
326
327 void DialogsProvider::MLAppendDir()
328 {
329     openDirectory( p_intf, false , false );
330 }
331
332
333 /****************************************************************************
334  * Sout emulation
335  ****************************************************************************/
336
337 void DialogsProvider::streamingDialog()
338 {
339     OpenDialog *o = new OpenDialog( p_intf->p_sys->p_mi, p_intf, true );
340     if ( o->exec() == QDialog::Accepted )
341     {
342         SoutDialog *s = new SoutDialog( p_intf->p_sys->p_mi, p_intf );
343         if( s->exec() == QDialog::Accepted )
344         {
345             msg_Err(p_intf, "mrl %s\n", qta(s->mrl));
346             /* Just do it */
347             int i_len = strlen( qtu(s->mrl) ) + 10;
348             char *psz_option = (char*)malloc(i_len);
349             snprintf( psz_option, i_len - 1, ":sout=%s", qtu(s->mrl));
350
351             playlist_AddExt( THEPL, qtu( o->mrl ), "Streaming",
352                              PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END,
353                              -1, &psz_option, 1, VLC_TRUE, VLC_FALSE );
354         }
355         delete s;
356     }
357     delete o;
358 }
359
360 /****************************************************************************
361  * Menus / Interaction
362  ****************************************************************************/
363
364 void DialogsProvider::menuAction( QObject *data )
365 {
366     QVLCMenu::DoAction( p_intf, data );
367 }
368
369 void DialogsProvider::menuUpdateAction( QObject *data )
370 {
371     MenuFunc * f = qobject_cast<MenuFunc *>(data);
372     f->doFunc( p_intf );
373 }
374
375 void DialogsProvider::SDMenuAction( QString data )
376 {
377     char *psz_sd = strdup( qtu( data ) );
378     if( !playlist_IsServicesDiscoveryLoaded( THEPL, psz_sd ) )
379         playlist_ServicesDiscoveryAdd( THEPL, psz_sd );
380     else
381         playlist_ServicesDiscoveryRemove( THEPL, psz_sd );
382
383     free( psz_sd );
384 }
385
386
387 void DialogsProvider::doInteraction( intf_dialog_args_t *p_arg )
388 {
389     InteractionDialog *qdialog;
390     interaction_dialog_t *p_dialog = p_arg->p_dialog;
391     switch( p_dialog->i_action )
392     {
393     case INTERACT_NEW:
394         qdialog = new InteractionDialog( p_intf, p_dialog );
395         p_dialog->p_private = (void*)qdialog;
396         if( !(p_dialog->i_status == ANSWERED_DIALOG) )
397             qdialog->show();
398         break;
399     case INTERACT_UPDATE:
400         qdialog = (InteractionDialog*)(p_dialog->p_private);
401         if( qdialog)
402             qdialog->update();
403         break;
404     case INTERACT_HIDE:
405         qdialog = (InteractionDialog*)(p_dialog->p_private);
406         if( qdialog )
407             qdialog->hide();
408         p_dialog->i_status = HIDDEN_DIALOG;
409         break;
410     case INTERACT_DESTROY:
411         qdialog = (InteractionDialog*)(p_dialog->p_private);
412         if( !p_dialog->i_flags & DIALOG_NONBLOCKING_ERROR )
413             delete qdialog;
414         p_dialog->i_status = DESTROYED_DIALOG;
415         break;
416     }
417 }
418
419 void DialogsProvider::switchToSkins()
420 {
421     var_SetString( p_intf, "intf-switch", "skins2" );
422 }
423
424 void DialogsProvider::popupMenu( int i_dialog )
425 {
426 }