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 "recoveryui.hxx"
21 : #include "docrecovery.hxx"
22 : #include <com/sun/star/lang/XInitialization.hpp>
23 : #include <com/sun/star/frame/Desktop.hpp>
24 : #include <com/sun/star/frame/XFramesSupplier.hpp>
25 : #include <com/sun/star/beans/NamedValue.hpp>
26 : #include <osl/file.hxx>
27 : #include <rtl/bootstrap.hxx>
28 : #include <comphelper/processfactory.hxx>
29 : #include <comphelper/configurationhelper.hxx>
30 :
31 : #include <vcl/svapp.hxx>
32 :
33 : #include <boost/scoped_ptr.hpp>
34 :
35 :
36 : #define IMPLEMENTATIONNAME_RECOVERYUI ::rtl::OUString("com.sun.star.comp.svx.RecoveryUI")
37 : #define SERVICENAME_RECOVERYUI ::rtl::OUString("com.sun.star.dialog.RecoveryUI")
38 :
39 :
40 : namespace svx
41 : {
42 :
43 : namespace svxdr = ::svx::DocRecovery;
44 :
45 : using namespace ::rtl;
46 : using namespace ::osl;
47 :
48 : //===============================================
49 0 : RecoveryUI::RecoveryUI(const css::uno::Reference< css::uno::XComponentContext >& xContext)
50 : : m_xContext (xContext )
51 : , m_pParentWindow(0 )
52 0 : , m_eJob (RecoveryUI::E_JOB_UNKNOWN)
53 : {
54 0 : }
55 :
56 : //===============================================
57 0 : RecoveryUI::~RecoveryUI()
58 : {
59 0 : }
60 :
61 : //===============================================
62 0 : ::rtl::OUString SAL_CALL RecoveryUI::getImplementationName()
63 : throw(css::uno::RuntimeException)
64 : {
65 0 : return RecoveryUI::st_getImplementationName();
66 : }
67 :
68 : //===============================================
69 0 : sal_Bool SAL_CALL RecoveryUI::supportsService(const ::rtl::OUString& sServiceName)
70 : throw(css::uno::RuntimeException)
71 : {
72 0 : const css::uno::Sequence< ::rtl::OUString > lServices = RecoveryUI::st_getSupportedServiceNames();
73 0 : sal_Int32 c = lServices.getLength();
74 0 : sal_Int32 i = 0;
75 0 : for (i=0; i<c; ++i)
76 : {
77 0 : const ::rtl::OUString& sSupportedService = lServices[i];
78 0 : if (sSupportedService.equals(sServiceName))
79 0 : return sal_True;
80 : }
81 0 : return sal_False;
82 : }
83 :
84 : //===============================================
85 0 : css::uno::Sequence< ::rtl::OUString > SAL_CALL RecoveryUI::getSupportedServiceNames()
86 : throw(css::uno::RuntimeException)
87 : {
88 0 : return RecoveryUI::st_getSupportedServiceNames();
89 : }
90 :
91 : //===============================================
92 0 : css::uno::Any SAL_CALL RecoveryUI::dispatchWithReturnValue(const css::util::URL& aURL,
93 : const css::uno::Sequence< css::beans::PropertyValue >& )
94 : throw(css::uno::RuntimeException)
95 : {
96 : // Internaly we use VCL ... every call into vcl based code must
97 : // be guarded by locking the global solar mutex.
98 0 : ::SolarMutexGuard aSolarLock;
99 :
100 0 : css::uno::Any aRet;
101 0 : RecoveryUI::EJob eJob = impl_classifyJob(aURL);
102 : // TODO think about outside arguments
103 :
104 0 : switch(eJob)
105 : {
106 : case RecoveryUI::E_DO_EMERGENCY_SAVE :
107 : {
108 0 : sal_Bool bRet = impl_doEmergencySave();
109 0 : aRet <<= bRet;
110 : break;
111 : }
112 :
113 : case RecoveryUI::E_DO_RECOVERY :
114 0 : impl_doRecovery();
115 0 : break;
116 :
117 : case RecoveryUI::E_DO_CRASHREPORT :
118 0 : impl_doCrashReport();
119 0 : break;
120 :
121 : default :
122 0 : break;
123 : }
124 :
125 0 : return aRet;
126 : }
127 :
128 : //===============================================
129 0 : void SAL_CALL RecoveryUI::dispatch(const css::util::URL& aURL ,
130 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
131 : throw(css::uno::RuntimeException)
132 : {
133 : // recycle this method :-)
134 0 : dispatchWithReturnValue(aURL, lArguments);
135 0 : }
136 :
137 : //===============================================
138 0 : void SAL_CALL RecoveryUI::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL& ) throw(css::uno::RuntimeException)
139 : {
140 : // TODO
141 : OSL_FAIL("RecoveryUI::addStatusListener()\nNot implemented yet!");
142 0 : }
143 :
144 : //===============================================
145 0 : void SAL_CALL RecoveryUI::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL& )
146 : throw(css::uno::RuntimeException)
147 : {
148 : // TODO
149 : OSL_FAIL("RecoveryUI::removeStatusListener()\nNot implemented yet!");
150 0 : }
151 :
152 : //===============================================
153 0 : ::rtl::OUString RecoveryUI::st_getImplementationName()
154 : {
155 0 : return ::rtl::OUString(IMPLEMENTATIONNAME_RECOVERYUI);
156 : }
157 :
158 : //===============================================
159 0 : css::uno::Sequence< ::rtl::OUString > RecoveryUI::st_getSupportedServiceNames()
160 : {
161 0 : css::uno::Sequence< ::rtl::OUString > lServiceNames(1); lServiceNames.getArray() [0] = SERVICENAME_RECOVERYUI;
162 0 : return lServiceNames;
163 : }
164 :
165 : //===============================================
166 0 : css::uno::Reference< css::uno::XInterface > SAL_CALL RecoveryUI::st_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
167 : {
168 0 : RecoveryUI* pNew = new RecoveryUI(comphelper::getComponentContext(xSMGR));
169 0 : return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XServiceInfo* >(pNew));
170 : }
171 :
172 : //===============================================
173 :
174 0 : static OUString GetCrashConfigDir()
175 : {
176 :
177 : #if defined(WNT)
178 : OUString ustrValue = OUString("${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}");
179 : #elif defined(MACOSX)
180 : OUString ustrValue = OUString("~");
181 : #else
182 0 : OUString ustrValue = OUString("$SYSUSERCONFIG");
183 : #endif
184 0 : Bootstrap::expandMacros( ustrValue );
185 :
186 : #if defined(WNT)
187 : ustrValue += OUString("/user/crashdata");
188 : #endif
189 0 : return ustrValue;
190 : }
191 :
192 : //===============================================
193 :
194 : #if defined(WNT)
195 : #define LCKFILE "crashdat.lck"
196 : #else
197 : #define LCKFILE ".crash_report_unsent"
198 : #endif
199 :
200 :
201 0 : static OUString GetUnsentURL()
202 : {
203 0 : OUString aURL = GetCrashConfigDir();
204 :
205 0 : aURL += OUString( "/" );
206 0 : aURL += OUString( LCKFILE );
207 :
208 0 : return aURL;
209 : }
210 :
211 : //===============================================
212 :
213 0 : static bool new_crash_pending()
214 : {
215 0 : OUString aUnsentURL = GetUnsentURL();
216 0 : File aFile( aUnsentURL );
217 :
218 0 : if ( FileBase::E_None == aFile.open( osl_File_OpenFlag_Read ) )
219 : {
220 0 : aFile.close();
221 0 : return true;
222 : }
223 :
224 0 : return false;
225 : }
226 : //===============================================
227 :
228 0 : static bool delete_pending_crash()
229 : {
230 0 : OUString aUnsentURL = GetUnsentURL();
231 0 : return ( FileBase::E_None == File::remove( aUnsentURL ) );
232 : }
233 :
234 0 : RecoveryUI::EJob RecoveryUI::impl_classifyJob(const css::util::URL& aURL)
235 : {
236 0 : m_eJob = RecoveryUI::E_JOB_UNKNOWN;
237 0 : if (aURL.Protocol.equals(RECOVERY_CMDPART_PROTOCOL))
238 : {
239 0 : if (aURL.Path.equals(RECOVERY_CMDPART_DO_EMERGENCY_SAVE))
240 0 : m_eJob = RecoveryUI::E_DO_EMERGENCY_SAVE;
241 : else
242 0 : if (aURL.Path.equals(RECOVERY_CMDPART_DO_RECOVERY))
243 0 : m_eJob = RecoveryUI::E_DO_RECOVERY;
244 : else
245 0 : if (aURL.Path.equals(RECOVERY_CMDPART_DO_CRASHREPORT))
246 0 : m_eJob = RecoveryUI::E_DO_CRASHREPORT;
247 : }
248 :
249 0 : return m_eJob;
250 : }
251 :
252 : //===============================================
253 0 : sal_Bool RecoveryUI::impl_doEmergencySave()
254 : {
255 : // create core service, which implements the real "emergency save" algorithm.
256 0 : svxdr::RecoveryCore* pCore = new svxdr::RecoveryCore(m_xContext, sal_True);
257 0 : css::uno::Reference< css::frame::XStatusListener > xCore(pCore);
258 :
259 : // create all needed dialogs for this operation
260 : // and bind it to the used core service
261 0 : svxdr::TabDialog4Recovery* pWizard = new svxdr::TabDialog4Recovery(m_pParentWindow);
262 0 : svxdr::IExtendedTabPage* pPage1 = new svxdr::SaveDialog (pWizard, pCore );
263 0 : pWizard->addTabPage(pPage1);
264 :
265 : // start the wizard
266 0 : short nRet = pWizard->Execute();
267 :
268 0 : delete pPage1 ;
269 0 : delete pWizard;
270 :
271 0 : return (nRet==DLG_RET_OK_AUTOLUNCH);
272 : }
273 :
274 : //===============================================
275 0 : void RecoveryUI::impl_doRecovery()
276 : {
277 0 : sal_Bool bRecoveryOnly( sal_False );
278 :
279 0 : ::rtl::OUString CFG_PACKAGE_RECOVERY( "org.openoffice.Office.Recovery/");
280 0 : ::rtl::OUString CFG_PATH_CRASHREPORTER( "CrashReporter" );
281 0 : ::rtl::OUString CFG_ENTRY_ENABLED( "Enabled" );
282 :
283 0 : sal_Bool bCrashRepEnabled(sal_False);
284 : css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
285 : m_xContext,
286 : CFG_PACKAGE_RECOVERY,
287 : CFG_PATH_CRASHREPORTER,
288 : CFG_ENTRY_ENABLED,
289 0 : ::comphelper::ConfigurationHelper::E_READONLY);
290 0 : aVal >>= bCrashRepEnabled;
291 0 : bRecoveryOnly = !bCrashRepEnabled;
292 :
293 : // create core service, which implements the real "emergency save" algorithm.
294 0 : svxdr::RecoveryCore* pCore = new svxdr::RecoveryCore(m_xContext, sal_False);
295 0 : css::uno::Reference< css::frame::XStatusListener > xCore(pCore);
296 :
297 : // create all needed dialogs for this operation
298 : // and bind it to the used core service
299 0 : boost::scoped_ptr<svxdr::TabDialog4Recovery> xWizard(new svxdr::TabDialog4Recovery(m_pParentWindow));
300 0 : svxdr::IExtendedTabPage* pPage1 = new svxdr::RecoveryDialog(xWizard.get(), pCore );
301 0 : svxdr::IExtendedTabPage* pPage2 = 0;
302 0 : svxdr::IExtendedTabPage* pPage3 = 0;
303 :
304 0 : xWizard->addTabPage(pPage1);
305 0 : if ( !bRecoveryOnly && new_crash_pending() )
306 : {
307 0 : pPage2 = new svxdr::ErrorRepWelcomeDialog(xWizard.get());
308 0 : pPage3 = new svxdr::ErrorRepSendDialog(xWizard.get());
309 0 : xWizard->addTabPage(pPage2);
310 0 : xWizard->addTabPage(pPage3);
311 : }
312 :
313 : // start the wizard
314 0 : xWizard->Execute();
315 :
316 0 : impl_showAllRecoveredDocs();
317 :
318 0 : delete pPage3 ;
319 0 : delete pPage2 ;
320 0 : delete pPage1 ;
321 :
322 0 : delete_pending_crash();
323 0 : }
324 :
325 : //===============================================
326 :
327 0 : void RecoveryUI::impl_doCrashReport()
328 : {
329 0 : if ( new_crash_pending() )
330 : {
331 0 : svxdr::TabDialog4Recovery* pWizard = new svxdr::TabDialog4Recovery (m_pParentWindow );
332 0 : svxdr::IExtendedTabPage* pPage1 = new svxdr::ErrorRepWelcomeDialog(pWizard, sal_False);
333 0 : svxdr::IExtendedTabPage* pPage2 = new svxdr::ErrorRepSendDialog (pWizard );
334 0 : pWizard->addTabPage(pPage1);
335 0 : pWizard->addTabPage(pPage2);
336 :
337 : // start the wizard
338 0 : pWizard->Execute();
339 :
340 0 : delete pPage2 ;
341 0 : delete pPage1 ;
342 0 : delete pWizard;
343 :
344 0 : delete_pending_crash();
345 : }
346 0 : }
347 :
348 : //===============================================
349 0 : void RecoveryUI::impl_showAllRecoveredDocs()
350 : {
351 0 : css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( m_xContext );
352 :
353 : css::uno::Reference< css::container::XIndexAccess > xTaskContainer(
354 0 : xDesktop->getFrames(),
355 0 : css::uno::UNO_QUERY_THROW);
356 :
357 0 : sal_Int32 c = xTaskContainer->getCount();
358 0 : sal_Int32 i = 0;
359 0 : for (i=0; i<c; ++i)
360 : {
361 : try
362 : {
363 0 : css::uno::Reference< css::frame::XFrame > xTask;
364 0 : xTaskContainer->getByIndex(i) >>= xTask;
365 0 : if (!xTask.is())
366 0 : continue;
367 :
368 0 : css::uno::Reference< css::awt::XWindow > xWindow = xTask->getContainerWindow();
369 0 : if (!xWindow.is())
370 0 : continue;
371 :
372 0 : xWindow->setVisible(sal_True);
373 : }
374 0 : catch(const css::uno::RuntimeException&)
375 0 : { throw; }
376 0 : catch(const css::uno::Exception&)
377 0 : { continue; }
378 0 : }
379 0 : }
380 :
381 : } // namespace svx
382 :
383 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|