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