Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / appl / shutdownicon.cxx
blob391286db89b9c991404a57e440584428e5d84ac7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <shutdownicon.hxx>
31 #include <app.hrc>
32 #include <sfx2/app.hxx>
33 #include <osl/mutex.hxx>
34 #include <svtools/imagemgr.hxx>
35 #include <svtools/miscopt.hxx>
36 #include <com/sun/star/task/XInteractionHandler.hpp>
37 #include <com/sun/star/frame/XDispatchResultListener.hpp>
38 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
39 #include <com/sun/star/frame/XFramesSupplier.hpp>
40 #include <com/sun/star/frame/XComponentLoader.hpp>
41 #include <com/sun/star/frame/XFrame.hpp>
42 #include <com/sun/star/util/XURLTransformer.hpp>
43 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
44 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
45 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
46 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
47 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
48 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
49 #include <com/sun/star/document/MacroExecMode.hpp>
50 #include <com/sun/star/document/UpdateDocMode.hpp>
51 #include <sfx2/filedlghelper.hxx>
52 #include <sfx2/fcontnr.hxx>
53 #include <comphelper/processfactory.hxx>
54 #include <cppuhelper/compbase1.hxx>
55 #include <sfx2/dispatch.hxx>
56 #include <comphelper/extract.hxx>
57 #include <tools/urlobj.hxx>
58 #include <osl/security.hxx>
59 #include <osl/file.hxx>
60 #include <rtl/bootstrap.hxx>
61 #ifdef UNX // need symlink
62 #include <unistd.h>
63 #include <errno.h>
64 #endif
65 #include <vcl/timer.hxx>
67 #include "sfx2/sfxresid.hxx"
69 using namespace ::com::sun::star;
70 using namespace ::com::sun::star::uno;
71 using namespace ::com::sun::star::frame;
72 using namespace ::com::sun::star::container;
73 using namespace ::com::sun::star::io;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::beans;
76 using namespace ::com::sun::star::util;
77 using namespace ::com::sun::star::ui::dialogs;
78 #ifdef WNT
79 using ::rtl::OUString;
80 #else
81 using namespace ::rtl;
82 #endif
83 using namespace ::sfx2;
85 #ifdef ENABLE_QUICKSTART_APPLET
86 # if !defined(WIN32) && !defined(QUARTZ)
87 extern "C" { static void SAL_CALL thisModule() {} }
88 # endif
89 #endif
91 #if defined(UNX) && defined(ENABLE_SYSTRAY_GTK) && !defined(PLUGIN_NAME)
92 #define PLUGIN_NAME "libqstart_gtkli.so"
93 #endif
95 class SfxNotificationListener_Impl : public cppu::WeakImplHelper1< XDispatchResultListener >
97 public:
98 virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& aEvent ) throw( RuntimeException );
99 virtual void SAL_CALL disposing( const EventObject& aEvent ) throw( RuntimeException );
102 void SAL_CALL SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
104 ShutdownIcon::LeaveModalMode();
107 void SAL_CALL SfxNotificationListener_Impl::disposing( const EventObject& ) throw( RuntimeException )
111 SFX_IMPL_XSERVICEINFO( ShutdownIcon, "com.sun.star.office.Quickstart", "com.sun.star.comp.desktop.QuickstartWrapper" ) \
112 SFX_IMPL_ONEINSTANCEFACTORY( ShutdownIcon );
114 bool ShutdownIcon::bModalMode = false;
115 ShutdownIcon* ShutdownIcon::pShutdownIcon = NULL;
117 #if !defined( ENABLE_QUICKSTART_APPLET ) || defined( UNX )
118 // To remove conditionals
119 extern "C" {
120 static void disabled_initSystray() { }
121 static void disabled_deInitSystray() { }
123 #endif
125 #define DOSTRING( x ) #x
126 #define STRING( x ) DOSTRING( x )
128 bool ShutdownIcon::LoadModule( osl::Module **pModule,
129 oslGenericFunction *pInit,
130 oslGenericFunction *pDeInit )
132 if ( pModule )
134 OSL_ASSERT ( pInit && pDeInit );
135 *pInit = *pDeInit = NULL;
136 *pModule = NULL;
139 #ifdef ENABLE_QUICKSTART_APPLET
140 # ifdef WIN32
141 if ( pModule )
143 *pInit = win32_init_sys_tray;
144 *pDeInit = win32_shutdown_sys_tray;
146 return true;
147 # elif defined QUARTZ
148 *pInit = aqua_init_systray;
149 *pDeInit = aqua_shutdown_systray;
150 return true;
151 # else // UNX
152 osl::Module *pPlugin;
153 pPlugin = new osl::Module();
155 oslGenericFunction pTmpInit = NULL;
156 oslGenericFunction pTmpDeInit = NULL;
157 if ( pPlugin->loadRelative( &thisModule, OUString (STRING( PLUGIN_NAME ) ) ) )
159 pTmpInit = pPlugin->getFunctionSymbol(
160 OUString( "plugin_init_sys_tray" ) );
161 pTmpDeInit = pPlugin->getFunctionSymbol(
162 OUString( "plugin_shutdown_sys_tray" ) );
164 if ( !pTmpInit || !pTmpDeInit )
166 delete pPlugin;
167 pPlugin = NULL;
169 if ( pModule )
171 *pModule = pPlugin;
172 *pInit = pTmpInit;
173 *pDeInit = pTmpDeInit;
175 else
177 bool bRet = pPlugin != NULL;
178 delete pPlugin;
179 return bRet;
181 # endif // UNX
182 #endif // ENABLE_QUICKSTART_APPLET
184 #if !defined( ENABLE_QUICKSTART_APPLET ) || defined( UNX )
185 // Avoid unreachable code. In the ENABLE_QUICKSTART_APPLET && !UNX
186 // case, we have already returned.
187 if ( pModule )
189 if ( !*pInit )
190 *pInit = disabled_initSystray;
191 if ( !*pDeInit )
192 *pDeInit = disabled_deInitSystray;
195 return true;
196 #endif // !ENABLE_QUICKSTART_APPLET || UNX
199 // These two timeouts are necessary to avoid there being
200 // plugin frames still on the stack, after unloading that
201 // code, causing a crash during disabling / termination.
202 class IdleUnloader : Timer
204 ::osl::Module *m_pModule;
205 public:
206 IdleUnloader (::osl::Module **pModule) :
207 m_pModule (*pModule)
209 *pModule = NULL;
210 Start();
212 virtual void Timeout()
214 delete m_pModule;
215 delete this;
219 class IdleTerminate : Timer
221 Reference< XDesktop > m_xDesktop;
222 public:
223 IdleTerminate (Reference< XDesktop > xDesktop)
225 m_xDesktop = xDesktop;
226 Start();
228 virtual void Timeout()
230 m_xDesktop->terminate();
231 delete this;
235 void ShutdownIcon::initSystray()
237 if (m_bInitialized)
238 return;
239 m_bInitialized = true;
241 (void) LoadModule( &m_pPlugin, &m_pInitSystray, &m_pDeInitSystray );
242 m_bVeto = true;
243 m_pInitSystray();
246 void ShutdownIcon::deInitSystray()
248 if (!m_bInitialized)
249 return;
251 if (m_pDeInitSystray)
252 m_pDeInitSystray();
254 m_bVeto = false;
255 m_pInitSystray = 0;
256 m_pDeInitSystray = 0;
257 new IdleUnloader (&m_pPlugin);
259 delete m_pFileDlg;
260 m_pFileDlg = NULL;
261 m_bInitialized = false;
265 ShutdownIcon::ShutdownIcon( Reference< XMultiServiceFactory > aSMgr ) :
266 ShutdownIconServiceBase( m_aMutex ),
267 m_bVeto ( false ),
268 m_bListenForTermination ( false ),
269 m_bSystemDialogs( false ),
270 m_pResMgr( NULL ),
271 m_pFileDlg( NULL ),
272 m_xServiceManager( aSMgr ),
273 m_pInitSystray( 0 ),
274 m_pDeInitSystray( 0 ),
275 m_pPlugin( 0 ),
276 m_bInitialized( false )
278 m_bSystemDialogs = SvtMiscOptions().UseSystemFileDialog();
281 ShutdownIcon::~ShutdownIcon()
283 deInitSystray();
284 new IdleUnloader (&m_pPlugin);
287 // ---------------------------------------------------------------------------
289 void ShutdownIcon::OpenURL( const ::rtl::OUString& aURL, const ::rtl::OUString& rTarget, const Sequence< PropertyValue >& aArgs )
291 if ( getInstance() && getInstance()->m_xDesktop.is() )
293 Reference < XDispatchProvider > xDispatchProvider( getInstance()->m_xDesktop, UNO_QUERY );
294 if ( xDispatchProvider.is() )
296 com::sun::star::util::URL aDispatchURL;
297 aDispatchURL.Complete = aURL;
299 Reference < com::sun::star::util::XURLTransformer > xURLTransformer(
300 ::comphelper::getProcessServiceFactory()->createInstance( OUString("com.sun.star.util.URLTransformer") ),
301 com::sun::star::uno::UNO_QUERY );
302 if ( xURLTransformer.is() )
306 Reference< com::sun::star::frame::XDispatch > xDispatch;
308 xURLTransformer->parseStrict( aDispatchURL );
309 xDispatch = xDispatchProvider->queryDispatch( aDispatchURL, rTarget, 0 );
310 if ( xDispatch.is() )
311 xDispatch->dispatch( aDispatchURL, aArgs );
313 catch ( com::sun::star::uno::RuntimeException& )
315 throw;
317 catch ( com::sun::star::uno::Exception& )
325 // ---------------------------------------------------------------------------
327 void ShutdownIcon::FileOpen()
329 if ( getInstance() && getInstance()->m_xDesktop.is() )
331 ::SolarMutexGuard aGuard;
332 EnterModalMode();
333 getInstance()->StartFileDialog();
337 // ---------------------------------------------------------------------------
339 void ShutdownIcon::FromTemplate()
341 if ( getInstance() && getInstance()->m_xDesktop.is() )
343 Reference < ::com::sun::star::frame::XFramesSupplier > xDesktop ( getInstance()->m_xDesktop, UNO_QUERY);
344 Reference < ::com::sun::star::frame::XFrame > xFrame( xDesktop->getActiveFrame() );
345 if ( !xFrame.is() )
346 xFrame = Reference < ::com::sun::star::frame::XFrame >( xDesktop, UNO_QUERY );
348 URL aTargetURL;
349 aTargetURL.Complete = OUString( "slot:5500" );
350 Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString("com.sun.star.util.URLTransformer")), UNO_QUERY );
351 xTrans->parseStrict( aTargetURL );
353 Reference < ::com::sun::star::frame::XDispatchProvider > xProv( xFrame, UNO_QUERY );
354 Reference < ::com::sun::star::frame::XDispatch > xDisp;
355 if ( xProv.is() )
357 if ( aTargetURL.Protocol.compareToAscii("slot:") == COMPARE_EQUAL )
358 xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
359 else
360 xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString("_blank"), 0 );
362 if ( xDisp.is() )
364 Sequence<PropertyValue> aArgs(1);
365 PropertyValue* pArg = aArgs.getArray();
366 pArg[0].Name = rtl::OUString("Referer");
367 pArg[0].Value <<= ::rtl::OUString("private:user");
368 Reference< ::com::sun::star::frame::XNotifyingDispatch > xNotifyer( xDisp, UNO_QUERY );
369 if ( xNotifyer.is() )
371 EnterModalMode();
372 xNotifyer->dispatchWithNotification( aTargetURL, aArgs, new SfxNotificationListener_Impl() );
374 else
375 xDisp->dispatch( aTargetURL, aArgs );
380 // ---------------------------------------------------------------------------
381 #include <tools/rcid.h>
382 OUString ShutdownIcon::GetResString( int id )
384 ::SolarMutexGuard aGuard;
386 if( ! m_pResMgr )
387 m_pResMgr = SfxResId::GetResMgr();
388 ResId aResId( id, *m_pResMgr );
389 aResId.SetRT( RSC_STRING );
390 if( !m_pResMgr || !m_pResMgr->IsAvailable( aResId ) )
391 return OUString();
393 return ResId(id, *m_pResMgr).toString();
396 // ---------------------------------------------------------------------------
398 OUString ShutdownIcon::GetUrlDescription( const OUString& aUrl )
400 ::SolarMutexGuard aGuard;
402 return OUString( SvFileInformationManager::GetDescription( INetURLObject( aUrl ) ) );
405 // ---------------------------------------------------------------------------
407 void ShutdownIcon::StartFileDialog()
409 ::SolarMutexGuard aGuard;
411 bool bDirty = ( m_bSystemDialogs != static_cast<bool>(SvtMiscOptions().UseSystemFileDialog()) );
413 if ( m_pFileDlg && bDirty )
415 // Destroy instance as changing the system file dialog setting
416 // forces us to create a new FileDialogHelper instance!
417 delete m_pFileDlg;
418 m_pFileDlg = NULL;
421 if ( !m_pFileDlg )
422 m_pFileDlg = new FileDialogHelper(
423 ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
424 SFXWB_MULTISELECTION, String() );
425 m_pFileDlg->StartExecuteModal( STATIC_LINK( this, ShutdownIcon, DialogClosedHdl_Impl ) );
428 // ---------------------------------------------------------------------------
430 IMPL_STATIC_LINK( ShutdownIcon, DialogClosedHdl_Impl, FileDialogHelper*, EMPTYARG )
432 DBG_ASSERT( pThis->m_pFileDlg, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" );
434 // use constructor for filling up filters automatically!
435 if ( ERRCODE_NONE == pThis->m_pFileDlg->GetError() )
437 Reference< XFilePicker > xPicker = pThis->m_pFileDlg->GetFilePicker();
442 if ( xPicker.is() )
445 Reference < XFilePickerControlAccess > xPickerControls ( xPicker, UNO_QUERY );
446 Reference < XFilterManager > xFilterManager ( xPicker, UNO_QUERY );
448 Sequence< OUString > sFiles = xPicker->getFiles();
449 int nFiles = sFiles.getLength();
451 int nArgs=3;
452 Sequence< PropertyValue > aArgs(3);
454 Reference < com::sun::star::task::XInteractionHandler > xInteraction(
455 ::comphelper::getProcessServiceFactory()->createInstance( OUString("com.sun.star.task.InteractionHandler") ),
456 com::sun::star::uno::UNO_QUERY );
458 aArgs[0].Name = OUString("InteractionHandler");
459 aArgs[0].Value <<= xInteraction;
461 sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
462 aArgs[1].Name = OUString("MacroExecutionMode");
463 aArgs[1].Value <<= nMacroExecMode;
465 sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
466 aArgs[2].Name = OUString("UpdateDocMode");
467 aArgs[2].Value <<= nUpdateDoc;
469 // use the filedlghelper to get the current filter name,
470 // because it removes the extensions before you get the filter name.
471 OUString aFilterName( pThis->m_pFileDlg->GetCurrentFilter() );
473 if ( xPickerControls.is() )
476 // Set readonly flag
478 sal_Bool bReadOnly = sal_False;
481 xPickerControls->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ) >>= bReadOnly;
483 // Only set porperty if readonly is set to TRUE
485 if ( bReadOnly )
487 aArgs.realloc( ++nArgs );
488 aArgs[nArgs-1].Name = OUString("ReadOnly");
489 aArgs[nArgs-1].Value <<= bReadOnly;
492 // Get version string
494 sal_Int32 iVersion = -1;
496 xPickerControls->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, ControlActions::GET_SELECTED_ITEM_INDEX ) >>= iVersion;
498 if ( iVersion >= 0 )
500 sal_Int16 uVersion = (sal_Int16)iVersion;
502 aArgs.realloc( ++nArgs );
503 aArgs[nArgs-1].Name = OUString("Version");
504 aArgs[nArgs-1].Value <<= uVersion;
507 // Retrieve the current filter
509 if ( aFilterName.isEmpty() )
510 xPickerControls->getValue( CommonFilePickerElementIds::LISTBOX_FILTER, ControlActions::GET_SELECTED_ITEM ) >>= aFilterName;
515 // Convert UI filter name to internal filter name
517 if ( !aFilterName.isEmpty() )
519 const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4UIName( aFilterName, 0, SFX_FILTER_NOTINFILEDLG );
521 if ( pFilter )
523 aFilterName = pFilter->GetFilterName();
525 if ( !aFilterName.isEmpty() )
527 aArgs.realloc( ++nArgs );
528 aArgs[nArgs-1].Name = OUString("FilterName");
529 aArgs[nArgs-1].Value <<= aFilterName;
534 if ( 1 == nFiles )
535 OpenURL( sFiles[0], OUString( "_default" ), aArgs );
536 else
538 OUString aBaseDirURL = sFiles[0];
539 if ( !aBaseDirURL.isEmpty() && aBaseDirURL[aBaseDirURL.getLength()-1] != '/' )
540 aBaseDirURL += OUString("/");
542 int iFiles;
543 for ( iFiles = 1; iFiles < nFiles; iFiles++ )
545 OUString aURL = aBaseDirURL;
546 aURL += sFiles[iFiles];
547 OpenURL( aURL, OUString( "_default" ), aArgs );
552 catch ( ... )
557 #ifdef WNT
558 // Destroy dialog to prevent problems with custom controls
559 // This fix is dependent on the dialog settings. Destroying the dialog here will
560 // crash the non-native dialog implementation! Therefore make this dependent on
561 // the settings.
562 if ( SvtMiscOptions().UseSystemFileDialog() )
564 delete pThis->m_pFileDlg;
565 pThis->m_pFileDlg = NULL;
567 #endif
569 LeaveModalMode();
570 return 0;
573 // ---------------------------------------------------------------------------
575 void ShutdownIcon::addTerminateListener()
577 ShutdownIcon* pInst = getInstance();
578 if ( ! pInst)
579 return;
581 if (pInst->m_bListenForTermination)
582 return;
584 Reference< XDesktop > xDesktop = pInst->m_xDesktop;
585 if ( ! xDesktop.is())
586 return;
588 xDesktop->addTerminateListener( pInst );
589 pInst->m_bListenForTermination = true;
592 // ---------------------------------------------------------------------------
594 void ShutdownIcon::terminateDesktop()
596 ShutdownIcon* pInst = getInstance();
597 if ( ! pInst)
598 return;
600 Reference< XDesktop > xDesktop = pInst->m_xDesktop;
601 if ( ! xDesktop.is())
602 return;
604 // always remove ourselves as listener
605 pInst->m_bListenForTermination = true;
606 xDesktop->removeTerminateListener( pInst );
608 // terminate desktop only if no tasks exist
609 Reference< XFramesSupplier > xSupplier( xDesktop, UNO_QUERY );
610 if ( xSupplier.is() )
612 Reference< XIndexAccess > xTasks ( xSupplier->getFrames(), UNO_QUERY );
613 if( xTasks.is() && xTasks->getCount() < 1 )
614 new IdleTerminate( xDesktop );
617 // remove the instance pointer
618 ShutdownIcon::pShutdownIcon = 0;
621 // ---------------------------------------------------------------------------
623 ShutdownIcon* ShutdownIcon::getInstance()
625 OSL_ASSERT( pShutdownIcon );
626 return pShutdownIcon;
629 // ---------------------------------------------------------------------------
631 ShutdownIcon* ShutdownIcon::createInstance()
633 if (pShutdownIcon)
634 return pShutdownIcon;
636 ShutdownIcon *pIcon = NULL;
637 try {
638 Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() );
639 pIcon = new ShutdownIcon( xSMgr );
640 pIcon->init ();
641 pShutdownIcon = pIcon;
642 } catch (...) {
643 delete pIcon;
646 return pShutdownIcon;
649 void ShutdownIcon::init() throw( ::com::sun::star::uno::Exception )
651 // access resource system and sfx only protected by solarmutex
652 ::SolarMutexGuard aSolarGuard;
653 ResMgr *pResMgr = SfxResId::GetResMgr();
655 ::osl::ResettableMutexGuard aGuard( m_aMutex );
656 m_pResMgr = pResMgr;
657 aGuard.clear();
658 Reference < XDesktop > xDesktop( m_xServiceManager->createInstance(
659 DEFINE_CONST_UNICODE( "com.sun.star.frame.Desktop" )),
660 UNO_QUERY );
661 aGuard.reset();
662 m_xDesktop = xDesktop;
665 // ---------------------------------------------------------------------------
667 void SAL_CALL ShutdownIcon::disposing()
669 m_xServiceManager = Reference< XMultiServiceFactory >();
670 m_xDesktop = Reference< XDesktop >();
673 // ---------------------------------------------------------------------------
675 // XEventListener
676 void SAL_CALL ShutdownIcon::disposing( const ::com::sun::star::lang::EventObject& )
677 throw(::com::sun::star::uno::RuntimeException)
681 // ---------------------------------------------------------------------------
683 // XTerminateListener
684 void SAL_CALL ShutdownIcon::queryTermination( const ::com::sun::star::lang::EventObject& )
685 throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException)
687 SAL_INFO("sfx2.shutdown", "ShutdownIcon::queryTermination: veto is " << m_bVeto);
688 ::osl::ClearableMutexGuard aGuard( m_aMutex );
690 if ( m_bVeto )
691 throw ::com::sun::star::frame::TerminationVetoException();
695 // ---------------------------------------------------------------------------
697 void SAL_CALL ShutdownIcon::notifyTermination( const ::com::sun::star::lang::EventObject& )
698 throw(::com::sun::star::uno::RuntimeException)
703 // ---------------------------------------------------------------------------
705 void SAL_CALL ShutdownIcon::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
706 throw( ::com::sun::star::uno::Exception )
708 ::osl::ResettableMutexGuard aGuard( m_aMutex );
710 // third argument only sets veto, everything else will be ignored!
711 if (aArguments.getLength() > 2)
713 sal_Bool bVeto = sal_True;
714 bVeto = ::cppu::any2bool(aArguments[2]);
715 m_bVeto = bVeto;
716 return;
719 if ( aArguments.getLength() > 0 )
721 if ( !ShutdownIcon::pShutdownIcon )
725 sal_Bool bQuickstart = sal_False;
726 bQuickstart = ::cppu::any2bool( aArguments[0] );
727 if( !bQuickstart && !GetAutostart() )
728 return;
729 aGuard.clear();
730 init ();
731 aGuard.reset();
732 if ( !m_xDesktop.is() )
733 return;
735 /* Create a sub-classed instance - foo */
736 ShutdownIcon::pShutdownIcon = this;
737 initSystray();
739 catch(const ::com::sun::star::lang::IllegalArgumentException&)
744 if ( aArguments.getLength() > 1 )
746 sal_Bool bAutostart = sal_False;
747 bAutostart = ::cppu::any2bool( aArguments[1] );
748 if (bAutostart && !GetAutostart())
749 SetAutostart( sal_True );
750 if (!bAutostart && GetAutostart())
751 SetAutostart( sal_False );
756 // -------------------------------
758 void ShutdownIcon::EnterModalMode()
760 bModalMode = sal_True;
763 // -------------------------------
765 void ShutdownIcon::LeaveModalMode()
767 bModalMode = sal_False;
770 #ifdef WNT
771 // defined in shutdowniconw32.cxx
772 #elif defined QUARTZ
773 // defined in shutdowniconaqua.cxx
774 #else
775 bool ShutdownIcon::IsQuickstarterInstalled()
777 #ifndef ENABLE_QUICKSTART_APPLET
778 return false;
779 #else // !ENABLE_QUICKSTART_APPLET
780 #ifdef UNX
781 return LoadModule( NULL, NULL, NULL);
782 #endif // UNX
783 #endif // !ENABLE_QUICKSTART_APPLET
785 #endif // !WNT
787 // ---------------------------------------------------------------------------
789 #if defined (ENABLE_QUICKSTART_APPLET) && defined (UNX)
791 * Return the XDG autostart directory.
792 * http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
793 * Available in Unix and with Quickstart enabled.
794 * @param bCreate Create the directory if it does not exist yet.
795 * @return OUString containing the autostart directory path.
797 static OUString getAutostartDir( bool bCreate = false )
799 OUString aShortcut;
800 const char *pConfigHome;
801 if( (pConfigHome = getenv("XDG_CONFIG_HOME") ) )
802 aShortcut = OStringToOUString( OString( pConfigHome ),
803 RTL_TEXTENCODING_UTF8 );
804 else
806 OUString aHomeURL;
807 osl::Security().getHomeDir( aHomeURL );
808 ::osl::File::getSystemPathFromFileURL( aHomeURL, aShortcut );
809 aShortcut += OUString( "/.config" );
811 aShortcut += OUString( "/autostart" );
812 if (bCreate)
814 OUString aShortcutUrl;
815 osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
816 osl::Directory::createPath( aShortcutUrl );
818 return aShortcut;
820 #endif
822 rtl::OUString ShutdownIcon::getShortcutName()
824 #ifndef ENABLE_QUICKSTART_APPLET
825 return OUString();
826 #else
828 OUString aShortcutName( "StarOffice 6.0" );
829 ResMgr* pMgr = SfxResId::GetResMgr();
830 if( pMgr )
832 ::SolarMutexGuard aGuard;
833 aShortcutName = SFX2_RESSTR(STR_QUICKSTART_LNKNAME);
835 #ifdef WNT
836 aShortcutName += OUString( ".lnk" );
838 OUString aShortcut(GetAutostartFolderNameW32());
839 aShortcut += OUString( "\\" );
840 aShortcut += aShortcutName;
841 #else // UNX
842 OUString aShortcut = getAutostartDir();
843 aShortcut += OUString( "/qstart.desktop" );
844 #endif // UNX
845 return aShortcut;
846 #endif // ENABLE_QUICKSTART_APPLET
849 bool ShutdownIcon::GetAutostart( )
851 #if defined QUARTZ
852 return true;
853 #else
854 bool bRet = false;
855 #ifdef ENABLE_QUICKSTART_APPLET
856 OUString aShortcut( getShortcutName() );
857 OUString aShortcutUrl;
858 osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
859 osl::File f( aShortcutUrl );
860 osl::File::RC error = f.open( osl_File_OpenFlag_Read );
861 if( error == osl::File::E_None )
863 f.close();
864 bRet = true;
866 #endif // ENABLE_QUICKSTART_APPLET
867 return bRet;
868 #endif
871 void ShutdownIcon::SetAutostart( bool bActivate )
873 #ifdef ENABLE_QUICKSTART_APPLET
874 OUString aShortcut( getShortcutName() );
876 if( bActivate && IsQuickstarterInstalled() )
878 #ifdef WNT
879 EnableAutostartW32( aShortcut );
880 #else // UNX
881 getAutostartDir( true );
883 OUString aPath( "${BRAND_BASE_DIR}/share/xdg/qstart.desktop" );
884 Bootstrap::expandMacros( aPath );
886 OUString aDesktopFile;
887 ::osl::File::getSystemPathFromFileURL( aPath, aDesktopFile );
889 OString aDesktopFileUnx = OUStringToOString( aDesktopFile,
890 osl_getThreadTextEncoding() );
891 OString aShortcutUnx = OUStringToOString( aShortcut,
892 osl_getThreadTextEncoding() );
893 if ((0 != symlink(aDesktopFileUnx.getStr(), aShortcutUnx.getStr())) && (errno == EEXIST))
895 unlink(aShortcutUnx.getStr());
896 int ret = symlink(aDesktopFileUnx.getStr(), aShortcutUnx.getStr());
897 (void)ret; //deliberately ignore return value, it's non-critical if it fails
900 ShutdownIcon *pIcon = ShutdownIcon::createInstance();
901 if( pIcon )
902 pIcon->initSystray();
903 #endif // UNX
905 else
907 OUString aShortcutUrl;
908 ::osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
909 ::osl::File::remove( aShortcutUrl );
910 #ifdef UNX
911 if (pShutdownIcon)
913 ShutdownIcon *pIcon = getInstance();
914 pIcon->deInitSystray();
916 #endif
918 #else
919 (void)bActivate; // unused variable
920 #endif // ENABLE_QUICKSTART_APPLET
923 static const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE = 0;
925 // XFastPropertySet
926 void SAL_CALL ShutdownIcon::setFastPropertyValue( ::sal_Int32 nHandle,
927 const ::com::sun::star::uno::Any& aValue )
928 throw (::com::sun::star::beans::UnknownPropertyException,
929 ::com::sun::star::beans::PropertyVetoException,
930 ::com::sun::star::lang::IllegalArgumentException,
931 ::com::sun::star::lang::WrappedTargetException,
932 ::com::sun::star::uno::RuntimeException)
934 switch(nHandle)
936 case PROPHANDLE_TERMINATEVETOSTATE :
938 // use new value in case it's a valid information only
939 ::sal_Bool bState( sal_False );
940 if (! (aValue >>= bState))
941 return;
943 m_bVeto = bState;
944 if (m_bVeto && ! m_bListenForTermination)
945 addTerminateListener();
947 break;
949 default :
950 throw ::com::sun::star::beans::UnknownPropertyException();
954 // XFastPropertySet
955 ::com::sun::star::uno::Any SAL_CALL ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle )
956 throw (::com::sun::star::beans::UnknownPropertyException,
957 ::com::sun::star::lang::WrappedTargetException,
958 ::com::sun::star::uno::RuntimeException)
960 ::com::sun::star::uno::Any aValue;
961 switch(nHandle)
963 case PROPHANDLE_TERMINATEVETOSTATE :
965 bool bState = (m_bListenForTermination && m_bVeto);
966 aValue <<= bState;
968 break;
970 default :
971 throw ::com::sun::star::beans::UnknownPropertyException();
974 return aValue;
977 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */