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_FILEPICKER_EVENTHANDLER_HXX
25 #define FPICKER_WIN32_VISTA_FILEPICKER_EVENTHANDLER_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 "comptr.hxx"
36 #include "vistatypes.h"
37 #include "IVistaFilePickerInternalNotify.hxx"
38 
39 #include <com/sun/star/ui/dialogs/XFilePickerListener.hpp>
40 #include <com/sun/star/uno/Reference.hxx>
41 
42 #include <cppuhelper/basemutex.hxx>
43 #include <cppuhelper/interfacecontainer.h>
44 #include <osl/interlck.h>
45 
46 #include <shobjidl.h>
47 
48 //-----------------------------------------------------------------------------
49 // namespace
50 //-----------------------------------------------------------------------------
51 
52 #ifdef css
53     #error "Clash on using CSS as namespace define."
54 #else
55     #define css ::com::sun::star
56 #endif
57 
58 namespace fpicker{
59 namespace win32{
60 namespace vista{
61 
62 //-----------------------------------------------------------------------------
63 // types, const etcpp.
64 //-----------------------------------------------------------------------------
65 
66 //-----------------------------------------------------------------------------
67 /** todo document me
68  */
69 class VistaFilePickerEventHandler : public ::cppu::BaseMutex
70                                   , public IFileDialogEvents
71                                   , public IFileDialogControlEvents
72 {
73     public:
74 
75         //------------------------------------------------------------------------------------
76         // ctor/dtor
77         //------------------------------------------------------------------------------------
78 
79                  VistaFilePickerEventHandler(IVistaFilePickerInternalNotify* pInternalNotify);
80         virtual ~VistaFilePickerEventHandler();
81 
82         //------------------------------------------------------------------------------------
83         // IUnknown
84         //------------------------------------------------------------------------------------
85         virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID rIID    ,
86                                                          void** ppObject);
87         virtual ULONG STDMETHODCALLTYPE AddRef();
88         virtual ULONG STDMETHODCALLTYPE Release();
89 
90         //------------------------------------------------------------------------------------
91         // IFileDialogEvents
92         //------------------------------------------------------------------------------------
93 
94         STDMETHODIMP OnFileOk(IFileDialog* pDialog);
95 
96         STDMETHODIMP OnFolderChanging(IFileDialog* pDialog,
97                                       IShellItem*  pFolder);
98 
99         STDMETHODIMP OnFolderChange(IFileDialog* pDialog);
100 
101         STDMETHODIMP OnSelectionChange(IFileDialog* pDialog);
102 
103         STDMETHODIMP OnShareViolation(IFileDialog*                 pDialog  ,
104                                       IShellItem*                  pItem    ,
105                                       FDE_SHAREVIOLATION_RESPONSE* pResponse);
106 
107         STDMETHODIMP OnTypeChange(IFileDialog* pDialog);
108 
109         STDMETHODIMP OnOverwrite(IFileDialog*            pDialog  ,
110                                  IShellItem*             pItem    ,
111                                  FDE_OVERWRITE_RESPONSE* pResponse);
112 
113         //------------------------------------------------------------------------------------
114         // IFileDialogControlEvents
115         //------------------------------------------------------------------------------------
116 
117         STDMETHODIMP OnItemSelected(IFileDialogCustomize* pCustomize,
118                                     DWORD                 nIDCtl    ,
119                                     DWORD                 nIDItem   );
120 
121         STDMETHODIMP OnButtonClicked(IFileDialogCustomize* pCustomize,
122                                      DWORD                 nIDCtl    );
123 
124         STDMETHODIMP OnCheckButtonToggled(IFileDialogCustomize* pCustomize,
125                                           DWORD                 nIDCtl    ,
126                                           BOOL                  bChecked  );
127 
128         STDMETHODIMP OnControlActivating(IFileDialogCustomize* pCustomize,
129                                          DWORD                 nIDCtl    );
130 
131         //------------------------------------------------------------------------------------
132         // XFilePickerNotifier
133         //------------------------------------------------------------------------------------
134 
135         virtual void SAL_CALL addFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener )
136             throw( css::uno::RuntimeException );
137 
138         virtual void SAL_CALL removeFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener )
139             throw( css::uno::RuntimeException );
140 
141         //------------------------------------------------------------------------------------
142         // native interface
143         //------------------------------------------------------------------------------------
144 
145         //------------------------------------------------------------------------------------
146         /** start listening for file picker events on the given file open dialog COM object.
147          *
148          *  The broadcaster will be cached internally so deregistration will be easy.
149          *  Further all needed informations are capsulated within this class (e.g. the listener handler).
150          *  Nobody outside must know such informations.
151          *
152          *  Nothing will happen if an inconsistent state will be detected
153          *  (means: double registration will be ignored).
154          *
155          *  @param  pBroadcaster
156          *          reference to the dialog, where we should start listening.
157          */
158         void startListening( const TFileDialog& pBroadcaster );
159 
160         //------------------------------------------------------------------------------------
161         /** stop listening for file picker events on the internally cached dialog COM object.
162          *
163          *  The  COM dialog provided on the startListeneing() call was cached internally.
164          *  And now its used to deregister this listener. Doing so the also internally cached
165          *  listener handle is used. If listener was not already registered - nothing will happen.
166          */
167         void stopListening();
168 
169     public:
170 
171         enum EEventType
172         {
173             E_FILE_SELECTION_CHANGED,
174             E_DIRECTORY_CHANGED,
175             E_HELP_REQUESTED,
176             E_CONTROL_STATE_CHANGED,
177             E_DIALOG_SIZE_CHANGED
178         };
179 
180     private:
181 
182         //------------------------------------------------------------------------------------
183         /// @todo document me
184         void impl_sendEvent(  EEventType eEventType,
185                             ::sal_Int16  nControlID);
186 
187     private:
188 
189         //------------------------------------------------------------------------------------
190         /// ref count for AddRef/Release()
191         oslInterlockedCount m_nRefCount;
192 
193         //------------------------------------------------------------------------------------
194         /// unique handle for this listener provided by the broadcaster on registration time
195         DWORD m_nListenerHandle;
196 
197         //------------------------------------------------------------------------------------
198         /// cached file dialog instance (there we listen for events)
199         TFileDialog m_pDialog;
200 
201         //---------------------------------------------------------------------
202         IVistaFilePickerInternalNotify* m_pInternalNotify;
203 
204         //---------------------------------------------------------------------
205         /** used to inform file picker listener asynchronously.
206          *  Those listener must be called asynchronously .. because
207          *  every request will block the caller thread. Mostly that will be
208          *  the main thread of the office. Further the global SolarMutex will
209          *  be locked during this time. If we call our listener back now synchronously ..
210          *  we will block on SolarMutex.acquire() forever .-))
211          */
212         ::cppu::OMultiTypeInterfaceContainerHelper m_lListener;
213 };
214 
215 } // namespace vista
216 } // namespace win32
217 } // namespace fpicker
218 
219 #undef css
220 
221 #endif  // FPICKER_WIN32_VISTA_FILEPICKER_EVENTHANDLER_HXX
222