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