Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sfx2/source/appl/shutdownicon.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
20
#include <sal/config.h>
21
#include <sal/log.hxx>
22
23
#include <shutdownicon.hxx>
24
#include <sfx2/strings.hrc>
25
#include <sfx2/app.hxx>
26
#include <svtools/imagemgr.hxx>
27
#include <com/sun/star/task/InteractionHandler.hpp>
28
#include <com/sun/star/frame/Desktop.hpp>
29
#include <com/sun/star/frame/TerminationVetoException.hpp>
30
#include <com/sun/star/frame/XDispatchResultListener.hpp>
31
#include <com/sun/star/frame/XNotifyingDispatch.hpp>
32
#include <com/sun/star/frame/XFramesSupplier.hpp>
33
#include <com/sun/star/frame/XFrame.hpp>
34
#include <com/sun/star/util/URLTransformer.hpp>
35
#include <com/sun/star/util/XURLTransformer.hpp>
36
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
37
#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
38
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
39
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
40
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
41
#include <com/sun/star/ui/dialogs/ControlActions.hpp>
42
#include <com/sun/star/document/MacroExecMode.hpp>
43
#include <com/sun/star/document/UpdateDocMode.hpp>
44
#include <sfx2/filedlghelper.hxx>
45
#include <sfx2/docfilt.hxx>
46
#include <sfx2/fcontnr.hxx>
47
#include <comphelper/processfactory.hxx>
48
#include <comphelper/propertyvalue.hxx>
49
#include <cppuhelper/implbase.hxx>
50
#include <cppuhelper/supportsservice.hxx>
51
#include <comphelper/extract.hxx>
52
#include <officecfg/Office/Common.hxx>
53
#include <tools/urlobj.hxx>
54
#include <tools/debug.hxx>
55
#include <osl/diagnose.h>
56
#include <osl/file.hxx>
57
#include <osl/module.hxx>
58
#include <rtl/ref.hxx>
59
#include <utility>
60
#include <vcl/svapp.hxx>
61
62
#include <sfx2/sfxresid.hxx>
63
64
using namespace ::com::sun::star;
65
using namespace ::com::sun::star::uno;
66
using namespace ::com::sun::star::frame;
67
using namespace ::com::sun::star::container;
68
using namespace ::com::sun::star::lang;
69
using namespace ::com::sun::star::beans;
70
using namespace ::com::sun::star::util;
71
using namespace ::com::sun::star::ui::dialogs;
72
using namespace ::sfx2;
73
74
class SfxNotificationListener_Impl : public cppu::WeakImplHelper< XDispatchResultListener >
75
{
76
public:
77
    virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& aEvent ) override;
78
    virtual void SAL_CALL disposing( const EventObject& aEvent ) override;
79
};
80
81
void SAL_CALL SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent& )
82
0
{
83
0
    ShutdownIcon::LeaveModalMode();
84
0
}
85
86
void SAL_CALL SfxNotificationListener_Impl::disposing( const EventObject& )
87
0
{
88
0
}
89
90
OUString SAL_CALL ShutdownIcon::getImplementationName()
91
0
{
92
0
    return u"com.sun.star.comp.desktop.QuickstartWrapper"_ustr;
93
0
}
94
95
sal_Bool SAL_CALL ShutdownIcon::supportsService(OUString const & ServiceName)
96
0
{
97
0
    return cppu::supportsService(this, ServiceName);
98
0
}
99
100
css::uno::Sequence<OUString> SAL_CALL ShutdownIcon::getSupportedServiceNames()
101
0
{
102
0
    return { u"com.sun.star.office.Quickstart"_ustr };
103
0
}
104
105
bool ShutdownIcon::bModalMode = false;
106
rtl::Reference<ShutdownIcon> ShutdownIcon::pShutdownIcon;
107
108
void ShutdownIcon::initSystray()
109
0
{
110
0
    if (m_bInitialized)
111
0
        return;
112
0
    m_bInitialized = true;
113
114
#ifdef ENABLE_QUICKSTART_APPLET
115
#  ifdef _WIN32
116
    win32_init_sys_tray();
117
#  elif defined MACOSX
118
    aqua_init_systray();
119
#  endif // MACOSX
120
#endif // ENABLE_QUICKSTART_APPLET
121
0
}
122
123
void ShutdownIcon::deInitSystray()
124
0
{
125
0
    if (!m_bInitialized)
126
0
        return;
127
128
#ifdef ENABLE_QUICKSTART_APPLET
129
#  ifdef _WIN32
130
    win32_shutdown_sys_tray();
131
#  elif defined MACOSX
132
    aqua_shutdown_systray();
133
#  endif // MACOSX
134
#endif // ENABLE_QUICKSTART_APPLET
135
136
0
    m_bVeto = false;
137
138
0
    m_pFileDlg.reset();
139
0
    m_bInitialized = false;
140
0
}
141
142
static bool UseSystemFileDialog()
143
0
{
144
0
    return !Application::IsHeadlessModeEnabled() && officecfg::Office::Common::Misc::UseSystemFileDialog::get();
145
0
}
146
147
ShutdownIcon::ShutdownIcon( css::uno::Reference< XComponentContext > xContext ) :
148
0
    m_bVeto ( false ),
