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