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 //------------------------------------------------------------------------
25 // includes
26 //------------------------------------------------------------------------
27 
28 #include <com/sun/star/lang/DisposedException.hpp>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
31 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
32 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
33 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
34 #include <cppuhelper/interfacecontainer.h>
35 #include <osl/diagnose.h>
36 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
37 #include <com/sun/star/uno/Any.hxx>
38 #include <FPServiceInfo.hxx>
39 #include <vos/mutex.hxx>
40 #include <vcl/svapp.hxx>
41 #include "SalAquaFolderPicker.hxx"
42 
43 #include <tools/urlobj.hxx>
44 #include <iostream>
45 
46 #include "resourceprovider.hxx"
47 
48 #ifndef _SV_RC_H
49 #include <tools/rc.hxx>
50 #endif
51 
52 #include <osl/file.hxx>
53 #include "CFStringUtilities.hxx"
54 #include "NSString_OOoAdditions.hxx"
55 #include "NSURL_OOoAdditions.hxx"
56 
57 #pragma mark DEFINES
58 #define CLASS_NAME "SalAquaFolderPicker"
59 
60 //------------------------------------------------------------------------
61 // namespace directives
62 //------------------------------------------------------------------------
63 
64 using namespace ::rtl;
65 using namespace ::com::sun::star;
66 using namespace ::com::sun::star::ui::dialogs;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::uno;
69 
70 //------------------------------------------------------------------------
71 // helper functions
72 //------------------------------------------------------------------------
73 
74 namespace
75 {
76     // controlling event notifications
FolderPicker_getSupportedServiceNames()77     uno::Sequence<rtl::OUString> SAL_CALL FolderPicker_getSupportedServiceNames()
78     {
79         uno::Sequence<rtl::OUString> aRet(2);
80         aRet[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.SystemFolderPicker" );
81         aRet[1] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.AquaFolderPicker" );
82         return aRet;
83     }
84 }
85 
86 //-----------------------------------------------------------------------------------------
87 // constructor
88 //-----------------------------------------------------------------------------------------
SalAquaFolderPicker(const uno::Reference<lang::XMultiServiceFactory> & xServiceMgr)89 SalAquaFolderPicker::SalAquaFolderPicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) :
90     m_xServiceMgr( xServiceMgr )
91 {
92     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
93 
94     m_nDialogType = NAVIGATIONSERVICES_DIRECTORY;
95 
96     DBG_PRINT_EXIT(CLASS_NAME, __func__);
97 }
98 
99 //-----------------------------------------------------------------------------------------
100 // XExecutableDialog functions
101 //-----------------------------------------------------------------------------------------
102 
setTitle(const rtl::OUString & aTitle)103 void SAL_CALL SalAquaFolderPicker::setTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
104 {
105     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);
106 
107     ::vos::OGuard aGuard( Application::GetSolarMutex() );
108 
109     implsetTitle(aTitle);
110 
111     DBG_PRINT_EXIT(CLASS_NAME, __func__);
112 }
113 
execute()114 sal_Int16 SAL_CALL SalAquaFolderPicker::execute() throw( uno::RuntimeException )
115 {
116     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
117 
118     ::vos::OGuard aGuard( Application::GetSolarMutex() );
119 
120     sal_Int16 retVal = 0;
121 
122     int nResult = runandwaitforresult();
123 
124     switch( nResult )
125     {
126     case NSOKButton:
127         OSL_TRACE("Dialog returned with OK");
128         retVal = ExecutableDialogResults::OK;
129         break;
130 
131     case NSCancelButton:
132         OSL_TRACE("Dialog was cancelled!");
133         retVal = ExecutableDialogResults::CANCEL;
134         break;
135 
136     default:
137         throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog returned with an unknown result!"), static_cast< XFolderPicker* >( this ));
138         break;
139     }
140 
141     DBG_PRINT_EXIT(CLASS_NAME, __func__);
142     return retVal;
143 }
144 
145 //------------------------------------------------------------------------------------
146 // XFolderPicker functions
147 //------------------------------------------------------------------------------------
148 
setDisplayDirectory(const rtl::OUString & aDirectory)149 void SAL_CALL SalAquaFolderPicker::setDisplayDirectory( const rtl::OUString& aDirectory )
150     throw( lang::IllegalArgumentException, uno::RuntimeException )
151 {
152     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", aDirectory);
153 
154     ::vos::OGuard aGuard( Application::GetSolarMutex() );
155 
156     implsetDisplayDirectory(aDirectory);
157 
158     DBG_PRINT_EXIT(CLASS_NAME, __func__);
159 }
160 
getDisplayDirectory()161 rtl::OUString SAL_CALL SalAquaFolderPicker::getDisplayDirectory() throw( uno::RuntimeException )
162 {
163     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
164 
165     ::vos::OGuard aGuard( Application::GetSolarMutex() );
166 
167     OUString aDirectory = implgetDisplayDirectory();
168 
169     DBG_PRINT_EXIT(CLASS_NAME, __func__, aDirectory);
170 
171     return aDirectory;
172 }
173 
getDirectory()174 rtl::OUString SAL_CALL SalAquaFolderPicker::getDirectory() throw( uno::RuntimeException )
175 {
176     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
177 
178     ::vos::OGuard aGuard( Application::GetSolarMutex() );
179 
180     NSArray *files = nil;
181     if (m_nDialogType == NAVIGATIONSERVICES_DIRECTORY) {
182         files = [(NSOpenPanel*)m_pDialog URLs];
183     }
184 
185     long nFiles = [files count];
186     OSL_TRACE("# of items: %d", nFiles);
187 
188     if (nFiles < 1) {
189         throw uno::RuntimeException(rtl::OUString::createFromAscii("no directory selected"), static_cast< XFolderPicker* >( this ));
190     }
191 
192     rtl::OUString aDirectory;
193 
194     NSURL *url = [files objectAtIndex:0];
195     OSL_TRACE("handling %s", [[url description] UTF8String]);
196 
197     aDirectory = [url OUStringForInfo:FULLPATH];
198 
199     implsetDisplayDirectory(aDirectory);
200 
201     OSL_TRACE("dir url: %s", OUStringToOString(aDirectory, RTL_TEXTENCODING_UTF8).getStr());
202 
203     DBG_PRINT_EXIT(CLASS_NAME, __func__);
204     return aDirectory;
205 }
206 
setDescription(const rtl::OUString & rDescription)207 void SAL_CALL SalAquaFolderPicker::setDescription( const rtl::OUString& rDescription )
208     throw( uno::RuntimeException )
209 {
210     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "description", rDescription);
211 
212     [m_pDialog setMessage:[NSString stringWithOUString:rDescription]];
213 
214     DBG_PRINT_EXIT(CLASS_NAME, __func__);
215 }
216 
217 // -------------------------------------------------
218 // XServiceInfo
219 // -------------------------------------------------
220 
getImplementationName()221 rtl::OUString SAL_CALL SalAquaFolderPicker::getImplementationName()
222     throw( uno::RuntimeException )
223 {
224     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
225 
226     rtl::OUString retVal = rtl::OUString::createFromAscii( FOLDER_PICKER_IMPL_NAME );
227 
228     DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
229 
230     return retVal;
231 }
232 
supportsService(const rtl::OUString & sServiceName)233 sal_Bool SAL_CALL SalAquaFolderPicker::supportsService( const rtl::OUString& sServiceName )
234     throw( uno::RuntimeException )
235 {
236     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "serviceName", sServiceName);
237 
238     sal_Bool retVal = sal_False;
239     uno::Sequence <rtl::OUString> supportedServicesNames = FolderPicker_getSupportedServiceNames();
240 
241     for( sal_Int32 n = supportedServicesNames.getLength(); n--; ) {
242         if( supportedServicesNames[n].compareTo( sServiceName ) == 0) {
243             retVal = sal_True;
244             break;
245         }
246     }
247 
248     DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
249     return retVal;
250 }
251 
getSupportedServiceNames()252 uno::Sequence<rtl::OUString> SAL_CALL SalAquaFolderPicker::getSupportedServiceNames()
253     throw( uno::RuntimeException )
254 {
255     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
256     DBG_PRINT_EXIT(CLASS_NAME, __func__);
257 
258     return FolderPicker_getSupportedServiceNames();
259 }
260 
261 //------------------------------------------------------------------------------------
262 // XCancellable
263 //------------------------------------------------------------------------------------
264 
cancel()265 void SAL_CALL SalAquaFolderPicker::cancel() throw( uno::RuntimeException )
266 {
267     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
268 
269     ::vos::OGuard aGuard( Application::GetSolarMutex() );
270 
271     [m_pDialog cancel:nil];
272 
273     DBG_PRINT_EXIT(CLASS_NAME, __func__);
274 }
275 
276 // -------------------------------------------------
277 // XEventListener
278 // -------------------------------------------------
279 
disposing(const lang::EventObject &)280 void SAL_CALL SalAquaFolderPicker::disposing( const lang::EventObject& )
281     throw( uno::RuntimeException )
282 {
283     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
284     DBG_PRINT_EXIT(CLASS_NAME, __func__);
285 }
286