| /************************************************************** |
| * |
| * 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; |
| } |