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