* Playtree start. Basic functionalities work. Still needs a lot of
[vlc.git] / modules / gui / skins2 / src / dialogs.cpp
1 /*****************************************************************************
2  * dialogs.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teulière <ipkiss@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #include "dialogs.hpp"
26 #include "../commands/async_queue.hpp"
27 #include "../commands/cmd_change_skin.hpp"
28 #include "../commands/cmd_quit.hpp"
29 #include "../commands/cmd_playlist.hpp"
30 #include "../commands/cmd_playtree.hpp"
31
32
33 /// Callback called when a new skin is chosen
34 void Dialogs::showChangeSkinCB( intf_dialog_args_t *pArg )
35 {
36     intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;
37
38     if( pArg->i_results )
39     {
40         if( pArg->psz_results[0] )
41         {
42             // Create a change skin command
43             CmdChangeSkin *pCmd =
44                 new CmdChangeSkin( pIntf, pArg->psz_results[0] );
45
46             // Push the command in the asynchronous command queue
47             AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
48             pQueue->remove( "change skin" );
49             pQueue->push( CmdGenericPtr( pCmd ) );
50         }
51     }
52     else if( !pIntf->p_sys->p_theme )
53     {
54         // If no theme is already loaded, it's time to quit!
55         CmdQuit *pCmd = new CmdQuit( pIntf );
56         AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
57         pQueue->push( CmdGenericPtr( pCmd ) );
58     }
59 }
60
61
62 void Dialogs::showPlaylistLoadCB( intf_dialog_args_t *pArg )
63 {
64     intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;
65
66     if( pArg->i_results && pArg->psz_results[0] )
67     {
68         // Create a Playlist Load command
69         CmdPlaylistLoad *pCmd =
70             new CmdPlaylistLoad( pIntf, pArg->psz_results[0] );
71
72         // Push the command in the asynchronous command queue
73         AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
74         pQueue->remove( "load playlist" );
75         pQueue->remove( "load playtree" );
76         pQueue->push( CmdGenericPtr( pCmd ) );
77     }
78 }
79
80
81 void Dialogs::showPlaylistSaveCB( intf_dialog_args_t *pArg )
82 {
83     intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;
84
85     if( pArg->i_results && pArg->psz_results[0] )
86     {
87         // Create a Playlist Save command
88         CmdPlaylistSave *pCmd =
89             new CmdPlaylistSave( pIntf, pArg->psz_results[0] );
90
91         // Push the command in the asynchronous command queue
92         AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
93         pQueue->remove( "load playlist" );
94         pQueue->remove( "load playtree" );
95         pQueue->push( CmdGenericPtr( pCmd ) );
96     }
97 }
98
99
100 /// Callback called when the popup menu is requested
101 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
102                         vlc_value_t old_val, vlc_value_t new_val, void *param )
103 {
104     Dialogs *p_dialogs = (Dialogs *)param;
105     p_dialogs->showPopupMenu( new_val.b_bool != 0 );
106
107     return VLC_SUCCESS;
108 }
109
110
111 Dialogs::Dialogs( intf_thread_t *pIntf ):
112     SkinObject( pIntf ), m_pProvider( NULL ), m_pModule( NULL )
113 {
114 }
115
116
117 Dialogs::~Dialogs()
118 {
119     if( m_pProvider && m_pModule )
120     {
121         // Detach the dialogs provider from its parent interface
122         vlc_object_detach( m_pProvider );
123
124         module_Unneed( m_pProvider, m_pModule );
125         vlc_object_destroy( m_pProvider );
126     }
127
128     /* Unregister callbacks */
129     var_DelCallback( getIntf()->p_sys->p_playlist, "intf-popupmenu",
130                      PopupMenuCB, this );
131 }
132
133
134 Dialogs *Dialogs::instance( intf_thread_t *pIntf )
135 {
136     if( ! pIntf->p_sys->p_dialogs )
137     {
138         Dialogs *pDialogs = new Dialogs( pIntf );
139         if( pDialogs->init() )
140         {
141             // Initialization succeeded
142             pIntf->p_sys->p_dialogs = pDialogs;
143         }
144         else
145         {
146             // Initialization failed
147             delete pDialogs;
148         }
149     }
150     return pIntf->p_sys->p_dialogs;
151 }
152
153
154 void Dialogs::destroy( intf_thread_t *pIntf )
155 {
156     if( pIntf->p_sys->p_dialogs )
157     {
158         delete pIntf->p_sys->p_dialogs;
159         pIntf->p_sys->p_dialogs = NULL;
160     }
161 }
162
163
164 bool Dialogs::init()
165 {
166     // Allocate descriptor
167     m_pProvider = (intf_thread_t *)vlc_object_create( getIntf(),
168                                                       VLC_OBJECT_DIALOGS );
169     if( m_pProvider == NULL )
170     {
171         msg_Err( getIntf(), "out of memory" );
172         return false;
173     }
174
175     m_pModule = module_Need( m_pProvider, "dialogs provider", NULL, 0 );
176     if( m_pModule == NULL )
177     {
178         msg_Err( getIntf(), "No suitable dialogs provider found" );
179         vlc_object_destroy( m_pProvider );
180         m_pProvider = NULL;
181         return false;
182     }
183
184     // Attach the dialogs provider to its parent interface
185     vlc_object_attach( m_pProvider, getIntf() );
186
187     // Initialize dialogs provider
188     // (returns as soon as initialization is done)
189     if( m_pProvider->pf_run )
190     {
191         m_pProvider->pf_run( m_pProvider );
192     }
193
194     /* Register callback for the intf-popupmenu variable */
195     var_AddCallback( getIntf()->p_sys->p_playlist, "intf-popupmenu",
196                      PopupMenuCB, this );
197
198     return true;
199 }
200
201
202 void Dialogs::showFileGeneric( const string &rTitle, const string &rExtensions,
203                                DlgCallback callback, int flags )
204 {
205     if( m_pProvider && m_pProvider->pf_show_dialog )
206     {
207         intf_dialog_args_t *p_arg =
208             (intf_dialog_args_t *)malloc( sizeof(intf_dialog_args_t) );
209         memset( p_arg, 0, sizeof(intf_dialog_args_t) );
210
211         p_arg->psz_title = strdup( rTitle.c_str() );
212         p_arg->psz_extensions = strdup( rExtensions.c_str() );
213
214         p_arg->b_save = flags & kSAVE;
215         p_arg->b_multiple = flags & kMULTIPLE;
216
217         p_arg->p_arg = getIntf();
218         p_arg->pf_callback = callback;
219
220         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE_GENERIC,
221                                      0, p_arg );
222     }
223 }
224
225
226 void Dialogs::showChangeSkin()
227 {
228     showFileGeneric( _("Open a skin file"),
229                      _("Skin files (*.vlt)|*.vlt|Skin files (*.xml)|*.xml"),
230                      showChangeSkinCB, kOPEN );
231 }
232
233
234 void Dialogs::showPlaylistLoad()
235 {
236     showFileGeneric( _("Open playlist"),
237                      _("All playlists|*.pls;*.m3u;*.asx;*.b4s|M3U files|*.m3u"),
238                      showPlaylistLoadCB, kOPEN );
239 }
240
241
242 void Dialogs::showPlaylistSave()
243 {
244     showFileGeneric( _("Save playlist"), _("M3U file|*.m3u"),
245                      showPlaylistSaveCB, kSAVE );
246 }
247
248
249 void Dialogs::showFileSimple( bool play )
250 {
251     if( m_pProvider && m_pProvider->pf_show_dialog )
252     {
253         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE_SIMPLE,
254                                      (int)play, 0 );
255     }
256 }
257
258
259 void Dialogs::showFile( bool play )
260 {
261     if( m_pProvider && m_pProvider->pf_show_dialog )
262     {
263         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE,
264                                      (int)play, 0 );
265     }
266 }
267
268
269 void Dialogs::showDirectory( bool play )
270 {
271     if( m_pProvider && m_pProvider->pf_show_dialog )
272     {
273         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_DIRECTORY,
274                                      (int)play, 0 );
275     }
276 }
277
278
279 void Dialogs::showDisc( bool play )
280 {
281     if( m_pProvider && m_pProvider->pf_show_dialog )
282     {
283         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_DISC,
284                                      (int)play, 0 );
285     }
286 }
287
288
289 void Dialogs::showNet( bool play )
290 {
291     if( m_pProvider && m_pProvider->pf_show_dialog )
292     {
293         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_NET,
294                                      (int)play, 0 );
295     }
296 }
297
298
299 void Dialogs::showMessages()
300 {
301     if( m_pProvider && m_pProvider->pf_show_dialog )
302     {
303         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_MESSAGES, 0, 0 );
304     }
305 }
306
307
308 void Dialogs::showPrefs()
309 {
310     if( m_pProvider && m_pProvider->pf_show_dialog )
311     {
312         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_PREFS, 0, 0 );
313     }
314 }
315
316
317 void Dialogs::showFileInfo()
318 {
319     if( m_pProvider && m_pProvider->pf_show_dialog )
320     {
321         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILEINFO, 0, 0 );
322     }
323 }
324
325
326 void Dialogs::showStreamingWizard()
327 {
328     if( m_pProvider && m_pProvider->pf_show_dialog )
329     {
330         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_WIZARD, 0, 0 );
331     }
332 }
333
334
335 void Dialogs::showPopupMenu( bool bShow )
336 {
337     if( m_pProvider && m_pProvider->pf_show_dialog )
338     {
339         m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_POPUPMENU,
340                                      (int)bShow, 0 );
341     }
342 }
343