xref: /trunk/main/fpicker/source/win32/filepicker/FileOpenDlg.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org 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 Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _FILEOPENDLG_HXX_
29 #define _FILEOPENDLG_HXX_
30 
31 //------------------------------------------------------------------------
32 // includes
33 //------------------------------------------------------------------------
34 
35 #include <sal/types.h>
36 
37 #ifndef _RTL_USTRING_HXX_
38 #include <rtl/ustring>
39 #endif
40 #include <rtl/ustrbuf.hxx>
41 
42 #include "platform_xp.h"
43 #include "getfilenamewrapper.hxx"
44 
45 // because we don't want to import the new W2k platform skd
46 // into our build environment if have stolen the definition
47 // for the new OPENFILENAME structure from the new headers
48 
49 #ifndef _CDSIZEOF_STRUCT
50 #define _CDSIZEOF_STRUCT(structname, member)  (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
51 #endif
52 
53 typedef struct _tagOFNA {
54    DWORD        lStructSize;
55    HWND         hwndOwner;
56    HINSTANCE    hInstance;
57    LPCSTR       lpstrFilter;
58    LPSTR        lpstrCustomFilter;
59    DWORD        nMaxCustFilter;
60    DWORD        nFilterIndex;
61    LPSTR        lpstrFile;
62    DWORD        nMaxFile;
63    LPSTR        lpstrFileTitle;
64    DWORD        nMaxFileTitle;
65    LPCSTR       lpstrInitialDir;
66    LPCSTR       lpstrTitle;
67    DWORD        Flags;
68    WORD         nFileOffset;
69    WORD         nFileExtension;
70    LPCSTR       lpstrDefExt;
71    LPARAM       lCustData;
72    LPOFNHOOKPROC lpfnHook;
73    LPCSTR       lpTemplateName;
74 #ifdef _MAC
75    LPEDITMENU   lpEditInfo;
76    LPCSTR       lpstrPrompt;
77 #endif
78 #if (_WIN32_WINNT >= 0x0500)
79    void *       pvReserved;
80    DWORD        dwReserved;
81    DWORD        FlagsEx;
82 #endif // (_WIN32_WINNT >= 0x0500)
83 } _OPENFILENAMEA, *_LPOPENFILENAMEA;
84 
85 typedef struct _tagOFNW {
86    DWORD        lStructSize;
87    HWND         hwndOwner;
88    HINSTANCE    hInstance;
89    LPCWSTR      lpstrFilter;
90    LPWSTR       lpstrCustomFilter;
91    DWORD        nMaxCustFilter;
92    DWORD        nFilterIndex;
93    LPWSTR       lpstrFile;
94    DWORD        nMaxFile;
95    LPWSTR       lpstrFileTitle;
96    DWORD        nMaxFileTitle;
97    LPCWSTR      lpstrInitialDir;
98    LPCWSTR      lpstrTitle;
99    DWORD        Flags;
100    WORD         nFileOffset;
101    WORD         nFileExtension;
102    LPCWSTR      lpstrDefExt;
103    LPARAM       lCustData;
104    LPOFNHOOKPROC lpfnHook;
105    LPCWSTR      lpTemplateName;
106 #if (_WIN32_WINNT >= 0x0500)
107    void *       pvReserved;
108    DWORD        dwReserved;
109    DWORD        FlagsEx;
110 #endif // (_WIN32_WINNT >= 0x0500)
111 } _OPENFILENAMEW, *_LPOPENFILENAMEW;
112 
113 #ifdef UNICODE
114 typedef _OPENFILENAMEW _OPENFILENAME;
115 typedef _LPOPENFILENAMEW _LPOPENFILENAME;
116 #else
117 typedef _OPENFILENAMEA _OPENFILENAME;
118 typedef _LPOPENFILENAMEA _LPOPENFILENAME;
119 #endif // UNICODE
120 
121 #if (_WIN32_WINNT >= 0x0500)
122     #define _OPENFILENAME_SIZE_VERSION_400A  _CDSIZEOF_STRUCT(_OPENFILENAMEA,lpTemplateName)
123     #define _OPENFILENAME_SIZE_VERSION_400W  _CDSIZEOF_STRUCT(_OPENFILENAMEW,lpTemplateName)
124     #ifdef UNICODE
125         #define _OPENFILENAME_SIZE_VERSION_400  _OPENFILENAME_SIZE_VERSION_400W
126     #else
127         #define _OPENFILENAME_SIZE_VERSION_400  _OPENFILENAME_SIZE_VERSION_400A
128     #endif // !UNICODE
129 #else
130     #error _WIN32_WINNT seams not to be valid.
131 #endif // (_WIN32_WINNT >= 0x0500)
132 
133 
134 //-------------------------------------------------------------
135 // A simple wrapper class around the Win32 GetOpenFileName API.
136 // This class is not thread-safe and only one instance at a
137 // time is allowed
138 //-------------------------------------------------------------
139 
140 class CFileOpenDialog
141 {
142 public:
143     // ctor
144     // bFileOpenDialog idicates if we want a FileOpen or FileSave
145     // dialog
146     // dwFlags see OPENFILENAME
147     // dwTemplateId - an ID for custom templates
148     // hInstance    - an instance handle for the module
149     // which provides the custom template, unused if dwTemplateId
150     // is 0
151     CFileOpenDialog(
152         bool bFileOpenDialog = sal_True,
153         sal_uInt32 dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
154         sal_uInt32 dwTemplateId = 0,
155         HINSTANCE hInstance = 0);
156 
157     virtual ~CFileOpenDialog();
158 
159     virtual void SAL_CALL setTitle(const rtl::OUString& aTitle);
160 
161     // to set a filter string using the M$ format
162     // e.g. FltName\0*.txt;*.rtf\0...\0\0
163     void SAL_CALL setFilter(const rtl::OUString& aFilter);
164 
165     // set the index of the current filter when the
166     // dialog is about to shown, the index starts with 1
167     // the function succeeded if the given filter index
168     // is greater than zero and is a valid position
169     // within filter string that was previously set
170     bool SAL_CALL setFilterIndex(sal_uInt32 aIndex);
171 
172     // get the index of the currently selected filter
173     // the index of the returned filter starts with 1
174     sal_uInt32 SAL_CALL getSelectedFilterIndex() const;
175 
176     // set the name and optional the path of the
177     // file that will be initially be shown when
178     // the dialog will be displayed
179     virtual void SAL_CALL setDefaultName(const rtl::OUString& aName);
180 
181     // set the initial directory
182     virtual void SAL_CALL setDisplayDirectory(const rtl::OUString& aDirectory);
183 
184     // returns only the path of the selected file
185     virtual rtl::OUString SAL_CALL getLastDisplayDirectory() const;
186 
187     // returns the full file name including drive letter, path
188     // file name and file extension
189     virtual rtl::OUString SAL_CALL getFullFileName() const;
190 
191     // returns the file name and the file extension without
192     // drive letter and path
193     rtl::OUString SAL_CALL getFileName() const;
194 
195     // returns the file extension of the selected file
196     rtl::OUString SAL_CALL getFileExtension();
197 
198     // set a default extension, only the first three letters of
199     // the given extension will be used; the given extension
200     // should not contain a '.'
201     void SAL_CALL setDefaultFileExtension(const rtl::OUString& aExtension);
202 
203     // enables or disables the multiselection mode for
204     // the FileOpen/FileSave dialog
205     void SAL_CALL setMultiSelectionMode(bool bMode);
206 
207     // returns whether multi-selection mode is enabled or not
208     bool SAL_CALL getMultiSelectionMode() const;
209 
210     // shows the dialog, calls preModal before
211     // showing the dialog and postModal after
212     // showing the dialog
213     // the method returns:
214     //  0 - when the dialog was canceled by the user
215     //  1 - when the dialog was closed with ok
216     // -1 - when an error occured
217     sal_Int16 SAL_CALL doModal();
218 
219     // returns the last dialog error that occured
220     sal_uInt32 SAL_CALL getLastDialogError() const;
221 
222     // retrievs the currently selected file
223     // including path and drive information
224     // can be called only if the dialog is
225     // already displayed
226     rtl::OUString SAL_CALL getCurrentFilePath() const;
227 
228     // retrievs the currently selected folder
229     rtl::OUString SAL_CALL getCurrentFolderPath() const;
230 
231     // retrievs the currently selected file name
232     // without drive and path
233     rtl::OUString SAL_CALL getCurrentFileName() const;
234 
235 protected:
236     // have to be overwritten when subclasses
237     // want to do special pre- and post-modal
238     // processing
239 
240     // if preModal return true processing will
241     // continue else doModal exit without showing
242     // a dialog and returns -1
243     virtual bool SAL_CALL preModal();
244 
245     // post modal processing
246     // the function should accept only values returned from
247     // doModal and act appropriately
248     virtual void SAL_CALL postModal(sal_Int16 nDialogResult);
249 
250     // message handler, to be overwritten by subclasses
251     virtual sal_uInt32 SAL_CALL onShareViolation(const rtl::OUString& aPathName);
252     virtual sal_uInt32 SAL_CALL onFileOk();
253     virtual void SAL_CALL onSelChanged(HWND hwndListBox);
254     virtual void SAL_CALL onHelp();
255 
256     // only called back if OFN_EXPLORER is set
257     virtual void SAL_CALL onInitDone();
258     virtual void SAL_CALL onFolderChanged();
259     virtual void SAL_CALL onTypeChanged(sal_uInt32 nFilterIndex);
260 
261     virtual void SAL_CALL onInitDialog(HWND hwndDlg) = 0;
262 
263     virtual sal_uInt32 SAL_CALL onCtrlCommand(HWND hwndDlg, sal_uInt16 ctrlId, sal_uInt16 notifyCode);
264 
265     sal_uInt32 SAL_CALL onWMNotify(HWND hwndChild, LPOFNOTIFYW lpOfNotify);
266 
267     // we use non-virtual functions to do necessary work before
268     // calling the virtual funtions (see Gamma: Template method)
269     void SAL_CALL handleInitDialog(HWND hwndDlg, HWND hwndChild);
270 
271 protected:
272 
273     // handle to the window of the
274     // FileOpen/FileSave dialog
275     // will be set on message
276     // WM_INITDIALOG, before this
277     // value is undefined
278     HWND    m_hwndFileOpenDlg;
279     HWND    m_hwndFileOpenDlgChild;
280 
281     _OPENFILENAME   m_ofn;
282 
283     // we connect the instance with the dialog window using
284     // SetProp, with this function we can reconnect from
285     // callback functions to this instance
286     static CFileOpenDialog* SAL_CALL getCurrentInstance(HWND hwnd);
287 
288     void SAL_CALL centerPositionToParent() const;
289 
290 private:
291     // FileOpen or FileSaveDialog
292     bool            m_bFileOpenDialog;
293     rtl::OUString   m_dialogTitle;
294     rtl::OUString   m_displayDirectory;
295     rtl::OUString   m_defaultExtension;
296 
297     mutable rtl::OUStringBuffer m_filterBuffer;
298     mutable rtl::OUStringBuffer m_fileTitleBuffer;
299     mutable rtl::OUStringBuffer m_helperBuffer;
300     mutable rtl::OUStringBuffer m_fileNameBuffer;
301 
302     CGetFileNameWrapper m_GetFileNameWrapper;
303 
304     WNDPROC             m_pfnBaseDlgProc;
305 
306     // callback function
307     static unsigned int CALLBACK ofnHookProc(
308         HWND hChildDlg, // handle to child dialog box
309         unsigned int uiMsg,     // message identifier
310         WPARAM wParam,  // message parameter
311         LPARAM lParam   // message parameter
312     );
313 
314     // we have to subclass the dialog in order
315     // to clean up the window property we are
316     // using to connect the window with a class
317     // instance in WM_NCDESTROY
318     static LRESULT CALLBACK BaseDlgProc(
319         HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam );
320 
321 private:
322     // avoid copy and assignment
323     CFileOpenDialog(const CFileOpenDialog&);
324     CFileOpenDialog& operator=(const CFileOpenDialog&);
325 };
326 
327 #endif
328