149
0
    m_bListenForTermination ( false ),
150
0
    m_bSystemDialogs(UseSystemFileDialog()),
151
0
    m_xContext(std::move( xContext )),
152
0
    m_bInitialized( false )
153
0
{
154
0
}
Unexecuted instantiation: ShutdownIcon::ShutdownIcon(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>)
Unexecuted instantiation: ShutdownIcon::ShutdownIcon(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>)
155
156
ShutdownIcon::~ShutdownIcon()
157
0
{
158
0
    deInitSystray();
159
0
}
160
161
162
void ShutdownIcon::OpenURL( const OUString& aURL, const OUString& rTarget, const Sequence< PropertyValue >& aArgs )
163
0
{
164
0
    if ( !getInstance() || !getInstance()->m_xDesktop.is() )
165
0
        return;
166
167
0
    css::uno::Reference < XDispatchProvider > xDispatchProvider = getInstance()->m_xDesktop;
168
0
    if ( !xDispatchProvider.is() )
169
0
        return;
170
171
0
    css::util::URL aDispatchURL;
172
0
    aDispatchURL.Complete = aURL;
173
174
0
    css::uno::Reference< util::XURLTransformer > xURLTransformer( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
175
0
    try
176
0
    {
177
0
        css::uno::Reference< css::frame::XDispatch > xDispatch;
178
179
0
        xURLTransformer->parseStrict( aDispatchURL );
180
0
        xDispatch = xDispatchProvider->queryDispatch( aDispatchURL, rTarget, 0 );
181
0
        if ( xDispatch.is() )
182
0
            xDispatch->dispatch( aDispatchURL, aArgs );
183
0
    }
184
0
    catch ( css::uno::RuntimeException& )
185
0
    {
186
0
        throw;
187
0
    }
188
0
    catch ( css::uno::Exception& )
189
0
    {
190
0
    }
191
0
}
192
193
194
void ShutdownIcon::FileOpen()
195
0
{
196
0
    if ( getInstance() && getInstance()->m_xDesktop.is() )
197
0
    {
198
0
        ::SolarMutexGuard aGuard;
199
0
        EnterModalMode();
200
0
        getInstance()->StartFileDialog();
201
0
    }
202
0
}
203
204
205
void ShutdownIcon::FromTemplate()
206
0
{
207
0
    ShutdownIcon::FromCommand( ".uno:NewDoc" );
208
0
}
209
210
void ShutdownIcon::FromCommand( const OUString& rCommand )
211
0
{
212
0
    if ( !getInstance() || !getInstance()->m_xDesktop.is() )
213
0
        return;
214
215
0
    css::uno::Reference < css::frame::XFramesSupplier > xDesktop = getInstance()->m_xDesktop;
216
0
    css::uno::Reference < css::frame::XFrame > xFrame( xDesktop->getActiveFrame() );
217
0
    if ( !xFrame.is() )
218
0
        xFrame = xDesktop;
219
220
0
    URL aTargetURL;
221
0
    aTargetURL.Complete = rCommand;
222
0
    css::uno::Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
223
0
    xTrans->parseStrict( aTargetURL );
224
225
0
    css::uno::Reference < css::frame::XDispatchProvider > xProv( xFrame, UNO_QUERY );
226
0
    css::uno::Reference < css::frame::XDispatch > xDisp;
227
0
    if ( xProv.is() )
228
0
    {
229
0
        xDisp = xProv->queryDispatch( aTargetURL, u"_self"_ustr, 0 );
230
0
    }
231
0
    if ( !xDisp.is() )
232
0
        return;
233
234
0
    Sequence<PropertyValue> aArgs { comphelper::makePropertyValue(u"Referer"_ustr, u"private:user"_ustr) };
235
0
    css::uno::Reference< css::frame::XNotifyingDispatch > xNotifier(xDisp, UNO_QUERY);
236
0
    if (xNotifier.is())
237
0
    {
238
0
        EnterModalMode();
239
0
        xNotifier->dispatchWithNotification(aTargetURL, aArgs, new SfxNotificationListener_Impl);
240
0
    }
241
0
    else
242
0
        xDisp->dispatch( aTargetURL, aArgs );
243
0
}
244
245
OUString ShutdownIcon::GetUrlDescription( std::u16string_view aUrl )
246
0
{
247
0
    return SvFileInformationManager::GetDescription( INetURLObject( aUrl ) );
248
0
}
249
250
void ShutdownIcon::StartFileDialog()
251
0
{
252
0
    ::SolarMutexGuard aGuard;
253
254
0
    bool bDirty = m_bSystemDialogs != UseSystemFileDialog();
255
256
0
    if ( m_pFileDlg && bDirty )
257
0
    {
258
        // Destroy instance as changing the system file dialog setting
259
        // forces us to create a new FileDialogHelper instance!
260
0
        m_pFileDlg.reset();
261
0
    }
262
263
0
    if ( !m_pFileDlg )
264
0
        m_pFileDlg.reset( new FileDialogHelper(
265
0
                ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
266
0
                FileDialogFlags::MultiSelection, OUString(), SfxFilterFlags::NONE, SfxFilterFlags::NONE, nullptr ) );
267
0
    m_pFileDlg->StartExecuteModal( LINK( this, ShutdownIcon, DialogClosedHdl_Impl ) );
268
0
}
269
270
IMPL_LINK( ShutdownIcon, DialogClosedHdl_Impl, FileDialogHelper*, /*unused*/, void )
271
0
{
272
0
    DBG_ASSERT( m_pFileDlg, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" );
273
274
    // use constructor for filling up filters automatically!
275
0
    if ( ERRCODE_NONE == m_pFileDlg->GetError() )
276
0
    {
277
0
        css::uno::Reference< XFilePicker3 >    xPicker = m_pFileDlg->GetFilePicker();
278
279
0
        try
280
0
        {
281
282
0
            if ( xPicker.is() )
283
0
            {
284
285
0
                css::uno::Reference < XFilePickerControlAccess > xPickerControls ( xPicker, UNO_QUERY );
286
287
0
                Sequence< OUString >        sFiles = xPicker->getSelectedFiles();
288
0
                int                         nFiles = sFiles.getLength();
289
290
0
                css::uno::Reference < css::task::XInteractionHandler2 > xInteraction(
291
0
                    task::InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), nullptr) );
292
293
0
                int                         nArgs=3;
294
0
                Sequence< PropertyValue >   aArgs{
295
0
                    comphelper::makePropertyValue(u"InteractionHandler"_ustr, xInteraction),
296
0
                    comphelper::makePropertyValue(u"MacroExecutionMode"_ustr, sal_Int16(css::document::MacroExecMode::USE_CONFIG)),
297
0
                    comphelper::makePropertyValue(u"UpdateDocMode"_ustr, sal_Int16(css::document::UpdateDocMode::ACCORDING_TO_CONFIG))
298
0
                };
299
300
                // use the filedlghelper to get the current filter name,
301
                // because it removes the extensions before you get the filter name.
302
0
                OUString aFilterName( m_pFileDlg->GetCurrentFilter() );
303
304
0
                if ( xPickerControls.is() )
305
0
                {
306
307
                    // Set readonly flag
308
309
0
                    bool    bReadOnly = false;
310
311
312
0
                    xPickerControls->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ) >>= bReadOnly;
313
314
                    // Only set property if readonly is set to TRUE
315
316
0
                    if ( bReadOnly )
317
0
                    {
318
0
                        aArgs.realloc( ++nArgs );
319
0
                        auto pArgs = aArgs.getArray();
320
0
                        pArgs[nArgs-1].Name  = "ReadOnly";
321
0
                        pArgs[nArgs-1].Value <<= bReadOnly;
322
0
                    }
323
324
                    // Get version string
325
326
0
                    sal_Int32   iVersion = -1;
327
328
0
                    xPickerControls->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, ControlActions::GET_SELECTED_ITEM_INDEX ) >>= iVersion;
329
330
0
                    if ( iVersion >= 0 )
331
0
                    {
332
0
                        sal_Int16   uVersion = static_cast<sal_Int16>(iVersion);
333
334
0
                        aArgs.realloc( ++nArgs );
335
0
                        auto pArgs = aArgs.getArray();
336
0
                        pArgs[nArgs-1].Name  = "Version";
337
0
                        pArgs[nArgs-1].Value <<= uVersion;
338
0
                    }
339
340
                    // Retrieve the current filter
341
342
0
                    if ( aFilterName.isEmpty() )
343
0
                        xPickerControls->getValue( CommonFilePickerElementIds::LISTBOX_FILTER, ControlActions::GET_SELECTED_ITEM ) >>= aFilterName;
344
345
0
                }
346
347
348
                // Convert UI filter name to internal filter name
349
350
0
                if ( !aFilterName.isEmpty() )
351
0
                {
352
0
                    std::shared_ptr<const SfxFilter> pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4UIName( aFilterName, SfxFilterFlags::NONE, SfxFilterFlags::NOTINFILEDLG );
353
354
0
                    if ( pFilter )
355
0
                    {
356
0
                        aFilterName = pFilter->GetFilterName();
357
358
0
                        if ( !aFilterName.isEmpty() )
359
0
                        {
360
0
                            aArgs.realloc( ++nArgs );
361
0
                            auto pArgs = aArgs.getArray();
362
0
                            pArgs[nArgs-1].Name  = "FilterName";
363
0
                            pArgs[nArgs-1].Value <<= aFilterName;
364
0
                        }
365
0
                    }
366
0
                }
367
368
0
                if ( 1 == nFiles )
369
0
                    OpenURL( sFiles[0], u"_default"_ustr, aArgs );
370
0
                else
371
0
                {
372
0
                    OUString    aBaseDirURL = sFiles[0];
373
0
                    if ( !aBaseDirURL.isEmpty() && !aBaseDirURL.endsWith("/") )
374
0
                        aBaseDirURL += "/";
375
376
0
                    int iFiles;
377
0
                    for ( iFiles = 1; iFiles < nFiles; iFiles++ )
378
0
                    {
379
0
                        OUString aURL = aBaseDirURL + sFiles[iFiles];
380
0
                        OpenURL( aURL, u"_default"_ustr, aArgs );
381
0
                    }
382
0
                }
383
0
            }
384
0
        }
385
0
        catch ( ... )
386
0
        {
387
0
        }
388
0
    }
389
390
#ifdef _WIN32
391
    // Destroy dialog to prevent problems with custom controls
392
    // This fix is dependent on the dialog settings. Destroying the dialog here will
393
    // crash the non-native dialog implementation! Therefore make this dependent on
394
    // the settings.
395
    if (UseSystemFileDialog())
396
    {
397
        m_pFileDlg.reset();
398
    }
399
#endif
400
401
0
    LeaveModalMode();
402
0
}
403
404
405
void ShutdownIcon::addTerminateListener()
406
0
{
407
0
    ShutdownIcon* pInst = getInstance();
408
0
    if ( ! pInst)
409
0
        return;
410
411
0
    if (pInst->m_bListenForTermination)
412
0
        return;
413
414
0
    css::uno::Reference< XDesktop2 > xDesktop = pInst->m_xDesktop;
415
0
    if ( ! xDesktop.is())
416
0
        return;
417
418
0
    xDesktop->addTerminateListener( pInst );
419
0
    pInst->m_bListenForTermination = true;
420
0
}
421
422
423
void ShutdownIcon::terminateDesktop()
424
0
{
425
0
    ShutdownIcon* pInst = getInstance();
426
0
    if ( ! pInst)
427
0
        return;
428
429
0
    css::uno::Reference< XDesktop2 > xDesktop = pInst->m_xDesktop;
430
0
    if ( ! xDesktop.is())
431
0
        return;
432
433
    // always remove ourselves as listener
434
0
    pInst->m_bListenForTermination = true;
435
0
    xDesktop->removeTerminateListener( pInst );
436
437
    // terminate desktop only if no tasks exist
438
0
    css::uno::Reference< XIndexAccess > xTasks = xDesktop->getFrames();
439
0
    if( xTasks.is() && xTasks->getCount() < 1 )
440
0
        Application::Quit();
441
442
    // remove the instance pointer
443
0
    ShutdownIcon::pShutdownIcon = nullptr;
444
0
}
445
446
447
ShutdownIcon* ShutdownIcon::getInstance()
448
0
{
449
0
    OSL_ASSERT( pShutdownIcon );
450
0
    return pShutdownIcon.get();
451
0
}
452
453
454
ShutdownIcon* ShutdownIcon::createInstance()
455
0
{
456
0
    if (pShutdownIcon)
457
0
        return pShutdownIcon.get();
458
459
0
    try {
460
0
        rtl::Reference<ShutdownIcon> pIcon(new ShutdownIcon( comphelper::getProcessComponentContext() ));
461
0
        pIcon->init ();
462
0
        pShutdownIcon = std::move(pIcon);
463
0
    } catch (...) {
464
0
    }
465
466
0
    return pShutdownIcon.get();
467
0
}
468
469
void ShutdownIcon::init()
470
0
{
471
0
    css::uno::Reference < XDesktop2 > xDesktop = Desktop::create( m_xContext );
472
0
    std::unique_lock aGuard(m_aMutex);
473
0
    m_xDesktop = std::move(xDesktop);
474
0
}
475
476
void ShutdownIcon::disposing(std::unique_lock<std::mutex>&)
477
0
{
478
0
    m_xContext.clear();
479
0
    m_xDesktop.clear();
480
481
0
    deInitSystray();
482
0
}
483
484
// XEventListener
485
void SAL_CALL ShutdownIcon::disposing( const css::lang::EventObject& )
486
0
{
487
0
}
488
489
// XTerminateListener
490
void SAL_CALL ShutdownIcon::queryTermination( const css::lang::EventObject& )
491
0
{
492
0
    SAL_INFO("sfx.appl", "ShutdownIcon::queryTermination: veto is " << m_bVeto);
493
0
    std::unique_lock  aGuard( m_aMutex );
494
495
0
    if ( m_bVeto )
496
0
        throw css::frame::TerminationVetoException();
497
0
}
498
499
500
void SAL_CALL ShutdownIcon::notifyTermination( const css::lang::EventObject& )
501
0
{
502
0
}
503
504
505
void SAL_CALL ShutdownIcon::initialize( const css::uno::Sequence< css::uno::Any>& aArguments )
506
0
{
507
0
    std::unique_lock aGuard( m_aMutex );
508
509
    // third argument only sets veto, everything else will be ignored!
510
0
    if (aArguments.getLength() > 2)
511
0
    {
512
0
        bool bVeto = ::cppu::any2bool(aArguments[2]);
513
0
        m_bVeto = bVeto;
514
0
        return;
515
0
    }
516
517
0
    if ( aArguments.getLength() > 0 )
518
0
    {
519
0
        if ( !ShutdownIcon::pShutdownIcon )
520
0
        {
521
0
            try
522
0
            {
523
0
                bool bQuickstart = ::cppu::any2bool( aArguments[0] );
524
0
                if( !bQuickstart && !GetAutostart() )
525
0
                    return;
526
0
                aGuard.unlock();
527
0
                init ();
528
0
                aGuard.lock();
529
0
                if ( !m_xDesktop.is() )
530
0
                    return;
531
532
                /* Create a sub-classed instance - foo */
533
0
                ShutdownIcon::pShutdownIcon = this;
534
0
                initSystray();
535
0
            }
536
0
            catch(const css::lang::IllegalArgumentException&)
537
0
            {
538
0
            }
539
0
        }
540
0
    }
541
0
    if ( aArguments.getLength() > 1 )
542
0
    {
543
0
            bool bAutostart = ::cppu::any2bool( aArguments[1] );
544
0
            if (bAutostart && !GetAutostart())
545
0
                SetAutostart( true );
546
0
            if (!bAutostart && GetAutostart())
547
0
                SetAutostart( false );
548
0
    }
549
550
0
}
551
552
553
void ShutdownIcon::EnterModalMode()
554
0
{
555
0
    bModalMode = true;
556
0
}
557
558
559
void ShutdownIcon::LeaveModalMode()
560
0
{
561
0
    bModalMode = false;
562
0
}
563
564
#ifdef _WIN32
565
// defined in shutdowniconw32.cxx
566
#elif defined MACOSX
567
// defined in shutdowniconaqua.cxx
568
#else
569
bool ShutdownIcon::IsQuickstarterInstalled()
570
0
{
571
0
    return false;
572
0
}
573
#endif
574
575
576
#ifdef ENABLE_QUICKSTART_APPLET
577
#ifdef _WIN32
578
OUString ShutdownIcon::getShortcutName()
579
{
580
    return GetAutostartFolderNameW32() + "\\" + SfxResId(STR_QUICKSTART_LNKNAME) + ".lnk";
581
}
582
#endif // _WIN32
583
#endif
584
585
bool ShutdownIcon::GetAutostart( )
586
0
{
587
#if defined MACOSX
588
    return true;
589
#elif defined ENABLE_QUICKSTART_APPLET
590
    bool bRet = false;
591
    OUString aShortcut( getShortcutName() );
592
    OUString aShortcutUrl;
593
    osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
594
    osl::File f( aShortcutUrl );
595
    osl::File::RC error = f.open( osl_File_OpenFlag_Read );
596
    if( error == osl::File::E_None )
597
    {
598
        f.close();
599
        bRet = true;
600
    }
601
    return bRet;
602
#else // ENABLE_QUICKSTART_APPLET
603
0
    return false;
604
0
#endif
605
0
}
606
607
void ShutdownIcon::SetAutostart( bool bActivate )
608
0
{
609
#ifdef ENABLE_QUICKSTART_APPLET
610
#ifndef MACOSX
611
    OUString aShortcut( getShortcutName() );
612
#endif
613
614
    if( bActivate && IsQuickstarterInstalled() )
615
    {
616
#ifdef _WIN32
617
        EnableAutostartW32( aShortcut );
618
#endif
619
    }
620
    else
621
    {
622
#ifndef MACOSX
623
        OUString aShortcutUrl;
624
        ::osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
625
        ::osl::File::remove( aShortcutUrl );
626
#endif
627
    }
628
#else
629
0
    (void)bActivate; // unused variable
630
0
#endif // ENABLE_QUICKSTART_APPLET
631
0
}
632
633
const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE = 0;
634
635
// XFastPropertySet
636
void SAL_CALL ShutdownIcon::setFastPropertyValue(       ::sal_Int32                  nHandle,
637
                                                  const css::uno::Any& aValue )
