blob: c81707e3bb22dc64b4d038d036e685858015fcc9 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"
#include <shutdownicon.hxx>
#include <app.hrc>
#include <sfx2/app.hxx>
#include <vos/mutex.hxx>
#include <svtools/imagemgr.hxx>
#include <svtools/miscopt.hxx>
// #include <cmdlineargs.hxx>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/frame/XDispatchResultListener.hpp>
#include <com/sun/star/frame/XNotifyingDispatch.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/ControlActions.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>
#include <sfx2/filedlghelper.hxx>
#include <sfx2/fcontnr.hxx>
#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif
#include <cppuhelper/compbase1.hxx>
#include <sfx2/dispatch.hxx>
#include <comphelper/extract.hxx>
#include <tools/urlobj.hxx>
#include <osl/security.hxx>
#include <osl/file.hxx>
#include <rtl/bootstrap.hxx>
#include <rtl/ustrbuf.hxx>
#include <tools/link.hxx>
#ifdef UNX // need symlink
#include <unistd.h>
#include <errno.h>
#endif
#include <vcl/timer.hxx>
#include "sfx2/sfxresid.hxx"
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::ui::dialogs;
using namespace ::vos;
#ifdef WNT
using ::rtl::OUString;
#else
using namespace ::rtl;
#endif
using namespace ::sfx2;
#ifdef ENABLE_QUICKSTART_APPLET
# if !defined(WIN32) && !defined(QUARTZ)
extern "C" { static void SAL_CALL thisModule() {} }
# endif
#endif
#if defined(UNX) && defined(ENABLE_SYSTRAY_GTK)
#define PLUGIN_NAME libqstart_gtk.so
#endif
class SfxNotificationListener_Impl : public cppu::WeakImplHelper1< XDispatchResultListener >
{
public:
virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& aEvent ) throw( RuntimeException );
virtual void SAL_CALL disposing( const EventObject& aEvent ) throw( RuntimeException );
};
void SAL_CALL SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
{
ShutdownIcon::LeaveModalMode();
}
void SAL_CALL SfxNotificationListener_Impl::disposing( const EventObject& ) throw( RuntimeException )
{
}
SFX_IMPL_XSERVICEINFO( ShutdownIcon, "com.sun.star.office.Quickstart", "com.sun.star.comp.desktop.QuickstartWrapper" ) \
SFX_IMPL_ONEINSTANCEFACTORY( ShutdownIcon );
bool ShutdownIcon::bModalMode = false;
ShutdownIcon* ShutdownIcon::pShutdownIcon = NULL;
// To remove conditionals
extern "C" {
static void disabled_initSystray() { }
static void disabled_deInitSystray() { }
}
#define DOSTRING( x ) #x
#define STRING( x ) DOSTRING( x )
bool ShutdownIcon::LoadModule( osl::Module **pModule,
oslGenericFunction *pInit,
oslGenericFunction *pDeInit )
{
if ( pModule )
{
OSL_ASSERT ( pInit && pDeInit );
*pInit = *pDeInit = NULL;
*pModule = NULL;
}
#ifdef ENABLE_QUICKSTART_APPLET
# ifdef WIN32
if ( pModule )
{
*pInit = win32_init_sys_tray;
*pDeInit = win32_shutdown_sys_tray;
}
return true;
# elif defined QUARTZ
*pInit = aqua_init_systray;
*pDeInit = aqua_shutdown_systray;
return true;
# else // UNX
osl::Module *pPlugin;
pPlugin = new osl::Module();
oslGenericFunction pTmpInit = NULL;
oslGenericFunction pTmpDeInit = NULL;
if ( pPlugin->loadRelative( &thisModule, OUString( RTL_CONSTASCII_USTRINGPARAM( STRING( PLUGIN_NAME ) ) ) ) )
{
pTmpInit = pPlugin->getFunctionSymbol(
OUString( RTL_CONSTASCII_USTRINGPARAM( "plugin_init_sys_tray" ) ) );
pTmpDeInit = pPlugin->getFunctionSymbol(
OUString( RTL_CONSTASCII_USTRINGPARAM( "plugin_shutdown_sys_tray" ) ) );
}
if ( !pTmpInit || !pTmpDeInit )
{
delete pPlugin;
pPlugin = NULL;
}
if ( pModule )
{
*pModule = pPlugin;
*pInit = pTmpInit;
*pDeInit = pTmpDeInit;
}
else
{
bool bRet = pPlugin != NULL;
delete pPlugin;
return bRet;
}
# endif // UNX
#endif // ENABLE_QUICKSTART_APPLET
if ( pModule )
{
if ( !*pInit )
*pInit = disabled_initSystray;
if ( !*pDeInit )
*pDeInit = disabled_deInitSystray;
}
return true;
}
struct AsyncDesktopTerminationData
{
Reference< XDesktop > mxDesktop;
AsyncDesktopTerminationData( const Reference< XDesktop > &xDesktop )
: mxDesktop( xDesktop ) {}
};
class IdleUnloader : Timer
{
::osl::Module *m_pModule;
public:
IdleUnloader (::osl::Module **pModule) :
m_pModule (*pModule)
{
*pModule = NULL;
Start();
}
virtual void Timeout()
{
delete m_pModule;
delete this;
}
};
void ShutdownIcon::initSystray()
{
if (m_bInitialized)
return;
m_bInitialized = true;
(void) LoadModule( &m_pPlugin, &m_pInitSystray, &m_pDeInitSystray );
m_bVeto = true;
m_pInitSystray();
}
void ShutdownIcon::deInitSystray()
{
if (!m_bInitialized)
return;
if (m_pDeInitSystray)
m_pDeInitSystray();
m_bVeto = false;
m_pInitSystray = 0;
m_pDeInitSystray = 0;
new IdleUnloader (&m_pPlugin);
delete m_pFileDlg;
m_pFileDlg = NULL;
m_bInitialized = false;
}
ShutdownIcon::ShutdownIcon( Reference< XMultiServiceFactory > aSMgr ) :
ShutdownIconServiceBase( m_aMutex ),
m_bVeto ( false ),
m_bListenForTermination ( false ),
m_bSystemDialogs( false ),
m_pResMgr( NULL ),
m_pFileDlg( NULL ),
m_xServiceManager( aSMgr ),
m_pInitSystray( 0 ),
m_pDeInitSystray( 0 ),
m_pPlugin( 0 ),
m_bInitialized( false )
{
m_bSystemDialogs = SvtMiscOptions().UseSystemFileDialog();
}
ShutdownIcon::~ShutdownIcon()
{
deInitSystray();
new IdleUnloader (&m_pPlugin);
}
// ---------------------------------------------------------------------------
void ShutdownIcon::OpenURL( const ::rtl::OUString& aURL, const ::rtl::OUString& rTarget, const Sequence< PropertyValue >& aArgs )
{
if ( getInstance() && getInstance()->m_xDesktop.is() )
{
Reference < XDispatchProvider > xDispatchProvider( getInstance()->m_xDesktop, UNO_QUERY );
if ( xDispatchProvider.is() )
{
com::sun::star::util::URL aDispatchURL;
aDispatchURL.Complete = aURL;
Reference < com::sun::star::util::XURLTransformer > xURLTransformer(
::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.util.URLTransformer") ),
com::sun::star::uno::UNO_QUERY );
if ( xURLTransformer.is() )
{
try
{
Reference< com::sun::star::frame::XDispatch > xDispatch;
xURLTransformer->parseStrict( aDispatchURL );
xDispatch = xDispatchProvider->queryDispatch( aDispatchURL, rTarget, 0 );
if ( xDispatch.is() )
xDispatch->dispatch( aDispatchURL, aArgs );
}
catch ( com::sun::star::uno::RuntimeException& )
{
throw;
}
catch ( com::sun::star::uno::Exception& )
{
}
}
}
}
}
// ---------------------------------------------------------------------------
void ShutdownIcon::FileOpen()
{
if ( getInstance() && getInstance()->m_xDesktop.is() )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
EnterModalMode();
getInstance()->StartFileDialog();
}
}
// ---------------------------------------------------------------------------
void ShutdownIcon::FromTemplate()
{
if ( getInstance() && getInstance()->m_xDesktop.is() )
{
Reference < ::com::sun::star::frame::XFramesSupplier > xDesktop ( getInstance()->m_xDesktop, UNO_QUERY);
Reference < ::com::sun::star::frame::XFrame > xFrame( xDesktop->getActiveFrame() );
if ( !xFrame.is() )
xFrame = Reference < ::com::sun::star::frame::XFrame >( xDesktop, UNO_QUERY );
URL aTargetURL;
aTargetURL.Complete = OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:5500" ) );
Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
xTrans->parseStrict( aTargetURL );
Reference < ::com::sun::star::frame::XDispatchProvider > xProv( xFrame, UNO_QUERY );
Reference < ::com::sun::star::frame::XDispatch > xDisp;
if ( xProv.is() )
{
if ( aTargetURL.Protocol.compareToAscii("slot:") == COMPARE_EQUAL )
xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
else
xDisp = xProv->queryDispatch( aTargetURL, ::rtl::OUString::createFromAscii("_blank"), 0 );
}
if ( xDisp.is() )
{
Sequence<PropertyValue> aArgs(1);
PropertyValue* pArg = aArgs.getArray();
pArg[0].Name = rtl::OUString::createFromAscii("Referer");
pArg[0].Value <<= ::rtl::OUString::createFromAscii("private:user");
Reference< ::com::sun::star::frame::XNotifyingDispatch > xNotifyer( xDisp, UNO_QUERY );
if ( xNotifyer.is() )
{
EnterModalMode();
xNotifyer->dispatchWithNotification( aTargetURL, aArgs, new SfxNotificationListener_Impl() );
}
else
xDisp->dispatch( aTargetURL, aArgs );
}
}
}
// ---------------------------------------------------------------------------
#include <tools/rcid.h>
OUString ShutdownIcon::GetResString( int id )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
if( ! m_pResMgr )
m_pResMgr = SfxResId::GetResMgr();
ResId aResId( id, *m_pResMgr );
aResId.SetRT( RSC_STRING );
if( !m_pResMgr || !m_pResMgr->IsAvailable( aResId ) )
return OUString();
UniString aRes( ResId(id, *m_pResMgr) );
return OUString( aRes );
}
// ---------------------------------------------------------------------------
OUString ShutdownIcon::GetUrlDescription( const OUString& aUrl )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
return OUString( SvFileInformationManager::GetDescription( INetURLObject( aUrl ) ) );
}
// ---------------------------------------------------------------------------
void ShutdownIcon::StartFileDialog()
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
bool bDirty = ( m_bSystemDialogs != static_cast<bool>(SvtMiscOptions().UseSystemFileDialog()) );
if ( m_pFileDlg && bDirty )
{
// Destroy instance as changing the system file dialog setting
// forces us to create a new FileDialogHelper instance!
delete m_pFileDlg;
m_pFileDlg = NULL;
}
if ( !m_pFileDlg )
m_pFileDlg = new FileDialogHelper( WB_OPEN | SFXWB_MULTISELECTION, String() );
m_pFileDlg->StartExecuteModal( STATIC_LINK( this, ShutdownIcon, DialogClosedHdl_Impl ) );
}
// ---------------------------------------------------------------------------
IMPL_STATIC_LINK( ShutdownIcon, DialogClosedHdl_Impl, FileDialogHelper*, EMPTYARG )
{
DBG_ASSERT( pThis->m_pFileDlg, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" );
// use ctor for filling up filters automatically! #89169#
if ( ERRCODE_NONE == pThis->m_pFileDlg->GetError() )
{
Reference< XFilePicker > xPicker = pThis->m_pFileDlg->GetFilePicker();
try
{
if ( xPicker.is() )
{
Reference < XFilePickerControlAccess > xPickerControls ( xPicker, UNO_QUERY );
Reference < XFilterManager > xFilterManager ( xPicker, UNO_QUERY );
Sequence< OUString > sFiles = xPicker->getFiles();
int nFiles = sFiles.getLength();
int nArgs=3;
Sequence< PropertyValue > aArgs(3);
Reference < com::sun::star::task::XInteractionHandler > xInteraction(
::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.task.InteractionHandler") ),
com::sun::star::uno::UNO_QUERY );
aArgs[0].Name = OUString::createFromAscii( "InteractionHandler" );
aArgs[0].Value <<= xInteraction;
sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
aArgs[1].Name = OUString::createFromAscii( "MacroExecutionMode" );
aArgs[1].Value <<= nMacroExecMode;
sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
aArgs[2].Name = OUString::createFromAscii( "UpdateDocMode" );
aArgs[2].Value <<= nUpdateDoc;
// pb: #102643# use the filedlghelper to get the current filter name,
// because it removes the extensions before you get the filter name.
OUString aFilterName( pThis->m_pFileDlg->GetCurrentFilter() );
if ( xPickerControls.is() )
{
// Set readonly flag
sal_Bool bReadOnly = sal_False;
xPickerControls->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ) >>= bReadOnly;
// #95239#: Only set porperty if readonly is set to TRUE
if ( bReadOnly )
{
aArgs.realloc( ++nArgs );
aArgs[nArgs-1].Name = OUString::createFromAscii( "ReadOnly" );
aArgs[nArgs-1].Value <<= bReadOnly;
}
// Get version string
sal_Int32 iVersion = -1;
xPickerControls->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, ControlActions::GET_SELECTED_ITEM_INDEX ) >>= iVersion;
if ( iVersion >= 0 )
{
sal_Int16 uVersion = (sal_Int16)iVersion;
aArgs.realloc( ++nArgs );
aArgs[nArgs-1].Name = OUString::createFromAscii( "Version" );
aArgs[nArgs-1].Value <<= uVersion;
}
// Retrieve the current filter
if ( !aFilterName.getLength() )
xPickerControls->getValue( CommonFilePickerElementIds::LISTBOX_FILTER, ControlActions::GET_SELECTED_ITEM ) >>= aFilterName;
}
// Convert UI filter name to internal filter name
if ( aFilterName.getLength() )
{
const SfxFilter* pFilter = SFX_APP()->GetFilterMatcher().GetFilter4UIName( aFilterName, 0, SFX_FILTER_NOTINFILEDLG );
if ( pFilter )
{
aFilterName = pFilter->GetFilterName();
if ( aFilterName.getLength() )
{
aArgs.realloc( ++nArgs );
aArgs[nArgs-1].Name = OUString::createFromAscii( "FilterName" );
aArgs[nArgs-1].Value <<= aFilterName;
}
}
}
if ( 1 == nFiles )
OpenURL( sFiles[0], OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ), aArgs );
else
{
OUString aBaseDirURL = sFiles[0];
if ( aBaseDirURL.getLength() > 0 && aBaseDirURL[aBaseDirURL.getLength()-1] != '/' )
aBaseDirURL += OUString::createFromAscii("/");
int iFiles;
for ( iFiles = 1; iFiles < nFiles; iFiles++ )
{
OUString aURL = aBaseDirURL;
aURL += sFiles[iFiles];
OpenURL( aURL, OUString( RTL_CONSTASCII_USTRINGPARAM( "_default" ) ), aArgs );
}
}
}
}
catch ( ... )
{
}
}
#ifdef WNT
// #103346 Destroy dialog to prevent problems with custom controls
// This fix is dependent on the dialog settings. Destroying the dialog here will
// crash the non-native dialog implementation! Therefore make this dependent on
// the settings.
if ( SvtMiscOptions().UseSystemFileDialog() )
{
delete pThis->m_pFileDlg;
pThis->m_pFileDlg = NULL;
}
#endif
LeaveModalMode();
return 0;
}
// ---------------------------------------------------------------------------
void ShutdownIcon::addTerminateListener()
{
ShutdownIcon* pInst = getInstance();
if ( ! pInst)
return;
if (pInst->m_bListenForTermination)
return;
Reference< XDesktop > xDesktop = pInst->m_xDesktop;
if ( ! xDesktop.is())
return;
xDesktop->addTerminateListener( pInst );
pInst->m_bListenForTermination = true;
}
// ---------------------------------------------------------------------------
void ShutdownIcon::terminateDesktop()
{
ShutdownIcon* pInst = getInstance();
if ( ! pInst)
return;
Reference< XDesktop > xDesktop = pInst->m_xDesktop;
if ( ! xDesktop.is())
return;
// always remove ourselves as listener
pInst->m_bListenForTermination = true;
xDesktop->removeTerminateListener( pInst );
// terminate desktop only if no tasks exist
Reference< XFramesSupplier > xSupplier( xDesktop, UNO_QUERY );
if ( xSupplier.is() )
{
Reference< XIndexAccess > xTasks ( xSupplier->getFrames(), UNO_QUERY );
if( xTasks.is() && xTasks->getCount() < 1 )
{
AsyncDesktopTerminationData * pData = new AsyncDesktopTerminationData( xDesktop );
if ( !Application::PostUserEvent( STATIC_LINK( 0, ShutdownIcon, AsyncDesktopTermination ), pData ) )
delete pData;
}
}
// remove the instance pointer
ShutdownIcon::pShutdownIcon = 0;
}
IMPL_STATIC_LINK_NOINSTANCE( ShutdownIcon, AsyncDesktopTermination, AsyncDesktopTerminationData*, pData )
{
if ( pData && pData->mxDesktop.is() )
pData->mxDesktop->terminate();
delete pData;
return 0;
}
// ---------------------------------------------------------------------------
ShutdownIcon* ShutdownIcon::getInstance()
{
OSL_ASSERT( pShutdownIcon );
return pShutdownIcon;
}
// ---------------------------------------------------------------------------
ShutdownIcon* ShutdownIcon::createInstance()
{
if (pShutdownIcon)
return pShutdownIcon;
ShutdownIcon *pIcon = NULL;
try {
Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() );
pIcon = new ShutdownIcon( xSMgr );
pIcon->init ();
pShutdownIcon = pIcon;
} catch (...) {
delete pIcon;
}
return pShutdownIcon;
}
void ShutdownIcon::init() throw( ::com::sun::star::uno::Exception )
{
// access resource system and sfx only protected by solarmutex
vos::OGuard aSolarGuard( Application::GetSolarMutex() );
ResMgr *pResMgr = SfxResId::GetResMgr();
::osl::ResettableMutexGuard aGuard( m_aMutex );
m_pResMgr = pResMgr;
aGuard.clear();
Reference < XDesktop > xDesktop( m_xServiceManager->createInstance(
DEFINE_CONST_UNICODE( "com.sun.star.frame.Desktop" )),
UNO_QUERY );
aGuard.reset();
m_xDesktop = xDesktop;
}
// ---------------------------------------------------------------------------
void SAL_CALL ShutdownIcon::disposing()
{
m_xServiceManager = Reference< XMultiServiceFactory >();
m_xDesktop = Reference< XDesktop >();
}
// ---------------------------------------------------------------------------
// XEventListener
void SAL_CALL ShutdownIcon::disposing( const ::com::sun::star::lang::EventObject& )
throw(::com::sun::star::uno::RuntimeException)
{
}
// ---------------------------------------------------------------------------
// XTerminateListener
void SAL_CALL ShutdownIcon::queryTermination( const ::com::sun::star::lang::EventObject& )
throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException)
{
::osl::ClearableMutexGuard aGuard( m_aMutex );
if ( m_bVeto )
throw ::com::sun::star::frame::TerminationVetoException();
}
// ---------------------------------------------------------------------------
void SAL_CALL ShutdownIcon::notifyTermination( const ::com::sun::star::lang::EventObject& )
throw(::com::sun::star::uno::RuntimeException)
{
}
// ---------------------------------------------------------------------------
void SAL_CALL ShutdownIcon::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
throw( ::com::sun::star::uno::Exception )
{
::osl::ResettableMutexGuard aGuard( m_aMutex );
// third argument only sets veto, everything else will be ignored!
if (aArguments.getLength() > 2)
{
sal_Bool bVeto = sal_True;
bVeto = ::cppu::any2bool(aArguments[2]);
m_bVeto = bVeto;
return;
}
if ( aArguments.getLength() > 0 )
{
if ( !ShutdownIcon::pShutdownIcon )
{
try
{
sal_Bool bQuickstart = sal_False;
bQuickstart = ::cppu::any2bool( aArguments[0] );
if( !bQuickstart && !GetAutostart() )
return;
aGuard.clear();
init ();
aGuard.reset();
if ( !m_xDesktop.is() )
return;
/* Create a sub-classed instance - foo */
ShutdownIcon::pShutdownIcon = this;
initSystray();
#ifdef OS2
// above win32 starts the quickstart thread, but we have
// quickstart running only when -quickstart is specified
// on command line (next boot).
// so if -quickstart was not specified, we cannot issue
// quickstart veto on shutdown.
if (bQuickstart)
{
// disable shutdown
ShutdownIcon::getInstance()->SetVeto( true );
ShutdownIcon::getInstance()->addTerminateListener();
}
#endif
}
catch(const ::com::sun::star::lang::IllegalArgumentException&)
{
}
}
}
if ( aArguments.getLength() > 1 )
{
sal_Bool bAutostart = sal_False;
bAutostart = ::cppu::any2bool( aArguments[1] );
if (bAutostart && !GetAutostart())
SetAutostart( sal_True );
if (!bAutostart && GetAutostart())
SetAutostart( sal_False );
}
}
// -------------------------------
void ShutdownIcon::EnterModalMode()
{
bModalMode = sal_True;
}
// -------------------------------
void ShutdownIcon::LeaveModalMode()
{
bModalMode = sal_False;
}
#ifdef WNT
// defined in shutdowniconw32.cxx
#elif defined(OS2)
// defined in shutdowniconOs2.cxx
#elif defined QUARTZ
// defined in shutdowniconaqua.cxx
#else
bool ShutdownIcon::IsQuickstarterInstalled()
{
#ifndef ENABLE_QUICKSTART_APPLET
return false;
#else // !ENABLE_QUICKSTART_APPLET
#ifdef UNX
return LoadModule( NULL, NULL, NULL);
#endif // UNX
#endif // !ENABLE_QUICKSTART_APPLET
}
#endif // !WNT
// ---------------------------------------------------------------------------
#if defined (ENABLE_QUICKSTART_APPLET) && defined (UNX)
static OUString getDotAutostart( bool bCreate = false )
{
OUString aShortcut;
const char *pConfigHome;
if( (pConfigHome = getenv("XDG_CONFIG_HOME") ) )
aShortcut = OStringToOUString( OString( pConfigHome ), RTL_TEXTENCODING_UTF8 );
else
{
OUString aHomeURL;
osl::Security().getHomeDir( aHomeURL );
::osl::File::getSystemPathFromFileURL( aHomeURL, aShortcut );
aShortcut += OUString( RTL_CONSTASCII_USTRINGPARAM( "/.config" ) );
}
aShortcut += OUString( RTL_CONSTASCII_USTRINGPARAM( "/autostart" ) );
if (bCreate)
{
OUString aShortcutUrl;
osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
osl::Directory::createPath( aShortcutUrl );
}
return aShortcut;
}
#endif
rtl::OUString ShutdownIcon::getShortcutName()
{
#ifndef ENABLE_QUICKSTART_APPLET
return OUString();
#else
OUString aShortcutName( RTL_CONSTASCII_USTRINGPARAM( "StarOffice 6.0" ) );
ResMgr* pMgr = SfxResId::GetResMgr();
if( pMgr )
{
::vos::OGuard aGuard( Application::GetSolarMutex() );
UniString aRes( SfxResId( STR_QUICKSTART_LNKNAME ) );
aShortcutName = OUString( aRes );
}
#ifdef WNT
aShortcutName += OUString( RTL_CONSTASCII_USTRINGPARAM( ".lnk" ) );
OUString aShortcut(GetAutostartFolderNameW32());
aShortcut += OUString( RTL_CONSTASCII_USTRINGPARAM( "\\" ) );
aShortcut += aShortcutName;
#else // UNX
OUStringBuffer aStrBuff( getDotAutostart() );
aStrBuff.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/" ) );
if ( sal_Int32 len = aShortcutName.getLength() )
aStrBuff.append( aShortcutName.getStr(), len );
else
aStrBuff.appendAscii( RTL_CONSTASCII_STRINGPARAM( "qstart" ) );
aStrBuff.appendAscii( RTL_CONSTASCII_STRINGPARAM( ".desktop" ) );
OUString aShortcut( aStrBuff.makeStringAndClear() );
#endif // UNX
return aShortcut;
#endif // ENABLE_QUICKSTART_APPLET
}
bool ShutdownIcon::GetAutostart( )
{
#if defined(OS2)
return GetAutostartOs2( );
#elif defined QUARTZ
return true;
#else
bool bRet = false;
#ifdef ENABLE_QUICKSTART_APPLET
OUString aShortcut( getShortcutName() );
OUString aShortcutUrl;
osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
osl::File f( aShortcutUrl );
osl::File::RC error = f.open( OpenFlag_Read );
if( error == osl::File::E_None )
{
f.close();
bRet = true;
}
#endif // ENABLE_QUICKSTART_APPLET
return bRet;
#endif
}
void ShutdownIcon::SetAutostart( bool bActivate )
{
#ifdef ENABLE_QUICKSTART_APPLET
OUString aShortcut( getShortcutName() );
if( bActivate && IsQuickstarterInstalled() )
{
#ifdef WNT
EnableAutostartW32( aShortcut );
#else // UNX
getDotAutostart( true );
OUString aPath( RTL_CONSTASCII_USTRINGPARAM("${OOO_BASE_DIR}/share/xdg/qstart.desktop" ) );
Bootstrap::expandMacros( aPath );
OUString aDesktopFile;
::osl::File::getSystemPathFromFileURL( aPath, aDesktopFile );
OString aDesktopFileUnx = OUStringToOString( aDesktopFile,
osl_getThreadTextEncoding() );
OString aShortcutUnx = OUStringToOString( aShortcut,
osl_getThreadTextEncoding() );
if ((0 != symlink( aDesktopFileUnx.getStr(), aShortcutUnx.getStr())) && (errno == EEXIST))
{
unlink( aShortcutUnx.getStr());
symlink( aDesktopFileUnx.getStr(), aShortcutUnx.getStr());
}
ShutdownIcon *pIcon = ShutdownIcon::createInstance();
if( pIcon )
pIcon->initSystray();
#endif // UNX
}
else
{
OUString aShortcutUrl;
::osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
::osl::File::remove( aShortcutUrl );
#ifdef UNX
if (pShutdownIcon)
{
ShutdownIcon *pIcon = getInstance();
pIcon->deInitSystray();
}
#endif
}
#elif defined OS2
SetAutostartOs2( bActivate );
#else
(void)bActivate; // unused variable
#endif // ENABLE_QUICKSTART_APPLET
}
static const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE = 0;
// XFastPropertySet
void SAL_CALL ShutdownIcon::setFastPropertyValue( ::sal_Int32 nHandle,
const ::com::sun::star::uno::Any& aValue )
throw (::com::sun::star::beans::UnknownPropertyException,
::com::sun::star::beans::PropertyVetoException,
::com::sun::star::lang::IllegalArgumentException,
::com::sun::star::lang::WrappedTargetException,
::com::sun::star::uno::RuntimeException)
{
switch(nHandle)
{
case PROPHANDLE_TERMINATEVETOSTATE :
{
// use new value in case it's a valid information only
::sal_Bool bState( sal_False );
if (! (aValue >>= bState))
return;
m_bVeto = bState;
if (m_bVeto && ! m_bListenForTermination)
addTerminateListener();
}
break;
default :
throw ::com::sun::star::beans::UnknownPropertyException();
}
}
// XFastPropertySet
::com::sun::star::uno::Any SAL_CALL ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle )
throw (::com::sun::star::beans::UnknownPropertyException,
::com::sun::star::lang::WrappedTargetException,
::com::sun::star::uno::RuntimeException)
{
::com::sun::star::uno::Any aValue;
switch(nHandle)
{
case PROPHANDLE_TERMINATEVETOSTATE :
{
bool bState = (m_bListenForTermination && m_bVeto);
aValue <<= bState;
}
break;
default :
throw ::com::sun::star::beans::UnknownPropertyException();
}
return aValue;
}