xref: /trunk/main/svx/source/unodraw/recoveryui.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 //===============================================
28 // includes
29 #include "recoveryui.hxx"
30 #include "docrecovery.hxx"
31 #include <com/sun/star/lang/XInitialization.hpp>
32 #include <com/sun/star/frame/XFramesSupplier.hpp>
33 #include <com/sun/star/beans/NamedValue.hpp>
34 #include <osl/file.hxx>
35 #include <rtl/bootstrap.hxx>
36 #include <comphelper/configurationhelper.hxx>
37 
38 #include <vcl/svapp.hxx>
39 
40 //===============================================
41 // const
42 
43 #define IMPLEMENTATIONNAME_RECOVERYUI       ::rtl::OUString::createFromAscii("com.sun.star.comp.svx.RecoveryUI")
44 #define SERVICENAME_RECOVERYUI              ::rtl::OUString::createFromAscii("com.sun.star.dialog.RecoveryUI")
45 
46 //===============================================
47 // namespace
48 
49 namespace svx
50 {
51 
52 namespace css   = ::com::sun::star;
53 namespace svxdr = ::svx::DocRecovery;
54 
55 using namespace ::rtl;
56 using namespace ::osl;
57 
58 //===============================================
RecoveryUI(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)59 RecoveryUI::RecoveryUI(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
60     : m_xSMGR        (xSMGR                    )
61     , m_pParentWindow(0                        )
62     , m_eJob         (RecoveryUI::E_JOB_UNKNOWN)
63 {
64 }
65 
66 //===============================================
~RecoveryUI()67 RecoveryUI::~RecoveryUI()
68 {
69 }
70 
71 //===============================================
getImplementationName()72 ::rtl::OUString SAL_CALL RecoveryUI::getImplementationName()
73 {
74     return RecoveryUI::st_getImplementationName();
75 }
76 
77 //===============================================
supportsService(const::rtl::OUString & sServiceName)78 sal_Bool SAL_CALL RecoveryUI::supportsService(const ::rtl::OUString& sServiceName)
79 {
80     const css::uno::Sequence< ::rtl::OUString > lServices = RecoveryUI::st_getSupportedServiceNames();
81           sal_Int32                             c         = lServices.getLength();
82           sal_Int32                             i         = 0;
83     for (i=0; i<c; ++i)
84     {
85         const ::rtl::OUString& sSupportedService = lServices[i];
86         if (sSupportedService.equals(sServiceName))
87             return sal_True;
88     }
89     return sal_False;
90 }
91 
92 //===============================================
getSupportedServiceNames()93 css::uno::Sequence< ::rtl::OUString > SAL_CALL RecoveryUI::getSupportedServiceNames()
94 {
95     return RecoveryUI::st_getSupportedServiceNames();
96 }
97 
98 //===============================================
dispatchWithReturnValue(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> &)99 css::uno::Any SAL_CALL RecoveryUI::dispatchWithReturnValue(const css::util::URL& aURL,
100                                                    const css::uno::Sequence< css::beans::PropertyValue >& )
101 {
102     // Internally we use VCL ... every call into vcl based code must
103     // be guarded by locking the global solar mutex.
104     ::vos::OGuard aSolarLock(&Application::GetSolarMutex());
105 
106     css::uno::Any aRet;
107     RecoveryUI::EJob eJob = impl_classifyJob(aURL);
108     // TODO think about outside arguments
109 
110     switch(eJob)
111     {
112         case RecoveryUI::E_DO_EMERGENCY_SAVE :
113         {
114             sal_Bool bRet = impl_doEmergencySave();
115             aRet <<= bRet;
116             break;
117         }
118 
119         case RecoveryUI::E_DO_RECOVERY :
120             impl_doRecovery();
121             break;
122 
123         case RecoveryUI::E_DO_CRASHREPORT :
124             impl_doCrashReport();
125             break;
126 
127         default :
128             break;
129     }
130 
131     return aRet;
132 }
133 
134 //===============================================
dispatch(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments)135 void SAL_CALL RecoveryUI::dispatch(const css::util::URL&                                  aURL      ,
136                                    const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
137 {
138     // recycle this method :-)
139     dispatchWithReturnValue(aURL, lArguments);
140 }
141 
142 //===============================================
addStatusListener(const css::uno::Reference<css::frame::XStatusListener> &,const css::util::URL &)143 void SAL_CALL RecoveryUI::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL& )
144 {
145     // TODO
146     OSL_ENSURE(sal_False, "RecoveryUI::addStatusListener()\nNot implemented yet!");
147 }
148 
149 //===============================================
removeStatusListener(const css::uno::Reference<css::frame::XStatusListener> &,const css::util::URL &)150 void SAL_CALL RecoveryUI::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL& )
151 {
152     // TODO
153     OSL_ENSURE(sal_False, "RecoveryUI::removeStatusListener()\nNot implemented yet!");
154 }
155 
156 //===============================================
st_getImplementationName()157 ::rtl::OUString RecoveryUI::st_getImplementationName()
158 {
159     static ::rtl::OUString IMPLEMENTATIONNAME = IMPLEMENTATIONNAME_RECOVERYUI;
160     return IMPLEMENTATIONNAME;
161 }
162 
163 //===============================================
st_getSupportedServiceNames()164 css::uno::Sequence< ::rtl::OUString > RecoveryUI::st_getSupportedServiceNames()
165 {
166     css::uno::Sequence< ::rtl::OUString > lServiceNames(1);    lServiceNames.getArray() [0] = SERVICENAME_RECOVERYUI;
167     return lServiceNames;
168 }
169 
170 //===============================================
st_createInstance(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)171 css::uno::Reference< css::uno::XInterface > SAL_CALL RecoveryUI::st_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
172 {
173     RecoveryUI* pNew = new RecoveryUI(xSMGR);
174     return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XServiceInfo* >(pNew));
175 }
176 
177 //===============================================
178 
GetCrashConfigDir()179 static OUString GetCrashConfigDir()
180 {
181 
182 #if defined(WNT) || defined(OS2)
183     OUString    ustrValue = OUString::createFromAscii("${$OOO_BASE_DIR/program/bootstrap.ini:UserInstallation}");
184 #elif defined(MACOSX)
185     OUString    ustrValue = OUString::createFromAscii("~");
186 #else
187     OUString    ustrValue = OUString::createFromAscii("$SYSUSERCONFIG");
188 #endif
189     Bootstrap::expandMacros( ustrValue );
190 
191 #if defined(WNT) || defined(OS2)
192     ustrValue += OUString::createFromAscii("/user/crashdata");
193 #endif
194     return ustrValue;
195 }
196 
197 //===============================================
198 
199 #if defined(WNT) || defined(OS2)
200 #define LCKFILE "crashdat.lck"
201 #else
202 #define LCKFILE ".crash_report_unsent"
203 #endif
204 
205 
GetUnsentURL()206 static OUString GetUnsentURL()
207 {
208     OUString    aURL = GetCrashConfigDir();
209 
210     aURL += OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
211     aURL += OUString( RTL_CONSTASCII_USTRINGPARAM( LCKFILE ) );
212 
213     return aURL;
214 }
215 
216 //===============================================
217 
new_crash_pending()218 static bool new_crash_pending()
219 {
220     OUString    aUnsentURL = GetUnsentURL();
221     File    aFile( aUnsentURL );
222 
223     if ( FileBase::E_None == aFile.open( OpenFlag_Read ) )
224     {
225         aFile.close();
226         return true;
227     }
228 
229     return false;
230 }
231 //===============================================
232 
delete_pending_crash()233 static bool delete_pending_crash()
234 {
235     OUString    aUnsentURL = GetUnsentURL();
236     return ( FileBase::E_None == File::remove( aUnsentURL ) );
237 }
238 
impl_classifyJob(const css::util::URL & aURL)239 RecoveryUI::EJob RecoveryUI::impl_classifyJob(const css::util::URL& aURL)
240 {
241     m_eJob = RecoveryUI::E_JOB_UNKNOWN;
242     if (aURL.Protocol.equals(RECOVERY_CMDPART_PROTOCOL))
243     {
244         if (aURL.Path.equals(RECOVERY_CMDPART_DO_EMERGENCY_SAVE))
245             m_eJob = RecoveryUI::E_DO_EMERGENCY_SAVE;
246         else
247         if (aURL.Path.equals(RECOVERY_CMDPART_DO_RECOVERY))
248             m_eJob = RecoveryUI::E_DO_RECOVERY;
249         else
250         if (aURL.Path.equals(RECOVERY_CMDPART_DO_CRASHREPORT))
251             m_eJob = RecoveryUI::E_DO_CRASHREPORT;
252     }
253 
254     return m_eJob;
255 }
256 
257 //===============================================
impl_doEmergencySave()258 sal_Bool RecoveryUI::impl_doEmergencySave()
259 {
260     // create core service, which implements the real "emergency save" algorithm.
261     svxdr::RecoveryCore* pCore = new svxdr::RecoveryCore(m_xSMGR, sal_True);
262     css::uno::Reference< css::frame::XStatusListener > xCore(pCore);
263 
264     // create all needed dialogs for this operation
265     // and bind it to the used core service
266     svxdr::TabDialog4Recovery* pWizard = new svxdr::TabDialog4Recovery(m_pParentWindow);
267     svxdr::IExtendedTabPage*   pPage1  = new svxdr::SaveDialog        (pWizard, pCore );
268     pWizard->addTabPage(pPage1);
269 
270     // start the wizard
271     short nRet = pWizard->Execute();
272 
273     delete pPage1 ;
274     delete pWizard;
275 
276     return (nRet==DLG_RET_OK_AUTOLUNCH);
277 }
278 
279 //===============================================
impl_doRecovery()280 void RecoveryUI::impl_doRecovery()
281 {
282     sal_Bool bRecoveryOnly( sal_False );
283 
284     ::rtl::OUString CFG_PACKAGE_RECOVERY( RTL_CONSTASCII_USTRINGPARAM  ( "org.openoffice.Office.Recovery/" ));
285     ::rtl::OUString CFG_PATH_CRASHREPORTER( RTL_CONSTASCII_USTRINGPARAM( "CrashReporter"                 ));
286     ::rtl::OUString CFG_ENTRY_ENABLED( RTL_CONSTASCII_USTRINGPARAM     ( "Enabled"                       ));
287 
288     sal_Bool bCrashRepEnabled( sal_True );
289     css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
290                                 m_xSMGR,
291                                 CFG_PACKAGE_RECOVERY,
292                                 CFG_PATH_CRASHREPORTER,
293                                 CFG_ENTRY_ENABLED,
294                                 ::comphelper::ConfigurationHelper::E_READONLY);
295     aVal >>= bCrashRepEnabled;
296     bRecoveryOnly = !bCrashRepEnabled;
297 
298     // create core service, which implements the real "emergency save" algorithm.
299     svxdr::RecoveryCore* pCore = new svxdr::RecoveryCore(m_xSMGR, sal_False);
300     css::uno::Reference< css::frame::XStatusListener > xCore(pCore);
301 
302     // create all needed dialogs for this operation
303     // and bind it to the used core service
304     svxdr::TabDialog4Recovery* pWizard = new svxdr::TabDialog4Recovery   (m_pParentWindow);
305     svxdr::IExtendedTabPage*   pPage1  = new svxdr::RecoveryDialog       (pWizard, pCore );
306     svxdr::IExtendedTabPage*   pPage2  = 0;
307     svxdr::IExtendedTabPage*   pPage3  = 0;
308 
309     pWizard->addTabPage(pPage1);
310     if ( !bRecoveryOnly && new_crash_pending() )
311     {
312         pPage2 = new svxdr::ErrorRepWelcomeDialog(pWizard        );
313         pPage3 = new svxdr::ErrorRepSendDialog   (pWizard        );
314         pWizard->addTabPage(pPage2);
315         pWizard->addTabPage(pPage3);
316     }
317 
318     // start the wizard
319     pWizard->Execute();
320 
321     impl_showAllRecoveredDocs();
322 
323     delete pPage3 ;
324     delete pPage2 ;
325     delete pPage1 ;
326     delete pWizard;
327 
328     delete_pending_crash();
329 }
330 
331 //===============================================
332 
impl_doCrashReport()333 void RecoveryUI::impl_doCrashReport()
334 {
335     if ( new_crash_pending() )
336     {
337         svxdr::TabDialog4Recovery* pWizard = new svxdr::TabDialog4Recovery   (m_pParentWindow   );
338         svxdr::IExtendedTabPage*   pPage1  = new svxdr::ErrorRepWelcomeDialog(pWizard, sal_False);
339         svxdr::IExtendedTabPage*   pPage2  = new svxdr::ErrorRepSendDialog   (pWizard           );
340         pWizard->addTabPage(pPage1);
341         pWizard->addTabPage(pPage2);
342 
343         // start the wizard
344         pWizard->Execute();
345 
346         delete pPage2 ;
347         delete pPage1 ;
348         delete pWizard;
349 
350         delete_pending_crash();
351     }
352 }
353 
354 //===============================================
impl_showAllRecoveredDocs()355 void RecoveryUI::impl_showAllRecoveredDocs()
356 {
357     css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
358         m_xSMGR->createInstance(SERVICENAME_DESKTOP),
359         css::uno::UNO_QUERY_THROW);
360 
361     css::uno::Reference< css::container::XIndexAccess > xTaskContainer(
362         xDesktop->getFrames(),
363         css::uno::UNO_QUERY_THROW);
364 
365     sal_Int32 c = xTaskContainer->getCount();
366     sal_Int32 i = 0;
367     for (i=0; i<c; ++i)
368     {
369         try
370         {
371             css::uno::Reference< css::frame::XFrame > xTask;
372             xTaskContainer->getByIndex(i) >>= xTask;
373             if (!xTask.is())
374                 continue;
375 
376             css::uno::Reference< css::awt::XWindow > xWindow = xTask->getContainerWindow();
377             if (!xWindow.is())
378                 continue;
379 
380             xWindow->setVisible(sal_True);
381         }
382         catch(const css::uno::RuntimeException& exRun)
383             { throw exRun; }
384         catch(const css::uno::Exception&)
385             { continue; }
386     }
387 }
388 
389 } // namespace svx
390