Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <shutdownicon.hxx>
21 : : #include <app.hrc>
22 : : #include <sfx2/app.hxx>
23 : : #include <osl/mutex.hxx>
24 : : #include <svtools/imagemgr.hxx>
25 : : #include <svtools/miscopt.hxx>
26 : : #include <com/sun/star/task/XInteractionHandler.hpp>
27 : : #include <com/sun/star/frame/XDispatchResultListener.hpp>
28 : : #include <com/sun/star/frame/XNotifyingDispatch.hpp>
29 : : #include <com/sun/star/frame/XFramesSupplier.hpp>
30 : : #include <com/sun/star/frame/XComponentLoader.hpp>
31 : : #include <com/sun/star/frame/XFrame.hpp>
32 : : #include <com/sun/star/util/URLTransformer.hpp>
33 : : #include <com/sun/star/util/XURLTransformer.hpp>
34 : : #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
35 : : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
36 : : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
37 : : #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
38 : : #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
39 : : #include <com/sun/star/ui/dialogs/ControlActions.hpp>
40 : : #include <com/sun/star/document/MacroExecMode.hpp>
41 : : #include <com/sun/star/document/UpdateDocMode.hpp>
42 : : #include <sfx2/filedlghelper.hxx>
43 : : #include <sfx2/fcontnr.hxx>
44 : : #include <comphelper/processfactory.hxx>
45 : : #include <cppuhelper/compbase1.hxx>
46 : : #include <sfx2/dispatch.hxx>
47 : : #include <comphelper/extract.hxx>
48 : : #include <tools/urlobj.hxx>
49 : : #include <osl/security.hxx>
50 : : #include <osl/file.hxx>
51 : : #include <rtl/bootstrap.hxx>
52 : : #include <rtl/ustrbuf.hxx>
53 : : #ifdef UNX // need symlink
54 : : #include <unistd.h>
55 : : #include <errno.h>
56 : : #endif
57 : : #include <vcl/timer.hxx>
58 : :
59 : : #include "sfx2/sfxresid.hxx"
60 : :
61 : : using namespace ::com::sun::star;
62 : : using namespace ::com::sun::star::uno;
63 : : using namespace ::com::sun::star::frame;
64 : : using namespace ::com::sun::star::container;
65 : : using namespace ::com::sun::star::io;
66 : : using namespace ::com::sun::star::lang;
67 : : using namespace ::com::sun::star::beans;
68 : : using namespace ::com::sun::star::util;
69 : : using namespace ::com::sun::star::ui::dialogs;
70 : : #ifdef WNT
71 : : using ::rtl::OUString;
72 : : #else
73 : : using namespace ::rtl;
74 : : #endif
75 : : using namespace ::sfx2;
76 : :
77 : : #ifdef ENABLE_QUICKSTART_APPLET
78 : : # if !defined(WIN32) && !defined(QUARTZ)
79 : 0 : extern "C" { static void SAL_CALL thisModule() {} }
80 : : # endif
81 : : #endif
82 : :
83 : : #if defined(UNX) && defined(ENABLE_SYSTRAY_GTK) && !defined(PLUGIN_NAME)
84 : : #define PLUGIN_NAME "libqstart_gtklo.so"
85 : : #endif
86 : :
87 [ # # ]: 0 : class SfxNotificationListener_Impl : public cppu::WeakImplHelper1< XDispatchResultListener >
88 : : {
89 : : public:
90 : : virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& aEvent ) throw( RuntimeException );
91 : : virtual void SAL_CALL disposing( const EventObject& aEvent ) throw( RuntimeException );
92 : : };
93 : :
94 : 0 : void SAL_CALL SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
95 : : {
96 : 0 : ShutdownIcon::LeaveModalMode();
97 : 0 : }
98 : :
99 : 0 : void SAL_CALL SfxNotificationListener_Impl::disposing( const EventObject& ) throw( RuntimeException )
100 : : {
101 : 0 : }
102 : :
103 [ # # ][ # # ]: 546 : SFX_IMPL_XSERVICEINFO( ShutdownIcon, "com.sun.star.office.Quickstart", "com.sun.star.comp.desktop.QuickstartWrapper" ) \
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
104 [ # # ][ # # ]: 0 : SFX_IMPL_ONEINSTANCEFACTORY( ShutdownIcon );
[ # # ]
105 : :
106 : : bool ShutdownIcon::bModalMode = false;
107 : : ShutdownIcon* ShutdownIcon::pShutdownIcon = NULL;
108 : :
109 : : #if !defined( ENABLE_QUICKSTART_APPLET ) || defined( UNX )
110 : : // To remove conditionals
111 : : extern "C" {
112 : 0 : static void disabled_initSystray() { }
113 : 0 : static void disabled_deInitSystray() { }
114 : : }
115 : : #endif
116 : :
117 : : #define DOSTRING( x ) #x
118 : : #define STRING( x ) DOSTRING( x )
119 : :
120 : 0 : bool ShutdownIcon::LoadModule( osl::Module **pModule,
121 : : oslGenericFunction *pInit,
122 : : oslGenericFunction *pDeInit )
123 : : {
124 [ # # ]: 0 : if ( pModule )
125 : : {
126 : : OSL_ASSERT ( pInit && pDeInit );
127 : 0 : *pInit = *pDeInit = NULL;
128 : 0 : *pModule = NULL;
129 : : }
130 : :
131 : : #ifdef ENABLE_QUICKSTART_APPLET
132 : : # ifdef WIN32
133 : : if ( pModule )
134 : : {
135 : : *pInit = win32_init_sys_tray;
136 : : *pDeInit = win32_shutdown_sys_tray;
137 : : }
138 : : return true;
139 : : # elif defined QUARTZ
140 : : *pInit = aqua_init_systray;
141 : : *pDeInit = aqua_shutdown_systray;
142 : : return true;
143 : : # else // UNX
144 : : osl::Module *pPlugin;
145 : 0 : pPlugin = new osl::Module();
146 : :
147 : 0 : oslGenericFunction pTmpInit = NULL;
148 : 0 : oslGenericFunction pTmpDeInit = NULL;
149 [ # # ][ # # ]: 0 : if ( pPlugin->loadRelative( &thisModule, OUString (STRING( PLUGIN_NAME ) ) ) )
150 : : {
151 : : pTmpInit = pPlugin->getFunctionSymbol(
152 [ # # ]: 0 : OUString( "plugin_init_sys_tray" ) );
153 : : pTmpDeInit = pPlugin->getFunctionSymbol(
154 [ # # ]: 0 : OUString( "plugin_shutdown_sys_tray" ) );
155 : : }
156 [ # # ][ # # ]: 0 : if ( !pTmpInit || !pTmpDeInit )
157 : : {
158 [ # # ]: 0 : delete pPlugin;
159 : 0 : pPlugin = NULL;
160 : : }
161 [ # # ]: 0 : if ( pModule )
162 : : {
163 : 0 : *pModule = pPlugin;
164 : 0 : *pInit = pTmpInit;
165 : 0 : *pDeInit = pTmpDeInit;
166 : : }
167 : : else
168 : : {
169 : 0 : bool bRet = pPlugin != NULL;
170 [ # # ]: 0 : delete pPlugin;
171 : 0 : return bRet;
172 : : }
173 : : # endif // UNX
174 : : #endif // ENABLE_QUICKSTART_APPLET
175 : :
176 : : #if !defined( ENABLE_QUICKSTART_APPLET ) || defined( UNX )
177 : : // Avoid unreachable code. In the ENABLE_QUICKSTART_APPLET && !UNX
178 : : // case, we have already returned.
179 [ # # ]: 0 : if ( pModule )
180 : : {
181 [ # # ]: 0 : if ( !*pInit )
182 : 0 : *pInit = disabled_initSystray;
183 [ # # ]: 0 : if ( !*pDeInit )
184 : 0 : *pDeInit = disabled_deInitSystray;
185 : : }
186 : :
187 : 0 : return true;
188 : : #endif // !ENABLE_QUICKSTART_APPLET || UNX
189 : : }
190 : :
191 : : // These two timeouts are necessary to avoid there being
192 : : // plugin frames still on the stack, after unloading that
193 : : // code, causing a crash during disabling / termination.
194 [ # # ]: 0 : class IdleUnloader : Timer
195 : : {
196 : : ::osl::Module *m_pModule;
197 : : public:
198 : 0 : IdleUnloader (::osl::Module **pModule) :
199 : 0 : m_pModule (*pModule)
200 : : {
201 : 0 : *pModule = NULL;
202 [ # # ]: 0 : Start();
203 : 0 : }
204 : 0 : virtual void Timeout()
205 : : {
206 [ # # ]: 0 : delete m_pModule;
207 [ # # ]: 0 : delete this;
208 : 0 : }
209 : : };
210 : :
211 [ # # ]: 0 : class IdleTerminate : Timer
212 : : {
213 : : Reference< XDesktop > m_xDesktop;
214 : : public:
215 : 0 : IdleTerminate (Reference< XDesktop > xDesktop)
216 : 0 : {
217 [ # # ]: 0 : m_xDesktop = xDesktop;
218 [ # # ]: 0 : Start();
219 : 0 : }
220 : 0 : virtual void Timeout()
221 : : {
222 : 0 : m_xDesktop->terminate();
223 [ # # ]: 0 : delete this;
224 : 0 : }
225 : : };
226 : :
227 : 0 : void ShutdownIcon::initSystray()
228 : : {
229 [ # # ]: 0 : if (m_bInitialized)
230 : 0 : return;
231 : 0 : m_bInitialized = true;
232 : :
233 : 0 : (void) LoadModule( &m_pPlugin, &m_pInitSystray, &m_pDeInitSystray );
234 : 0 : m_bVeto = true;
235 : 0 : m_pInitSystray();
236 : : }
237 : :
238 : 0 : void ShutdownIcon::deInitSystray()
239 : : {
240 [ # # ]: 0 : if (!m_bInitialized)
241 : 0 : return;
242 : :
243 [ # # ]: 0 : if (m_pDeInitSystray)
244 : 0 : m_pDeInitSystray();
245 : :
246 : 0 : m_bVeto = false;
247 : 0 : m_pInitSystray = 0;
248 : 0 : m_pDeInitSystray = 0;
249 [ # # ]: 0 : new IdleUnloader (&m_pPlugin);
250 : :
251 [ # # ]: 0 : delete m_pFileDlg;
252 : 0 : m_pFileDlg = NULL;
253 : 0 : m_bInitialized = false;
254 : : }
255 : :
256 : :
257 : 0 : ShutdownIcon::ShutdownIcon( Reference< XMultiServiceFactory > aSMgr ) :
258 : : ShutdownIconServiceBase( m_aMutex ),
259 : : m_bVeto ( false ),
260 : : m_bListenForTermination ( false ),
261 : : m_bSystemDialogs( false ),
262 : : m_pResMgr( NULL ),
263 : : m_pFileDlg( NULL ),
264 : : m_xServiceManager( aSMgr ),
265 : : m_pInitSystray( 0 ),
266 : : m_pDeInitSystray( 0 ),
267 : : m_pPlugin( 0 ),
268 [ # # ]: 0 : m_bInitialized( false )
269 : : {
270 [ # # ][ # # ]: 0 : m_bSystemDialogs = SvtMiscOptions().UseSystemFileDialog();
[ # # ]
271 : 0 : }
272 : :
273 [ # # ]: 0 : ShutdownIcon::~ShutdownIcon()
274 : : {
275 [ # # ]: 0 : deInitSystray();
276 [ # # ][ # # ]: 0 : new IdleUnloader (&m_pPlugin);
277 [ # # ]: 0 : }
278 : :
279 : : // ---------------------------------------------------------------------------
280 : :
281 : 0 : void ShutdownIcon::OpenURL( const ::rtl::OUString& aURL, const ::rtl::OUString& rTarget, const Sequence< PropertyValue >& aArgs )
282 : : {
283 [ # # ][ # # ]: 0 : if ( getInstance() && getInstance()->m_xDesktop.is() )
[ # # ]
284 : : {
285 [ # # ][ # # ]: 0 : Reference < XDispatchProvider > xDispatchProvider( getInstance()->m_xDesktop, UNO_QUERY );
286 [ # # ]: 0 : if ( xDispatchProvider.is() )
287 : : {
288 : 0 : com::sun::star::util::URL aDispatchURL;
289 : 0 : aDispatchURL.Complete = aURL;
290 : :
291 [ # # ][ # # ]: 0 : Reference< util::XURLTransformer > xURLTransformer( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
292 : : try
293 : : {
294 : 0 : Reference< com::sun::star::frame::XDispatch > xDispatch;
295 : :
296 [ # # ][ # # ]: 0 : xURLTransformer->parseStrict( aDispatchURL );
297 [ # # ][ # # ]: 0 : xDispatch = xDispatchProvider->queryDispatch( aDispatchURL, rTarget, 0 );
[ # # ]
298 [ # # ]: 0 : if ( xDispatch.is() )
299 [ # # ][ # # ]: 0 : xDispatch->dispatch( aDispatchURL, aArgs );
300 : : }
301 [ # # # ]: 0 : catch ( com::sun::star::uno::RuntimeException& )
302 : : {
303 : 0 : throw;
304 : : }
305 [ # # ]: 0 : catch ( com::sun::star::uno::Exception& )
306 : : {
307 : 0 : }
308 : 0 : }
309 : : }
310 : 0 : }
311 : :
312 : : // ---------------------------------------------------------------------------
313 : :
314 : 0 : void ShutdownIcon::FileOpen()
315 : : {
316 [ # # ][ # # ]: 0 : if ( getInstance() && getInstance()->m_xDesktop.is() )
[ # # ]
317 : : {
318 [ # # ]: 0 : ::SolarMutexGuard aGuard;
319 [ # # ]: 0 : EnterModalMode();
320 [ # # ][ # # ]: 0 : getInstance()->StartFileDialog();
[ # # ]
321 : : }
322 : 0 : }
323 : :
324 : : // ---------------------------------------------------------------------------
325 : :
326 : 0 : void ShutdownIcon::FromTemplate()
327 : : {
328 [ # # ][ # # ]: 0 : if ( getInstance() && getInstance()->m_xDesktop.is() )
[ # # ]
329 : : {
330 [ # # ][ # # ]: 0 : Reference < ::com::sun::star::frame::XFramesSupplier > xDesktop ( getInstance()->m_xDesktop, UNO_QUERY);
331 [ # # ][ # # ]: 0 : Reference < ::com::sun::star::frame::XFrame > xFrame( xDesktop->getActiveFrame() );
332 [ # # ]: 0 : if ( !xFrame.is() )
333 [ # # ][ # # ]: 0 : xFrame = Reference < ::com::sun::star::frame::XFrame >( xDesktop, UNO_QUERY );
334 : :
335 : 0 : URL aTargetURL;
336 : 0 : aTargetURL.Complete = OUString( "slot:5500" );
337 [ # # ][ # # ]: 0 : Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
338 [ # # ][ # # ]: 0 : xTrans->parseStrict( aTargetURL );
339 : :
340 [ # # ]: 0 : Reference < ::com::sun::star::frame::XDispatchProvider > xProv( xFrame, UNO_QUERY );
341 : 0 : Reference < ::com::sun::star::frame::XDispatch > xDisp;
342 [ # # ]: 0 : if ( xProv.is() )
343 : : {
344 [ # # ]: 0 : if ( aTargetURL.Protocol.compareToAscii("slot:") == COMPARE_EQUAL )
345 [ # # ][ # # ]: 0 : xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
[ # # ]
346 : : else
347 [ # # ][ # # ]: 0 : xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString("_blank"), 0 );
[ # # ]
348 : : }
349 [ # # ]: 0 : if ( xDisp.is() )
350 : : {
351 [ # # ]: 0 : Sequence<PropertyValue> aArgs(1);
352 [ # # ]: 0 : PropertyValue* pArg = aArgs.getArray();
353 : 0 : pArg[0].Name = rtl::OUString("Referer");
354 [ # # ]: 0 : pArg[0].Value <<= ::rtl::OUString("private:user");
355 [ # # ]: 0 : Reference< ::com::sun::star::frame::XNotifyingDispatch > xNotifyer( xDisp, UNO_QUERY );
356 [ # # ]: 0 : if ( xNotifyer.is() )
357 : : {
358 [ # # ]: 0 : EnterModalMode();
359 [ # # ][ # # ]: 0 : xNotifyer->dispatchWithNotification( aTargetURL, aArgs, new SfxNotificationListener_Impl() );
[ # # ][ # # ]
[ # # ]
360 : : }
361 : : else
362 [ # # ][ # # ]: 0 : xDisp->dispatch( aTargetURL, aArgs );
[ # # ]
363 : 0 : }
364 : : }
365 : 0 : }
366 : :
367 : : // ---------------------------------------------------------------------------
368 : : #include <tools/rcid.h>
369 : 0 : OUString ShutdownIcon::GetResString( int id )
370 : : {
371 [ # # ]: 0 : ::SolarMutexGuard aGuard;
372 : :
373 [ # # ]: 0 : if( ! m_pResMgr )
374 [ # # ]: 0 : m_pResMgr = SfxResId::GetResMgr();
375 : 0 : ResId aResId( id, *m_pResMgr );
376 : 0 : aResId.SetRT( RSC_STRING );
377 [ # # ][ # # ]: 0 : if( !m_pResMgr || !m_pResMgr->IsAvailable( aResId ) )
[ # # ][ # # ]
378 : 0 : return OUString();
379 : :
380 [ # # ][ # # ]: 0 : return ResId(id, *m_pResMgr).toString();
381 : : }
382 : :
383 : : // ---------------------------------------------------------------------------
384 : :
385 : 0 : OUString ShutdownIcon::GetUrlDescription( const OUString& aUrl )
386 : : {
387 [ # # ]: 0 : ::SolarMutexGuard aGuard;
388 : :
389 [ # # ][ # # ]: 0 : return OUString( SvFileInformationManager::GetDescription( INetURLObject( aUrl ) ) );
[ # # ][ # # ]
[ # # ][ # # ]
390 : : }
391 : :
392 : : // ---------------------------------------------------------------------------
393 : :
394 : 0 : void ShutdownIcon::StartFileDialog()
395 : : {
396 [ # # ]: 0 : ::SolarMutexGuard aGuard;
397 : :
398 [ # # ][ # # ]: 0 : bool bDirty = ( m_bSystemDialogs != static_cast<bool>(SvtMiscOptions().UseSystemFileDialog()) );
[ # # ]
399 : :
400 [ # # ][ # # ]: 0 : if ( m_pFileDlg && bDirty )
401 : : {
402 : : // Destroy instance as changing the system file dialog setting
403 : : // forces us to create a new FileDialogHelper instance!
404 [ # # ][ # # ]: 0 : delete m_pFileDlg;
405 : 0 : m_pFileDlg = NULL;
406 : : }
407 : :
408 [ # # ]: 0 : if ( !m_pFileDlg )
409 : : m_pFileDlg = new FileDialogHelper(
410 : : ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
411 [ # # ][ # # ]: 0 : SFXWB_MULTISELECTION, String() );
[ # # ][ # # ]
412 [ # # ][ # # ]: 0 : m_pFileDlg->StartExecuteModal( STATIC_LINK( this, ShutdownIcon, DialogClosedHdl_Impl ) );
[ # # ]
413 : 0 : }
414 : :
415 : : // ---------------------------------------------------------------------------
416 : :
417 : 0 : IMPL_STATIC_LINK( ShutdownIcon, DialogClosedHdl_Impl, FileDialogHelper*, EMPTYARG )
418 : : {
419 : : DBG_ASSERT( pThis->m_pFileDlg, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" );
420 : :
421 : : // use constructor for filling up filters automatically!
422 [ # # ]: 0 : if ( ERRCODE_NONE == pThis->m_pFileDlg->GetError() )
423 : : {
424 [ # # ]: 0 : Reference< XFilePicker > xPicker = pThis->m_pFileDlg->GetFilePicker();
425 : :
426 : : try
427 : : {
428 : :
429 [ # # ]: 0 : if ( xPicker.is() )
430 : : {
431 : :
432 [ # # ]: 0 : Reference < XFilePickerControlAccess > xPickerControls ( xPicker, UNO_QUERY );
433 [ # # ]: 0 : Reference < XFilterManager > xFilterManager ( xPicker, UNO_QUERY );
434 : :
435 [ # # ][ # # ]: 0 : Sequence< OUString > sFiles = xPicker->getFiles();
436 : 0 : int nFiles = sFiles.getLength();
437 : :
438 : 0 : int nArgs=3;
439 [ # # ]: 0 : Sequence< PropertyValue > aArgs(3);
440 : :
441 : : Reference < com::sun::star::task::XInteractionHandler > xInteraction(
442 [ # # ][ # # ]: 0 : ::comphelper::getProcessServiceFactory()->createInstance( OUString("com.sun.star.task.InteractionHandler") ),
443 [ # # ][ # # ]: 0 : com::sun::star::uno::UNO_QUERY );
444 : :
445 [ # # ]: 0 : aArgs[0].Name = OUString("InteractionHandler");
446 [ # # ][ # # ]: 0 : aArgs[0].Value <<= xInteraction;
447 : :
448 : 0 : sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
449 [ # # ]: 0 : aArgs[1].Name = OUString("MacroExecutionMode");
450 [ # # ][ # # ]: 0 : aArgs[1].Value <<= nMacroExecMode;
451 : :
452 : 0 : sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
453 [ # # ]: 0 : aArgs[2].Name = OUString("UpdateDocMode");
454 [ # # ][ # # ]: 0 : aArgs[2].Value <<= nUpdateDoc;
455 : :
456 : : // use the filedlghelper to get the current filter name,
457 : : // because it removes the extensions before you get the filter name.
458 [ # # ][ # # ]: 0 : OUString aFilterName( pThis->m_pFileDlg->GetCurrentFilter() );
[ # # ]
459 : :
460 [ # # ]: 0 : if ( xPickerControls.is() )
461 : : {
462 : :
463 : : // Set readonly flag
464 : :
465 : 0 : sal_Bool bReadOnly = sal_False;
466 : :
467 : :
468 [ # # ][ # # ]: 0 : xPickerControls->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ) >>= bReadOnly;
469 : :
470 : : // Only set porperty if readonly is set to TRUE
471 : :
472 [ # # ]: 0 : if ( bReadOnly )
473 : : {
474 [ # # ]: 0 : aArgs.realloc( ++nArgs );
475 [ # # ]: 0 : aArgs[nArgs-1].Name = OUString("ReadOnly");
476 [ # # ][ # # ]: 0 : aArgs[nArgs-1].Value <<= bReadOnly;
477 : : }
478 : :
479 : : // Get version string
480 : :
481 : 0 : sal_Int32 iVersion = -1;
482 : :
483 [ # # ][ # # ]: 0 : xPickerControls->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, ControlActions::GET_SELECTED_ITEM_INDEX ) >>= iVersion;
484 : :
485 [ # # ]: 0 : if ( iVersion >= 0 )
486 : : {
487 : 0 : sal_Int16 uVersion = (sal_Int16)iVersion;
488 : :
489 [ # # ]: 0 : aArgs.realloc( ++nArgs );
490 [ # # ]: 0 : aArgs[nArgs-1].Name = OUString("Version");
491 [ # # ][ # # ]: 0 : aArgs[nArgs-1].Value <<= uVersion;
492 : : }
493 : :
494 : : // Retrieve the current filter
495 : :
496 [ # # ]: 0 : if ( aFilterName.isEmpty() )
497 [ # # ][ # # ]: 0 : xPickerControls->getValue( CommonFilePickerElementIds::LISTBOX_FILTER, ControlActions::GET_SELECTED_ITEM ) >>= aFilterName;
498 : :
499 : : }
500 : :
501 : :
502 : : // Convert UI filter name to internal filter name
503 : :
504 [ # # ]: 0 : if ( !aFilterName.isEmpty() )
505 : : {
506 [ # # ][ # # ]: 0 : const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4UIName( aFilterName, 0, SFX_FILTER_NOTINFILEDLG );
[ # # ][ # # ]
[ # # ]
507 : :
508 [ # # ]: 0 : if ( pFilter )
509 : : {
510 [ # # ]: 0 : aFilterName = pFilter->GetFilterName();
511 : :
512 [ # # ]: 0 : if ( !aFilterName.isEmpty() )
513 : : {
514 [ # # ]: 0 : aArgs.realloc( ++nArgs );
515 [ # # ]: 0 : aArgs[nArgs-1].Name = OUString("FilterName");
516 [ # # ][ # # ]: 0 : aArgs[nArgs-1].Value <<= aFilterName;
517 : : }
518 : : }
519 : : }
520 : :
521 [ # # ]: 0 : if ( 1 == nFiles )
522 [ # # ][ # # ]: 0 : OpenURL( sFiles[0], OUString( "_default" ), aArgs );
523 : : else
524 : : {
525 [ # # ]: 0 : OUString aBaseDirURL = sFiles[0];
526 [ # # ][ # # ]: 0 : if ( !aBaseDirURL.isEmpty() && aBaseDirURL[aBaseDirURL.getLength()-1] != '/' )
[ # # ]
527 : 0 : aBaseDirURL += OUString("/");
528 : :
529 : : int iFiles;
530 [ # # ]: 0 : for ( iFiles = 1; iFiles < nFiles; iFiles++ )
531 : : {
532 : 0 : OUString aURL = aBaseDirURL;
533 [ # # ]: 0 : aURL += sFiles[iFiles];
534 [ # # ]: 0 : OpenURL( aURL, OUString( "_default" ), aArgs );
535 : 0 : }
536 [ # # ][ # # ]: 0 : }
537 : : }
538 : : }
539 [ # # ]: 0 : catch ( ... )
540 : : {
541 : 0 : }
542 : : }
543 : :
544 : : #ifdef WNT
545 : : // Destroy dialog to prevent problems with custom controls
546 : : // This fix is dependent on the dialog settings. Destroying the dialog here will
547 : : // crash the non-native dialog implementation! Therefore make this dependent on
548 : : // the settings.
549 : : if ( SvtMiscOptions().UseSystemFileDialog() )
550 : : {
551 : : delete pThis->m_pFileDlg;
552 : : pThis->m_pFileDlg = NULL;
553 : : }
554 : : #endif
555 : :
556 : 0 : LeaveModalMode();
557 : 0 : return 0;
558 : : }
559 : :
560 : : // ---------------------------------------------------------------------------
561 : :
562 : 0 : void ShutdownIcon::addTerminateListener()
563 : : {
564 [ # # ]: 0 : ShutdownIcon* pInst = getInstance();
565 [ # # ]: 0 : if ( ! pInst)
566 : : return;
567 : :
568 [ # # ]: 0 : if (pInst->m_bListenForTermination)
569 : : return;
570 : :
571 : 0 : Reference< XDesktop > xDesktop = pInst->m_xDesktop;
572 [ # # ]: 0 : if ( ! xDesktop.is())
573 : : return;
574 : :
575 [ # # ][ # # ]: 0 : xDesktop->addTerminateListener( pInst );
[ # # ][ # # ]
576 [ # # ]: 0 : pInst->m_bListenForTermination = true;
577 : : }
578 : :
579 : : // ---------------------------------------------------------------------------
580 : :
581 : 0 : void ShutdownIcon::terminateDesktop()
582 : : {
583 [ # # ]: 0 : ShutdownIcon* pInst = getInstance();
584 [ # # ]: 0 : if ( ! pInst)
585 : : return;
586 : :
587 : 0 : Reference< XDesktop > xDesktop = pInst->m_xDesktop;
588 [ # # ]: 0 : if ( ! xDesktop.is())
589 : : return;
590 : :
591 : : // always remove ourselves as listener
592 : 0 : pInst->m_bListenForTermination = true;
593 [ # # ][ # # ]: 0 : xDesktop->removeTerminateListener( pInst );
[ # # ][ # # ]
594 : :
595 : : // terminate desktop only if no tasks exist
596 [ # # ]: 0 : Reference< XFramesSupplier > xSupplier( xDesktop, UNO_QUERY );
597 [ # # ]: 0 : if ( xSupplier.is() )
598 : : {
599 [ # # ][ # # ]: 0 : Reference< XIndexAccess > xTasks ( xSupplier->getFrames(), UNO_QUERY );
[ # # ]
600 [ # # ][ # # ]: 0 : if( xTasks.is() && xTasks->getCount() < 1 )
[ # # ][ # # ]
[ # # ]
601 [ # # ][ # # ]: 0 : new IdleTerminate( xDesktop );
602 : : }
603 : :
604 : : // remove the instance pointer
605 [ # # ]: 0 : ShutdownIcon::pShutdownIcon = 0;
606 : : }
607 : :
608 : : // ---------------------------------------------------------------------------
609 : :
610 : 0 : ShutdownIcon* ShutdownIcon::getInstance()
611 : : {
612 : : OSL_ASSERT( pShutdownIcon );
613 : 0 : return pShutdownIcon;
614 : : }
615 : :
616 : : // ---------------------------------------------------------------------------
617 : :
618 : 0 : ShutdownIcon* ShutdownIcon::createInstance()
619 : : {
620 [ # # ]: 0 : if (pShutdownIcon)
621 : 0 : return pShutdownIcon;
622 : :
623 : 0 : ShutdownIcon *pIcon = NULL;
624 : : try {
625 [ # # ]: 0 : Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() );
626 [ # # ]: 0 : pIcon = new ShutdownIcon( xSMgr );
627 [ # # ]: 0 : pIcon->init ();
628 : 0 : pShutdownIcon = pIcon;
629 : 0 : } catch (...) {
630 [ # # # # ]: 0 : delete pIcon;
631 : : }
632 : :
633 : 0 : return pShutdownIcon;
634 : : }
635 : :
636 : 0 : void ShutdownIcon::init() throw( ::com::sun::star::uno::Exception )
637 : : {
638 : : // access resource system and sfx only protected by solarmutex
639 [ # # ]: 0 : ::SolarMutexGuard aSolarGuard;
640 [ # # ]: 0 : ResMgr *pResMgr = SfxResId::GetResMgr();
641 : :
642 [ # # ]: 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
643 : 0 : m_pResMgr = pResMgr;
644 [ # # ]: 0 : aGuard.clear();
645 [ # # ]: 0 : Reference < XDesktop > xDesktop( m_xServiceManager->createInstance(
646 : 0 : DEFINE_CONST_UNICODE( "com.sun.star.frame.Desktop" )),
647 [ # # ][ # # ]: 0 : UNO_QUERY );
[ # # ][ # # ]
[ # # ]
648 [ # # ]: 0 : aGuard.reset();
649 [ # # ][ # # ]: 0 : m_xDesktop = xDesktop;
[ # # ]
650 : 0 : }
651 : :
652 : : // ---------------------------------------------------------------------------
653 : :
654 : 0 : void SAL_CALL ShutdownIcon::disposing()
655 : : {
656 [ # # ]: 0 : m_xServiceManager = Reference< XMultiServiceFactory >();
657 [ # # ]: 0 : m_xDesktop = Reference< XDesktop >();
658 : 0 : }
659 : :
660 : : // ---------------------------------------------------------------------------
661 : :
662 : : // XEventListener
663 : 0 : void SAL_CALL ShutdownIcon::disposing( const ::com::sun::star::lang::EventObject& )
664 : : throw(::com::sun::star::uno::RuntimeException)
665 : : {
666 : 0 : }
667 : :
668 : : // ---------------------------------------------------------------------------
669 : :
670 : : // XTerminateListener
671 : 0 : void SAL_CALL ShutdownIcon::queryTermination( const ::com::sun::star::lang::EventObject& )
672 : : throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException)
673 : : {
674 : : SAL_INFO("sfx2.shutdown", "ShutdownIcon::queryTermination: veto is " << m_bVeto);
675 [ # # ]: 0 : ::osl::ClearableMutexGuard aGuard( m_aMutex );
676 : :
677 [ # # ]: 0 : if ( m_bVeto )
678 [ # # ][ # # ]: 0 : throw ::com::sun::star::frame::TerminationVetoException();
679 : 0 : }
680 : :
681 : :
682 : : // ---------------------------------------------------------------------------
683 : :
684 : 0 : void SAL_CALL ShutdownIcon::notifyTermination( const ::com::sun::star::lang::EventObject& )
685 : : throw(::com::sun::star::uno::RuntimeException)
686 : : {
687 : 0 : }
688 : :
689 : :
690 : : // ---------------------------------------------------------------------------
691 : :
692 : 0 : void SAL_CALL ShutdownIcon::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
693 : : throw( ::com::sun::star::uno::Exception )
694 : : {
695 [ # # ]: 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
696 : :
697 : : // third argument only sets veto, everything else will be ignored!
698 [ # # ]: 0 : if (aArguments.getLength() > 2)
699 : : {
700 : 0 : sal_Bool bVeto = sal_True;
701 [ # # ]: 0 : bVeto = ::cppu::any2bool(aArguments[2]);
702 : 0 : m_bVeto = bVeto;
703 : : return;
704 : : }
705 : :
706 [ # # ]: 0 : if ( aArguments.getLength() > 0 )
707 : : {
708 [ # # ]: 0 : if ( !ShutdownIcon::pShutdownIcon )
709 : : {
710 : : try
711 : : {
712 : 0 : sal_Bool bQuickstart = sal_False;
713 [ # # ]: 0 : bQuickstart = ::cppu::any2bool( aArguments[0] );
714 [ # # ][ # # ]: 0 : if( !bQuickstart && !GetAutostart() )
[ # # ][ # # ]
715 : : return;
716 [ # # ]: 0 : aGuard.clear();
717 [ # # ]: 0 : init ();
718 [ # # ]: 0 : aGuard.reset();
719 [ # # ]: 0 : if ( !m_xDesktop.is() )
720 : : return;
721 : :
722 : : /* Create a sub-classed instance - foo */
723 : 0 : ShutdownIcon::pShutdownIcon = this;
724 [ # # ]: 0 : initSystray();
725 : : }
726 [ # # ]: 0 : catch(const ::com::sun::star::lang::IllegalArgumentException&)
727 : : {
728 : : }
729 : : }
730 : : }
731 [ # # ]: 0 : if ( aArguments.getLength() > 1 )
732 : : {
733 : 0 : sal_Bool bAutostart = sal_False;
734 [ # # ]: 0 : bAutostart = ::cppu::any2bool( aArguments[1] );
735 [ # # ][ # # ]: 0 : if (bAutostart && !GetAutostart())
[ # # ][ # # ]
736 [ # # ]: 0 : SetAutostart( sal_True );
737 [ # # ][ # # ]: 0 : if (!bAutostart && GetAutostart())
[ # # ][ # # ]
738 [ # # ]: 0 : SetAutostart( sal_False );
739 [ # # ][ # # ]: 0 : }
[ # # ]
740 : :
741 : : }
742 : :
743 : : // -------------------------------
744 : :
745 : 0 : void ShutdownIcon::EnterModalMode()
746 : : {
747 : 0 : bModalMode = sal_True;
748 : 0 : }
749 : :
750 : : // -------------------------------
751 : :
752 : 0 : void ShutdownIcon::LeaveModalMode()
753 : : {
754 : 0 : bModalMode = sal_False;
755 : 0 : }
756 : :
757 : : #ifdef WNT
758 : : // defined in shutdowniconw32.cxx
759 : : #elif defined QUARTZ
760 : : // defined in shutdowniconaqua.cxx
761 : : #else
762 : 0 : bool ShutdownIcon::IsQuickstarterInstalled()
763 : : {
764 : : #ifndef ENABLE_QUICKSTART_APPLET
765 : : return false;
766 : : #else // !ENABLE_QUICKSTART_APPLET
767 : : #ifdef UNX
768 : 0 : return LoadModule( NULL, NULL, NULL);
769 : : #endif // UNX
770 : : #endif // !ENABLE_QUICKSTART_APPLET
771 : : }
772 : : #endif // !WNT
773 : :
774 : : // ---------------------------------------------------------------------------
775 : :
776 : : #if defined (ENABLE_QUICKSTART_APPLET) && defined (UNX)
777 : : /**
778 : : * Return the XDG autostart directory.
779 : : * http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
780 : : * Available in Unix and with Quickstart enabled.
781 : : * @param bCreate Create the directory if it does not exist yet.
782 : : * @return OUString containing the autostart directory path.
783 : : */
784 : 0 : static OUString getAutostartDir( bool bCreate = false )
785 : : {
786 : 0 : OUString aShortcut;
787 : : const char *pConfigHome;
788 [ # # ]: 0 : if( (pConfigHome = getenv("XDG_CONFIG_HOME") ) )
789 : : aShortcut = OStringToOUString( OString( pConfigHome ),
790 [ # # ]: 0 : RTL_TEXTENCODING_UTF8 );
791 : : else
792 : : {
793 : 0 : OUString aHomeURL;
794 [ # # ][ # # ]: 0 : osl::Security().getHomeDir( aHomeURL );
[ # # ]
795 [ # # ]: 0 : ::osl::File::getSystemPathFromFileURL( aHomeURL, aShortcut );
796 : 0 : aShortcut += OUString( "/.config" );
797 : : }
798 : 0 : aShortcut += OUString( "/autostart" );
799 [ # # ]: 0 : if (bCreate)
800 : : {
801 : 0 : OUString aShortcutUrl;
802 [ # # ]: 0 : osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
803 [ # # ]: 0 : osl::Directory::createPath( aShortcutUrl );
804 : : }
805 : 0 : return aShortcut;
806 : : }
807 : : #endif
808 : :
809 : 0 : rtl::OUString ShutdownIcon::getShortcutName()
810 : : {
811 : : #ifndef ENABLE_QUICKSTART_APPLET
812 : : return OUString();
813 : : #else
814 : :
815 : 0 : OUString aShortcutName( "StarOffice 6.0" );
816 [ # # ]: 0 : ResMgr* pMgr = SfxResId::GetResMgr();
817 [ # # ]: 0 : if( pMgr )
818 : : {
819 [ # # ]: 0 : ::SolarMutexGuard aGuard;
820 [ # # ][ # # ]: 0 : aShortcutName = SFX2_RESSTR(STR_QUICKSTART_LNKNAME);
[ # # ]
821 : : }
822 : : #ifdef WNT
823 : : aShortcutName += OUString( ".lnk" );
824 : :
825 : : OUString aShortcut(GetAutostartFolderNameW32());
826 : : aShortcut += OUString( "\\" );
827 : : aShortcut += aShortcutName;
828 : : #else // UNX
829 [ # # ]: 0 : OUString aShortcut = getAutostartDir();
830 : 0 : aShortcut += OUString( "/qstart.desktop" );
831 : : #endif // UNX
832 : 0 : return aShortcut;
833 : : #endif // ENABLE_QUICKSTART_APPLET
834 : : }
835 : :
836 : 0 : bool ShutdownIcon::GetAutostart( )
837 : : {
838 : : #if defined QUARTZ
839 : : return true;
840 : : #else
841 : 0 : bool bRet = false;
842 : : #ifdef ENABLE_QUICKSTART_APPLET
843 [ # # ]: 0 : OUString aShortcut( getShortcutName() );
844 : 0 : OUString aShortcutUrl;
845 [ # # ]: 0 : osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
846 : 0 : osl::File f( aShortcutUrl );
847 [ # # ]: 0 : osl::File::RC error = f.open( osl_File_OpenFlag_Read );
848 [ # # ]: 0 : if( error == osl::File::E_None )
849 : : {
850 [ # # ]: 0 : f.close();
851 : 0 : bRet = true;
852 : : }
853 : : #endif // ENABLE_QUICKSTART_APPLET
854 [ # # ]: 0 : return bRet;
855 : : #endif
856 : : }
857 : :
858 : 0 : void ShutdownIcon::SetAutostart( bool bActivate )
859 : : {
860 : : #ifdef ENABLE_QUICKSTART_APPLET
861 [ # # ]: 0 : OUString aShortcut( getShortcutName() );
862 : :
863 [ # # ][ # # ]: 0 : if( bActivate && IsQuickstarterInstalled() )
[ # # ][ # # ]
864 : : {
865 : : #ifdef WNT
866 : : EnableAutostartW32( aShortcut );
867 : : #else // UNX
868 [ # # ]: 0 : getAutostartDir( true );
869 : :
870 : 0 : OUString aPath( "${BRAND_BASE_DIR}/share/xdg/qstart.desktop" );
871 : 0 : Bootstrap::expandMacros( aPath );
872 : :
873 : 0 : OUString aDesktopFile;
874 [ # # ]: 0 : ::osl::File::getSystemPathFromFileURL( aPath, aDesktopFile );
875 : :
876 : : OString aDesktopFileUnx = OUStringToOString( aDesktopFile,
877 [ # # ][ # # ]: 0 : osl_getThreadTextEncoding() );
878 : : OString aShortcutUnx = OUStringToOString( aShortcut,
879 [ # # ][ # # ]: 0 : osl_getThreadTextEncoding() );
880 [ # # ][ # # ]: 0 : if ((0 != symlink(aDesktopFileUnx.getStr(), aShortcutUnx.getStr())) && (errno == EEXIST))
[ # # ]
881 : : {
882 : 0 : unlink(aShortcutUnx.getStr());
883 : 0 : int ret = symlink(aDesktopFileUnx.getStr(), aShortcutUnx.getStr());
884 : : (void)ret; //deliberately ignore return value, it's non-critical if it fails
885 : : }
886 : :
887 [ # # ]: 0 : ShutdownIcon *pIcon = ShutdownIcon::createInstance();
888 [ # # ]: 0 : if( pIcon )
889 [ # # ]: 0 : pIcon->initSystray();
890 : : #endif // UNX
891 : : }
892 : : else
893 : : {
894 : 0 : OUString aShortcutUrl;
895 [ # # ]: 0 : ::osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
896 [ # # ]: 0 : ::osl::File::remove( aShortcutUrl );
897 : : #ifdef UNX
898 [ # # ]: 0 : if (pShutdownIcon)
899 : : {
900 [ # # ]: 0 : ShutdownIcon *pIcon = getInstance();
901 [ # # ]: 0 : pIcon->deInitSystray();
902 : 0 : }
903 : : #endif
904 : 0 : }
905 : : #else
906 : : (void)bActivate; // unused variable
907 : : #endif // ENABLE_QUICKSTART_APPLET
908 : 0 : }
909 : :
910 : : static const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE = 0;
911 : :
912 : : // XFastPropertySet
913 : 0 : void SAL_CALL ShutdownIcon::setFastPropertyValue( ::sal_Int32 nHandle,
914 : : const ::com::sun::star::uno::Any& aValue )
915 : : throw (::com::sun::star::beans::UnknownPropertyException,
916 : : ::com::sun::star::beans::PropertyVetoException,
917 : : ::com::sun::star::lang::IllegalArgumentException,
918 : : ::com::sun::star::lang::WrappedTargetException,
919 : : ::com::sun::star::uno::RuntimeException)
920 : : {
921 [ # # ]: 0 : switch(nHandle)
922 : : {
923 : : case PROPHANDLE_TERMINATEVETOSTATE :
924 : : {
925 : : // use new value in case it's a valid information only
926 : 0 : ::sal_Bool bState( sal_False );
927 [ # # ]: 0 : if (! (aValue >>= bState))
928 : 0 : return;
929 : :
930 : 0 : m_bVeto = bState;
931 [ # # ][ # # ]: 0 : if (m_bVeto && ! m_bListenForTermination)
932 [ # # ]: 0 : addTerminateListener();
933 : : }
934 : 0 : break;
935 : :
936 : : default :
937 [ # # ]: 0 : throw ::com::sun::star::beans::UnknownPropertyException();
938 : : }
939 : : }
940 : :
941 : : // XFastPropertySet
942 : 0 : ::com::sun::star::uno::Any SAL_CALL ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle )
943 : : throw (::com::sun::star::beans::UnknownPropertyException,
944 : : ::com::sun::star::lang::WrappedTargetException,
945 : : ::com::sun::star::uno::RuntimeException)
946 : : {
947 : 0 : ::com::sun::star::uno::Any aValue;
948 [ # # ]: 0 : switch(nHandle)
949 : : {
950 : : case PROPHANDLE_TERMINATEVETOSTATE :
951 : : {
952 [ # # ][ # # ]: 0 : bool bState = (m_bListenForTermination && m_bVeto);
953 [ # # ]: 0 : aValue <<= bState;
954 : : }
955 : 0 : break;
956 : :
957 : : default :
958 [ # # ]: 0 : throw ::com::sun::star::beans::UnknownPropertyException();
959 : : }
960 : :
961 : 0 : return aValue;
962 : : }
963 : :
964 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|