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