Line data Source code
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 :
22 : #include <cassert>
23 :
24 : #include <boost/logic/tribool.hpp>
25 : #include <config_folders.h>
26 : #include <shutdownicon.hxx>
27 : #include <app.hrc>
28 : #include <sfx2/app.hxx>
29 : #include <osl/mutex.hxx>
30 : #include <svtools/imagemgr.hxx>
31 : #include <svtools/miscopt.hxx>
32 : #include <com/sun/star/task/InteractionHandler.hpp>
33 : #include <com/sun/star/frame/Desktop.hpp>
34 : #include <com/sun/star/frame/XDispatchResultListener.hpp>
35 : #include <com/sun/star/frame/XNotifyingDispatch.hpp>
36 : #include <com/sun/star/frame/XFramesSupplier.hpp>
37 : #include <com/sun/star/frame/XComponentLoader.hpp>
38 : #include <com/sun/star/frame/XFrame.hpp>
39 : #include <com/sun/star/util/URLTransformer.hpp>
40 : #include <com/sun/star/util/XURLTransformer.hpp>
41 : #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
42 : #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
43 : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
44 : #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
45 : #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
46 : #include <com/sun/star/ui/dialogs/ControlActions.hpp>
47 : #include <com/sun/star/document/MacroExecMode.hpp>
48 : #include <com/sun/star/document/UpdateDocMode.hpp>
49 : #include <sfx2/filedlghelper.hxx>
50 : #include <sfx2/fcontnr.hxx>
51 : #include <comphelper/processfactory.hxx>
52 : #include <cppuhelper/compbase1.hxx>
53 : #include <cppuhelper/supportsservice.hxx>
54 : #include <sfx2/dispatch.hxx>
55 : #include <comphelper/extract.hxx>
56 : #include <tools/urlobj.hxx>
57 : #include <osl/security.hxx>
58 : #include <osl/file.hxx>
59 : #include <rtl/bootstrap.hxx>
60 : #include <rtl/ref.hxx>
61 : #include <rtl/ustrbuf.hxx>
62 : #ifdef UNX // need symlink
63 : #include <unistd.h>
64 : #include <errno.h>
65 : #endif
66 :
67 : #include <sfx2/sfxresid.hxx>
68 :
69 : using namespace ::com::sun::star;
70 : using namespace ::com::sun::star::uno;
71 : using namespace ::com::sun::star::frame;
72 : using namespace ::com::sun::star::container;
73 : using namespace ::com::sun::star::io;
74 : using namespace ::com::sun::star::lang;
75 : using namespace ::com::sun::star::beans;
76 : using namespace ::com::sun::star::util;
77 : using namespace ::com::sun::star::ui::dialogs;
78 : using namespace ::sfx2;
79 :
80 : #ifdef ENABLE_QUICKSTART_APPLET
81 : # if !defined(WIN32) && !defined(MACOSX)
82 0 : extern "C" { static void SAL_CALL thisModule() {} }
83 : # endif
84 : #endif
85 :
86 0 : class SfxNotificationListener_Impl : public cppu::WeakImplHelper1< XDispatchResultListener >
87 : {
88 : public:
89 : virtual void SAL_CALL dispatchFinished( const DispatchResultEvent& aEvent ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
90 : virtual void SAL_CALL disposing( const EventObject& aEvent ) throw( RuntimeException, std::exception ) SAL_OVERRIDE;
91 : };
92 :
93 0 : void SAL_CALL SfxNotificationListener_Impl::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException, std::exception )
94 : {
95 0 : ShutdownIcon::LeaveModalMode();
96 0 : }
97 :
98 0 : void SAL_CALL SfxNotificationListener_Impl::disposing( const EventObject& ) throw( RuntimeException, std::exception )
99 : {
100 0 : }
101 :
102 1 : OUString SAL_CALL ShutdownIcon::getImplementationName()
103 : throw (css::uno::RuntimeException, std::exception)
104 : {
105 1 : return OUString("com.sun.star.comp.desktop.QuickstartWrapper");
106 : }
107 :
108 0 : sal_Bool SAL_CALL ShutdownIcon::supportsService(OUString const & ServiceName)
109 : throw (css::uno::RuntimeException, std::exception)
110 : {
111 0 : return cppu::supportsService(this, ServiceName);
112 : }
113 :
114 1 : css::uno::Sequence<OUString> SAL_CALL ShutdownIcon::getSupportedServiceNames()
115 : throw (css::uno::RuntimeException, std::exception)
116 : {
117 1 : css::uno::Sequence< OUString > aSeq(1);
118 1 : aSeq[0] = "com.sun.star.office.Quickstart";
119 1 : return aSeq;
120 : }
121 :
122 : bool ShutdownIcon::bModalMode = false;
123 : ShutdownIcon* ShutdownIcon::pShutdownIcon = NULL;
124 :
125 : #if !defined( ENABLE_QUICKSTART_APPLET )
126 : // To remove conditionals
127 : extern "C" {
128 : static void disabled_initSystray() { }
129 : static void disabled_deInitSystray() { }
130 : }
131 : #endif
132 :
133 : namespace {
134 :
135 216 : boost::logic::tribool loaded(boost::logic::indeterminate);
136 : oslGenericFunction pInitSystray(nullptr);
137 : oslGenericFunction pDeInitSystray(nullptr);
138 :
139 0 : bool LoadModule()
140 : {
141 0 : if (boost::logic::indeterminate(loaded))
142 : {
143 : #ifdef ENABLE_QUICKSTART_APPLET
144 : # ifdef WIN32
145 : pInitSystray = win32_init_sys_tray;
146 : pDeInitSystray = win32_shutdown_sys_tray;
147 : loaded = true;
148 : # elif defined MACOSX
149 : pInitSystray = aqua_init_systray;
150 : pDeInitSystray = aqua_shutdown_systray;
151 : loaded = true;
152 : # else // UNX
153 0 : osl::Module plugin;
154 0 : oslGenericFunction pTmpInit = NULL;
155 0 : oslGenericFunction pTmpDeInit = NULL;
156 0 : if ( plugin.loadRelative( &thisModule, "libqstart_gtklo.so" ) )
157 : {
158 0 : pTmpInit = plugin.getFunctionSymbol( "plugin_init_sys_tray" );
159 0 : pTmpDeInit = plugin.getFunctionSymbol( "plugin_shutdown_sys_tray" );
160 : }
161 0 : if ( !pTmpInit || !pTmpDeInit )
162 : {
163 0 : loaded = false;
164 : }
165 : else
166 : {
167 0 : plugin.release();
168 0 : pInitSystray = pTmpInit;
169 0 : pDeInitSystray = pTmpDeInit;
170 0 : loaded = true;
171 0 : }
172 : # endif // UNX
173 : #else
174 : pInitSystray = disabled_initSystray;
175 : pDeInitSystray = disabled_deInitSystray;
176 : loaded = false;
177 : #endif // ENABLE_QUICKSTART_APPLET
178 : }
179 : assert(!boost::logic::indeterminate(loaded));
180 0 : return loaded;
181 : }
182 :
183 : }
184 :
185 0 : void ShutdownIcon::initSystray()
186 : {
187 0 : if (m_bInitialized)
188 0 : return;
189 0 : m_bInitialized = true;
190 :
191 0 : (void) LoadModule();
192 0 : m_bVeto = true;
193 0 : pInitSystray();
194 : }
195 :
196 2 : void ShutdownIcon::deInitSystray()
197 : {
198 2 : if (!m_bInitialized)
199 4 : return;
200 :
201 0 : if (pDeInitSystray)
202 0 : pDeInitSystray();
203 :
204 0 : m_bVeto = false;
205 0 : pInitSystray = 0;
206 0 : pDeInitSystray = 0;
207 :
208 0 : delete m_pFileDlg;
209 0 : m_pFileDlg = NULL;
210 0 : m_bInitialized = false;
211 : }
212 :
213 :
214 1 : ShutdownIcon::ShutdownIcon( const ::com::sun::star::uno::Reference< XComponentContext > & rxContext ) :
215 : ShutdownIconServiceBase( m_aMutex ),
216 : m_bVeto ( false ),
217 : m_bListenForTermination ( false ),
218 : m_bSystemDialogs( false ),
219 : m_pResMgr( NULL ),
220 : m_pFileDlg( NULL ),
221 : m_xContext( rxContext ),
222 1 : m_bInitialized( false )
223 : {
224 1 : m_bSystemDialogs = SvtMiscOptions().UseSystemFileDialog();
225 1 : }
226 :
227 3 : ShutdownIcon::~ShutdownIcon()
228 : {
229 1 : deInitSystray();
230 2 : }
231 :
232 :
233 :
234 0 : void ShutdownIcon::OpenURL( const OUString& aURL, const OUString& rTarget, const Sequence< PropertyValue >& aArgs )
235 : {
236 0 : if ( getInstance() && getInstance()->m_xDesktop.is() )
237 : {
238 0 : ::com::sun::star::uno::Reference < XDispatchProvider > xDispatchProvider( getInstance()->m_xDesktop, UNO_QUERY );
239 0 : if ( xDispatchProvider.is() )
240 : {
241 0 : com::sun::star::util::URL aDispatchURL;
242 0 : aDispatchURL.Complete = aURL;
243 :
244 0 : ::com::sun::star::uno::Reference< util::XURLTransformer > xURLTransformer( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
245 : try
246 : {
247 0 : ::com::sun::star::uno::Reference< com::sun::star::frame::XDispatch > xDispatch;
248 :
249 0 : xURLTransformer->parseStrict( aDispatchURL );
250 0 : xDispatch = xDispatchProvider->queryDispatch( aDispatchURL, rTarget, 0 );
251 0 : if ( xDispatch.is() )
252 0 : xDispatch->dispatch( aDispatchURL, aArgs );
253 : }
254 0 : catch ( com::sun::star::uno::RuntimeException& )
255 : {
256 0 : throw;
257 : }
258 0 : catch ( com::sun::star::uno::Exception& )
259 : {
260 0 : }
261 0 : }
262 : }
263 0 : }
264 :
265 :
266 :
267 0 : void ShutdownIcon::FileOpen()
268 : {
269 0 : if ( getInstance() && getInstance()->m_xDesktop.is() )
270 : {
271 0 : ::SolarMutexGuard aGuard;
272 0 : EnterModalMode();
273 0 : getInstance()->StartFileDialog();
274 : }
275 0 : }
276 :
277 :
278 :
279 0 : void ShutdownIcon::FromTemplate()
280 : {
281 0 : if ( getInstance() && getInstance()->m_xDesktop.is() )
282 : {
283 0 : ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFramesSupplier > xDesktop ( getInstance()->m_xDesktop, UNO_QUERY);
284 0 : ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame > xFrame( xDesktop->getActiveFrame() );
285 0 : if ( !xFrame.is() )
286 0 : xFrame = ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFrame >( xDesktop, UNO_QUERY );
287 :
288 0 : URL aTargetURL;
289 0 : aTargetURL.Complete = ".uno:NewDoc";
290 0 : ::com::sun::star::uno::Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
291 0 : xTrans->parseStrict( aTargetURL );
292 :
293 0 : ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatchProvider > xProv( xFrame, UNO_QUERY );
294 0 : ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > xDisp;
295 0 : if ( xProv.is() )
296 : {
297 0 : xDisp = xProv->queryDispatch( aTargetURL, OUString("_self"), 0 );
298 : }
299 0 : if ( xDisp.is() )
300 : {
301 0 : Sequence<PropertyValue> aArgs(1);
302 0 : PropertyValue* pArg = aArgs.getArray();
303 0 : pArg[0].Name = "Referer";
304 0 : pArg[0].Value <<= OUString("private:user");
305 0 : ::com::sun::star::uno::Reference< ::com::sun::star::frame::XNotifyingDispatch > xNotifyer( xDisp, UNO_QUERY );
306 0 : if ( xNotifyer.is() )
307 : {
308 0 : EnterModalMode();
309 0 : xNotifyer->dispatchWithNotification( aTargetURL, aArgs, new SfxNotificationListener_Impl() );
310 : }
311 : else
312 0 : xDisp->dispatch( aTargetURL, aArgs );
313 0 : }
314 : }
315 0 : }
316 :
317 :
318 : #include <tools/rcid.h>
319 0 : OUString ShutdownIcon::GetResString( int id )
320 : {
321 0 : ::SolarMutexGuard aGuard;
322 :
323 0 : if( ! m_pResMgr )
324 0 : m_pResMgr = SfxResId::GetResMgr();
325 0 : ResId aResId( id, *m_pResMgr );
326 0 : aResId.SetRT( RSC_STRING );
327 0 : if (!m_pResMgr->IsAvailable(aResId))
328 0 : return OUString();
329 :
330 0 : return ResId(id, *m_pResMgr).toString();
331 : }
332 :
333 :
334 :
335 0 : OUString ShutdownIcon::GetUrlDescription( const OUString& aUrl )
336 : {
337 0 : ::SolarMutexGuard aGuard;
338 :
339 0 : return OUString( SvFileInformationManager::GetDescription( INetURLObject( aUrl ) ) );
340 : }
341 :
342 :
343 :
344 0 : void ShutdownIcon::StartFileDialog()
345 : {
346 0 : ::SolarMutexGuard aGuard;
347 :
348 0 : bool bDirty = ( m_bSystemDialogs != static_cast<bool>(SvtMiscOptions().UseSystemFileDialog()) );
349 :
350 0 : if ( m_pFileDlg && bDirty )
351 : {
352 : // Destroy instance as changing the system file dialog setting
353 : // forces us to create a new FileDialogHelper instance!
354 0 : delete m_pFileDlg;
355 0 : m_pFileDlg = NULL;
356 : }
357 :
358 0 : if ( !m_pFileDlg )
359 : m_pFileDlg = new FileDialogHelper(
360 : ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION,
361 0 : SFXWB_MULTISELECTION, OUString() );
362 0 : m_pFileDlg->StartExecuteModal( LINK( this, ShutdownIcon, DialogClosedHdl_Impl ) );
363 0 : }
364 :
365 :
366 :
367 0 : IMPL_LINK( ShutdownIcon, DialogClosedHdl_Impl, FileDialogHelper*, )
368 : {
369 : DBG_ASSERT( m_pFileDlg, "ShutdownIcon, DialogClosedHdl_Impl(): no file dialog" );
370 :
371 : // use constructor for filling up filters automatically!
372 0 : if ( ERRCODE_NONE == m_pFileDlg->GetError() )
373 : {
374 0 : ::com::sun::star::uno::Reference< XFilePicker > xPicker = m_pFileDlg->GetFilePicker();
375 :
376 : try
377 : {
378 :
379 0 : if ( xPicker.is() )
380 : {
381 :
382 0 : ::com::sun::star::uno::Reference < XFilePickerControlAccess > xPickerControls ( xPicker, UNO_QUERY );
383 0 : ::com::sun::star::uno::Reference < XFilterManager > xFilterManager ( xPicker, UNO_QUERY );
384 :
385 0 : Sequence< OUString > sFiles = xPicker->getFiles();
386 0 : int nFiles = sFiles.getLength();
387 :
388 0 : int nArgs=3;
389 0 : Sequence< PropertyValue > aArgs(3);
390 :
391 : ::com::sun::star::uno::Reference < com::sun::star::task::XInteractionHandler2 > xInteraction(
392 0 : task::InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), 0) );
393 :
394 0 : aArgs[0].Name = "InteractionHandler";
395 0 : aArgs[0].Value <<= xInteraction;
396 :
397 0 : sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
398 0 : aArgs[1].Name = "MacroExecutionMode";
399 0 : aArgs[1].Value <<= nMacroExecMode;
400 :
401 0 : sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
402 0 : aArgs[2].Name = "UpdateDocMode";
403 0 : aArgs[2].Value <<= nUpdateDoc;
404 :
405 : // use the filedlghelper to get the current filter name,
406 : // because it removes the extensions before you get the filter name.
407 0 : OUString aFilterName( m_pFileDlg->GetCurrentFilter() );
408 :
409 0 : if ( xPickerControls.is() )
410 : {
411 :
412 : // Set readonly flag
413 :
414 0 : bool bReadOnly = false;
415 :
416 :
417 0 : xPickerControls->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 ) >>= bReadOnly;
418 :
419 : // Only set porperty if readonly is set to TRUE
420 :
421 0 : if ( bReadOnly )
422 : {
423 0 : aArgs.realloc( ++nArgs );
424 0 : aArgs[nArgs-1].Name = "ReadOnly";
425 0 : aArgs[nArgs-1].Value <<= bReadOnly;
426 : }
427 :
428 : // Get version string
429 :
430 0 : sal_Int32 iVersion = -1;
431 :
432 0 : xPickerControls->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION, ControlActions::GET_SELECTED_ITEM_INDEX ) >>= iVersion;
433 :
434 0 : if ( iVersion >= 0 )
435 : {
436 0 : sal_Int16 uVersion = (sal_Int16)iVersion;
437 :
438 0 : aArgs.realloc( ++nArgs );
439 0 : aArgs[nArgs-1].Name = "Version";
440 0 : aArgs[nArgs-1].Value <<= uVersion;
441 : }
442 :
443 : // Retrieve the current filter
444 :
445 0 : if ( aFilterName.isEmpty() )
446 0 : xPickerControls->getValue( CommonFilePickerElementIds::LISTBOX_FILTER, ControlActions::GET_SELECTED_ITEM ) >>= aFilterName;
447 :
448 : }
449 :
450 :
451 : // Convert UI filter name to internal filter name
452 :
453 0 : if ( !aFilterName.isEmpty() )
454 : {
455 0 : const SfxFilter* pFilter = SfxGetpApp()->GetFilterMatcher().GetFilter4UIName( aFilterName, SfxFilterFlags::NONE, SfxFilterFlags::NOTINFILEDLG );
456 :
457 0 : if ( pFilter )
458 : {
459 0 : aFilterName = pFilter->GetFilterName();
460 :
461 0 : if ( !aFilterName.isEmpty() )
462 : {
463 0 : aArgs.realloc( ++nArgs );
464 0 : aArgs[nArgs-1].Name = "FilterName";
465 0 : aArgs[nArgs-1].Value <<= aFilterName;
466 : }
467 : }
468 : }
469 :
470 0 : if ( 1 == nFiles )
471 0 : OpenURL( sFiles[0], OUString( "_default" ), aArgs );
472 : else
473 : {
474 0 : OUString aBaseDirURL = sFiles[0];
475 0 : if ( !aBaseDirURL.isEmpty() && !aBaseDirURL.endsWith("/") )
476 0 : aBaseDirURL += "/";
477 :
478 : int iFiles;
479 0 : for ( iFiles = 1; iFiles < nFiles; iFiles++ )
480 : {
481 0 : OUString aURL = aBaseDirURL;
482 0 : aURL += sFiles[iFiles];
483 0 : OpenURL( aURL, OUString( "_default" ), aArgs );
484 0 : }
485 0 : }
486 : }
487 : }
488 0 : catch ( ... )
489 : {
490 0 : }
491 : }
492 :
493 : #ifdef WNT
494 : // Destroy dialog to prevent problems with custom controls
495 : // This fix is dependent on the dialog settings. Destroying the dialog here will
496 : // crash the non-native dialog implementation! Therefore make this dependent on
497 : // the settings.
498 : if ( SvtMiscOptions().UseSystemFileDialog() )
499 : {
500 : delete m_pFileDlg;
501 : m_pFileDlg = NULL;
502 : }
503 : #endif
504 :
505 0 : LeaveModalMode();
506 0 : return 0;
507 : }
508 :
509 :
510 :
511 0 : void ShutdownIcon::addTerminateListener()
512 : {
513 0 : ShutdownIcon* pInst = getInstance();
514 0 : if ( ! pInst)
515 0 : return;
516 :
517 0 : if (pInst->m_bListenForTermination)
518 0 : return;
519 :
520 0 : ::com::sun::star::uno::Reference< XDesktop2 > xDesktop = pInst->m_xDesktop;
521 0 : if ( ! xDesktop.is())
522 0 : return;
523 :
524 0 : xDesktop->addTerminateListener( pInst );
525 0 : pInst->m_bListenForTermination = true;
526 : }
527 :
528 :
529 :
530 0 : void ShutdownIcon::terminateDesktop()
531 : {
532 0 : ShutdownIcon* pInst = getInstance();
533 0 : if ( ! pInst)
534 0 : return;
535 :
536 0 : ::com::sun::star::uno::Reference< XDesktop2 > xDesktop = pInst->m_xDesktop;
537 0 : if ( ! xDesktop.is())
538 0 : return;
539 :
540 : // always remove ourselves as listener
541 0 : pInst->m_bListenForTermination = true;
542 0 : xDesktop->removeTerminateListener( pInst );
543 :
544 : // terminate desktop only if no tasks exist
545 0 : ::com::sun::star::uno::Reference< XIndexAccess > xTasks ( xDesktop->getFrames(), UNO_QUERY );
546 0 : if( xTasks.is() && xTasks->getCount() < 1 )
547 0 : Application::Quit();
548 :
549 : // remove the instance pointer
550 0 : ShutdownIcon::pShutdownIcon = 0;
551 : }
552 :
553 :
554 :
555 0 : ShutdownIcon* ShutdownIcon::getInstance()
556 : {
557 : OSL_ASSERT( pShutdownIcon );
558 0 : return pShutdownIcon;
559 : }
560 :
561 :
562 :
563 0 : ShutdownIcon* ShutdownIcon::createInstance()
564 : {
565 0 : if (pShutdownIcon)
566 0 : return pShutdownIcon;
567 :
568 0 : ShutdownIcon *pIcon = NULL;
569 : try {
570 0 : pIcon = new ShutdownIcon( comphelper::getProcessComponentContext() );
571 0 : pIcon->init ();
572 0 : pShutdownIcon = pIcon;
573 0 : } catch (...) {
574 0 : delete pIcon;
575 : }
576 :
577 0 : return pShutdownIcon;
578 : }
579 :
580 0 : void ShutdownIcon::init() throw( ::com::sun::star::uno::Exception )
581 : {
582 : // access resource system and sfx only protected by solarmutex
583 0 : ::SolarMutexGuard aSolarGuard;
584 0 : ResMgr *pResMgr = SfxResId::GetResMgr();
585 :
586 0 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
587 0 : m_pResMgr = pResMgr;
588 0 : aGuard.clear();
589 0 : ::com::sun::star::uno::Reference < XDesktop2 > xDesktop = Desktop::create( m_xContext );
590 0 : aGuard.reset();
591 0 : m_xDesktop = xDesktop;
592 0 : }
593 :
594 :
595 :
596 1 : void SAL_CALL ShutdownIcon::disposing()
597 : {
598 1 : m_xContext.clear();
599 1 : m_xDesktop.clear();
600 :
601 1 : deInitSystray();
602 1 : }
603 :
604 :
605 :
606 : // XEventListener
607 0 : void SAL_CALL ShutdownIcon::disposing( const ::com::sun::star::lang::EventObject& )
608 : throw(::com::sun::star::uno::RuntimeException, std::exception)
609 : {
610 0 : }
611 :
612 :
613 :
614 : // XTerminateListener
615 0 : void SAL_CALL ShutdownIcon::queryTermination( const ::com::sun::star::lang::EventObject& )
616 : throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException, std::exception)
617 : {
618 : SAL_INFO("sfx.appl", "ShutdownIcon::queryTermination: veto is " << m_bVeto);
619 0 : ::osl::ClearableMutexGuard aGuard( m_aMutex );
620 :
621 0 : if ( m_bVeto )
622 0 : throw ::com::sun::star::frame::TerminationVetoException();
623 0 : }
624 :
625 :
626 :
627 :
628 0 : void SAL_CALL ShutdownIcon::notifyTermination( const ::com::sun::star::lang::EventObject& )
629 : throw(::com::sun::star::uno::RuntimeException, std::exception)
630 : {
631 0 : }
632 :
633 :
634 :
635 :
636 1 : void SAL_CALL ShutdownIcon::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>& aArguments )
637 : throw( ::com::sun::star::uno::Exception, std::exception )
638 : {
639 1 : ::osl::ResettableMutexGuard aGuard( m_aMutex );
640 :
641 : // third argument only sets veto, everything else will be ignored!
642 1 : if (aArguments.getLength() > 2)
643 : {
644 0 : bool bVeto = ::cppu::any2bool(aArguments[2]);
645 0 : m_bVeto = bVeto;
646 0 : return;
647 : }
648 :
649 1 : if ( aArguments.getLength() > 0 )
650 : {
651 0 : if ( !ShutdownIcon::pShutdownIcon )
652 : {
653 : try
654 : {
655 0 : bool bQuickstart = ::cppu::any2bool( aArguments[0] );
656 0 : if( !bQuickstart && !GetAutostart() )
657 0 : return;
658 0 : aGuard.clear();
659 0 : init ();
660 0 : aGuard.reset();
661 0 : if ( !m_xDesktop.is() )
662 0 : return;
663 :
664 : /* Create a sub-classed instance - foo */
665 0 : ShutdownIcon::pShutdownIcon = this;
666 0 : initSystray();
667 : }
668 0 : catch(const ::com::sun::star::lang::IllegalArgumentException&)
669 : {
670 : }
671 : }
672 : }
673 1 : if ( aArguments.getLength() > 1 )
674 : {
675 0 : bool bAutostart = ::cppu::any2bool( aArguments[1] );
676 0 : if (bAutostart && !GetAutostart())
677 0 : SetAutostart( true );
678 0 : if (!bAutostart && GetAutostart())
679 0 : SetAutostart( false );
680 1 : }
681 :
682 : }
683 :
684 :
685 :
686 0 : void ShutdownIcon::EnterModalMode()
687 : {
688 0 : bModalMode = true;
689 0 : }
690 :
691 :
692 :
693 0 : void ShutdownIcon::LeaveModalMode()
694 : {
695 0 : bModalMode = false;
696 0 : }
697 :
698 : #ifdef WNT
699 : // defined in shutdowniconw32.cxx
700 : #elif defined MACOSX
701 : // defined in shutdowniconaqua.cxx
702 : #else
703 0 : bool ShutdownIcon::IsQuickstarterInstalled()
704 : {
705 : #ifndef ENABLE_QUICKSTART_APPLET
706 : return false;
707 : #else // !ENABLE_QUICKSTART_APPLET
708 : #ifdef UNX
709 0 : return LoadModule();
710 : #endif // UNX
711 : #endif // !ENABLE_QUICKSTART_APPLET
712 : }
713 : #endif // !WNT
714 :
715 :
716 :
717 : #if defined (ENABLE_QUICKSTART_APPLET) && defined (UNX)
718 : /**
719 : * Return the XDG autostart directory.
720 : * http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
721 : * Available in Unix and with Quickstart enabled.
722 : * @param bCreate Create the directory if it does not exist yet.
723 : * @return OUString containing the autostart directory path.
724 : */
725 0 : static OUString getAutostartDir( bool bCreate = false )
726 : {
727 0 : OUString aShortcut;
728 : const char *pConfigHome;
729 0 : if( (pConfigHome = getenv("XDG_CONFIG_HOME") ) )
730 0 : aShortcut = OStringToOUString( OString( pConfigHome ),
731 0 : RTL_TEXTENCODING_UTF8 );
732 : else
733 : {
734 0 : OUString aHomeURL;
735 0 : osl::Security().getHomeDir( aHomeURL );
736 0 : ::osl::File::getSystemPathFromFileURL( aHomeURL, aShortcut );
737 0 : aShortcut += "/.config";
738 : }
739 0 : aShortcut += "/autostart";
740 0 : if (bCreate)
741 : {
742 0 : OUString aShortcutUrl;
743 0 : osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
744 0 : osl::Directory::createPath( aShortcutUrl );
745 : }
746 0 : return aShortcut;
747 : }
748 : #endif
749 :
750 0 : OUString ShutdownIcon::getShortcutName()
751 : {
752 : #ifndef ENABLE_QUICKSTART_APPLET
753 : return OUString();
754 : #else
755 :
756 0 : OUString aShortcutName( "StarOffice 6.0" );
757 0 : ResMgr* pMgr = SfxResId::GetResMgr();
758 0 : if( pMgr )
759 : {
760 0 : ::SolarMutexGuard aGuard;
761 0 : aShortcutName = SFX2_RESSTR(STR_QUICKSTART_LNKNAME);
762 : }
763 : #ifdef WNT
764 : aShortcutName += ".lnk";
765 :
766 : OUString aShortcut(GetAutostartFolderNameW32());
767 : aShortcut += "\\";
768 : aShortcut += aShortcutName;
769 : #else // UNX
770 0 : OUString aShortcut = getAutostartDir();
771 0 : aShortcut += "/qstart.desktop";
772 : #endif // UNX
773 0 : return aShortcut;
774 : #endif // ENABLE_QUICKSTART_APPLET
775 : }
776 :
777 0 : bool ShutdownIcon::GetAutostart( )
778 : {
779 : #if defined MACOSX
780 : return true;
781 : #else
782 0 : bool bRet = false;
783 : #ifdef ENABLE_QUICKSTART_APPLET
784 0 : OUString aShortcut( getShortcutName() );
785 0 : OUString aShortcutUrl;
786 0 : osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
787 0 : osl::File f( aShortcutUrl );
788 0 : osl::File::RC error = f.open( osl_File_OpenFlag_Read );
789 0 : if( error == osl::File::E_None )
790 : {
791 0 : f.close();
792 0 : bRet = true;
793 : }
794 : #endif // ENABLE_QUICKSTART_APPLET
795 0 : return bRet;
796 : #endif
797 : }
798 :
799 0 : void ShutdownIcon::SetAutostart( bool bActivate )
800 : {
801 : #ifdef ENABLE_QUICKSTART_APPLET
802 0 : OUString aShortcut( getShortcutName() );
803 :
804 0 : if( bActivate && IsQuickstarterInstalled() )
805 : {
806 : #ifdef WNT
807 : EnableAutostartW32( aShortcut );
808 : #else // UNX
809 0 : getAutostartDir( true );
810 :
811 0 : OUString aPath( "${BRAND_BASE_DIR}/" LIBO_SHARE_FOLDER "/xdg/qstart.desktop" );
812 0 : rtl::Bootstrap::expandMacros( aPath );
813 :
814 0 : OUString aDesktopFile;
815 0 : ::osl::File::getSystemPathFromFileURL( aPath, aDesktopFile );
816 :
817 : OString aDesktopFileUnx = OUStringToOString( aDesktopFile,
818 0 : osl_getThreadTextEncoding() );
819 : OString aShortcutUnx = OUStringToOString( aShortcut,
820 0 : osl_getThreadTextEncoding() );
821 0 : if ((0 != symlink(aDesktopFileUnx.getStr(), aShortcutUnx.getStr())) && (errno == EEXIST))
822 : {
823 0 : unlink(aShortcutUnx.getStr());
824 0 : int ret = symlink(aDesktopFileUnx.getStr(), aShortcutUnx.getStr());
825 : (void)ret; //deliberately ignore return value, it's non-critical if it fails
826 : }
827 :
828 0 : ShutdownIcon *pIcon = ShutdownIcon::createInstance();
829 0 : if( pIcon )
830 0 : pIcon->initSystray();
831 : #endif // UNX
832 : }
833 : else
834 : {
835 0 : OUString aShortcutUrl;
836 0 : ::osl::File::getFileURLFromSystemPath( aShortcut, aShortcutUrl );
837 0 : ::osl::File::remove( aShortcutUrl );
838 : #ifdef UNX
839 0 : if (pShutdownIcon)
840 : {
841 0 : ShutdownIcon *pIcon = getInstance();
842 0 : pIcon->deInitSystray();
843 0 : }
844 : #endif
845 0 : }
846 : #else
847 : (void)bActivate; // unused variable
848 : #endif // ENABLE_QUICKSTART_APPLET
849 0 : }
850 :
851 : static const ::sal_Int32 PROPHANDLE_TERMINATEVETOSTATE = 0;
852 :
853 : // XFastPropertySet
854 0 : void SAL_CALL ShutdownIcon::setFastPropertyValue( ::sal_Int32 nHandle,
855 : const ::com::sun::star::uno::Any& aValue )
856 : throw (::com::sun::star::beans::UnknownPropertyException,
857 : ::com::sun::star::beans::PropertyVetoException,
858 : ::com::sun::star::lang::IllegalArgumentException,
859 : ::com::sun::star::lang::WrappedTargetException,
860 : ::com::sun::star::uno::RuntimeException, std::exception)
861 : {
862 0 : switch(nHandle)
863 : {
864 : case PROPHANDLE_TERMINATEVETOSTATE :
865 : {
866 : // use new value in case it's a valid information only
867 0 : bool bState( false );
868 0 : if (! (aValue >>= bState))
869 0 : return;
870 :
871 0 : m_bVeto = bState;
872 0 : if (m_bVeto && ! m_bListenForTermination)
873 0 : addTerminateListener();
874 : }
875 0 : break;
876 :
877 : default :
878 0 : throw ::com::sun::star::beans::UnknownPropertyException();
879 : }
880 : }
881 :
882 : // XFastPropertySet
883 0 : ::com::sun::star::uno::Any SAL_CALL ShutdownIcon::getFastPropertyValue( ::sal_Int32 nHandle )
884 : throw (::com::sun::star::beans::UnknownPropertyException,
885 : ::com::sun::star::lang::WrappedTargetException,
886 : ::com::sun::star::uno::RuntimeException, std::exception)
887 : {
888 0 : ::com::sun::star::uno::Any aValue;
889 0 : switch(nHandle)
890 : {
891 : case PROPHANDLE_TERMINATEVETOSTATE :
892 : {
893 0 : bool bState = (m_bListenForTermination && m_bVeto);
894 0 : aValue <<= bState;
895 : }
896 0 : break;
897 :
898 : default :
899 0 : throw ::com::sun::star::beans::UnknownPropertyException();
900 : }
901 :
902 0 : return aValue;
903 : }
904 :
905 : namespace {
906 :
907 1 : struct Instance {
908 1 : explicit Instance(
909 : css::uno::Reference<css::uno::XComponentContext> const & context):
910 1 : instance(static_cast<cppu::OWeakObject *>(new ShutdownIcon(context)))
911 1 : {}
912 :
913 : rtl::Reference<css::uno::XInterface> instance;
914 : };
915 :
916 : struct Singleton:
917 : public rtl::StaticWithArg<
918 : Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
919 : {};
920 :
921 : }
922 :
923 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
924 1 : com_sun_star_comp_desktop_QuickstartWrapper_get_implementation(
925 : css::uno::XComponentContext *context,
926 : css::uno::Sequence<css::uno::Any> const &)
927 : {
928 : return cppu::acquire(static_cast<cppu::OWeakObject *>(
929 1 : Singleton::get(context).instance.get()));
930 648 : }
931 :
932 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|