638
0
{
639
0
    switch(nHandle)
640
0
    {
641
0
        case PROPHANDLE_TERMINATEVETOSTATE :
642
0
             {
643
                // use new value in case it's a valid information only
644
0
                bool bState( false );
645
0
                if (! (aValue >>= bState))
646
0
                    return;
647
648
0
                m_bVeto = bState;
649
0
                if (m_bVeto && ! m_bListenForTermination)
650
0
                    addTerminateListener();
651
0
             }
652
0
             break;
653
654
0
        default :
655
0
            throw css::beans::UnknownPropertyException(OUString::number(nHandle));
656
0
    }
657
0
}
658
659
// XFastPropertySet
660
css::uno::Any SAL_CALL ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle )
661
0
{
662
0
    css::uno::Any aValue;
663
0
    switch(nHandle)
664
0
    {
665
0
        case PROPHANDLE_TERMINATEVETOSTATE :
666
0
             {
667
0
                bool bState   = (m_bListenForTermination && m_bVeto);
668
0
                aValue <<= bState;
669
0
             }
670
0
             break;
671
672
0
        default :
673
0
            throw css::beans::UnknownPropertyException(OUString::number(nHandle));
674
0
    }
675
676
0
    return aValue;
677
0
}
678
679
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
680
com_sun_star_comp_desktop_QuickstartWrapper_get_implementation(
681
    css::uno::XComponentContext *context,
682
    css::uno::Sequence<css::uno::Any> const &)
683
0
{
684
0
    return cppu::acquire(new ShutdownIcon(context));
685
0
}
686
687
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */