1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SalAquaPicker.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 //------------------------------------------------------------------------
33 //------------------------------------------------------------------------
35 #include <com/sun/star/lang/DisposedException.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <cppuhelper/interfacecontainer.h>
38 #include <osl/diagnose.h>
39 #include <com/sun/star/uno/Any.hxx>
40 #include <FPServiceInfo.hxx>
41 #include <vos/mutex.hxx>
42 #include <vcl/svapp.hxx>
43 #ifndef _SALAQUAPICKER_HXX_
44 #include "SalAquaPicker.hxx"
46 #include <tools/urlobj.hxx>
47 #include <osl/file.hxx>
48 #include "CFStringUtilities.hxx"
49 #include "NSString_OOoAdditions.hxx"
51 #ifndef _NSURL_OOOADDITIONS_HXX_
52 #include "NSURL_OOoAdditions.hxx"
55 #include "SalAquaFilePicker.hxx"
60 #define CLASS_NAME "SalAquaPicker"
61 #define kSetHideExtensionStateKey @"NSNavLastUserSetHideExtensionButtonState"
63 //------------------------------------------------------------------------
64 // namespace directives
65 //------------------------------------------------------------------------
67 using namespace ::rtl
;
68 using namespace ::com::sun::star
;
69 using namespace ::com::sun::star::lang
;
70 using namespace ::com::sun::star::uno
;
73 SalAquaPicker::SalAquaPicker()
75 , m_pControlHelper(new ControlHelper())
77 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
);
78 DBG_PRINT_EXIT(CLASS_NAME
, __func__
);
81 SalAquaPicker::~SalAquaPicker()
83 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
);
85 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
87 NSAutoreleasePool
*pool
= [NSAutoreleasePool
new];
89 if (NULL
!= m_pControlHelper
)
90 delete m_pControlHelper
;
92 if (NULL
!= m_pDialog
)
97 DBG_PRINT_EXIT(CLASS_NAME
, __func__
);
100 void SAL_CALL
SalAquaPicker::implInitialize()
102 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
);
104 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
106 if (m_pDialog
!= nil
) {
110 switch (m_nDialogType
)
112 case NAVIGATIONSERVICES_OPEN
:
113 OSL_TRACE("NAVIGATIONSERVICES_OPEN");
114 m_pDialog
= [NSOpenPanel openPanel
];
115 [(NSOpenPanel
*)m_pDialog setCanChooseDirectories
:NO
];
116 [(NSOpenPanel
*)m_pDialog setCanChooseFiles
:YES
];
119 case NAVIGATIONSERVICES_SAVE
:
120 OSL_TRACE("NAVIGATIONSERVICES_SAVE");
121 m_pDialog
= [NSSavePanel savePanel
];
122 [(NSSavePanel
*)m_pDialog setCanSelectHiddenExtension
:NO
]; //changed for issue #102102
123 /* I would have loved to use
124 * [(NSSavePanel*)m_pDialog setExtensionHidden:YES];
125 * here but unfortunately this
126 * a) only works when the dialog is already displayed because it seems to act on the corresponding checkbox (that we don't show but that doesn't matter)
127 * b) Mac OS X saves this setting on an application-based level which means that the last state is always being restored again when the app runs for the next time
129 * So the only reliable way seems to be using the NSUserDefaults object because that is where that value is stored and
130 * to just overwrite it if it has the wrong value.
132 NSUserDefaults
*pDefaults
= [NSUserDefaults standardUserDefaults
];
133 NSNumber
*pExtn
= [pDefaults objectForKey
:kSetHideExtensionStateKey
];
134 if(pExtn
== nil
|| [pExtn boolValue
] == NO
) {
135 OSL_TRACE("Hiding extension");
136 [pDefaults setBool
:YES forKey
:kSetHideExtensionStateKey
];
140 case NAVIGATIONSERVICES_DIRECTORY
:
141 OSL_TRACE("NAVIGATIONSERVICES_DIRECTORY");
142 m_pDialog
= [NSOpenPanel openPanel
];
143 [(NSOpenPanel
*)m_pDialog setCanChooseDirectories
:YES
];
144 [(NSOpenPanel
*)m_pDialog setCanChooseFiles
:NO
];
148 OSL_TRACE("m_nDialogType is UNKNOWN: %d", m_nDialogType
);
152 if (m_pDialog
== nil
) {
153 OSL_TRACE("An error occurred while creating the dialog!");
156 [(NSOpenPanel
*)m_pDialog setCanCreateDirectories
:YES
];
157 //Retain the dialog instance or it will go away immediately
161 DBG_PRINT_EXIT(CLASS_NAME
, __func__
);
164 int SalAquaPicker::run()
166 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
);
168 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
170 NSAutoreleasePool
*pool
= [NSAutoreleasePool
new];
172 if (m_pDialog
== NULL
) {
173 //this is the case e.g. for the folder picker at this stage
177 NSView
*userPane
= m_pControlHelper
->getUserPane();
178 if (userPane
!= NULL
) {
179 [m_pDialog setAccessoryView
:userPane
];
184 NSString
*startDirectory
;
185 if (m_sDisplayDirectory
.getLength() > 0) {
186 NSString
*temp
= [NSString stringWithOUString
:m_sDisplayDirectory
];
187 NSURL
*url
= [NSURL URLWithString
:temp
];
188 startDirectory
= [url path
];
190 OSL_TRACE("start dir: %s", [startDirectory UTF8String
]);
191 // NSLog(@"%@", startDirectory);
194 startDirectory
= NSHomeDirectory();
197 switch(m_nDialogType
) {
198 case NAVIGATIONSERVICES_DIRECTORY
:
199 case NAVIGATIONSERVICES_OPEN
:
200 retVal
= [(NSOpenPanel
*)m_pDialog runModalForDirectory
:startDirectory file
:nil types
:nil
];
202 case NAVIGATIONSERVICES_SAVE
:
203 retVal
= [m_pDialog runModalForDirectory
:startDirectory file
:[NSString stringWithOUString
:((SalAquaFilePicker
*)this)->getSaveFileName()]/*[m_pDialog saveFilename]*/];
205 // [m_pDialog beginSheetForDirectory:startDirectory file:[m_pDialog saveFilename] modalForWindow:[NSApp keyWindow] modalDelegate:((SalAquaFilePicker*)this)->getDelegate() didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
210 if (retVal
== NSFileHandlingPanelOKButton
) {
211 implsetDisplayDirectory([[NSURL fileURLWithPath
:[m_pDialog directory
]] OUStringForInfo
:FULLPATH
]);
214 DBG_PRINT_EXIT(CLASS_NAME
, __func__
, retVal
);
221 int SalAquaPicker::runandwaitforresult()
223 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
);
225 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
227 int status
= this->run();
229 DBG_PRINT_EXIT(CLASS_NAME
, __func__
, status
);
233 void SAL_CALL
SalAquaPicker::implsetDisplayDirectory( const rtl::OUString
& aDirectory
)
234 throw( lang::IllegalArgumentException
, uno::RuntimeException
)
236 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
, "directory", aDirectory
);
238 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
240 if (aDirectory
!= m_sDisplayDirectory
) {
241 m_sDisplayDirectory
= aDirectory
;
244 DBG_PRINT_EXIT(CLASS_NAME
, __func__
);
247 rtl::OUString SAL_CALL
SalAquaPicker::implgetDisplayDirectory() throw( uno::RuntimeException
)
249 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
);
250 DBG_PRINT_EXIT(CLASS_NAME
, __func__
, m_sDisplayDirectory
);
252 return m_sDisplayDirectory
;
255 void SAL_CALL
SalAquaPicker::implsetTitle( const rtl::OUString
& aTitle
) throw( uno::RuntimeException
)
257 DBG_PRINT_ENTRY(CLASS_NAME
, __func__
, "title", aTitle
);
259 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
261 if (m_pDialog
!= nil
) {
262 [m_pDialog setTitle
:[NSString stringWithOUString
:aTitle
]];
265 DBG_PRINT_EXIT(CLASS_NAME
, __func__
);