1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 
31 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
32 #include <com/sun/star/awt/XRequestCallback.hpp>
33 #include <com/sun/star/frame/XDesktop.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 
36 #include <comphelper_module.hxx>
37 #include "officerestartmanager.hxx"
38 
39 using namespace ::com::sun::star;
40 
41 namespace comphelper
42 {
43 
44 // ----------------------------------------------------------
45 uno::Sequence< ::rtl::OUString > SAL_CALL OOfficeRestartManager::getSupportedServiceNames_static()
46 {
47     uno::Sequence< rtl::OUString > aResult( 1 );
48     aResult[0] = getServiceName_static();
49     return aResult;
50 }
51 
52 // ----------------------------------------------------------
53 ::rtl::OUString SAL_CALL OOfficeRestartManager::getImplementationName_static()
54 {
55     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.task.OfficeRestartManager" ) );
56 }
57 
58 // ----------------------------------------------------------
59 ::rtl::OUString SAL_CALL OOfficeRestartManager::getSingletonName_static()
60 {
61     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) );
62 }
63 
64 // ----------------------------------------------------------
65 ::rtl::OUString SAL_CALL OOfficeRestartManager::getServiceName_static()
66 {
67     return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.task.OfficeRestartManager" ) );
68 }
69 
70 // ----------------------------------------------------------
71 uno::Reference< uno::XInterface > SAL_CALL OOfficeRestartManager::Create( const uno::Reference< uno::XComponentContext >& rxContext )
72 {
73     return static_cast< cppu::OWeakObject* >( new OOfficeRestartManager( rxContext ) );
74 }
75 
76 // XRestartManager
77 // ----------------------------------------------------------
78 void SAL_CALL OOfficeRestartManager::requestRestart( const uno::Reference< task::XInteractionHandler >& /* xInteractionHandler */ )
79     throw (uno::Exception, uno::RuntimeException)
80 {
81     if ( !m_xContext.is() )
82         throw uno::RuntimeException();
83 
84     {
85         ::osl::MutexGuard aGuard( m_aMutex );
86 
87         // if the restart already running there is no need to trigger it again
88         if ( m_bRestartRequested )
89             return;
90 
91         m_bRestartRequested = sal_True;
92 
93         // the office is still not initialized, no need to terminate, changing the state is enough
94         if ( !m_bOfficeInitialized )
95             return;
96     }
97 
98     // TODO: use InteractionHandler to report errors
99     try
100     {
101         // register itself as a job that should be executed asynchronously
102         uno::Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_SET_THROW );
103 
104         uno::Reference< awt::XRequestCallback > xRequestCallback(
105             xFactory->createInstanceWithContext(
106                  ::rtl::OUString::createFromAscii("com.sun.star.awt.AsyncCallback"),
107                  m_xContext ),
108              uno::UNO_QUERY_THROW );
109 
110         xRequestCallback->addCallback( this, uno::Any() );
111     }
112     catch ( uno::Exception& )
113     {
114         // the try to request restart has failed
115         m_bRestartRequested = sal_False;
116     }
117 }
118 
119 // ----------------------------------------------------------
120 ::sal_Bool SAL_CALL OOfficeRestartManager::isRestartRequested( ::sal_Bool bOfficeInitialized )
121     throw (uno::Exception, uno::RuntimeException)
122 {
123     ::osl::MutexGuard aGuard( m_aMutex );
124 
125     if ( bOfficeInitialized && !m_bOfficeInitialized )
126         m_bOfficeInitialized = bOfficeInitialized;
127 
128     return m_bRestartRequested;
129 }
130 
131 // XCallback
132 // ----------------------------------------------------------
133 void SAL_CALL OOfficeRestartManager::notify( const uno::Any& /* aData */ )
134     throw ( uno::RuntimeException )
135 {
136     try
137     {
138         sal_Bool bSuccess = sal_False;
139 
140         if ( m_xContext.is() )
141         {
142             uno::Reference< lang::XMultiComponentFactory > xFactory( m_xContext->getServiceManager(), uno::UNO_SET_THROW );
143             uno::Reference< frame::XDesktop > xDesktop(
144                 xFactory->createInstanceWithContext(
145                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), m_xContext ),
146                 uno::UNO_QUERY_THROW );
147 
148             // Turn Quickstarter veto off
149             uno::Reference< beans::XPropertySet > xPropertySet( xDesktop, uno::UNO_QUERY_THROW );
150             ::rtl::OUString aVetoPropName( RTL_CONSTASCII_USTRINGPARAM( "SuspendQuickstartVeto" ) );
151             uno::Any aValue;
152             aValue <<= (sal_Bool)sal_True;
153             xPropertySet->setPropertyValue( aVetoPropName, aValue );
154 
155             try
156             {
157                 bSuccess = xDesktop->terminate();
158             } catch( uno::Exception& )
159             {}
160 
161             if ( !bSuccess )
162             {
163                 aValue <<= (sal_Bool)sal_False;
164                 xPropertySet->setPropertyValue( aVetoPropName, aValue );
165             }
166         }
167 
168         if ( !bSuccess )
169             m_bRestartRequested = sal_False;
170     }
171     catch( uno::Exception& )
172     {
173         // the try to restart has failed
174         m_bRestartRequested = sal_False;
175     }
176 }
177 
178 // XServiceInfo
179 // ----------------------------------------------------------
180 ::rtl::OUString SAL_CALL OOfficeRestartManager::getImplementationName() throw (uno::RuntimeException)
181 {
182     return getImplementationName_static();
183 }
184 
185 // ----------------------------------------------------------
186 ::sal_Bool SAL_CALL OOfficeRestartManager::supportsService( const ::rtl::OUString& aServiceName ) throw (uno::RuntimeException)
187 {
188     const uno::Sequence< rtl::OUString > & aSupportedNames = getSupportedServiceNames_static();
189     for ( sal_Int32 nInd = 0; nInd < aSupportedNames.getLength(); nInd++ )
190     {
191         if ( aSupportedNames[ nInd ].equals( aServiceName ) )
192             return sal_True;
193     }
194 
195     return sal_False;
196 }
197 
198 // ----------------------------------------------------------
199 uno::Sequence< ::rtl::OUString > SAL_CALL OOfficeRestartManager::getSupportedServiceNames() throw (uno::RuntimeException)
200 {
201     return getSupportedServiceNames_static();
202 }
203 
204 } // namespace comphelper
205 
206 void createRegistryInfo_OOfficeRestartManager()
207 {
208     static ::comphelper::module::OAutoRegistration< ::comphelper::OOfficeRestartManager > aAutoRegistration;
209     static ::comphelper::module::OSingletonRegistration< ::comphelper::OOfficeRestartManager > aSingletonRegistration;
210 }
211