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 FPICKER_WIN32_VISTA_FILEPICKERIMPL_HXX
29 #define FPICKER_WIN32_VISTA_FILEPICKERIMPL_HXX
30 
31 //-----------------------------------------------------------------------------
32 // includes
33 //-----------------------------------------------------------------------------
34 
35 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
36 #pragma warning( disable : 4917 )
37 #endif
38 
39 #include "platform_vista.h"
40 #include "asyncrequests.hxx"
41 #include "comptr.hxx"
42 #include "vistatypes.h"
43 #include "FilterContainer.hxx"
44 #include "VistaFilePickerEventHandler.hxx"
45 #include "IVistaFilePickerInternalNotify.hxx"
46 #include "..\misc\resourceprovider.hxx"
47 
48 #include <com/sun/star/uno/Sequence.hxx>
49 
50 #include <comphelper/sequenceashashmap.hxx>
51 #include <cppuhelper/interfacecontainer.h>
52 #include <cppuhelper/basemutex.hxx>
53 #include <osl/thread.hxx>
54 #include <osl/conditn.hxx>
55 #include <rtl/ustring.hxx>
56 
57 #if defined _MSC_VER
58 #pragma warning(push, 1)
59 #endif
60 #include <shobjidl.h>
61 #if defined _MSC_VER
62 #pragma warning(pop)
63 #endif
64 
65 //-----------------------------------------------------------------------------
66 // namespace
67 //-----------------------------------------------------------------------------
68 
69 #ifdef css
70     #error "Clash on using CSS as namespace define."
71 #else
72     #define css ::com::sun::star
73 #endif
74 
75 namespace fpicker{
76 namespace win32{
77 namespace vista{
78 
79 //-----------------------------------------------------------------------------
80 // types, const etcpp
81 //-----------------------------------------------------------------------------
82 
83 static const ::sal_Int32 FEATURE_AUTOEXTENSION  =    1;
84 static const ::sal_Int32 FEATURE_PASSWORD       =    2;
85 static const ::sal_Int32 FEATURE_FILTEROPTIONS  =    4;
86 static const ::sal_Int32 FEATURE_SELECTION      =    8;
87 static const ::sal_Int32 FEATURE_TEMPLATE       =   16;
88 static const ::sal_Int32 FEATURE_LINK           =   32;
89 static const ::sal_Int32 FEATURE_PREVIEW        =   64;
90 static const ::sal_Int32 FEATURE_IMAGETEMPLATE  =  128;
91 static const ::sal_Int32 FEATURE_PLAY           =  256;
92 static const ::sal_Int32 FEATURE_READONLY       =  512;
93 static const ::sal_Int32 FEATURE_VERSION        = 1024;
94 
95 static const ::rtl::OUString PROP_PICKER_LISTENER     = ::rtl::OUString::createFromAscii("picker_listener"    ); // [XFilePickerListenert]
96 static const ::rtl::OUString PROP_DIALOG_SHOW_RESULT  = ::rtl::OUString::createFromAscii("dialog_show_result" ); // [sal_Bool] true=OK, false=CANCEL
97 static const ::rtl::OUString PROP_SELECTED_FILES      = ::rtl::OUString::createFromAscii("selected_files"     ); // [seq< OUString >] contains all user selected files (can be empty!)
98 static const ::rtl::OUString PROP_MULTISELECTION_MODE = ::rtl::OUString::createFromAscii("multiselection_mode"); // [sal_Bool] true=ON, false=OFF
99 static const ::rtl::OUString PROP_TITLE               = ::rtl::OUString::createFromAscii("title"              ); // [OUString]
100 static const ::rtl::OUString PROP_FILENAME			  = ::rtl::OUString::createFromAscii("filename"           ); // [OUString]
101 static const ::rtl::OUString PROP_DIRECTORY           = ::rtl::OUString::createFromAscii("directory"          ); // [OUString]
102 static const ::rtl::OUString PROP_FEATURES            = ::rtl::OUString::createFromAscii("features"           ); // [sal_Int32]
103 static const ::rtl::OUString PROP_TEMPLATE_DESCR	  = ::rtl::OUString::createFromAscii("templatedescription"); // [sal_Int32]
104 static const ::rtl::OUString PROP_FILTER_TITLE        = ::rtl::OUString::createFromAscii("filter_title"       ); // [OUString]
105 static const ::rtl::OUString PROP_FILTER_VALUE        = ::rtl::OUString::createFromAscii("filter_value"       ); // [OUString]
106 static const ::rtl::OUString PROP_FORCE               = ::rtl::OUString::createFromAscii("force"              ); // [sal_Bool]
107 static const ::rtl::OUString PROP_FILTER_GROUP		  = ::rtl::OUString::createFromAscii("filter_group"       ); // [seq< css:beans::StringPair >] contains a group of filters
108 
109 static const ::rtl::OUString PROP_CONTROL_ID          = ::rtl::OUString::createFromAscii("control_id"         ); // [sal_Int16]
110 static const ::rtl::OUString PROP_CONTROL_ACTION      = ::rtl::OUString::createFromAscii("control_action"     ); // [sal_Int16]
111 static const ::rtl::OUString PROP_CONTROL_VALUE       = ::rtl::OUString::createFromAscii("control_value"      ); // [Any]
112 static const ::rtl::OUString PROP_CONTROL_LABEL       = ::rtl::OUString::createFromAscii("control_label"      ); // [OUString]
113 static const ::rtl::OUString PROP_CONTROL_ENABLE      = ::rtl::OUString::createFromAscii("control_enable"     ); // [sal_Bool] true=ON, false=OFF
114 static const ::rtl::OUString STRING_SEPARATOR         = ::rtl::OUString::createFromAscii("------------------------------------------" );
115 
116 //-----------------------------------------------------------------------------
117 /** native implementation of the file picker on Vista and upcoming windows versions.
118  *  This dialog uses COM internaly. Further it marshall every request so it will
119  *  be executed within it's own STA thread !
120  */
121 //-----------------------------------------------------------------------------
122 class VistaFilePickerImpl : private ::cppu::BaseMutex
123                           , public  RequestHandler
124                           , public  IVistaFilePickerInternalNotify
125 {
126     public:
127 
128         //---------------------------------------------------------------------
129         /** used for marshalling requests.
130          *  Will be used to map requests to the right implementations.
131          */
132         enum ERequest
133         {
134             E_NO_REQUEST,
135             E_ADD_PICKER_LISTENER,
136             E_REMOVE_PICKER_LISTENER,
137             E_APPEND_FILTER,
138             E_SET_CURRENT_FILTER,
139             E_GET_CURRENT_FILTER,
140             E_CREATE_OPEN_DIALOG,
141             E_CREATE_SAVE_DIALOG,
142             E_SET_MULTISELECTION_MODE,
143             E_SET_TITLE,
144 			E_SET_FILENAME,
145             E_GET_DIRECTORY,
146             E_SET_DIRECTORY,
147 			E_SET_DEFAULT_NAME,
148 			E_GET_SELECTED_FILES,
149             E_SHOW_DIALOG_MODAL,
150             E_SET_CONTROL_VALUE,
151             E_GET_CONTROL_VALUE,
152             E_SET_CONTROL_LABEL,
153             E_GET_CONTROL_LABEL,
154             E_ENABLE_CONTROL,
155 			E_APPEND_FILTERGROUP
156         };
157 
158     public:
159 
160         //---------------------------------------------------------------------
161         // ctor/dtor - nothing special
162         //---------------------------------------------------------------------
163                  VistaFilePickerImpl();
164         virtual ~VistaFilePickerImpl();
165 
166         //---------------------------------------------------------------------
167         // RequestHandler
168         //---------------------------------------------------------------------
169 
170         virtual void before();
171         virtual void doRequest(const RequestRef& rRequest);
172         virtual void after();
173 
174         //---------------------------------------------------------------------
175 		// IVistaFilePickerInternalNotify
176 		//---------------------------------------------------------------------
177         virtual void onAutoExtensionChanged (bool bChecked);
178 		virtual bool onFileTypeChanged( UINT nTypeIndex );
179 
180     private:
181 
182         //---------------------------------------------------------------------
183         /// implementation of request E_ADD_FILEPICKER_LISTENER
184         void impl_sta_addFilePickerListener(const RequestRef& rRequest);
185 
186         //---------------------------------------------------------------------
187         /// implementation of request E_REMOVE_FILEPICKER_LISTENER
188         void impl_sta_removeFilePickerListener(const RequestRef& rRequest);
189 
190         //---------------------------------------------------------------------
191         /// implementation of request E_APPEND_FILTER
192         void impl_sta_appendFilter(const RequestRef& rRequest);
193 
194         //---------------------------------------------------------------------
195         /// implementation of request E_APPEND_FILTERGROUP
196         void impl_sta_appendFilterGroup(const RequestRef& rRequest);
197 
198 		//---------------------------------------------------------------------
199         /// implementation of request E_SET_CURRENT_FILTER
200         void impl_sta_setCurrentFilter(const RequestRef& rRequest);
201 
202         //---------------------------------------------------------------------
203         /// implementation of request E_GET_CURRENT_FILTER
204         void impl_sta_getCurrentFilter(const RequestRef& rRequest);
205 
206         //---------------------------------------------------------------------
207         /// implementation of request E_CREATE_OPEN_DIALOG
208         void impl_sta_CreateOpenDialog(const RequestRef& rRequest);
209 
210         //---------------------------------------------------------------------
211         /// implementation of request E_CREATE_SAVE_DIALOG
212         void impl_sta_CreateSaveDialog(const RequestRef& rRequest);
213 
214         //---------------------------------------------------------------------
215         /// implementation of request E_SET_MULTISELECTION_MODE
216         void impl_sta_SetMultiSelectionMode(const RequestRef& rRequest);
217 
218         //---------------------------------------------------------------------
219         /// implementation of request E_SET_TITLE
220         void impl_sta_SetTitle(const RequestRef& rRequest);
221 
222         //---------------------------------------------------------------------
223         /// implementation of request E_SET_FILENAME
224         void impl_sta_SetFileName(const RequestRef& rRequest);
225 
226         //---------------------------------------------------------------------
227         /// implementation of request E_SET_DIRECTORY
228         void impl_sta_SetDirectory(const RequestRef& rRequest);
229 
230 		//---------------------------------------------------------------------
231         /// implementation of request E_GET_DIRECTORY
232         void impl_sta_GetDirectory(const RequestRef& rRequest);
233 
234 		//---------------------------------------------------------------------
235         /// implementation of request E_SET_DEFAULT_NAME
236         void impl_sta_SetDefaultName(const RequestRef& rRequest);
237 
238         //---------------------------------------------------------------------
239         /// implementation of request E_GET_SELECTED_FILES
240         void impl_sta_getSelectedFiles(const RequestRef& rRequest);
241 
242         //---------------------------------------------------------------------
243         /// implementation of request E_SHOW_DIALOG_MODAL
244         void impl_sta_ShowDialogModal(const RequestRef& rRequest);
245 
246         //---------------------------------------------------------------------
247         /// implementation of request E_SET_CONTROL_VALUE
248         void impl_sta_SetControlValue(const RequestRef& rRequest);
249 
250         //---------------------------------------------------------------------
251         /// implementation of request E_GET_CONTROL_VALUE
252         void impl_sta_GetControlValue(const RequestRef& rRequest);
253 
254         //---------------------------------------------------------------------
255         /// implementation of request E_SET_CONTROL_LABEL
256         void impl_sta_SetControlLabel(const RequestRef& rRequest);
257 
258         //---------------------------------------------------------------------
259         /// implementation of request E_GET_CONTROL_LABEL
260         void impl_sta_GetControlLabel(const RequestRef& rRequest);
261 
262         //---------------------------------------------------------------------
263         /// implementation of request E_ENABLE_CONTROL
264         void impl_sta_EnableControl(const RequestRef& rRequest);
265 
266         //---------------------------------------------------------------------
267         /** create all needed (optional!) UI controls adressed by the field nFeatures.
268          *  The given number nFeatures is used as a flag field. Use const values FEATURE_XXX
269          *  to adress it.
270          *
271          *  Internal new controls will be added to the dialog. Every control can be accessed
272          *  by it's own control id. Those control ID must be one of the const set
273          *  css::ui::dialogs::ExtendedFilePickerElementIds.
274          *
275          *  @see setControlValue()
276          *  @see getControlValue()
277          *  @see setControlLabel()
278          *  @see getControlLabel()
279          *  @see enableControl()
280          *
281          *  @param  nFeatures
282          *          flag field(!) knows all features wich must be enabled.
283          */
284 		void impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_Int32 nTemplate);
285 
286         //---------------------------------------------------------------------
287         /** returns an interface, which can be used to customize the internaly used
288          *  COM dialog.
289          *
290          *  Because we use two member (open/save dialog) internaly, this method
291          *  ask the current active one for it's customization interface.
292          *
293          *  @return the customization interface for the current used dialog.
294          *          Must not be null.
295          */
296         TFileDialogCustomize impl_getCustomizeInterface();
297         TFileDialog impl_getBaseDialogInterface();
298 
299         //---------------------------------------------------------------------
300         /// fill filter list of internal used dialog.
301         void impl_sta_setFiltersOnDialog();
302 
303 		void impl_SetDefaultExtension( const rtl::OUString& currentFilter );
304 
305    private:
306 
307         //---------------------------------------------------------------------
308         /// COM object representing a file open dialog
309         TFileOpenDialog m_iDialogOpen;
310 
311         //---------------------------------------------------------------------
312         /// COM object representing a file save dialog
313         TFileSaveDialog m_iDialogSave;
314 
315         //---------------------------------------------------------------------
316         /// knows the return state of the last COM call
317         HRESULT m_hLastResult;
318 
319         //---------------------------------------------------------------------
320         /// @todo document me
321         CFilterContainer m_lFilters;
322 
323         //---------------------------------------------------------------------
324         /** cache last selected list of files
325          *  Because those list must be retrieved directly after closing the dialog
326          *  (and only in case it was finished successfully) we cache it internaly.
327          *  Because the outside provided UNO API decouple showing the dialog
328          *  and asking for results .-)
329          */
330         css::uno::Sequence< ::rtl::OUString > m_lLastFiles;
331 
332         //---------------------------------------------------------------------
333         /** help us to handle dialog events and provide them to interested office
334          *  listener.
335          */
336         TFileDialogEvents m_iEventHandler;
337 
338         //---------------------------------------------------------------------
339         /// @todo document me
340         ::sal_Bool m_bInExecute;
341 
342         ::sal_Bool m_bWasExecuted;
343 
344 		// handle to parent window
345 		HWND m_hParentWindow;
346 
347 		//
348 		::rtl::OUString m_sDirectory;
349 
350 		//
351 		::rtl::OUString m_sFilename;
352 
353         // Resource provider
354         CResourceProvider m_ResProvider;
355 };
356 
357 } // namespace vista
358 } // namespace win32
359 } // namespace fpicker
360 
361 #undef css
362 
363 #endif // FPICKER_WIN32_VISTA_FILEPICKERIMPL_HXX
364