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