LibreOffice Module svx (master) 1
recoveryui.cxx
Go to the documentation of this file.
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 <config_folders.h>
21
22#include <docrecovery.hxx>
23#include <com/sun/star/frame/Desktop.hpp>
24#include <com/sun/star/frame/XSynchronousDispatch.hpp>
25#include <com/sun/star/lang/XServiceInfo.hpp>
27#include <osl/file.hxx>
28#include <rtl/bootstrap.hxx>
29#include <rtl/ref.hxx>
31
32#include <vcl/svapp.hxx>
33
34namespace svxdr = svx::DocRecovery;
35using namespace ::osl;
36
37namespace {
38
39class RecoveryUI : public ::cppu::WeakImplHelper< css::lang::XServiceInfo ,
40 css::frame::XSynchronousDispatch > // => XDispatch!
41{
42
43 // const, types, etcpp.
44 private:
45
47 enum EJob
48 {
49 E_JOB_UNKNOWN,
50 E_DO_EMERGENCY_SAVE,
51 E_DO_RECOVERY,
52 E_DO_BRINGTOFRONT,
53 };
54
55
56 // member
57 private:
58
60 css::uno::Reference< css::uno::XComponentContext > m_xContext;
61
63 weld::Window* m_pParentWindow;
64
66 RecoveryUI::EJob m_eJob;
67
68 // Active dialog
69 weld::Dialog* m_pDialog;
70
71 // interface
72 public:
73
74
76 explicit RecoveryUI(const css::uno::Reference< css::uno::XComponentContext >& xContext);
77
78 // css.lang.XServiceInfo
79
80 virtual OUString SAL_CALL getImplementationName() override;
81
82 virtual sal_Bool SAL_CALL supportsService(const OUString& sServiceName) override;
83
84 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
85
86
87 virtual css::uno::Any SAL_CALL dispatchWithReturnValue(const css::util::URL& aURL,
88 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) override;
89
90 void SetActiveDialog(weld::Dialog* pDialog)
91 {
92 m_pDialog = pDialog;
93 }
94
95 // helper
96 private:
97
98 EJob impl_classifyJob(const css::util::URL& aURL);
99
100 bool impl_doEmergencySave();
101
102 bool impl_doRecovery();
103
104 void impl_showAllRecoveredDocs();
105
106 bool impl_doBringToFront();
107};
108
109RecoveryUI::RecoveryUI(const css::uno::Reference< css::uno::XComponentContext >& xContext)
110 : m_xContext(xContext)
111 , m_pParentWindow(nullptr)
112 , m_eJob(RecoveryUI::E_JOB_UNKNOWN)
113 , m_pDialog(nullptr)
114{
115}
116
117OUString SAL_CALL RecoveryUI::getImplementationName()
118{
119 return "com.sun.star.comp.svx.RecoveryUI";
120}
121
122sal_Bool SAL_CALL RecoveryUI::supportsService(const OUString& sServiceName)
123{
124 return cppu::supportsService(this, sServiceName);
125}
126
127css::uno::Sequence< OUString > SAL_CALL RecoveryUI::getSupportedServiceNames()
128{
129 return { "com.sun.star.dialog.RecoveryUI" };
130}
131
132css::uno::Any SAL_CALL RecoveryUI::dispatchWithReturnValue(const css::util::URL& aURL,
133 const css::uno::Sequence< css::beans::PropertyValue >& )
134{
135 // Internally we use VCL ... every call into vcl based code must
136 // be guarded by locking the global solar mutex.
137 ::SolarMutexGuard aSolarLock;
138
139 css::uno::Any aRet;
140 RecoveryUI::EJob eJob = impl_classifyJob(aURL);
141 // TODO think about outside arguments
142
143 switch(eJob)
144 {
145 case RecoveryUI::E_DO_EMERGENCY_SAVE:
146 {
147 bool bRet = impl_doEmergencySave();
148 aRet <<= bRet;
149 break;
150 }
151
152 case RecoveryUI::E_DO_RECOVERY:
153 {
154 bool bRet = impl_doRecovery();
155 aRet <<= bRet;
156 break;
157 }
158
159 case RecoveryUI::E_DO_BRINGTOFRONT:
160 {
161 bool bRet = impl_doBringToFront();
162 aRet <<= bRet;
163 break;
164 }
165
166 default:
167 {
168 aRet <<= false;
169 break;
170 }
171 }
172
173 return aRet;
174}
175
176
177OUString GetCrashConfigDir()
178{
179
180#if defined(_WIN32)
181 OUString ustrValue = "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/bootstrap.ini:UserInstallation}";
182#elif defined(MACOSX)
183 OUString ustrValue = "~";
184#else
185 OUString ustrValue = "$SYSUSERCONFIG";
186#endif
187 rtl::Bootstrap::expandMacros( ustrValue );
188
189#if defined(_WIN32)
190 ustrValue += "/user/crashdata";
191#endif
192 return ustrValue;
193}
194
195
196#if defined(_WIN32)
197#define LCKFILE "crashdat.lck"
198#else
199#define LCKFILE ".crash_report_unsent"
200#endif
201
202
203OUString GetUnsentURL()
204{
205 OUString aURL = GetCrashConfigDir() + "/" LCKFILE;
206 return aURL;
207}
208
209
210bool delete_pending_crash()
211{
212 OUString aUnsentURL = GetUnsentURL();
213 return ( FileBase::E_None == File::remove( aUnsentURL ) );
214}
215
216RecoveryUI::EJob RecoveryUI::impl_classifyJob(const css::util::URL& aURL)
217{
218 m_eJob = RecoveryUI::E_JOB_UNKNOWN;
219 if (aURL.Protocol == RECOVERY_CMDPART_PROTOCOL)
220 {
222 m_eJob = RecoveryUI::E_DO_EMERGENCY_SAVE;
223 else if (aURL.Path == RECOVERY_CMDPART_DO_RECOVERY)
224 m_eJob = RecoveryUI::E_DO_RECOVERY;
225 else if (aURL.Path == RECOVERY_CMDPART_DO_BRINGTOFRONT)
226 m_eJob = RecoveryUI::E_DO_BRINGTOFRONT;
227 }
228
229 return m_eJob;
230}
231
232struct DialogReleaseGuard
233{
234 RecoveryUI& m_rRecoveryUI;
235
236 DialogReleaseGuard(RecoveryUI& rRecoveryUI, weld::Dialog* p)
237 : m_rRecoveryUI(rRecoveryUI)
238 {
239 m_rRecoveryUI.SetActiveDialog(p);
240 }
241 ~DialogReleaseGuard()
242 {
243 m_rRecoveryUI.SetActiveDialog(nullptr);
244 }
245};
246
247bool RecoveryUI::impl_doEmergencySave()
248{
249 // create core service, which implements the real "emergency save" algorithm.
250 rtl::Reference<svxdr::RecoveryCore> pCore = new svxdr::RecoveryCore(m_xContext, true);
251
252 // create dialog for this operation and bind it to the used core service
253 std::unique_ptr<svxdr::SaveDialog> xDialog(new svxdr::SaveDialog(m_pParentWindow, pCore.get()));
254 DialogReleaseGuard dialogReleaseGuard(*this, xDialog->getDialog());
255
256 // start the dialog
257 short nRet = xDialog->run();
258 return (nRet==DLG_RET_OK_AUTOLUNCH);
259}
260
261bool RecoveryUI::impl_doRecovery()
262{
263 // create core service, which implements the real "emergency save" algorithm.
264 rtl::Reference<svxdr::RecoveryCore> pCore = new svxdr::RecoveryCore(m_xContext, false);
265
266 // create all needed dialogs for this operation
267 // and bind it to the used core service
268 std::unique_ptr<svxdr::RecoveryDialog> xDialog(new svxdr::RecoveryDialog(m_pParentWindow, pCore.get()));
269 DialogReleaseGuard dialogReleaseGuard(*this, xDialog->getDialog());
270
271 // start the dialog
272 short nRet = xDialog->run();
273
274 impl_showAllRecoveredDocs();
275
276 delete_pending_crash();
277
278 return nRet != RET_CANCEL;
279}
280
281void RecoveryUI::impl_showAllRecoveredDocs()
282{
283 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( m_xContext );
284
285 css::uno::Reference< css::container::XIndexAccess > xTaskContainer(
286 xDesktop->getFrames(),
287 css::uno::UNO_QUERY_THROW);
288
289 sal_Int32 c = xTaskContainer->getCount();
290 sal_Int32 i = 0;
291 for (i=0; i<c; ++i)
292 {
293 try
294 {
295 css::uno::Reference< css::frame::XFrame > xTask;
296 xTaskContainer->getByIndex(i) >>= xTask;
297 if (!xTask.is())
298 continue;
299
300 css::uno::Reference< css::awt::XWindow > xWindow = xTask->getContainerWindow();
301 if (!xWindow.is())
302 continue;
303
304 xWindow->setVisible(true);
305 }
306 catch(const css::uno::RuntimeException&)
307 { throw; }
308 catch(const css::uno::Exception&)
309 { continue; }
310 }
311}
312
313bool RecoveryUI::impl_doBringToFront()
314{
315 if (!m_pDialog || !m_pDialog->get_visible())
316 return false;
317 m_pDialog->present();
318 return true;
319}
320
321}
322
323extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
325 css::uno::XComponentContext *context,
326 css::uno::Sequence<css::uno::Any> const &)
327{
328 return cppu::acquire(new RecoveryUI(context));
329}
330
331/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
URL aURL
#define DLG_RET_OK_AUTOLUNCH
Definition: docrecovery.hxx:67
#define RECOVERY_CMDPART_DO_EMERGENCY_SAVE
Definition: docrecovery.hxx:36
#define RECOVERY_CMDPART_DO_RECOVERY
Definition: docrecovery.hxx:37
#define RECOVERY_CMDPART_PROTOCOL
Definition: docrecovery.hxx:34
#define RECOVERY_CMDPART_DO_BRINGTOFRONT
Definition: docrecovery.hxx:38
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_svx_RecoveryUI_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: recoveryui.cxx:324
#define LCKFILE
Definition: recoveryui.cxx:199
unsigned char sal_Bool
RET_CANCEL