]> git.sesse.net Git - vlc/blob - modules/gui/wince/dialogs.cpp
2495c936d6f4a118f60184c866d0c7c9369d976b
[vlc] / modules / gui / wince / dialogs.cpp
1 /*****************************************************************************
2  * dialogs.cpp : WinCE plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2005 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@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 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28
29 #include <vlc/vlc.h>
30 #include <vlc_aout.h>
31 #include <vlc_interface.h>
32
33 #include "wince.h"
34
35 #include <commctrl.h>
36 #include <commdlg.h>
37 #include <shlobj.h>
38
39 /* Dialogs Provider */
40 class DialogsProvider: public CBaseWindow
41 {
42 public:
43     /* Constructor */
44     DialogsProvider( intf_thread_t *, CBaseWindow *, HINSTANCE = 0 );
45     virtual ~DialogsProvider();
46
47 protected:
48     virtual LRESULT WndProc( HWND, UINT, WPARAM, LPARAM );
49
50 private:
51
52     void OnExit( void );
53     void OnIdle( void );
54     void OnPlaylist( void );
55     void OnMessages( void );
56     void OnFileInfo( void );
57     void OnPreferences( void );
58     void OnPopupMenu( void );
59
60     void OnOpen( int, int );
61     void OnOpenFileSimple( int );
62     void OnOpenDirectory( int );
63     void OnOpenFileGeneric( intf_dialog_args_t * );
64
65     /* GetOpenFileName replacement */
66     BOOL (WINAPI *GetOpenFile)(void *);
67     HMODULE h_gsgetfile_dll;
68
69 public:
70     /* Secondary windows */
71     OpenDialog          *p_open_dialog;
72     Playlist            *p_playlist_dialog;
73     Messages            *p_messages_dialog;
74     PrefsDialog         *p_prefs_dialog;
75     FileInfo            *p_fileinfo_dialog;
76 };
77
78 CBaseWindow *CreateDialogsProvider( intf_thread_t *p_intf,
79                                     CBaseWindow *p_parent, HINSTANCE h_inst )
80 {
81     return new DialogsProvider( p_intf, p_parent, h_inst );
82 }
83
84 /*****************************************************************************
85  * Constructor.
86  *****************************************************************************/
87 DialogsProvider::DialogsProvider( intf_thread_t *p_intf,
88                                   CBaseWindow *p_parent, HINSTANCE h_inst )
89   :  CBaseWindow( p_intf, p_parent, h_inst )
90 {
91     /* Initializations */
92     p_open_dialog = NULL;
93     p_playlist_dialog = NULL;
94     p_messages_dialog = NULL;
95     p_fileinfo_dialog = NULL;
96     p_prefs_dialog = NULL;
97
98     /* Create dummy window */
99     hWnd = CreateWindow( _T("VLC WinCE"), _T("DialogsProvider"), 0,
100                          0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
101                          p_parent->GetHandle(), NULL, h_inst, (void *)this );
102
103     GetOpenFile = 0;
104     h_gsgetfile_dll = LoadLibrary( _T("gsgetfile") );
105     if( h_gsgetfile_dll )
106     {
107         GetOpenFile = (BOOL (WINAPI *)(void *))
108             GetProcAddress( h_gsgetfile_dll, _T("gsGetOpenFileName") );
109     }
110
111     if( !GetOpenFile )
112         GetOpenFile = (BOOL (WINAPI *)(void *))::GetOpenFileName;
113 }
114
115 DialogsProvider::~DialogsProvider()
116 {
117     /* Clean up */
118     if( p_open_dialog )     delete p_open_dialog;
119     if( p_playlist_dialog ) delete p_playlist_dialog;
120     if( p_messages_dialog ) delete p_messages_dialog;
121     if( p_fileinfo_dialog ) delete p_fileinfo_dialog;
122     if( p_prefs_dialog )    delete p_prefs_dialog;
123
124     if( h_gsgetfile_dll ) FreeLibrary( h_gsgetfile_dll );
125 }
126
127 LRESULT DialogsProvider::WndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
128 {
129     switch( msg )
130     {
131     case WM_APP + INTF_DIALOG_FILE: OnOpen( FILE_ACCESS, wp ); return TRUE;
132     case WM_APP + INTF_DIALOG_NET: OnOpen( NET_ACCESS, wp ); return TRUE;
133     case WM_APP + INTF_DIALOG_FILE_SIMPLE: OnOpenFileSimple( wp ); return TRUE;
134     case WM_APP + INTF_DIALOG_DIRECTORY: OnOpenDirectory( wp ); return TRUE;
135     case WM_APP + INTF_DIALOG_FILE_GENERIC:
136         OnOpenFileGeneric( (intf_dialog_args_t*)lp ); return TRUE;
137     case WM_APP + INTF_DIALOG_PLAYLIST: OnPlaylist(); return TRUE;
138     case WM_APP + INTF_DIALOG_MESSAGES: OnMessages(); return TRUE;
139     case WM_APP + INTF_DIALOG_FILEINFO: OnFileInfo(); return TRUE;
140     case WM_APP + INTF_DIALOG_PREFS: OnPreferences(); return TRUE;
141     case WM_APP + INTF_DIALOG_POPUPMENU: OnPopupMenu(); return TRUE;
142     }
143
144     return DefWindowProc( hwnd, msg, wp, lp );
145 }
146
147 void DialogsProvider::OnIdle( void )
148 {
149     /* Update the log window */
150     if( p_messages_dialog ) p_messages_dialog->UpdateLog();
151
152     /* Update the playlist */
153     if( p_playlist_dialog ) p_playlist_dialog->UpdatePlaylist();
154
155     /* Update the fileinfo windows */
156     if( p_fileinfo_dialog ) p_fileinfo_dialog->UpdateFileInfo();
157 }
158
159 void DialogsProvider::OnPopupMenu( void )
160 {
161     POINT point = {0};
162     PopupMenu( p_intf, hWnd, point );
163 }
164
165 void DialogsProvider::OnPlaylist( void )
166 {
167 #if 1
168     Playlist *playlist = new Playlist( p_intf, this, hInst );
169     CreateDialogBox( hWnd, playlist );
170     delete playlist;
171 #else
172     /* Show/hide the playlist window */
173     if( !p_playlist_dialog )
174         p_playlist_dialog = new Playlist( p_intf, this, hInst );
175
176     if( p_playlist_dialog )
177     {
178         p_playlist_dialog->ShowPlaylist( !p_playlist_dialog->IsShown() );
179     }
180 #endif
181 }
182
183 void DialogsProvider::OnMessages( void )
184 {
185     /* Show/hide the log window */
186     if( !p_messages_dialog )
187         p_messages_dialog = new Messages( p_intf, this, hInst );
188
189     if( p_messages_dialog )
190     {
191         p_messages_dialog->Show( !p_messages_dialog->IsShown() );
192     }
193 }
194
195 void DialogsProvider::OnFileInfo( void )
196 {
197 #if 1
198     FileInfo *fileinfo = new FileInfo( p_intf, this, hInst );
199     CreateDialogBox( hWnd, fileinfo );
200     delete fileinfo;
201 #else
202     /* Show/hide the file info window */
203     if( !p_fileinfo_dialog )
204         p_fileinfo_dialog = new FileInfo( p_intf, this, hInst );
205
206     if( p_fileinfo_dialog )
207     {
208         p_fileinfo_dialog->Show( !p_fileinfo_dialog->IsShown() );
209     }
210 #endif
211 }
212
213 void DialogsProvider::OnPreferences( void )
214 {
215 #if 1
216     PrefsDialog *preferences = new PrefsDialog( p_intf, this, hInst );
217     CreateDialogBox( hWnd, preferences );
218     delete preferences;
219 #else
220     /* Show/hide the open dialog */
221     if( !p_prefs_dialog )
222         p_prefs_dialog = new PrefsDialog( p_intf, this, hInst );
223
224     if( p_prefs_dialog )
225     {
226         p_prefs_dialog->Show( !p_prefs_dialog->IsShown() );
227     }
228 #endif
229 }
230
231 void DialogsProvider::OnOpen( int i_access, int i_arg )
232 {
233     /* Show/hide the open dialog */
234     if( !p_open_dialog )
235         p_open_dialog = new OpenDialog( p_intf, this, hInst, i_access, i_arg );
236
237     if( p_open_dialog )
238     {
239         p_open_dialog->Show( !p_open_dialog->IsShown() );
240     }
241 }
242
243 void DialogsProvider::OnOpenFileGeneric( intf_dialog_args_t *p_arg )
244 {
245     if( p_arg == NULL )
246     {
247         msg_Dbg( p_intf, "OnOpenFileGeneric() called with NULL arg" );
248         return;
249     }
250
251     /* Convert the filter string */
252     TCHAR *psz_filters = (TCHAR *)
253         malloc( (strlen(p_arg->psz_extensions) + 2) * sizeof(TCHAR) );
254     _tcscpy( psz_filters, _FROMMB(p_arg->psz_extensions) );
255
256     int i;
257     for( i = 0; psz_filters[i]; i++ )
258     {
259         if( psz_filters[i] == '|' ) psz_filters[i] = 0;
260     }
261     psz_filters[++i] = 0;
262
263     OPENFILENAME ofn;
264     TCHAR szFile[MAX_PATH] = _T("\0");
265
266     memset( &ofn, 0, sizeof(OPENFILENAME) );
267     ofn.lStructSize = sizeof(OPENFILENAME);
268     ofn.hwndOwner = hWnd;
269     ofn.hInstance = hInst;
270     ofn.lpstrFilter = psz_filters;
271     ofn.lpstrCustomFilter = NULL;
272     ofn.nMaxCustFilter = 0;
273     ofn.nFilterIndex = 1;
274     ofn.lpstrFile = (LPTSTR)szFile; 
275     ofn.nMaxFile = MAX_PATH;
276     ofn.lpstrFileTitle = NULL; 
277     ofn.nMaxFileTitle = 40;
278     ofn.lpstrInitialDir = NULL;
279     ofn.lpstrTitle = _FROMMB(p_arg->psz_title);
280     ofn.Flags = 0; 
281     ofn.nFileOffset = 0;
282     ofn.nFileExtension = 0;
283     ofn.lpstrDefExt = NULL;
284     ofn.lCustData = 0L;
285     ofn.lpfnHook = NULL;
286     ofn.lpTemplateName = NULL;
287
288     SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
289
290     if( p_arg->b_save && GetSaveFileName( &ofn ) )
291     {
292         p_arg->i_results = 1;
293         p_arg->psz_results = (char **)malloc( p_arg->i_results *
294                                               sizeof(char *) );
295         p_arg->psz_results[0] = strdup( _TOMB(ofn.lpstrFile) );
296     }
297
298     if( !p_arg->b_save && GetOpenFile( &ofn ) )
299     {
300         p_arg->i_results = 1;
301         p_arg->psz_results = (char **)malloc( p_arg->i_results *
302                                               sizeof(char *) );
303         p_arg->psz_results[0] = strdup( _TOMB(ofn.lpstrFile) );
304     }
305
306     /* Callback */
307     if( p_arg->pf_callback )
308     {
309         p_arg->pf_callback( p_arg );
310     }
311
312     if( p_arg->psz_results )
313     {
314         for( int i = 0; i < p_arg->i_results; i++ )
315         {
316             free( p_arg->psz_results[i] );
317         }
318         free( p_arg->psz_results );
319     }
320     if( p_arg->psz_title ) free( p_arg->psz_title );
321     if( p_arg->psz_extensions ) free( p_arg->psz_extensions );
322
323     free( p_arg );
324 }
325
326 void DialogsProvider::OnOpenFileSimple( int i_arg )
327 {
328     OPENFILENAME ofn;
329     TCHAR szFile[MAX_PATH] = _T("\0");
330     static TCHAR szFilter[] = _T("All (*.*)\0*.*\0");
331
332     playlist_t *p_playlist = (playlist_t *)
333         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
334     if( p_playlist == NULL ) return;
335
336     memset( &ofn, 0, sizeof(OPENFILENAME) );
337     ofn.lStructSize = sizeof(OPENFILENAME);
338     ofn.hwndOwner = hWnd;
339     ofn.hInstance = hInst;
340     ofn.lpstrFilter = szFilter;
341     ofn.lpstrCustomFilter = NULL;
342     ofn.nMaxCustFilter = 0;
343     ofn.nFilterIndex = 1;     
344     ofn.lpstrFile = (LPTSTR)szFile; 
345     ofn.nMaxFile = MAX_PATH;
346     ofn.lpstrFileTitle = NULL; 
347     ofn.nMaxFileTitle = 40;
348     ofn.lpstrInitialDir = NULL;
349     ofn.lpstrTitle = _T("Quick Open File");
350     ofn.Flags = 0; 
351     ofn.nFileOffset = 0;
352     ofn.nFileExtension = 0;
353     ofn.lpstrDefExt = NULL;
354     ofn.lCustData = 0L;
355     ofn.lpfnHook = NULL;
356     ofn.lpTemplateName = NULL;
357
358     SHFullScreen( GetForegroundWindow(), SHFS_HIDESIPBUTTON );
359
360     if( GetOpenFile( &ofn ) )
361     {
362         char *psz_filename = _TOMB(ofn.lpstrFile);
363         playlist_Add( p_playlist, psz_filename, psz_filename,
364                       PLAYLIST_APPEND | (i_arg?PLAYLIST_GO:0), PLAYLIST_END );
365     }
366
367     vlc_object_release( p_playlist );
368 }
369
370 void DialogsProvider::OnOpenDirectory( int i_arg )
371 {
372     TCHAR psz_result[MAX_PATH];
373     LPMALLOC p_malloc = 0;
374     LPITEMIDLIST pidl;
375     BROWSEINFO bi;
376     playlist_t *p_playlist = 0;
377
378 #ifdef UNDER_CE
379 #   define SHGetMalloc MySHGetMalloc
380 #   define SHBrowseForFolder MySHBrowseForFolder
381 #   define SHGetPathFromIDList MySHGetPathFromIDList
382
383     HMODULE ceshell_dll = LoadLibrary( _T("ceshell") );
384     if( !ceshell_dll ) return;
385
386     HRESULT (WINAPI *SHGetMalloc)(LPMALLOC *) =
387         (HRESULT (WINAPI *)(LPMALLOC *))
388         GetProcAddress( ceshell_dll, _T("SHGetMalloc") );
389     LPITEMIDLIST (WINAPI *SHBrowseForFolder)(LPBROWSEINFO) =
390         (LPITEMIDLIST (WINAPI *)(LPBROWSEINFO))
391         GetProcAddress( ceshell_dll, _T("SHBrowseForFolder") );
392     BOOL (WINAPI *SHGetPathFromIDList)(LPCITEMIDLIST, LPTSTR) =
393         (BOOL (WINAPI *)(LPCITEMIDLIST, LPTSTR))
394         GetProcAddress( ceshell_dll, _T("SHGetPathFromIDList") );
395
396     if( !SHGetMalloc || !SHBrowseForFolder || !SHGetPathFromIDList )
397     {
398         msg_Err( p_intf, "couldn't load SHBrowseForFolder API" );
399         FreeLibrary( ceshell_dll );
400         return;
401     }
402 #endif
403
404     if( !SUCCEEDED( SHGetMalloc(&p_malloc) ) ) goto error;
405
406     p_playlist = (playlist_t *)
407         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
408     if( !p_playlist ) goto error;
409
410     memset( &bi, 0, sizeof(BROWSEINFO) );
411     bi.hwndOwner = hWnd;
412     bi.pszDisplayName = psz_result;
413     bi.ulFlags = BIF_EDITBOX;
414 #ifndef UNDER_CE
415     bi.ulFlags |= BIF_USENEWUI;
416 #endif
417
418     if( (pidl = SHBrowseForFolder( &bi ) ) )
419     {
420         if( SHGetPathFromIDList( pidl, psz_result ) )
421         {
422             char *psz_filename = _TOMB(psz_result);
423             playlist_Add( p_playlist, psz_filename, psz_filename,
424                           PLAYLIST_APPEND | (i_arg ? PLAYLIST_GO : 0),
425                           PLAYLIST_END );
426         }
427         p_malloc->Free( pidl );
428     }
429
430  error:
431
432     if( p_malloc) p_malloc->Release();
433     if( p_playlist ) vlc_object_release( p_playlist );
434
435 #ifdef UNDER_CE
436     FreeLibrary( ceshell_dll );
437 #endif
438 }