]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs_provider.cpp
Fix corruption in SD parser (Closes:#889)
[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 #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             case INTF_DIALOG_DISC:
84             case INTF_DIALOG_NET:
85             case INTF_DIALOG_CAPTURE:
86                 openDialog( de->i_dialog ); break;
87             case INTF_DIALOG_PLAYLIST:
88                 playlistDialog(); break;
89             case INTF_DIALOG_MESSAGES:
90                 messagesDialog(); break;
91             case INTF_DIALOG_PREFS:
92                prefsDialog(); break;
93             case INTF_DIALOG_POPUPMENU:
94             case INTF_DIALOG_AUDIOPOPUPMENU:
95             case INTF_DIALOG_VIDEOPOPUPMENU:
96             case INTF_DIALOG_MISCPOPUPMENU:
97                popupMenu( de->i_dialog ); break;
98             case INTF_DIALOG_FILEINFO:
99                mediaInfoDialog(); break;
100             case INTF_DIALOG_INTERACTION:
101                doInteraction( de->p_arg ); break;
102             case INTF_DIALOG_VLM:
103             case INTF_DIALOG_BOOKMARKS:
104                bookmarksDialog(); break;
105             case INTF_DIALOG_WIZARD:
106             default:
107                msg_Warn( p_intf, "unimplemented dialog\n" );
108         }
109     }
110 }
111
112 /****************************************************************************
113  * Individual simple dialogs
114  ****************************************************************************/
115 void DialogsProvider::playlistDialog()
116 {
117     PlaylistDialog::getInstance( p_intf )->toggleVisible();
118 }
119
120 void DialogsProvider::prefsDialog()
121 {
122     PrefsDialog::getInstance( p_intf )->toggleVisible();
123 }
124 void DialogsProvider::extendedDialog()
125 {
126     ExtendedDialog::getInstance( p_intf )->toggleVisible();
127 }
128
129 void DialogsProvider::messagesDialog()
130 {
131     MessagesDialog::getInstance( p_intf )->toggleVisible();
132 }
133
134 void DialogsProvider::helpDialog()
135 {
136     HelpDialog::getInstance( p_intf )->toggleVisible();
137 }
138
139 void DialogsProvider::aboutDialog()
140 {
141     AboutDialog::getInstance( p_intf )->toggleVisible();
142 }
143
144 void DialogsProvider::mediaInfoDialog()
145 {
146     MediaInfoDialog::getInstance( p_intf )->toggleVisible();
147 }
148
149 void DialogsProvider::bookmarksDialog()
150 {
151 }
152
153 /****************************************************************************
154  * All the open/add stuff
155  ****************************************************************************/
156
157 void DialogsProvider::openDialog()
158 {
159     openDialog( 0 );
160 }
161 void DialogsProvider::PLAppendDialog()
162 {
163 }
164 void DialogsProvider::MLAppendDialog()
165 {
166 }
167 void DialogsProvider::openDialog( int i_tab )
168 {
169     OpenDialog::getInstance( p_intf->p_sys->p_mi  , p_intf )->showTab( i_tab );
170 }
171
172 /**** Simple open ****/
173
174 QStringList DialogsProvider::showSimpleOpen()
175 {
176     QString FileTypes;
177     FileTypes = _("Media Files");
178     FileTypes += " ( ";
179     FileTypes += EXTENSIONS_MEDIA;
180     FileTypes += ");;";
181     FileTypes += _("Video Files");
182     FileTypes += " ( ";
183     FileTypes += EXTENSIONS_VIDEO;
184     FileTypes += ");;";
185     FileTypes += _("Sound Files");
186     FileTypes += " ( ";
187     FileTypes += EXTENSIONS_AUDIO;
188     FileTypes += ");;";
189     FileTypes += _("PlayList Files");
190     FileTypes += " ( ";
191     FileTypes += EXTENSIONS_PLAYLIST;
192     FileTypes += ");;";
193     FileTypes += _("All Files");
194     FileTypes += " (*.*)";
195     FileTypes.replace(QString(";*"), QString(" *"));
196     return QFileDialog::getOpenFileNames( NULL, qfu(I_OP_SEL_FILES ),
197                     p_intf->p_libvlc->psz_homedir, FileTypes );
198 }
199
200 void DialogsProvider::addFromSimple( bool pl, bool go)
201 {
202     QStringList files = DialogsProvider::showSimpleOpen();
203     int i = 0;
204     foreach( QString file, files )
205     {
206         const char * psz_utf8 = qtu( file );
207         playlist_Add( THEPL, psz_utf8, NULL,
208                       go ? ( PLAYLIST_APPEND | ( i ? 0 : PLAYLIST_GO ) |
209                                                ( i ? PLAYLIST_PREPARSE : 0 ) )
210                          : ( PLAYLIST_APPEND | PLAYLIST_PREPARSE ),
211                       PLAYLIST_END,
212                       pl ? VLC_TRUE : VLC_FALSE );
213         i++;
214     }
215 }
216
217 void DialogsProvider::simplePLAppendDialog()
218 {
219     addFromSimple( true, false );
220 }
221
222 void DialogsProvider::simpleMLAppendDialog()
223 {
224     addFromSimple( false, false );
225 }
226
227 void DialogsProvider::simpleOpenDialog()
228 {
229     addFromSimple( true, true );
230 }
231
232 void DialogsProvider::openPlaylist()
233 {
234     QStringList files = showSimpleOpen();
235     foreach( QString file, files )
236     {
237         playlist_Import( THEPL, qtu(file) );
238     }
239 }
240
241 void DialogsProvider::savePlaylist()
242 {
243     QFileDialog *qfd = new QFileDialog( NULL,
244                                    qtr("Choose a filename to save playlist"),
245                                    p_intf->p_libvlc->psz_homedir,
246                                    qfu("XSPF playlist (*.xspf);; ") +
247                                    qfu("M3U playlist (*.m3u);; Any (*.*) ") );
248     qfd->setFileMode( QFileDialog::AnyFile );
249     qfd->setAcceptMode( QFileDialog::AcceptSave );
250     qfd->setConfirmOverwrite( true );
251
252     if( qfd->exec() == QDialog::Accepted )
253     {
254         if( qfd->selectedFiles().count() > 0 )
255         {
256             char *psz_module, *psz_m3u = "export-m3u",
257                  *psz_xspf = "export-xspf";
258
259             QString file = qfd->selectedFiles().first();
260             QString filter = qfd->selectedFilter();
261
262             if( file.contains(".xsp") ||
263                 ( filter.contains(".xspf") && !file.contains(".m3u") ) )
264             {
265                 psz_module = psz_xspf;
266                 if( !file.contains( ".xsp" ) )
267                     file.append( ".xspf" );
268             }
269             else
270             {
271                 psz_module = psz_m3u;
272                 if( !file.contains( ".m3u" ) )
273                     file.append( ".m3u" );
274             }
275
276             playlist_Export( THEPL, qtu(file), THEPL->p_local_category,
277                              psz_module);
278         }
279     }
280     delete qfd;
281 }
282
283 static void openDirectory( intf_thread_t* p_intf, bool pl, bool go )
284 {
285     QString dir = QFileDialog::getExistingDirectory ( 0,
286                                                      _("Open directory") );
287     input_item_t *p_input = input_ItemNewExt( THEPL, qtu(dir), NULL,
288                                                0, NULL, -1 );
289     playlist_AddInput( THEPL, p_input,
290                        go ? ( PLAYLIST_APPEND | PLAYLIST_GO ) : PLAYLIST_APPEND,
291                        PLAYLIST_END, pl);
292     input_Read( THEPL, p_input, VLC_FALSE );
293 }
294
295 void DialogsProvider::PLAppendDir()
296 {
297     openDirectory( p_intf, true, false );
298 }
299
300 void DialogsProvider::MLAppendDir()
301 {
302     openDirectory( p_intf, false , false );
303 }
304
305
306 /****************************************************************************
307  * Sout emulation
308  ****************************************************************************/
309
310 void DialogsProvider::streamingDialog()
311 {
312     OpenDialog *o = new OpenDialog( p_intf->p_sys->p_mi, p_intf, true );
313     if ( o->exec() == QDialog::Accepted )
314     {
315         SoutDialog *s = new SoutDialog( p_intf->p_sys->p_mi, p_intf );
316         if( s->exec() == QDialog::Accepted )
317         {
318             msg_Err(p_intf, "mrl %s\n", qta(s->mrl));
319             /* Just do it */
320             int i_len = strlen( qtu(s->mrl) ) + 10;
321             char *psz_option = (char*)malloc(i_len);
322             snprintf( psz_option, i_len - 1, ":sout=%s", qtu(s->mrl));
323
324             playlist_AddExt( THEPL, qtu( o->mrl ), "Streaming",
325                              PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END,
326                              -1, &psz_option, 1, VLC_TRUE );
327         }
328         delete s;
329     }
330     delete o;
331 }
332
333 /****************************************************************************
334  * Menus / Interaction
335  ****************************************************************************/
336
337 void DialogsProvider::menuAction( QObject *data )
338 {
339     QVLCMenu::DoAction( p_intf, data );
340 }
341
342 void DialogsProvider::menuUpdateAction( QObject *data )
343 {
344     MenuFunc * f = qobject_cast<MenuFunc *>(data);
345     f->doFunc( p_intf );
346 }
347
348 void DialogsProvider::SDMenuAction( QString data )
349 {
350     char *psz_sd = strdup( qtu( data ) );
351     if( !playlist_IsServicesDiscoveryLoaded( THEPL, psz_sd ) )
352         playlist_ServicesDiscoveryAdd( THEPL, psz_sd );
353     else
354         playlist_ServicesDiscoveryRemove( THEPL, psz_sd );
355
356     free( psz_sd );
357 }
358
359
360 void DialogsProvider::doInteraction( intf_dialog_args_t *p_arg )
361 {
362     InteractionDialog *qdialog;
363     interaction_dialog_t *p_dialog = p_arg->p_dialog;
364     switch( p_dialog->i_action )
365     {
366     case INTERACT_NEW:
367         qdialog = new InteractionDialog( p_intf, p_dialog );
368         p_dialog->p_private = (void*)qdialog;
369         if( !(p_dialog->i_status == ANSWERED_DIALOG) )
370             qdialog->show();
371         break;
372     case INTERACT_UPDATE:
373         qdialog = (InteractionDialog*)(p_dialog->p_private);
374         if( qdialog)
375             qdialog->update();
376         break;
377     case INTERACT_HIDE:
378         qdialog = (InteractionDialog*)(p_dialog->p_private);
379         if( qdialog )
380             qdialog->hide();
381         p_dialog->i_status = HIDDEN_DIALOG;
382         break;
383     case INTERACT_DESTROY:
384         qdialog = (InteractionDialog*)(p_dialog->p_private);
385         if( !p_dialog->i_flags & DIALOG_NONBLOCKING_ERROR )
386             delete qdialog;
387         p_dialog->i_status = DESTROYED_DIALOG;
388         break;
389     }
390 }
391
392 void DialogsProvider::switchToSkins()
393 {
394     var_SetString( p_intf, "intf-switch", "skins2" );
395 }
396
397 void DialogsProvider::popupMenu( int i_dialog )
398 {
399 }