3808ef2b27
and cid#1545526 COPY_INSTEAD_OF_MOVE cid#1545442 COPY_INSTEAD_OF_MOVE cid#1545426 COPY_INSTEAD_OF_MOVE cid#1545425 COPY_INSTEAD_OF_MOVE cid#1545387 COPY_INSTEAD_OF_MOVE cid#1545379 COPY_INSTEAD_OF_MOVE cid#1545337 COPY_INSTEAD_OF_MOVE cid#1545334 COPY_INSTEAD_OF_MOVE cid#1545289 COPY_INSTEAD_OF_MOVE cid#1545282 COPY_INSTEAD_OF_MOVE cid#1545270 COPY_INSTEAD_OF_MOVE cid#1545237 COPY_INSTEAD_OF_MOVE Change-Id: Iae44a7347c85ae2e367bf672214b2013f30466f6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161968 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
681 lines
20 KiB
C++
681 lines
20 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* 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 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
#include <sal/log.hxx>
|
|
|
|
#include "shutdownicon.hxx"
|
|
#include <sfx2/strings.hrc>
|
|
#include <sfx2/app.hxx>
|
|
#include <svtools/imagemgr.hxx>
|
|
#include <com/sun/star/task/InteractionHandler.hpp>
|
|
#include <com/sun/star/frame/Desktop.hpp>
|
|
#include <com/sun/star/frame/TerminationVetoException.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/XFrame.hpp>
|
|
#include <com/sun/star/util/URLTransformer.hpp>
|
|
#include <com/sun/star/util/XURLTransformer.hpp>
|
|
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
|
|
#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
|
|
#include <com/sun/star/ui/dialogs/TemplateDescription.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/docfilt.hxx>
|
|
#include <sfx2/fcontnr.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <comphelper/propertyvalue.hxx>
|
|
#include <cppuhelper/implbase.hxx>
|
|
#include <cppuhelper/supportsservice.hxx>
|
|
#include <comphelper/extract.hxx>
|
|
#include <officecfg/Office/Common.hxx>
|
|
#include <tools/urlobj.hxx>
|
|
#include <tools/debug.hxx>
|
|
#include <osl/file.hxx>
|
|
#include <osl/module.hxx>
|
|
#include <rtl/ref.hxx>
|
|
#include <utility>
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#include <sfx2/sfxresid.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace ::com::sun::star::uno;
|
|
using namespace ::com::sun::star::frame;
|
|
using namespace ::com::sun::star::container;
|
|
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 ::sfx2;
|
|
|
|
class SfxNotificationListener_Impl : public cppu::WeakImplHelper< XDispatchResultListener >
|
|
{
|
|
public:
|
|
virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& aEvent ) override;
|
|
virtual void SAL_CALL disposing( const EventObject& aEvent ) override;
|
|
};
|
|
|
|
void SAL_CALL SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent& )
|
|
{
|
|
ShutdownIcon::LeaveModalMode();
|
|
}
|
|
|
|
void SAL_CALL SfxNotificationListener_Impl::disposing( const EventObject& )
|
|
{
|
|
}
|
|
|
|
OUString SAL_CALL ShutdownIcon::getImplementationName()
|
|
{
|
|
return "com.sun.star.comp.desktop.QuickstartWrapper";
|
|
}
|
|
|
|
sal_Bool SAL_CALL ShutdownIcon::supportsService(OUString const & ServiceName)
|
|
{
|
|
return cppu::supportsService(this, ServiceName);
|
|
}
|
|
|
|
css::uno::Sequence<OUString> SAL_CALL ShutdownIcon::getSupportedServiceNames()
|
|
{
|
|
return { "com.sun.star.office.Quickstart" };
|
|
}
|
|
|
|
bool ShutdownIcon::bModalMode = false;
|
|
rtl::Reference<ShutdownIcon> ShutdownIcon::pShutdownIcon;
|
|
|
|
void ShutdownIcon::initSystray()
|
|
{
|
|
if (m_bInitialized)
|
|
return;
|
|
m_bInitialized = true;
|
|
|
|
#ifdef ENABLE_QUICKSTART_APPLET
|
|
# ifdef _WIN32
|
|
win32_init_sys_tray();
|
|
# elif defined MACOSX
|
|
aqua_init_systray();
|
|
# endif // MACOSX
|
|
#endif // ENABLE_QUICKSTART_APPLET
|
|
}
|
|
|
|
void ShutdownIcon::deInitSystray()
|
|
{
|
|
if (!m_bInitialized)
|
|
return;
|
|
|
|
#ifdef ENABLE_QUICKSTART_APPLET
|
|
# ifdef _WIN32
|
|
win32_shutdown_sys_tray();
|
|
# elif defined MACOSX
|
|
aqua_shutdown_systray();
|
|
# endif // MACOSX
|
|
#endif // ENABLE_QUICKSTART_APPLET
|
|
|
|
m_bVeto = false;
|
|
|
|
m_pFileDlg.reset();
|
|
m_bInitialized = false;
|
|
}
|
|
|
|
static bool UseSystemFileDialog()
|
|
{
|
|
return !Application::IsHeadlessModeEnabled() && officecfg::Office::Common::Misc::UseSystemFileDialog::get();
|
|
}
|
|
|
|
ShutdownIcon::ShutdownIcon( css::uno::Reference< XComponentContext > xContext ) :
|
|
m_bVeto ( false ),
|
|
m_bListenForTermination ( false ),
|
|
m_bSystemDialogs(UseSystemFileDialog()),
|
|
m_xContext(std::move( xContext )),
|
|
m_bInitialized( false )
|
|
{
|
|
}
|
|
|
|
ShutdownIcon::~ShutdownIcon()
|
|
{
|
|
deInitSystray();
|
|
}
|
|
|
|
|
|
void ShutdownIcon::OpenURL( const OUString& aURL, const OUString& rTarget, const Sequence< PropertyValue >& aArgs )
|
|
{
|
|
if ( !getInstance() || !getInstance()->m_xDesktop.is() )
|
|
return;
|
|
|
|
css::uno::Reference < XDispatchProvider > xDispatchProvider = getInstance()->m_xDesktop;
|
|
if ( !xDispatchProvider.is() )
|
|
return;
|
|
|
|
css::util::URL aDispatchURL;
|
|
aDispatchURL.Complete = aURL;
|
|
|
|
css::uno::Reference< util::XURLTransformer > xURLTransformer( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
|
|
try
|
|
{
|
|
css::uno::Reference< css::frame::XDispatch > xDispatch;
|
|
|
|
xURLTransformer->parseStrict( aDispatchURL );
|
|
xDispatch = xDispatchProvider->queryDispatch( aDispatchURL, rTarget, 0 );
|
|
if ( xDispatch.is() )
|
|
xDispatch->dispatch( aDispatchURL, aArgs );
|
|
}
|
|
catch ( css::uno::RuntimeException& )
|
|
{
|
|
throw;
|
|
}
|
|
catch ( css::uno::Exception& )
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
void ShutdownIcon::FileOpen()
|
|
{
|
|
if ( getInstance() && getInstance()->m_xDesktop.is() )
|
|
{
|
|
::SolarMutexGuard aGuard;
|
|
EnterModalMode();
|
|
getInstance()->StartFileDialog();
|
|
}
|
|
}
|
|
|
|
|
|
void ShutdownIcon::FromTemplate()
|
|
{
|
|
if ( !getInstance() || !getInstance()->m_xDesktop.is() )
|
|
return;
|
|
|
|
css::uno::Reference < css::frame::XFramesSupplier > xDesktop = getInstance()->m_xDesktop;
|
|
css::uno::Reference < css::frame::XFrame > xFrame( xDesktop->getActiveFrame() );
|
|
if ( !xFrame.is() )
|
|
xFrame = xDesktop;
|
|
|
|
URL aTargetURL;
|
|
aTargetURL.Complete = ".uno:NewDoc";
|
|
css::uno::Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
|
|
xTrans->parseStrict( aTargetURL );
|
|
|
|
css::uno::Reference < css::frame::XDispatchProvider > xProv( xFrame, UNO_QUERY );
|
|
css::uno::Reference < css::frame::XDispatch > xDisp;
|
|
if ( xProv.is() )
|
|
{
|
|
xDisp = xProv->queryDispatch( aTargetURL, "_self", 0 );
|
|
}
|
|
if ( !xDisp.is() )
|
|
return;
|
|
|
|
Sequence<PropertyValue> aArgs { comphelper::makePropertyValue("Referer", OUString("private:user")) };
|
|
css::uno::Reference< css::frame::XNotifyingDispatch > xNotifier(xDisp, UNO_QUERY);
|
|
if (xNotifier.is())
|
|
{
|
|
EnterModalMode();
|
|
xNotifier->dispatchWithNotification(aTargetURL, aArgs, new SfxNotificationListener_Impl);
|
|
}
|
|
else
|
|
xDisp->dispatch( aTargetURL, aArgs );
|
|
}
|
|
|
|
OUString ShutdownIcon::GetUrlDescription( std::u16string_view aUrl )
|
|
{
|
|
return SvFileInformationManager::GetDescription( INetURLObject( aUrl ) );
|
|
}
|
|
|
|
void ShutdownIcon::StartFileDialog()
|
|
{
|
|
::SolarMutexGuard aGuard;
|
|
|
|
bool bDirty = m_bSystemDialogs != UseSystemFileDialog();
|
|
|
|
if ( m_pFileDlg && bDirty )
|
|
{
|
|
// Destroy instance as changing the system file dialog setting
|
|
// forces us to create a new FileDialogHelper instance!
|
|
m_pFileDlg.reset();
|
|
}
|
|
|
|
if ( !m_pFileDlg )
|
|
m_pFileDlg.reset( new FileDialogHelper(
|
|
ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
|
|
FileDialogFlags::MultiSelection, OUString(), SfxFilterFlags::NONE, SfxFilterFlags::NONE, nullptr ) );
|
|
m_pFileDlg->StartExecuteModal( LINK( this, ShutdownIcon, DialogClosedHdl_Impl ) );
|
|
}
|
|
|
|
IMPL_LINK( ShutdownIcon, DialogClosedHdl_Impl, FileDialogHelper*, /*unused*/, void )
|
|
{
|
|
DBG_ASSERT( m_pFileDlg, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" );
|
|
|
|
// use constructor for filling up filters automatically!
|
|
if ( ERRCODE_NONE == m_pFileDlg->GetError() )
|
|
{
|
|
css::uno::Reference< XFilePicker3 > xPicker = m_pFileDlg->GetFilePicker();
|
|
|
|
try
|
|
{
|
|
|
|
if ( xPicker.is() )
|
|
{
|
|
|
|
css::uno::Reference < XFilePickerControlAccess > xPickerControls ( xPicker, UNO_QUERY );
|
|
|
|
Sequence< OUString > sFiles = xPicker->getSelectedFiles();
|
|
int nFiles = sFiles.getLength();
|
|
|
|
css::uno::Reference < css::task::XInteractionHandler2 > xInteraction(
|
|
task::InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), nullptr) );
|
|
|
|
int nArgs=3;
|
|
Sequence< PropertyValue > aArgs{
|
|
comphelper::makePropertyValue("InteractionHandler", xInteraction),
|
|
comphelper::makePropertyValue("MacroExecutionMode", sal_Int16(css::document::MacroExecMode::USE_CONFIG)),
|
|
comphelper::makePropertyValue("UpdateDocMode", sal_Int16(css::document::UpdateDocMode::ACCORDING_TO_CONFIG))
|
|
};
|
|
|
|
// use the filedlghelper to get the current filter name,
|
|
// because it removes the extensions before you get the filter name.
|
|
OUString aFilterName( m_pFileDlg->GetCurrentFilter() );
|
|
|
|
if ( xPickerControls.is() )
|
|
{
|
|
|
|
// Set readonly flag
|
|
|
|
bool bReadOnly = false;
|
|
|
|
|
|
xPickerControls->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ) >>= bReadOnly;
|
|
|
|
// Only set property if readonly is set to TRUE
|
|
|
|
if ( bReadOnly )
|
|
{
|
|
aArgs.realloc( ++nArgs );
|
|
auto pArgs = aArgs.getArray();
|
|
pArgs[nArgs-1].Name = "ReadOnly";
|
|
pArgs[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 = static_cast<sal_Int16>(iVersion);
|
|
|
|
aArgs.realloc( ++nArgs );
|
|
auto pArgs = aArgs.getArray();
|
|
pArgs[nArgs-1].Name = "Version";
|
|
pArgs[nArgs-1].Value <<= uVersion;
|
|
}
|
|
|
|
// Retrieve the current filter
|
|
|
|
if ( aFilterName.isEmpty() )
|
|
xPickerControls->getValue( CommonFilePickerElementIds::LISTBOX_FILTER, ControlActions::GET_SELECTED_ITEM ) >>= aFilterName;
|
|
|
|
}
|
|
|
|
|
|
// Convert UI filter name to internal filter name
|
|
|
|
if ( !aFilterName.isEmpty() )
|
|
{
|
|
std::shared_ptr<const SfxFilter> pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4UIName( aFilterName, SfxFilterFlags::NONE, SfxFilterFlags::NOTINFILEDLG );
|
|
|
|
if ( pFilter )
|
|
{
|
|
aFilterName = pFilter->GetFilterName();
|
|
|
|
if ( !aFilterName.isEmpty() )
|
|
{
|
|
aArgs.realloc( ++nArgs );
|
|
auto pArgs = aArgs.getArray();
|
|
pArgs[nArgs-1].Name = "FilterName";
|
|
pArgs[nArgs-1].Value <<= aFilterName;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( 1 == nFiles )
|
|
OpenURL( sFiles[0], "_default", aArgs );
|
|
else
|
|
{
|
|
OUString aBaseDirURL = sFiles[0];
|
|
if ( !aBaseDirURL.isEmpty() && !aBaseDirURL.endsWith("/") )
|
|
aBaseDirURL += "/";
|
|
|
|
int iFiles;
|
|
for ( iFiles = 1; iFiles < nFiles; iFiles++ )
|
|
{
|
|
OUString aURL = aBaseDirURL + sFiles[iFiles];
|
|
OpenURL( aURL, "_default", aArgs );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
}
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
// 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 (UseSystemFileDialog())
|
|
{
|
|
m_pFileDlg.reset();
|
|
}
|
|
#endif
|
|
|
|
LeaveModalMode();
|
|
}
|
|
|
|
|
|
void ShutdownIcon::addTerminateListener()
|
|
{
|
|
ShutdownIcon* pInst = getInstance();
|
|
if ( ! pInst)
|
|
return;
|
|
|
|
if (pInst->m_bListenForTermination)
|
|
return;
|
|
|
|
css::uno::Reference< XDesktop2 > xDesktop = pInst->m_xDesktop;
|
|
if ( ! xDesktop.is())
|
|
return;
|
|
|
|
xDesktop->addTerminateListener( pInst );
|
|
pInst->m_bListenForTermination = true;
|
|
}
|
|
|
|
|
|
void ShutdownIcon::terminateDesktop()
|
|
{
|
|
ShutdownIcon* pInst = getInstance();
|
|
if ( ! pInst)
|
|
return;
|
|
|
|
css::uno::Reference< XDesktop2 > 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
|
|
css::uno::Reference< XIndexAccess > xTasks = xDesktop->getFrames();
|
|
if( xTasks.is() && xTasks->getCount() < 1 )
|
|
Application::Quit();
|
|
|
|
// remove the instance pointer
|
|
ShutdownIcon::pShutdownIcon = nullptr;
|
|
}
|
|
|
|
|
|
ShutdownIcon* ShutdownIcon::getInstance()
|
|
{
|
|
OSL_ASSERT( pShutdownIcon );
|
|
return pShutdownIcon.get();
|
|
}
|
|
|
|
|
|
ShutdownIcon* ShutdownIcon::createInstance()
|
|
{
|
|
if (pShutdownIcon)
|
|
return pShutdownIcon.get();
|
|
|
|
try {
|
|
rtl::Reference<ShutdownIcon> pIcon(new ShutdownIcon( comphelper::getProcessComponentContext() ));
|
|
pIcon->init ();
|
|
pShutdownIcon = pIcon;
|
|
} catch (...) {
|
|
}
|
|
|
|
return pShutdownIcon.get();
|
|
}
|
|
|
|
void ShutdownIcon::init()
|
|
{
|
|
css::uno::Reference < XDesktop2 > xDesktop = Desktop::create( m_xContext );
|
|
std::unique_lock aGuard(m_aMutex);
|
|
m_xDesktop = std::move(xDesktop);
|
|
}
|
|
|
|
void ShutdownIcon::disposing(std::unique_lock<std::mutex>&)
|
|
{
|
|
m_xContext.clear();
|
|
m_xDesktop.clear();
|
|
|
|
deInitSystray();
|
|
}
|
|
|
|
// XEventListener
|
|
void SAL_CALL ShutdownIcon::disposing( const css::lang::EventObject& )
|
|
{
|
|
}
|
|
|
|
// XTerminateListener
|
|
void SAL_CALL ShutdownIcon::queryTermination( const css::lang::EventObject& )
|
|
{
|
|
SAL_INFO("sfx.appl", "ShutdownIcon::queryTermination: veto is " << m_bVeto);
|
|
std::unique_lock aGuard( m_aMutex );
|
|
|
|
if ( m_bVeto )
|
|
throw css::frame::TerminationVetoException();
|
|
}
|
|
|
|
|
|
void SAL_CALL ShutdownIcon::notifyTermination( const css::lang::EventObject& )
|
|
{
|
|
}
|
|
|
|
|
|
void SAL_CALL ShutdownIcon::initialize( const css::uno::Sequence< css::uno::Any>& aArguments )
|
|
{
|
|
std::unique_lock aGuard( m_aMutex );
|
|
|
|
// third argument only sets veto, everything else will be ignored!
|
|
if (aArguments.getLength() > 2)
|
|
{
|
|
bool bVeto = ::cppu::any2bool(aArguments[2]);
|
|
m_bVeto = bVeto;
|
|
return;
|
|
}
|
|
|
|
if ( aArguments.getLength() > 0 )
|
|
{
|
|
if ( !ShutdownIcon::pShutdownIcon )
|
|
{
|
|
try
|
|
{
|
|
bool bQuickstart = ::cppu::any2bool( aArguments[0] );
|
|
if( !bQuickstart && !GetAutostart() )
|
|
return;
|
|
aGuard.unlock();
|
|
init ();
|
|
aGuard.lock();
|
|
if ( !m_xDesktop.is() )
|
|
return;
|
|
|
|
/* Create a sub-classed instance - foo */
|
|
ShutdownIcon::pShutdownIcon = this;
|
|
initSystray();
|
|
}
|
|
catch(const css::lang::IllegalArgumentException&)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
if ( aArguments.getLength() > 1 )
|
|
{
|
|
bool bAutostart = ::cppu::any2bool( aArguments[1] );
|
|
if (bAutostart && !GetAutostart())
|
|
SetAutostart( true );
|
|
if (!bAutostart && GetAutostart())
|
|
SetAutostart( false );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void ShutdownIcon::EnterModalMode()
|
|
{
|
|
bModalMode = true;
|
|
}
|
|
|
|
|
|
void ShutdownIcon::LeaveModalMode()
|
|
{
|
|
bModalMode = false;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
// defined in shutdowniconw32.cxx
|
|
#elif defined MACOSX
|
|
// defined in shutdowniconaqua.cxx
|
|
#else
|
|
bool ShutdownIcon::IsQuickstarterInstalled()
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef ENABLE_QUICKSTART_APPLET
|
|
#ifdef _WIN32
|
|
OUString ShutdownIcon::getShortcutName()
|
|
{
|
|
return GetAutostartFolderNameW32() + "\\" + SfxResId(STR_QUICKSTART_LNKNAME) + ".lnk";
|
|
}
|
|
#endif // _WIN32
|
|
#endif
|
|
|
|
bool ShutdownIcon::GetAutostart( )
|
|
{
|
|
#if defined MACOSX
|
|
return true;
|
|
#elif defined ENABLE_QUICKSTART_APPLET
|
|
bool bRet = false;
|
|
OUString aShortcut( getShortcutName() );
|
|
OUString aShortcutUrl;
|
|
osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
|
|
osl::File f( aShortcutUrl );
|
|
osl::File::RC error = f.open( osl_File_OpenFlag_Read );
|
|
if( error == osl::File::E_None )
|
|
{
|
|
f.close();
|
|
bRet = true;
|
|
}
|
|
return bRet;
|
|
#else // ENABLE_QUICKSTART_APPLET
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
void ShutdownIcon::SetAutostart( bool bActivate )
|
|
{
|
|
#ifdef ENABLE_QUICKSTART_APPLET
|
|
#ifndef MACOSX
|
|
OUString aShortcut( getShortcutName() );
|
|
#endif
|
|
|
|
if( bActivate && IsQuickstarterInstalled() )
|
|
{
|
|
#ifdef _WIN32
|
|
EnableAutostartW32( aShortcut );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#ifndef MACOSX
|
|
OUString aShortcutUrl;
|
|
::osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
|
|
::osl::File::remove( aShortcutUrl );
|
|
#endif
|
|
}
|
|
#else
|
|
(void)bActivate; // unused variable
|
|
#endif // ENABLE_QUICKSTART_APPLET
|
|
}
|
|
|
|
const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE = 0;
|
|
|
|
// XFastPropertySet
|
|
void SAL_CALL ShutdownIcon::setFastPropertyValue( ::sal_Int32 nHandle,
|
|
const css::uno::Any& aValue )
|
|
{
|
|
switch(nHandle)
|
|
{
|
|
case PROPHANDLE_TERMINATEVETOSTATE :
|
|
{
|
|
// use new value in case it's a valid information only
|
|
bool bState( false );
|
|
if (! (aValue >>= bState))
|
|
return;
|
|
|
|
m_bVeto = bState;
|
|
if (m_bVeto && ! m_bListenForTermination)
|
|
addTerminateListener();
|
|
}
|
|
break;
|
|
|
|
default :
|
|
throw css::beans::UnknownPropertyException(OUString::number(nHandle));
|
|
}
|
|
}
|
|
|
|
// XFastPropertySet
|
|
css::uno::Any SAL_CALL ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle )
|
|
{
|
|
css::uno::Any aValue;
|
|
switch(nHandle)
|
|
{
|
|
case PROPHANDLE_TERMINATEVETOSTATE :
|
|
{
|
|
bool bState = (m_bListenForTermination && m_bVeto);
|
|
aValue <<= bState;
|
|
}
|
|
break;
|
|
|
|
default :
|
|
throw css::beans::UnknownPropertyException(OUString::number(nHandle));
|
|
}
|
|
|
|
return aValue;
|
|
}
|
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
|
|
com_sun_star_comp_desktop_QuickstartWrapper_get_implementation(
|
|
css::uno::XComponentContext *context,
|
|
css::uno::Sequence<css::uno::Any> const &)
|
|
{
|
|
return cppu::acquire(new ShutdownIcon(context));
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|