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>
33 #include <vcl/svapp.hxx>
35 namespace svxdr
= svx::DocRecovery
;
36 using namespace ::osl
;
40 class RecoveryUI
: public ::cppu::WeakImplHelper
< css::lang::XServiceInfo
,
41 css::frame::XSynchronousDispatch
> // => XDispatch!
44 // const, types, etcpp.
61 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
64 weld::Window
* m_pParentWindow
;
67 RecoveryUI::EJob m_eJob
;
70 weld::Dialog
* m_pDialog
;
77 explicit RecoveryUI(css::uno::Reference
< css::uno::XComponentContext
> xContext
);
79 // css.lang.XServiceInfo
81 virtual OUString SAL_CALL
getImplementationName() override
;
83 virtual sal_Bool SAL_CALL
supportsService(const OUString
& sServiceName
) override
;
85 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
88 virtual css::uno::Any SAL_CALL
dispatchWithReturnValue(const css::util::URL
& aURL
,
89 const css::uno::Sequence
< css::beans::PropertyValue
>& lArguments
) override
;
91 void SetActiveDialog(weld::Dialog
* pDialog
)
99 EJob
impl_classifyJob(const css::util::URL
& aURL
);
101 bool impl_doEmergencySave();
103 bool impl_doRecovery();
105 void impl_showAllRecoveredDocs();
107 bool impl_doBringToFront();
110 RecoveryUI::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
)
118 OUString SAL_CALL
RecoveryUI::getImplementationName()
120 return u
"com.sun.star.comp.svx.RecoveryUI"_ustr
;
123 sal_Bool SAL_CALL
RecoveryUI::supportsService(const OUString
& sServiceName
)
125 return cppu::supportsService(this, sServiceName
);
128 css::uno::Sequence
< OUString
> SAL_CALL
RecoveryUI::getSupportedServiceNames()
130 return { u
"com.sun.star.dialog.RecoveryUI"_ustr
};
133 css::uno::Any SAL_CALL
RecoveryUI::dispatchWithReturnValue(const css::util::URL
& aURL
,
134 const css::uno::Sequence
< css::beans::PropertyValue
>& )
136 // Internally we use VCL ... every call into vcl based code must
137 // be guarded by locking the global solar mutex.
138 ::SolarMutexGuard aSolarLock
;
141 RecoveryUI::EJob eJob
= impl_classifyJob(aURL
);
142 // TODO think about outside arguments
146 case RecoveryUI::E_DO_EMERGENCY_SAVE
:
148 bool bRet
= impl_doEmergencySave();
153 case RecoveryUI::E_DO_RECOVERY
:
155 bool bRet
= impl_doRecovery();
160 case RecoveryUI::E_DO_BRINGTOFRONT
:
162 bool bRet
= impl_doBringToFront();
178 OUString
GetCrashConfigDir()
182 OUString ustrValue
= "${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/bootstrap.ini:UserInstallation}";
183 #elif defined(MACOSX)
184 OUString ustrValue
= "~";
186 OUString ustrValue
= u
"$SYSUSERCONFIG"_ustr
;
188 rtl::Bootstrap::expandMacros( ustrValue
);
191 ustrValue
+= "/user/crashdata";
198 #define LCKFILE "crashdat.lck"
200 #define LCKFILE ".crash_report_unsent"
204 OUString
GetUnsentURL()
206 OUString aURL
= GetCrashConfigDir() + "/" LCKFILE
;
211 bool delete_pending_crash()
213 OUString aUnsentURL
= GetUnsentURL();
214 return ( FileBase::E_None
== File::remove( aUnsentURL
) );
217 RecoveryUI::EJob
RecoveryUI::impl_classifyJob(const css::util::URL
& aURL
)
219 m_eJob
= RecoveryUI::E_JOB_UNKNOWN
;
220 if (aURL
.Protocol
== RECOVERY_CMDPART_PROTOCOL
)
222 if (aURL
.Path
== RECOVERY_CMDPART_DO_EMERGENCY_SAVE
)
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
;
233 struct DialogReleaseGuard
235 RecoveryUI
& m_rRecoveryUI
;
237 DialogReleaseGuard(RecoveryUI
& rRecoveryUI
, weld::Dialog
* p
)
238 : m_rRecoveryUI(rRecoveryUI
)
240 m_rRecoveryUI
.SetActiveDialog(p
);
242 ~DialogReleaseGuard()
244 m_rRecoveryUI
.SetActiveDialog(nullptr);
248 bool RecoveryUI::impl_doEmergencySave()
250 // create core service, which implements the real "emergency save" algorithm.
251 rtl::Reference
<svxdr::RecoveryCore
> pCore
= new svxdr::RecoveryCore(m_xContext
, true);
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());
258 short nRet
= xDialog
->run();
259 return (nRet
==DLG_RET_OK_AUTOLAUNCH
);
262 bool RecoveryUI::impl_doRecovery()
264 // create core service, which implements the real "emergency save" algorithm.
265 rtl::Reference
<svxdr::RecoveryCore
> pCore
= new svxdr::RecoveryCore(m_xContext
, false);
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());
273 short nRet
= xDialog
->run();
275 impl_showAllRecoveredDocs();
277 delete_pending_crash();
279 return nRet
!= RET_CANCEL
;
282 void RecoveryUI::impl_showAllRecoveredDocs()
284 css::uno::Reference
< css::frame::XDesktop2
> xDesktop
= css::frame::Desktop::create( m_xContext
);
286 css::uno::Reference
< css::container::XIndexAccess
> xTaskContainer(
287 xDesktop
->getFrames(),
288 css::uno::UNO_QUERY_THROW
);
290 sal_Int32 c
= xTaskContainer
->getCount();
296 css::uno::Reference
< css::frame::XFrame
> xTask
;
297 xTaskContainer
->getByIndex(i
) >>= xTask
;
301 css::uno::Reference
< css::awt::XWindow
> xWindow
= xTask
->getContainerWindow();
305 xWindow
->setVisible(true);
307 catch(const css::uno::RuntimeException
&)
309 catch(const css::uno::Exception
&)
314 bool RecoveryUI::impl_doBringToFront()
316 if (!m_pDialog
|| !m_pDialog
->get_visible())
318 m_pDialog
->present();
324 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
325 com_sun_star_comp_svx_RecoveryUI_get_implementation(
326 css::uno::XComponentContext
*context
,
327 css::uno::Sequence
<css::uno::Any
> const &)
329 return cppu::acquire(new RecoveryUI(context
));
332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */