1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <shutdownicon.hxx>
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/InteractionHandler.hpp>
27 #include <com/sun/star/frame/Desktop.hpp>
28 #include <com/sun/star/frame/XDispatchResultListener.hpp>
29 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
30 #include <com/sun/star/frame/XFramesSupplier.hpp>
31 #include <com/sun/star/frame/XComponentLoader.hpp>
32 #include <com/sun/star/frame/XFrame.hpp>
33 #include <com/sun/star/util/URLTransformer.hpp>
34 #include <com/sun/star/util/XURLTransformer.hpp>
35 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
36 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
37 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
38 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
39 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
40 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
41 #include <com/sun/star/document/MacroExecMode.hpp>
42 #include <com/sun/star/document/UpdateDocMode.hpp>
43 #include <sfx2/filedlghelper.hxx>
44 #include <sfx2/fcontnr.hxx>
45 #include <comphelper/processfactory.hxx>
46 #include <cppuhelper/compbase1.hxx>
47 #include <sfx2/dispatch.hxx>
48 #include <comphelper/extract.hxx>
49 #include <tools/urlobj.hxx>
50 #include <osl/security.hxx>
51 #include <osl/file.hxx>
52 #include <rtl/bootstrap.hxx>
53 #include <rtl/ustrbuf.hxx>
54 #ifdef UNX // need symlink
58 #include <vcl/timer.hxx>
60 #include "sfx2/sfxresid.hxx"
62 using namespace ::com::sun::star
;
63 using namespace ::com::sun::star::uno
;
64 using namespace ::com::sun::star::frame
;
65 using namespace ::com::sun::star::container
;
66 using namespace ::com::sun::star::io
;
67 using namespace ::com::sun::star::lang
;
68 using namespace ::com::sun::star::beans
;
69 using namespace ::com::sun::star::util
;
70 using namespace ::com::sun::star::ui::dialogs
;
73 using namespace ::rtl
;
75 using namespace ::sfx2
;
77 #ifdef ENABLE_QUICKSTART_APPLET
78 # if !defined(WIN32) && !defined(MACOSX)
79 extern "C" { static void SAL_CALL
thisModule() {} }
83 #if defined(UNX) && defined(ENABLE_SYSTRAY_GTK) && !defined(PLUGIN_NAME)
84 #define PLUGIN_NAME "libqstart_gtklo.so"
87 class SfxNotificationListener_Impl
: public cppu::WeakImplHelper1
< XDispatchResultListener
>
90 virtual void SAL_CALL
dispatchFinished( const DispatchResultEvent
& aEvent
) throw( RuntimeException
);
91 virtual void SAL_CALL
disposing( const EventObject
& aEvent
) throw( RuntimeException
);
94 void SAL_CALL
SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent
& ) throw( RuntimeException
)
96 ShutdownIcon::LeaveModalMode();
99 void SAL_CALL
SfxNotificationListener_Impl::disposing( const EventObject
& ) throw( RuntimeException
)
103 SFX_IMPL_XSERVICEINFO_CTX( ShutdownIcon
, "com.sun.star.office.Quickstart", "com.sun.star.comp.desktop.QuickstartWrapper" ) \
104 SFX_IMPL_ONEINSTANCEFACTORY( ShutdownIcon
);
106 bool ShutdownIcon::bModalMode
= false;
107 ShutdownIcon
* ShutdownIcon::pShutdownIcon
= NULL
;
109 #if !defined( ENABLE_QUICKSTART_APPLET ) || defined( UNX )
110 // To remove conditionals
112 static void disabled_initSystray() { }
113 static void disabled_deInitSystray() { }
117 bool ShutdownIcon::LoadModule( osl::Module
**pModule
,
118 oslGenericFunction
*pInit
,
119 oslGenericFunction
*pDeInit
)
123 OSL_ASSERT ( pInit
&& pDeInit
);
124 *pInit
= *pDeInit
= NULL
;
128 #ifdef ENABLE_QUICKSTART_APPLET
132 *pInit
= win32_init_sys_tray
;
133 *pDeInit
= win32_shutdown_sys_tray
;
136 # elif defined MACOSX
137 *pInit
= aqua_init_systray
;
138 *pDeInit
= aqua_shutdown_systray
;
141 osl::Module
*pPlugin
;
142 pPlugin
= new osl::Module();
144 oslGenericFunction pTmpInit
= NULL
;
145 oslGenericFunction pTmpDeInit
= NULL
;
147 #define DOSTRING( x ) #x
148 #define STRING( x ) DOSTRING( x )
150 if ( pPlugin
->loadRelative( &thisModule
, OUString (STRING( PLUGIN_NAME
) ) ) )
152 pTmpInit
= pPlugin
->getFunctionSymbol(
153 OUString( "plugin_init_sys_tray" ) );
154 pTmpDeInit
= pPlugin
->getFunctionSymbol(
155 OUString( "plugin_shutdown_sys_tray" ) );
157 if ( !pTmpInit
|| !pTmpDeInit
)
166 *pDeInit
= pTmpDeInit
;
170 bool bRet
= pPlugin
!= NULL
;
175 #endif // ENABLE_QUICKSTART_APPLET
177 #if !defined( ENABLE_QUICKSTART_APPLET ) || defined( UNX )
178 // Avoid unreachable code. In the ENABLE_QUICKSTART_APPLET && !UNX
179 // case, we have already returned.
183 *pInit
= disabled_initSystray
;
185 *pDeInit
= disabled_deInitSystray
;
189 #endif // !ENABLE_QUICKSTART_APPLET || UNX
192 // These two timeouts are necessary to avoid there being
193 // plugin frames still on the stack, after unloading that
194 // code, causing a crash during disabling / termination.
195 class IdleUnloader
: Timer
197 ::osl::Module
*m_pModule
;
199 IdleUnloader (::osl::Module
**pModule
) :
205 virtual void Timeout()
212 class IdleTerminate
: Timer
214 Reference
< XDesktop2
> m_xDesktop
;
216 IdleTerminate (Reference
< XDesktop2
> xDesktop
)
218 m_xDesktop
= xDesktop
;
221 virtual void Timeout()
223 m_xDesktop
->terminate();
228 void ShutdownIcon::initSystray()
232 m_bInitialized
= true;
234 (void) LoadModule( &m_pPlugin
, &m_pInitSystray
, &m_pDeInitSystray
);
239 void ShutdownIcon::deInitSystray()
244 if (m_pDeInitSystray
)
249 m_pDeInitSystray
= 0;
250 new IdleUnloader (&m_pPlugin
);
254 m_bInitialized
= false;
258 ShutdownIcon::ShutdownIcon( const Reference
< XComponentContext
> & rxContext
) :
259 ShutdownIconServiceBase( m_aMutex
),
261 m_bListenForTermination ( false ),
262 m_bSystemDialogs( false ),
265 m_xContext( rxContext
),
267 m_pDeInitSystray( 0 ),
269 m_bInitialized( false )
271 m_bSystemDialogs
= SvtMiscOptions().UseSystemFileDialog();
274 ShutdownIcon::~ShutdownIcon()
277 new IdleUnloader (&m_pPlugin
);
280 // ---------------------------------------------------------------------------
282 void ShutdownIcon::OpenURL( const OUString
& aURL
, const OUString
& rTarget
, const Sequence
< PropertyValue
>& aArgs
)
284 if ( getInstance() && getInstance()->m_xDesktop
.is() )
286 Reference
< XDispatchProvider
> xDispatchProvider( getInstance()->m_xDesktop
, UNO_QUERY
);
287 if ( xDispatchProvider
.is() )
289 com::sun::star::util::URL aDispatchURL
;
290 aDispatchURL
.Complete
= aURL
;
292 Reference
< util::XURLTransformer
> xURLTransformer( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
295 Reference
< com::sun::star::frame::XDispatch
> xDispatch
;
297 xURLTransformer
->parseStrict( aDispatchURL
);
298 xDispatch
= xDispatchProvider
->queryDispatch( aDispatchURL
, rTarget
, 0 );
299 if ( xDispatch
.is() )
300 xDispatch
->dispatch( aDispatchURL
, aArgs
);
302 catch ( com::sun::star::uno::RuntimeException
& )
306 catch ( com::sun::star::uno::Exception
& )
313 // ---------------------------------------------------------------------------
315 void ShutdownIcon::FileOpen()
317 if ( getInstance() && getInstance()->m_xDesktop
.is() )
319 ::SolarMutexGuard aGuard
;
321 getInstance()->StartFileDialog();
325 // ---------------------------------------------------------------------------
327 void ShutdownIcon::FromTemplate()
329 if ( getInstance() && getInstance()->m_xDesktop
.is() )
331 Reference
< ::com::sun::star::frame::XFramesSupplier
> xDesktop ( getInstance()->m_xDesktop
, UNO_QUERY
);
332 Reference
< ::com::sun::star::frame::XFrame
> xFrame( xDesktop
->getActiveFrame() );
334 xFrame
= Reference
< ::com::sun::star::frame::XFrame
>( xDesktop
, UNO_QUERY
);
337 aTargetURL
.Complete
= OUString( "slot:5500" );
338 Reference
< util::XURLTransformer
> xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
339 xTrans
->parseStrict( aTargetURL
);
341 Reference
< ::com::sun::star::frame::XDispatchProvider
> xProv( xFrame
, UNO_QUERY
);
342 Reference
< ::com::sun::star::frame::XDispatch
> xDisp
;
345 if ( aTargetURL
.Protocol
.compareToAscii("slot:") == COMPARE_EQUAL
)
346 xDisp
= xProv
->queryDispatch( aTargetURL
, OUString(), 0 );
348 xDisp
= xProv
->queryDispatch( aTargetURL
, OUString("_blank"), 0 );
352 Sequence
<PropertyValue
> aArgs(1);
353 PropertyValue
* pArg
= aArgs
.getArray();
354 pArg
[0].Name
= OUString("Referer");
355 pArg
[0].Value
<<= OUString("private:user");
356 Reference
< ::com::sun::star::frame::XNotifyingDispatch
> xNotifyer( xDisp
, UNO_QUERY
);
357 if ( xNotifyer
.is() )
360 xNotifyer
->dispatchWithNotification( aTargetURL
, aArgs
, new SfxNotificationListener_Impl() );
363 xDisp
->dispatch( aTargetURL
, aArgs
);
368 // ---------------------------------------------------------------------------
369 #include <tools/rcid.h>
370 OUString
ShutdownIcon::GetResString( int id
)
372 ::SolarMutexGuard aGuard
;
375 m_pResMgr
= SfxResId::GetResMgr();
376 ResId
aResId( id
, *m_pResMgr
);
377 aResId
.SetRT( RSC_STRING
);
378 if( !m_pResMgr
|| !m_pResMgr
->IsAvailable( aResId
) )
381 return ResId(id
, *m_pResMgr
).toString();
384 // ---------------------------------------------------------------------------
386 OUString
ShutdownIcon::GetUrlDescription( const OUString
& aUrl
)
388 ::SolarMutexGuard aGuard
;
390 return OUString( SvFileInformationManager::GetDescription( INetURLObject( aUrl
) ) );
393 // ---------------------------------------------------------------------------
395 void ShutdownIcon::StartFileDialog()
397 ::SolarMutexGuard aGuard
;
399 bool bDirty
= ( m_bSystemDialogs
!= static_cast<bool>(SvtMiscOptions().UseSystemFileDialog()) );
401 if ( m_pFileDlg
&& bDirty
)
403 // Destroy instance as changing the system file dialog setting
404 // forces us to create a new FileDialogHelper instance!
410 m_pFileDlg
= new FileDialogHelper(
411 ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION
,
412 SFXWB_MULTISELECTION
, String() );
413 m_pFileDlg
->StartExecuteModal( STATIC_LINK( this, ShutdownIcon
, DialogClosedHdl_Impl
) );
416 // ---------------------------------------------------------------------------
418 IMPL_STATIC_LINK( ShutdownIcon
, DialogClosedHdl_Impl
, FileDialogHelper
*, EMPTYARG
)
420 DBG_ASSERT( pThis
->m_pFileDlg
, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" );
422 // use constructor for filling up filters automatically!
423 if ( ERRCODE_NONE
== pThis
->m_pFileDlg
->GetError() )
425 Reference
< XFilePicker
> xPicker
= pThis
->m_pFileDlg
->GetFilePicker();
433 Reference
< XFilePickerControlAccess
> xPickerControls ( xPicker
, UNO_QUERY
);
434 Reference
< XFilterManager
> xFilterManager ( xPicker
, UNO_QUERY
);
436 Sequence
< OUString
> sFiles
= xPicker
->getFiles();
437 int nFiles
= sFiles
.getLength();
440 Sequence
< PropertyValue
> aArgs(3);
442 Reference
< com::sun::star::task::XInteractionHandler2
> xInteraction(
443 task::InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), 0) );
445 aArgs
[0].Name
= OUString("InteractionHandler");
446 aArgs
[0].Value
<<= xInteraction
;
448 sal_Int16 nMacroExecMode
= ::com::sun::star::document::MacroExecMode::USE_CONFIG
;
449 aArgs
[1].Name
= OUString("MacroExecutionMode");
450 aArgs
[1].Value
<<= nMacroExecMode
;
452 sal_Int16 nUpdateDoc
= ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG
;
453 aArgs
[2].Name
= OUString("UpdateDocMode");
454 aArgs
[2].Value
<<= nUpdateDoc
;
456 // use the filedlghelper to get the current filter name,
457 // because it removes the extensions before you get the filter name.
458 OUString
aFilterName( pThis
->m_pFileDlg
->GetCurrentFilter() );
460 if ( xPickerControls
.is() )
465 sal_Bool bReadOnly
= sal_False
;
468 xPickerControls
->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY
, 0 ) >>= bReadOnly
;
470 // Only set porperty if readonly is set to TRUE
474 aArgs
.realloc( ++nArgs
);
475 aArgs
[nArgs
-1].Name
= OUString("ReadOnly");
476 aArgs
[nArgs
-1].Value
<<= bReadOnly
;
479 // Get version string
481 sal_Int32 iVersion
= -1;
483 xPickerControls
->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION
, ControlActions::GET_SELECTED_ITEM_INDEX
) >>= iVersion
;
487 sal_Int16 uVersion
= (sal_Int16
)iVersion
;
489 aArgs
.realloc( ++nArgs
);
490 aArgs
[nArgs
-1].Name
= OUString("Version");
491 aArgs
[nArgs
-1].Value
<<= uVersion
;
494 // Retrieve the current filter
496 if ( aFilterName
.isEmpty() )
497 xPickerControls
->getValue( CommonFilePickerElementIds::LISTBOX_FILTER
, ControlActions::GET_SELECTED_ITEM
) >>= aFilterName
;
502 // Convert UI filter name to internal filter name
504 if ( !aFilterName
.isEmpty() )
506 const SfxFilter
* pFilter
= SFX_APP()->GetFilterMatcher().GetFilter4UIName( aFilterName
, 0, SFX_FILTER_NOTINFILEDLG
);
510 aFilterName
= pFilter
->GetFilterName();
512 if ( !aFilterName
.isEmpty() )
514 aArgs
.realloc( ++nArgs
);
515 aArgs
[nArgs
-1].Name
= OUString("FilterName");
516 aArgs
[nArgs
-1].Value
<<= aFilterName
;
522 OpenURL( sFiles
[0], OUString( "_default" ), aArgs
);
525 OUString aBaseDirURL
= sFiles
[0];
526 if ( !aBaseDirURL
.isEmpty() && aBaseDirURL
[aBaseDirURL
.getLength()-1] != '/' )
530 for ( iFiles
= 1; iFiles
< nFiles
; iFiles
++ )
532 OUString aURL
= aBaseDirURL
;
533 aURL
+= sFiles
[iFiles
];
534 OpenURL( aURL
, OUString( "_default" ), aArgs
);
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
549 if ( SvtMiscOptions().UseSystemFileDialog() )
551 delete pThis
->m_pFileDlg
;
552 pThis
->m_pFileDlg
= NULL
;
560 // ---------------------------------------------------------------------------
562 void ShutdownIcon::addTerminateListener()
564 ShutdownIcon
* pInst
= getInstance();
568 if (pInst
->m_bListenForTermination
)
571 Reference
< XDesktop2
> xDesktop
= pInst
->m_xDesktop
;
572 if ( ! xDesktop
.is())
575 xDesktop
->addTerminateListener( pInst
);
576 pInst
->m_bListenForTermination
= true;
579 // ---------------------------------------------------------------------------
581 void ShutdownIcon::terminateDesktop()
583 ShutdownIcon
* pInst
= getInstance();
587 Reference
< XDesktop2
> xDesktop
= pInst
->m_xDesktop
;
588 if ( ! xDesktop
.is())
591 // always remove ourselves as listener
592 pInst
->m_bListenForTermination
= true;
593 xDesktop
->removeTerminateListener( pInst
);
595 // terminate desktop only if no tasks exist
596 Reference
< XIndexAccess
> xTasks ( xDesktop
->getFrames(), UNO_QUERY
);
597 if( xTasks
.is() && xTasks
->getCount() < 1 )
598 new IdleTerminate( xDesktop
);
600 // remove the instance pointer
601 ShutdownIcon::pShutdownIcon
= 0;
604 // ---------------------------------------------------------------------------
606 ShutdownIcon
* ShutdownIcon::getInstance()
608 OSL_ASSERT( pShutdownIcon
);
609 return pShutdownIcon
;
612 // ---------------------------------------------------------------------------
614 ShutdownIcon
* ShutdownIcon::createInstance()
617 return pShutdownIcon
;
619 ShutdownIcon
*pIcon
= NULL
;
621 pIcon
= new ShutdownIcon( comphelper::getProcessComponentContext() );
623 pShutdownIcon
= pIcon
;
628 return pShutdownIcon
;
631 void ShutdownIcon::init() throw( ::com::sun::star::uno::Exception
)
633 // access resource system and sfx only protected by solarmutex
634 ::SolarMutexGuard aSolarGuard
;
635 ResMgr
*pResMgr
= SfxResId::GetResMgr();
637 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
640 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_xContext
);
642 m_xDesktop
= xDesktop
;
645 // ---------------------------------------------------------------------------
647 void SAL_CALL
ShutdownIcon::disposing()
653 // ---------------------------------------------------------------------------
656 void SAL_CALL
ShutdownIcon::disposing( const ::com::sun::star::lang::EventObject
& )
657 throw(::com::sun::star::uno::RuntimeException
)
661 // ---------------------------------------------------------------------------
663 // XTerminateListener
664 void SAL_CALL
ShutdownIcon::queryTermination( const ::com::sun::star::lang::EventObject
& )
665 throw(::com::sun::star::frame::TerminationVetoException
, ::com::sun::star::uno::RuntimeException
)
667 SAL_INFO("sfx2.appl", "ShutdownIcon::queryTermination: veto is " << m_bVeto
);
668 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
671 throw ::com::sun::star::frame::TerminationVetoException();
675 // ---------------------------------------------------------------------------
677 void SAL_CALL
ShutdownIcon::notifyTermination( const ::com::sun::star::lang::EventObject
& )
678 throw(::com::sun::star::uno::RuntimeException
)
683 // ---------------------------------------------------------------------------
685 void SAL_CALL
ShutdownIcon::initialize( const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
>& aArguments
)
686 throw( ::com::sun::star::uno::Exception
)
688 ::osl::ResettableMutexGuard
aGuard( m_aMutex
);
690 // third argument only sets veto, everything else will be ignored!
691 if (aArguments
.getLength() > 2)
693 sal_Bool bVeto
= sal_True
;
694 bVeto
= ::cppu::any2bool(aArguments
[2]);
699 if ( aArguments
.getLength() > 0 )
701 if ( !ShutdownIcon::pShutdownIcon
)
705 sal_Bool bQuickstart
= sal_False
;
706 bQuickstart
= ::cppu::any2bool( aArguments
[0] );
707 if( !bQuickstart
&& !GetAutostart() )
712 if ( !m_xDesktop
.is() )
715 /* Create a sub-classed instance - foo */
716 ShutdownIcon::pShutdownIcon
= this;
719 catch(const ::com::sun::star::lang::IllegalArgumentException
&)
724 if ( aArguments
.getLength() > 1 )
726 sal_Bool bAutostart
= sal_False
;
727 bAutostart
= ::cppu::any2bool( aArguments
[1] );
728 if (bAutostart
&& !GetAutostart())
729 SetAutostart( sal_True
);
730 if (!bAutostart
&& GetAutostart())
731 SetAutostart( sal_False
);
736 // -------------------------------
738 void ShutdownIcon::EnterModalMode()
740 bModalMode
= sal_True
;
743 // -------------------------------
745 void ShutdownIcon::LeaveModalMode()
747 bModalMode
= sal_False
;
751 // defined in shutdowniconw32.cxx
753 // defined in shutdowniconaqua.cxx
755 bool ShutdownIcon::IsQuickstarterInstalled()
757 #ifndef ENABLE_QUICKSTART_APPLET
759 #else // !ENABLE_QUICKSTART_APPLET
761 return LoadModule( NULL
, NULL
, NULL
);
763 #endif // !ENABLE_QUICKSTART_APPLET
767 // ---------------------------------------------------------------------------
769 #if defined (ENABLE_QUICKSTART_APPLET) && defined (UNX)
771 * Return the XDG autostart directory.
772 * http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
773 * Available in Unix and with Quickstart enabled.
774 * @param bCreate Create the directory if it does not exist yet.
775 * @return OUString containing the autostart directory path.
777 static OUString
getAutostartDir( bool bCreate
= false )
780 const char *pConfigHome
;
781 if( (pConfigHome
= getenv("XDG_CONFIG_HOME") ) )
782 aShortcut
= OStringToOUString( OString( pConfigHome
),
783 RTL_TEXTENCODING_UTF8
);
787 osl::Security().getHomeDir( aHomeURL
);
788 ::osl::File::getSystemPathFromFileURL( aHomeURL
, aShortcut
);
789 aShortcut
+= "/.config";
791 aShortcut
+= "/autostart";
794 OUString aShortcutUrl
;
795 osl::File::getFileURLFromSystemPath( aShortcut
, aShortcutUrl
);
796 osl::Directory::createPath( aShortcutUrl
);
802 OUString
ShutdownIcon::getShortcutName()
804 #ifndef ENABLE_QUICKSTART_APPLET
808 OUString
aShortcutName( "StarOffice 6.0" );
809 ResMgr
* pMgr
= SfxResId::GetResMgr();
812 ::SolarMutexGuard aGuard
;
813 aShortcutName
= SFX2_RESSTR(STR_QUICKSTART_LNKNAME
);
816 aShortcutName
+= ".lnk";
818 OUString
aShortcut(GetAutostartFolderNameW32());
820 aShortcut
+= aShortcutName
;
822 OUString aShortcut
= getAutostartDir();
823 aShortcut
+= "/qstart.desktop";
826 #endif // ENABLE_QUICKSTART_APPLET
829 bool ShutdownIcon::GetAutostart( )
835 #ifdef ENABLE_QUICKSTART_APPLET
836 OUString
aShortcut( getShortcutName() );
837 OUString aShortcutUrl
;
838 osl::File::getFileURLFromSystemPath( aShortcut
, aShortcutUrl
);
839 osl::File
f( aShortcutUrl
);
840 osl::File::RC error
= f
.open( osl_File_OpenFlag_Read
);
841 if( error
== osl::File::E_None
)
846 #endif // ENABLE_QUICKSTART_APPLET
851 void ShutdownIcon::SetAutostart( bool bActivate
)
853 #ifdef ENABLE_QUICKSTART_APPLET
854 OUString
aShortcut( getShortcutName() );
856 if( bActivate
&& IsQuickstarterInstalled() )
859 EnableAutostartW32( aShortcut
);
861 getAutostartDir( true );
863 OUString
aPath( "${BRAND_BASE_DIR}/share/xdg/qstart.desktop" );
864 Bootstrap::expandMacros( aPath
);
866 OUString aDesktopFile
;
867 ::osl::File::getSystemPathFromFileURL( aPath
, aDesktopFile
);
869 OString aDesktopFileUnx
= OUStringToOString( aDesktopFile
,
870 osl_getThreadTextEncoding() );
871 OString aShortcutUnx
= OUStringToOString( aShortcut
,
872 osl_getThreadTextEncoding() );
873 if ((0 != symlink(aDesktopFileUnx
.getStr(), aShortcutUnx
.getStr())) && (errno
== EEXIST
))
875 unlink(aShortcutUnx
.getStr());
876 int ret
= symlink(aDesktopFileUnx
.getStr(), aShortcutUnx
.getStr());
877 (void)ret
; //deliberately ignore return value, it's non-critical if it fails
880 ShutdownIcon
*pIcon
= ShutdownIcon::createInstance();
882 pIcon
->initSystray();
887 OUString aShortcutUrl
;
888 ::osl::File::getFileURLFromSystemPath( aShortcut
, aShortcutUrl
);
889 ::osl::File::remove( aShortcutUrl
);
893 ShutdownIcon
*pIcon
= getInstance();
894 pIcon
->deInitSystray();
899 (void)bActivate
; // unused variable
900 #endif // ENABLE_QUICKSTART_APPLET
903 static const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE
= 0;
906 void SAL_CALL
ShutdownIcon::setFastPropertyValue( ::sal_Int32 nHandle
,
907 const ::com::sun::star::uno::Any
& aValue
)
908 throw (::com::sun::star::beans::UnknownPropertyException
,
909 ::com::sun::star::beans::PropertyVetoException
,
910 ::com::sun::star::lang::IllegalArgumentException
,
911 ::com::sun::star::lang::WrappedTargetException
,
912 ::com::sun::star::uno::RuntimeException
)
916 case PROPHANDLE_TERMINATEVETOSTATE
:
918 // use new value in case it's a valid information only
919 ::sal_Bool
bState( sal_False
);
920 if (! (aValue
>>= bState
))
924 if (m_bVeto
&& ! m_bListenForTermination
)
925 addTerminateListener();
930 throw ::com::sun::star::beans::UnknownPropertyException();
935 ::com::sun::star::uno::Any SAL_CALL
ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle
)
936 throw (::com::sun::star::beans::UnknownPropertyException
,
937 ::com::sun::star::lang::WrappedTargetException
,
938 ::com::sun::star::uno::RuntimeException
)
940 ::com::sun::star::uno::Any aValue
;
943 case PROPHANDLE_TERMINATEVETOSTATE
:
945 bool bState
= (m_bListenForTermination
&& m_bVeto
);
951 throw ::com::sun::star::beans::UnknownPropertyException();
957 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */