1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_folders.h>
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>
26 #include <cppuhelper/implbase.hxx>
27 #include <osl/file.hxx>
28 #include <rtl/bootstrap.hxx>
29 #include <rtl/ref.hxx>
30 #include <cppuhelper/supportsservice.hxx>
32 #include <vcl/svapp.hxx>
34 namespace svxdr
= svx::DocRecovery
;
35 using namespace ::osl
;
39 class RecoveryUI
: public ::cppu::WeakImplHelper
< css::lang::XServiceInfo
,
40 css::frame::XSynchronousDispatch
> // => XDispatch!
43 // const, types, etcpp.
60 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
63 weld::Window
* m_pParentWindow
;
66 RecoveryUI::EJob m_eJob
;
69 weld::Dialog
* m_pDialog
;
76 explicit RecoveryUI(const css::uno::Reference
< css::uno::XComponentContext
>& xContext
);
78 // css.lang.XServiceInfo
80 virtual OUString SAL_CALL
getImplementationName() override
;
82 virtual sal_Bool SAL_CALL
supportsService(const OUString
& sServiceName
) override
;
84 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
87 virtual css::uno::Any SAL_CALL
dispatchWithReturnValue(const css::util::URL
& aURL
,
88 const css::uno::Sequence
< css::beans::PropertyValue
>& lArguments
) override
;
90 void SetActiveDialog(weld::Dialog
* pDialog
)
98 EJob
impl_classifyJob(const css::util::URL
& aURL
);
100 bool impl_doEmergencySave();
102 bool impl_doRecovery();
104 void impl_showAllRecoveredDocs();
106 bool impl_doBringToFront();
109 RecoveryUI::RecoveryUI(const css::uno::Reference
< css::uno::XComponentContext
>& xContext
)
110 : m_xContext(xContext
)
111 , m_pParentWindow(nullptr)
112 , m_eJob(RecoveryUI::E_JOB_UNKNOWN
)
117 OUString SAL_CALL
RecoveryUI::getImplementationName()
119 return "com.sun.star.comp.svx.RecoveryUI";
122 sal_Bool SAL_CALL
RecoveryUI::supportsService(const OUString
& sServiceName
)
124 return cppu::supportsService(this, sServiceName
);
127 css::uno::Sequence
< OUString
> SAL_CALL
RecoveryUI::getSupportedServiceNames()
129 return { "com.sun.star.dialog.RecoveryUI" };
132 css::uno::Any SAL_CALL
RecoveryUI::dispatchWithReturnValue(const css::util::URL
& aURL
,
133 const css::uno::Sequence
< css::beans::PropertyValue
>& )
135 // Internally we use VCL ... every call into vcl based code must
136 // be guarded by locking the global solar mutex.
137 ::SolarMutexGuard aSolarLock
;
140 RecoveryUI::EJob eJob
= impl_classifyJob(aURL
);
141 // TODO think about outside arguments
145 case RecoveryUI::E_DO_EMERGENCY_SAVE
:
147 bool bRet
= impl_doEmergencySave();
152 case RecoveryUI::E_DO_RECOVERY
:
154 bool bRet
= impl_doRecovery();
159 case RecoveryUI::E_DO_BRINGTOFRONT
:
161 bool bRet
= impl_doBringToFront();
177 OUString
GetCrashConfigDir()
181 OUString ustrValue
= "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/bootstrap.ini:UserInstallation}";
182 #elif defined(MACOSX)
183 OUString ustrValue
= "~";
185 OUString ustrValue
= "$SYSUSERCONFIG";
187 rtl::Bootstrap::expandMacros( ustrValue
);
190 ustrValue
+= "/user/crashdata";
197 #define LCKFILE "crashdat.lck"
199 #define LCKFILE ".crash_report_unsent"
203 OUString
GetUnsentURL()
205 OUString aURL
= GetCrashConfigDir() + "/" LCKFILE
;
210 bool delete_pending_crash()
212 OUString aUnsentURL
= GetUnsentURL();
213 return ( FileBase::E_None
== File::remove( aUnsentURL
) );
216 RecoveryUI::EJob
RecoveryUI::impl_classifyJob(const css::util::URL
& aURL
)
218 m_eJob
= RecoveryUI::E_JOB_UNKNOWN
;
219 if (aURL
.Protocol
== RECOVERY_CMDPART_PROTOCOL
)
221 if (aURL
.Path
== RECOVERY_CMDPART_DO_EMERGENCY_SAVE
)
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
;
232 struct DialogReleaseGuard
234 RecoveryUI
& m_rRecoveryUI
;
236 DialogReleaseGuard(RecoveryUI
& rRecoveryUI
, weld::Dialog
* p
)
237 : m_rRecoveryUI(rRecoveryUI
)
239 m_rRecoveryUI
.SetActiveDialog(p
);
241 ~DialogReleaseGuard()
243 m_rRecoveryUI
.SetActiveDialog(nullptr);
247 bool RecoveryUI::impl_doEmergencySave()
249 // create core service, which implements the real "emergency save" algorithm.
250 rtl::Reference
<svxdr::RecoveryCore
> pCore
= new svxdr::RecoveryCore(m_xContext
, true);
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());
257 short nRet
= xDialog
->run();
258 return (nRet
==DLG_RET_OK_AUTOLUNCH
);
261 bool RecoveryUI::impl_doRecovery()
263 // create core service, which implements the real "emergency save" algorithm.
264 rtl::Reference
<svxdr::RecoveryCore
> pCore
= new svxdr::RecoveryCore(m_xContext
, false);
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());
272 short nRet
= xDialog
->run();
274 impl_showAllRecoveredDocs();
276 delete_pending_crash();
278 return nRet
!= RET_CANCEL
;
281 void RecoveryUI::impl_showAllRecoveredDocs()
283 css::uno::Reference
< css::frame::XDesktop2
> xDesktop
= css::frame::Desktop::create( m_xContext
);
285 css::uno::Reference
< css::container::XIndexAccess
> xTaskContainer(
286 xDesktop
->getFrames(),
287 css::uno::UNO_QUERY_THROW
);
289 sal_Int32 c
= xTaskContainer
->getCount();
295 css::uno::Reference
< css::frame::XFrame
> xTask
;
296 xTaskContainer
->getByIndex(i
) >>= xTask
;
300 css::uno::Reference
< css::awt::XWindow
> xWindow
= xTask
->getContainerWindow();
304 xWindow
->setVisible(true);
306 catch(const css::uno::RuntimeException
&)
308 catch(const css::uno::Exception
&)
313 bool RecoveryUI::impl_doBringToFront()
315 if (!m_pDialog
|| !m_pDialog
->get_visible())
317 m_pDialog
->present();
323 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
324 com_sun_star_comp_svx_RecoveryUI_get_implementation(
325 css::uno::XComponentContext
*context
,
326 css::uno::Sequence
<css::uno::Any
> const &)
328 return cppu::acquire(new RecoveryUI(context
));
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */