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 "recoveryui.hxx"
21 #include "docrecovery.hxx"
22 #include <com/sun/star/lang/XInitialization.hpp>
23 #include <com/sun/star/frame/Desktop.hpp>
24 #include <com/sun/star/frame/XFramesSupplier.hpp>
25 #include <com/sun/star/beans/NamedValue.hpp>
26 #include <osl/file.hxx>
27 #include <rtl/bootstrap.hxx>
28 #include <comphelper/processfactory.hxx>
29 #include <comphelper/configurationhelper.hxx>
31 #include <vcl/svapp.hxx>
33 #include <boost/scoped_ptr.hpp>
36 #define IMPLEMENTATIONNAME_RECOVERYUI OUString("com.sun.star.comp.svx.RecoveryUI")
37 #define SERVICENAME_RECOVERYUI OUString("com.sun.star.dialog.RecoveryUI")
43 namespace svxdr
= ::svx::DocRecovery
;
45 using namespace ::rtl
;
46 using namespace ::osl
;
48 //===============================================
49 RecoveryUI::RecoveryUI(const css::uno::Reference
< css::uno::XComponentContext
>& xContext
)
50 : m_xContext (xContext
)
52 , m_eJob (RecoveryUI::E_JOB_UNKNOWN
)
56 //===============================================
57 RecoveryUI::~RecoveryUI()
61 //===============================================
62 OUString SAL_CALL
RecoveryUI::getImplementationName()
63 throw(css::uno::RuntimeException
)
65 return RecoveryUI::st_getImplementationName();
68 //===============================================
69 sal_Bool SAL_CALL
RecoveryUI::supportsService(const OUString
& sServiceName
)
70 throw(css::uno::RuntimeException
)
72 const css::uno::Sequence
< OUString
> lServices
= RecoveryUI::st_getSupportedServiceNames();
73 sal_Int32 c
= lServices
.getLength();
77 const OUString
& sSupportedService
= lServices
[i
];
78 if (sSupportedService
.equals(sServiceName
))
84 //===============================================
85 css::uno::Sequence
< OUString
> SAL_CALL
RecoveryUI::getSupportedServiceNames()
86 throw(css::uno::RuntimeException
)
88 return RecoveryUI::st_getSupportedServiceNames();
91 //===============================================
92 css::uno::Any SAL_CALL
RecoveryUI::dispatchWithReturnValue(const css::util::URL
& aURL
,
93 const css::uno::Sequence
< css::beans::PropertyValue
>& )
94 throw(css::uno::RuntimeException
)
96 // Internaly we use VCL ... every call into vcl based code must
97 // be guarded by locking the global solar mutex.
98 ::SolarMutexGuard aSolarLock
;
101 RecoveryUI::EJob eJob
= impl_classifyJob(aURL
);
102 // TODO think about outside arguments
106 case RecoveryUI::E_DO_EMERGENCY_SAVE
:
108 sal_Bool bRet
= impl_doEmergencySave();
113 case RecoveryUI::E_DO_RECOVERY
:
117 case RecoveryUI::E_DO_CRASHREPORT
:
118 impl_doCrashReport();
128 //===============================================
129 void SAL_CALL
RecoveryUI::dispatch(const css::util::URL
& aURL
,
130 const css::uno::Sequence
< css::beans::PropertyValue
>& lArguments
)
131 throw(css::uno::RuntimeException
)
133 // recycle this method :-)
134 dispatchWithReturnValue(aURL
, lArguments
);
137 //===============================================
138 void SAL_CALL
RecoveryUI::addStatusListener(const css::uno::Reference
< css::frame::XStatusListener
>&, const css::util::URL
& ) throw(css::uno::RuntimeException
)
141 OSL_FAIL("RecoveryUI::addStatusListener()\nNot implemented yet!");
144 //===============================================
145 void SAL_CALL
RecoveryUI::removeStatusListener(const css::uno::Reference
< css::frame::XStatusListener
>&, const css::util::URL
& )
146 throw(css::uno::RuntimeException
)
149 OSL_FAIL("RecoveryUI::removeStatusListener()\nNot implemented yet!");
152 //===============================================
153 OUString
RecoveryUI::st_getImplementationName()
155 return OUString(IMPLEMENTATIONNAME_RECOVERYUI
);
158 //===============================================
159 css::uno::Sequence
< OUString
> RecoveryUI::st_getSupportedServiceNames()
161 css::uno::Sequence
< OUString
> lServiceNames(1); lServiceNames
.getArray() [0] = SERVICENAME_RECOVERYUI
;
162 return lServiceNames
;
165 //===============================================
166 css::uno::Reference
< css::uno::XInterface
> SAL_CALL
RecoveryUI::st_createInstance(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
)
168 RecoveryUI
* pNew
= new RecoveryUI(comphelper::getComponentContext(xSMGR
));
169 return css::uno::Reference
< css::uno::XInterface
>(static_cast< css::lang::XServiceInfo
* >(pNew
));
172 //===============================================
174 static OUString
GetCrashConfigDir()
178 OUString ustrValue
= OUString("${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}");
179 #elif defined(MACOSX)
180 OUString ustrValue
= OUString("~");
182 OUString ustrValue
= OUString("$SYSUSERCONFIG");
184 Bootstrap::expandMacros( ustrValue
);
187 ustrValue
+= "/user/crashdata";
192 //===============================================
195 #define LCKFILE "crashdat.lck"
197 #define LCKFILE ".crash_report_unsent"
201 static OUString
GetUnsentURL()
203 OUString aURL
= GetCrashConfigDir();
206 aURL
+= OUString( LCKFILE
);
211 //===============================================
213 static bool new_crash_pending()
215 OUString aUnsentURL
= GetUnsentURL();
216 File
aFile( aUnsentURL
);
218 if ( FileBase::E_None
== aFile
.open( osl_File_OpenFlag_Read
) )
226 //===============================================
228 static bool delete_pending_crash()
230 OUString aUnsentURL
= GetUnsentURL();
231 return ( FileBase::E_None
== File::remove( aUnsentURL
) );
234 RecoveryUI::EJob
RecoveryUI::impl_classifyJob(const css::util::URL
& aURL
)
236 m_eJob
= RecoveryUI::E_JOB_UNKNOWN
;
237 if (aURL
.Protocol
.equals(RECOVERY_CMDPART_PROTOCOL
))
239 if (aURL
.Path
.equals(RECOVERY_CMDPART_DO_EMERGENCY_SAVE
))
240 m_eJob
= RecoveryUI::E_DO_EMERGENCY_SAVE
;
242 if (aURL
.Path
.equals(RECOVERY_CMDPART_DO_RECOVERY
))
243 m_eJob
= RecoveryUI::E_DO_RECOVERY
;
245 if (aURL
.Path
.equals(RECOVERY_CMDPART_DO_CRASHREPORT
))
246 m_eJob
= RecoveryUI::E_DO_CRASHREPORT
;
252 //===============================================
253 sal_Bool
RecoveryUI::impl_doEmergencySave()
255 // create core service, which implements the real "emergency save" algorithm.
256 svxdr::RecoveryCore
* pCore
= new svxdr::RecoveryCore(m_xContext
, true);
257 css::uno::Reference
< css::frame::XStatusListener
> xCore(pCore
);
259 // create all needed dialogs for this operation
260 // and bind it to the used core service
261 svxdr::TabDialog4Recovery
* pWizard
= new svxdr::TabDialog4Recovery(m_pParentWindow
);
262 svxdr::IExtendedTabPage
* pPage1
= new svxdr::SaveDialog (pWizard
, pCore
);
263 pWizard
->addTabPage(pPage1
);
266 short nRet
= pWizard
->Execute();
271 return (nRet
==DLG_RET_OK_AUTOLUNCH
);
274 //===============================================
275 void RecoveryUI::impl_doRecovery()
277 bool bRecoveryOnly( false );
279 OUString
CFG_PACKAGE_RECOVERY( "org.openoffice.Office.Recovery/");
280 OUString
CFG_PATH_CRASHREPORTER( "CrashReporter" );
281 OUString
CFG_ENTRY_ENABLED( "Enabled" );
283 sal_Bool
bCrashRepEnabled(sal_False
);
284 css::uno::Any aVal
= ::comphelper::ConfigurationHelper::readDirectKey(
286 CFG_PACKAGE_RECOVERY
,
287 CFG_PATH_CRASHREPORTER
,
289 ::comphelper::ConfigurationHelper::E_READONLY
);
290 aVal
>>= bCrashRepEnabled
;
291 bRecoveryOnly
= !bCrashRepEnabled
;
293 // create core service, which implements the real "emergency save" algorithm.
294 svxdr::RecoveryCore
* pCore
= new svxdr::RecoveryCore(m_xContext
, false);
295 css::uno::Reference
< css::frame::XStatusListener
> xCore(pCore
);
297 // create all needed dialogs for this operation
298 // and bind it to the used core service
299 boost::scoped_ptr
<svxdr::TabDialog4Recovery
> xWizard(new svxdr::TabDialog4Recovery(m_pParentWindow
));
300 svxdr::IExtendedTabPage
* pPage1
= new svxdr::RecoveryDialog(xWizard
.get(), pCore
);
301 svxdr::IExtendedTabPage
* pPage2
= 0;
302 svxdr::IExtendedTabPage
* pPage3
= 0;
304 xWizard
->addTabPage(pPage1
);
305 if ( !bRecoveryOnly
&& new_crash_pending() )
307 pPage2
= new svxdr::ErrorRepWelcomeDialog(xWizard
.get());
308 pPage3
= new svxdr::ErrorRepSendDialog(xWizard
.get());
309 xWizard
->addTabPage(pPage2
);
310 xWizard
->addTabPage(pPage3
);
316 impl_showAllRecoveredDocs();
322 delete_pending_crash();
325 //===============================================
327 void RecoveryUI::impl_doCrashReport()
329 if ( new_crash_pending() )
331 svxdr::TabDialog4Recovery
* pWizard
= new svxdr::TabDialog4Recovery (m_pParentWindow
);
332 svxdr::IExtendedTabPage
* pPage1
= new svxdr::ErrorRepWelcomeDialog(pWizard
, sal_False
);
333 svxdr::IExtendedTabPage
* pPage2
= new svxdr::ErrorRepSendDialog (pWizard
);
334 pWizard
->addTabPage(pPage1
);
335 pWizard
->addTabPage(pPage2
);
344 delete_pending_crash();
348 //===============================================
349 void RecoveryUI::impl_showAllRecoveredDocs()
351 css::uno::Reference
< css::frame::XDesktop2
> xDesktop
= css::frame::Desktop::create( m_xContext
);
353 css::uno::Reference
< css::container::XIndexAccess
> xTaskContainer(
354 xDesktop
->getFrames(),
355 css::uno::UNO_QUERY_THROW
);
357 sal_Int32 c
= xTaskContainer
->getCount();
363 css::uno::Reference
< css::frame::XFrame
> xTask
;
364 xTaskContainer
->getByIndex(i
) >>= xTask
;
368 css::uno::Reference
< css::awt::XWindow
> xWindow
= xTask
->getContainerWindow();
372 xWindow
->setVisible(sal_True
);
374 catch(const css::uno::RuntimeException
&)
376 catch(const css::uno::Exception
&)
383 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */