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