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