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>
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
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
;
79 using ::rtl::OUString
;
81 using namespace ::rtl
;
83 using namespace ::sfx2
;
85 #ifdef ENABLE_QUICKSTART_APPLET
86 # if !defined(WIN32) && !defined(QUARTZ)
87 extern "C" { static void SAL_CALL
thisModule() {} }
91 #if defined(UNX) && defined(ENABLE_SYSTRAY_GTK) && !defined(PLUGIN_NAME)
92 #define PLUGIN_NAME "libqstart_gtkli.so"
95 class SfxNotificationListener_Impl
: public cppu::WeakImplHelper1
< XDispatchResultListener
>
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
120 static void disabled_initSystray() { }
121 static void disabled_deInitSystray() { }
125 #define DOSTRING( x ) #x
126 #define STRING( x ) DOSTRING( x )
128 bool ShutdownIcon::LoadModule( osl::Module
**pModule
,
129 oslGenericFunction
*pInit
,
130 oslGenericFunction
*pDeInit
)
134 OSL_ASSERT ( pInit
&& pDeInit
);
135 *pInit
= *pDeInit
= NULL
;
139 #ifdef ENABLE_QUICKSTART_APPLET
143 *pInit
= win32_init_sys_tray
;
144 *pDeInit
= win32_shutdown_sys_tray
;
147 # elif defined QUARTZ
148 *pInit
= aqua_init_systray
;
149 *pDeInit
= aqua_shutdown_systray
;
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
)
173 *pDeInit
= pTmpDeInit
;
177 bool bRet
= pPlugin
!= NULL
;
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.
190 *pInit
= disabled_initSystray
;
192 *pDeInit
= disabled_deInitSystray
;
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
;
206 IdleUnloader (::osl::Module
**pModule
) :
212 virtual void Timeout()
219 class IdleTerminate
: Timer
221 Reference
< XDesktop
> m_xDesktop
;
223 IdleTerminate (Reference
< XDesktop
> xDesktop
)
225 m_xDesktop
= xDesktop
;
228 virtual void Timeout()
230 m_xDesktop
->terminate();
235 void ShutdownIcon::initSystray()
239 m_bInitialized
= true;
241 (void) LoadModule( &m_pPlugin
, &m_pInitSystray
, &m_pDeInitSystray
);
246 void ShutdownIcon::deInitSystray()
251 if (m_pDeInitSystray
)
256 m_pDeInitSystray
= 0;
257 new IdleUnloader (&m_pPlugin
);
261 m_bInitialized
= false;
265 ShutdownIcon::ShutdownIcon( Reference
< XMultiServiceFactory
> aSMgr
) :
266 ShutdownIconServiceBase( m_aMutex
),
268 m_bListenForTermination ( false ),
269 m_bSystemDialogs( false ),
272 m_xServiceManager( aSMgr
),
274 m_pDeInitSystray( 0 ),
276 m_bInitialized( false )
278 m_bSystemDialogs
= SvtMiscOptions().UseSystemFileDialog();
281 ShutdownIcon::~ShutdownIcon()
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
& )
317 catch ( com::sun::star::uno::Exception
& )
325 // ---------------------------------------------------------------------------
327 void ShutdownIcon::FileOpen()
329 if ( getInstance() && getInstance()->m_xDesktop
.is() )
331 ::SolarMutexGuard aGuard
;
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() );
346 xFrame
= Reference
< ::com::sun::star::frame::XFrame
>( xDesktop
, UNO_QUERY
);
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
;
357 if ( aTargetURL
.Protocol
.compareToAscii("slot:") == COMPARE_EQUAL
)
358 xDisp
= xProv
->queryDispatch( aTargetURL
, ::rtl::OUString(), 0 );
360 xDisp
= xProv
->queryDispatch( aTargetURL
, ::rtl::OUString("_blank"), 0 );
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() )
372 xNotifyer
->dispatchWithNotification( aTargetURL
, aArgs
, new SfxNotificationListener_Impl() );
375 xDisp
->dispatch( aTargetURL
, aArgs
);
380 // ---------------------------------------------------------------------------
381 #include <tools/rcid.h>
382 OUString
ShutdownIcon::GetResString( int id
)
384 ::SolarMutexGuard aGuard
;
387 m_pResMgr
= SfxResId::GetResMgr();
388 ResId
aResId( id
, *m_pResMgr
);
389 aResId
.SetRT( RSC_STRING
);
390 if( !m_pResMgr
|| !m_pResMgr
->IsAvailable( aResId
) )
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!
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();
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();
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() )
478 sal_Bool bReadOnly
= sal_False
;
481 xPickerControls
->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY
, 0 ) >>= bReadOnly
;
483 // Only set porperty if readonly is set to TRUE
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
;
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
);
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
;
535 OpenURL( sFiles
[0], OUString( "_default" ), aArgs
);
538 OUString aBaseDirURL
= sFiles
[0];
539 if ( !aBaseDirURL
.isEmpty() && aBaseDirURL
[aBaseDirURL
.getLength()-1] != '/' )
540 aBaseDirURL
+= OUString("/");
543 for ( iFiles
= 1; iFiles
< nFiles
; iFiles
++ )
545 OUString aURL
= aBaseDirURL
;
546 aURL
+= sFiles
[iFiles
];
547 OpenURL( aURL
, OUString( "_default" ), aArgs
);
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
562 if ( SvtMiscOptions().UseSystemFileDialog() )
564 delete pThis
->m_pFileDlg
;
565 pThis
->m_pFileDlg
= NULL
;
573 // ---------------------------------------------------------------------------
575 void ShutdownIcon::addTerminateListener()
577 ShutdownIcon
* pInst
= getInstance();
581 if (pInst
->m_bListenForTermination
)
584 Reference
< XDesktop
> xDesktop
= pInst
->m_xDesktop
;
585 if ( ! xDesktop
.is())
588 xDesktop
->addTerminateListener( pInst
);
589 pInst
->m_bListenForTermination
= true;
592 // ---------------------------------------------------------------------------
594 void ShutdownIcon::terminateDesktop()
596 ShutdownIcon
* pInst
= getInstance();
600 Reference
< XDesktop
> xDesktop
= pInst
->m_xDesktop
;
601 if ( ! xDesktop
.is())
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()
634 return pShutdownIcon
;
636 ShutdownIcon
*pIcon
= NULL
;
638 Reference
< XMultiServiceFactory
> xSMgr( comphelper::getProcessServiceFactory() );
639 pIcon
= new ShutdownIcon( xSMgr
);
641 pShutdownIcon
= 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
);
658 Reference
< XDesktop
> xDesktop( m_xServiceManager
->createInstance(
659 DEFINE_CONST_UNICODE( "com.sun.star.frame.Desktop" )),
662 m_xDesktop
= xDesktop
;
665 // ---------------------------------------------------------------------------
667 void SAL_CALL
ShutdownIcon::disposing()
669 m_xServiceManager
= Reference
< XMultiServiceFactory
>();
670 m_xDesktop
= Reference
< XDesktop
>();
673 // ---------------------------------------------------------------------------
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
);
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]);
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() )
732 if ( !m_xDesktop
.is() )
735 /* Create a sub-classed instance - foo */
736 ShutdownIcon::pShutdownIcon
= this;
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
;
771 // defined in shutdowniconw32.cxx
773 // defined in shutdowniconaqua.cxx
775 bool ShutdownIcon::IsQuickstarterInstalled()
777 #ifndef ENABLE_QUICKSTART_APPLET
779 #else // !ENABLE_QUICKSTART_APPLET
781 return LoadModule( NULL
, NULL
, NULL
);
783 #endif // !ENABLE_QUICKSTART_APPLET
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 )
800 const char *pConfigHome
;
801 if( (pConfigHome
= getenv("XDG_CONFIG_HOME") ) )
802 aShortcut
= OStringToOUString( OString( pConfigHome
),
803 RTL_TEXTENCODING_UTF8
);
807 osl::Security().getHomeDir( aHomeURL
);
808 ::osl::File::getSystemPathFromFileURL( aHomeURL
, aShortcut
);
809 aShortcut
+= OUString( "/.config" );
811 aShortcut
+= OUString( "/autostart" );
814 OUString aShortcutUrl
;
815 osl::File::getFileURLFromSystemPath( aShortcut
, aShortcutUrl
);
816 osl::Directory::createPath( aShortcutUrl
);
822 rtl::OUString
ShutdownIcon::getShortcutName()
824 #ifndef ENABLE_QUICKSTART_APPLET
828 OUString
aShortcutName( "StarOffice 6.0" );
829 ResMgr
* pMgr
= SfxResId::GetResMgr();
832 ::SolarMutexGuard aGuard
;
833 aShortcutName
= SFX2_RESSTR(STR_QUICKSTART_LNKNAME
);
836 aShortcutName
+= OUString( ".lnk" );
838 OUString
aShortcut(GetAutostartFolderNameW32());
839 aShortcut
+= OUString( "\\" );
840 aShortcut
+= aShortcutName
;
842 OUString aShortcut
= getAutostartDir();
843 aShortcut
+= OUString( "/qstart.desktop" );
846 #endif // ENABLE_QUICKSTART_APPLET
849 bool ShutdownIcon::GetAutostart( )
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
)
866 #endif // ENABLE_QUICKSTART_APPLET
871 void ShutdownIcon::SetAutostart( bool bActivate
)
873 #ifdef ENABLE_QUICKSTART_APPLET
874 OUString
aShortcut( getShortcutName() );
876 if( bActivate
&& IsQuickstarterInstalled() )
879 EnableAutostartW32( aShortcut
);
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();
902 pIcon
->initSystray();
907 OUString aShortcutUrl
;
908 ::osl::File::getFileURLFromSystemPath( aShortcut
, aShortcutUrl
);
909 ::osl::File::remove( aShortcutUrl
);
913 ShutdownIcon
*pIcon
= getInstance();
914 pIcon
->deInitSystray();
919 (void)bActivate
; // unused variable
920 #endif // ENABLE_QUICKSTART_APPLET
923 static const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE
= 0;
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
)
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
))
944 if (m_bVeto
&& ! m_bListenForTermination
)
945 addTerminateListener();
950 throw ::com::sun::star::beans::UnknownPropertyException();
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
;
963 case PROPHANDLE_TERMINATEVETOSTATE
:
965 bool bState
= (m_bListenForTermination
&& m_bVeto
);
971 throw ::com::sun::star::beans::UnknownPropertyException();
977 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */