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 #include <svx/dialmgr.hxx>
27
28 #include <svx/dialogs.hrc>
29 #include "docrecovery.hxx"
30 #include "docrecovery.hrc"
31
32 #include <comphelper/processfactory.hxx>
33 #include <comphelper/sequenceashashmap.hxx>
34 #include <comphelper/configurationhelper.hxx>
35 #include <svtools/imagemgr.hxx>
36 #include <svtools/xtextedt.hxx>
37 #include <tools/urlobj.hxx>
38 #include <vcl/msgbox.hxx>
39 #include <vcl/svapp.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <vcl/scrbar.hxx>
42
43 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
44 #include <toolkit/helper/vclunohelper.hxx>
45 #endif
46
47 //#include "com/sun/star/lang/XMultiServiceFactory.hpp"
48 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
49 #include <com/sun/star/lang/XInitialization.hpp>
50 //#include <com/sun/star/beans/PropertyValue.hpp>
51 #include <com/sun/star/beans/NamedValue.hpp>
52 #include <com/sun/star/util/URL.hpp>
53 #include <com/sun/star/util/XURLTransformer.hpp>
54 #include <com/sun/star/frame/XDispatch.hpp>
55 #include <com/sun/star/awt/XWindow.hpp>
56 #include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
57 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
58 #include <osl/file.hxx>
59 #include <osl/security.hxx>
60 #include <rtl/bootstrap.hxx>
61 #include <unotools/pathoptions.hxx>
62 #include <unotools/localfilehelper.hxx>
63
64 #define RET_BACK 100
65
66 //===============================================
67 // namespace
68 namespace svx{
69 namespace DocRecovery{
70
71 namespace css = ::com::sun::star;
72
73 using namespace ::rtl;
74 using namespace ::osl;
75
76 //===============================================
TabDialog4Recovery(Window * pParent)77 TabDialog4Recovery::TabDialog4Recovery(Window* pParent)
78 : TabDialog (pParent, SVX_RES( RID_SVX_TABDLG_DOCRECOVERY ))
79 , m_pActualPage(m_lTabPages.begin() )
80 {
81 }
82
83 //===============================================
~TabDialog4Recovery()84 TabDialog4Recovery::~TabDialog4Recovery()
85 {
86 m_lTabPages.clear();
87 }
88
89 //===============================================
addTabPage(IExtendedTabPage * pPage)90 void TabDialog4Recovery::addTabPage(IExtendedTabPage* pPage)
91 {
92 if (pPage)
93 m_lTabPages.push_back(pPage);
94 }
95
96 //===============================================
Execute()97 short TabDialog4Recovery::Execute()
98 {
99 ::vos::OGuard aLock(Application::GetSolarMutex());
100
101 Show();
102 m_pActualPage = m_lTabPages.begin();
103 while(sal_True)
104 {
105 IExtendedTabPage* pPage = *m_pActualPage;
106 SetViewWindow(pPage);
107 pPage->Show();
108 pPage->setDefButton();
109 short nRet = pPage->execute();
110 pPage->Hide();
111
112 switch(nRet)
113 {
114 case DLG_RET_OK :
115 {
116 ++m_pActualPage;
117 if (m_pActualPage == m_lTabPages.end())
118 return nRet;
119 }
120 break;
121
122 case DLG_RET_BACK :
123 {
124 if (m_pActualPage != m_lTabPages.begin())
125 --m_pActualPage;
126 }
127 break;
128
129 case DLG_RET_UNKNOWN :
130 case DLG_RET_CANCEL :
131 case DLG_RET_OK_AUTOLUNCH :
132 return nRet;
133 }
134 }
135 }
136
137 //===============================================
RecoveryCore(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,sal_Bool bUsedForSaving)138 RecoveryCore::RecoveryCore(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
139 sal_Bool bUsedForSaving)
140 : m_xSMGR ( xSMGR )
141 , m_pListener ( 0 )
142 , m_bListenForSaving(bUsedForSaving)
143 {
144 impl_startListening();
145 }
146
147 //===============================================
~RecoveryCore()148 RecoveryCore::~RecoveryCore()
149 {
150 impl_stopListening();
151 }
152
153 //===============================================
getSMGR()154 css::uno::Reference< css::lang::XMultiServiceFactory > RecoveryCore::getSMGR()
155 {
156 return m_xSMGR;
157 }
158
159 //===============================================
getURLListAccess()160 TURLList* RecoveryCore::getURLListAccess()
161 {
162 return &m_lURLs;
163 }
164
165 //===============================================
existsBrokenTempEntries()166 sal_Bool RecoveryCore::existsBrokenTempEntries()
167 {
168 TURLList::const_iterator pIt;
169 for ( pIt = m_lURLs.begin();
170 pIt != m_lURLs.end() ;
171 ++pIt )
172 {
173 const TURLInfo& rInfo = *pIt;
174 if (RecoveryCore::isBrokenTempEntry(rInfo))
175 return sal_True;
176 }
177
178 return sal_False;
179 }
180
181 //===============================================
existsNonRecoveredEntries()182 sal_Bool RecoveryCore::existsNonRecoveredEntries()
183 {
184 TURLList::const_iterator pIt;
185 for ( pIt = m_lURLs.begin();
186 pIt != m_lURLs.end() ;
187 ++pIt )
188 {
189 const TURLInfo& rInfo = *pIt;
190 if (rInfo.RecoveryState == E_NOT_RECOVERED_YET)
191 return sal_True;
192 }
193
194 return sal_False;
195 }
196
197 //===============================================
isBrokenTempEntry(const TURLInfo & rInfo)198 sal_Bool RecoveryCore::isBrokenTempEntry(const TURLInfo& rInfo)
199 {
200 if (!rInfo.TempURL.getLength())
201 return sal_False;
202
203 // Note: If the original files was recovery ... but a temp file
204 // exists ... an error inside the temp file exists!
205 if (
206 !(rInfo.RecoveryState == E_RECOVERY_FAILED ) &&
207 !(rInfo.RecoveryState == E_ORIGINAL_DOCUMENT_RECOVERED)
208 )
209 return sal_False;
210
211 return sal_True;
212 }
213
214 //===============================================
saveBrokenTempEntries(const::rtl::OUString & sPath)215 void RecoveryCore::saveBrokenTempEntries(const ::rtl::OUString& sPath)
216 {
217 if (!sPath.getLength())
218 return;
219
220 if (!m_xRealCore.is())
221 return;
222
223 // prepare all needed parameters for the following dispatch() request.
224 css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP);
225 css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3);
226 lCopyArgs[0].Name = PROP_DISPATCHASYNCHRON;
227 lCopyArgs[0].Value <<= sal_False;
228 lCopyArgs[1].Name = PROP_SAVEPATH;
229 lCopyArgs[1].Value <<= sPath;
230 lCopyArgs[2].Name = PROP_ENTRYID;
231 // lCopyArgs[2].Value will be changed during next loop ...
232
233 // work on a copied list only ...
234 // Reason: We will get notifications from the core for every
235 // changed or removed element. And that will change our m_lURLs list.
236 // That's not a good idea, if we use a stl iterator inbetween .-)
237 TURLList lURLs = m_lURLs;
238 TURLList::const_iterator pIt;
239 for ( pIt = lURLs.begin();
240 pIt != lURLs.end() ;
241 ++pIt )
242 {
243 const TURLInfo& rInfo = *pIt;
244 if (!RecoveryCore::isBrokenTempEntry(rInfo))
245 continue;
246
247 lCopyArgs[2].Value <<= rInfo.ID;
248 m_xRealCore->dispatch(aCopyURL, lCopyArgs);
249 }
250 }
251
252 //===============================================
saveAllTempEntries(const::rtl::OUString & sPath)253 void RecoveryCore::saveAllTempEntries(const ::rtl::OUString& sPath)
254 {
255 if (!sPath.getLength())
256 return;
257
258 if (!m_xRealCore.is())
259 return;
260
261 // prepare all needed parameters for the following dispatch() request.
262 css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP);
263 css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3);
264 lCopyArgs[0].Name = PROP_DISPATCHASYNCHRON;
265 lCopyArgs[0].Value <<= sal_False;
266 lCopyArgs[1].Name = PROP_SAVEPATH;
267 lCopyArgs[1].Value <<= sPath;
268 lCopyArgs[2].Name = PROP_ENTRYID;
269 // lCopyArgs[2].Value will be changed during next loop ...
270
271 // work on a copied list only ...
272 // Reason: We will get notifications from the core for every
273 // changed or removed element. And that will change our m_lURLs list.
274 // That's not a good idea, if we use a stl iterator inbetween .-)
275 TURLList lURLs = m_lURLs;
276 TURLList::const_iterator pIt;
277 for ( pIt = lURLs.begin();
278 pIt != lURLs.end() ;
279 ++pIt )
280 {
281 const TURLInfo& rInfo = *pIt;
282 if (!rInfo.TempURL.getLength())
283 continue;
284
285 lCopyArgs[2].Value <<= rInfo.ID;
286 m_xRealCore->dispatch(aCopyURL, lCopyArgs);
287 }
288 }
289
290 //===============================================
forgetBrokenTempEntries()291 void RecoveryCore::forgetBrokenTempEntries()
292 {
293 if (!m_xRealCore.is())
294 return;
295
296 css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
297 css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
298 lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON;
299 lRemoveArgs[0].Value <<= sal_False;
300 lRemoveArgs[1].Name = PROP_ENTRYID;
301 // lRemoveArgs[1].Value will be changed during next loop ...
302
303 // work on a copied list only ...
304 // Reason: We will get notifications from the core for every
305 // changed or removed element. And that will change our m_lURLs list.
306 // That's not a good idea, if we use a stl iterator inbetween .-)
307 TURLList lURLs = m_lURLs;
308 TURLList::const_iterator pIt;
309 for ( pIt = lURLs.begin();
310 pIt != lURLs.end() ;
311 ++pIt )
312 {
313 const TURLInfo& rInfo = *pIt;
314 if (!RecoveryCore::isBrokenTempEntry(rInfo))
315 continue;
316
317 lRemoveArgs[1].Value <<= rInfo.ID;
318 m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
319 }
320 }
321
322 //===============================================
forgetAllRecoveryEntries()323 void RecoveryCore::forgetAllRecoveryEntries()
324 {
325 if (!m_xRealCore.is())
326 return;
327
328 css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
329 css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
330 lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON;
331 lRemoveArgs[0].Value <<= sal_False;
332 lRemoveArgs[1].Name = PROP_ENTRYID;
333 // lRemoveArgs[1].Value will be changed during next loop ...
334
335 // work on a copied list only ...
336 // Reason: We will get notifications from the core for every
337 // changed or removed element. And that will change our m_lURLs list.
338 // That's not a good idea, if we use a stl iterator inbetween .-)
339 TURLList lURLs = m_lURLs;
340 TURLList::const_iterator pIt;
341 for ( pIt = lURLs.begin();
342 pIt != lURLs.end() ;
343 ++pIt )
344 {
345 const TURLInfo& rInfo = *pIt;
346 lRemoveArgs[1].Value <<= rInfo.ID;
347 m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
348 }
349 }
350
351 //===============================================
forgetBrokenRecoveryEntries()352 void RecoveryCore::forgetBrokenRecoveryEntries()
353 {
354 if (!m_xRealCore.is())
355 return;
356
357 css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
358 css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
359 lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON;
360 lRemoveArgs[0].Value <<= sal_False;
361 lRemoveArgs[1].Name = PROP_ENTRYID;
362 // lRemoveArgs[1].Value will be changed during next loop ...
363
364 // work on a copied list only ...
365 // Reason: We will get notifications from the core for every
366 // changed or removed element. And that will change our m_lURLs list.
367 // That's not a good idea, if we use a stl iterator inbetween .-)
368 TURLList lURLs = m_lURLs;
369 TURLList::const_iterator pIt;
370 for ( pIt = lURLs.begin();
371 pIt != lURLs.end() ;
372 ++pIt )
373 {
374 const TURLInfo& rInfo = *pIt;
375 if (!RecoveryCore::isBrokenTempEntry(rInfo))
376 continue;
377
378 lRemoveArgs[1].Value <<= rInfo.ID;
379 m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
380 }
381 }
382
383 //===============================================
setProgressHandler(const css::uno::Reference<css::task::XStatusIndicator> & xProgress)384 void RecoveryCore::setProgressHandler(const css::uno::Reference< css::task::XStatusIndicator >& xProgress)
385 {
386 m_xProgress = xProgress;
387 }
388
389 //===============================================
setUpdateListener(IRecoveryUpdateListener * pListener)390 void RecoveryCore::setUpdateListener(IRecoveryUpdateListener* pListener)
391 {
392 m_pListener = pListener;
393 }
394
395 //===============================================
doEmergencySavePrepare()396 void RecoveryCore::doEmergencySavePrepare()
397 {
398 if (!m_xRealCore.is())
399 return;
400
401 css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_PREPARE_EMERGENCY_SAVE);
402
403 css::uno::Sequence< css::beans::PropertyValue > lArgs(1);
404 lArgs[0].Name = PROP_DISPATCHASYNCHRON;
405 lArgs[0].Value <<= sal_False;
406
407 m_xRealCore->dispatch(aURL, lArgs);
408 }
409
410 //===============================================
doEmergencySave()411 void RecoveryCore::doEmergencySave()
412 {
413 if (!m_xRealCore.is())
414 return;
415
416 css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_EMERGENCY_SAVE);
417
418 css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
419 lArgs[0].Name = PROP_STATUSINDICATOR;
420 lArgs[0].Value <<= m_xProgress;
421 lArgs[1].Name = PROP_DISPATCHASYNCHRON;
422 lArgs[1].Value <<= sal_True;
423
424 m_xRealCore->dispatch(aURL, lArgs);
425 }
426
427 //===============================================
doRecovery()428 void RecoveryCore::doRecovery()
429 {
430 if (!m_xRealCore.is())
431 return;
432
433 css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_RECOVERY);
434
435 css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
436 lArgs[0].Name = PROP_STATUSINDICATOR;
437 lArgs[0].Value <<= m_xProgress;
438 lArgs[1].Name = PROP_DISPATCHASYNCHRON;
439 lArgs[1].Value <<= sal_True;
440
441 m_xRealCore->dispatch(aURL, lArgs);
442 }
443
444 //===============================================
mapDocState2RecoverState(sal_Int32 eDocState)445 ERecoveryState RecoveryCore::mapDocState2RecoverState(sal_Int32 eDocState)
446 {
447 // ???
448 ERecoveryState eRecState = E_NOT_RECOVERED_YET;
449
450 /* Attention:
451 Some of the following states can occur at the
452 same time. So we have to check for the "worst case" first!
453
454 DAMAGED -> INCOMPLETE -> HANDLED
455 */
456
457 // running ...
458 if (
459 ((eDocState & E_TRY_LOAD_BACKUP ) == E_TRY_LOAD_BACKUP ) ||
460 ((eDocState & E_TRY_LOAD_ORIGINAL) == E_TRY_LOAD_ORIGINAL)
461 )
462 eRecState = E_RECOVERY_IS_IN_PROGRESS;
463 // red
464 else
465 if ((eDocState & E_DAMAGED) == E_DAMAGED)
466 eRecState = E_RECOVERY_FAILED;
467 // yellow
468 else
469 if ((eDocState & E_INCOMPLETE) == E_INCOMPLETE)
470 eRecState = E_ORIGINAL_DOCUMENT_RECOVERED;
471 // green
472 else
473 if ((eDocState & E_SUCCEDED) == E_SUCCEDED)
474 eRecState = E_SUCCESSFULLY_RECOVERED;
475
476 return eRecState;
477 }
478
479 //===============================================
statusChanged(const css::frame::FeatureStateEvent & aEvent)480 void SAL_CALL RecoveryCore::statusChanged(const css::frame::FeatureStateEvent& aEvent)
481 {
482 // a) special notification about start/stop async dispatch!
483 // FeatureDescriptor = "start" || "stop"
484 if (aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_START))
485 {
486 if (m_pListener)
487 m_pListener->start();
488 return;
489 }
490
491 if (aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_STOP))
492 {
493 if (m_pListener)
494 m_pListener->end();
495 return;
496 }
497
498 // b) normal notification about changed items
499 // FeatureDescriptor = "Update"
500 // State = Lits of informations [seq< NamedValue >]
501 if (! aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_UPDATE))
502 return;
503
504 ::comphelper::SequenceAsHashMap lInfo(aEvent.State);
505 TURLInfo aNew;
506
507 aNew.ID = lInfo.getUnpackedValueOrDefault(STATEPROP_ID , (sal_Int32)0 );
508 aNew.DocState = lInfo.getUnpackedValueOrDefault(STATEPROP_STATE , (sal_Int32)0 );
509 aNew.OrgURL = lInfo.getUnpackedValueOrDefault(STATEPROP_ORGURL , ::rtl::OUString());
510 aNew.TempURL = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPURL , ::rtl::OUString());
511 aNew.FactoryURL = lInfo.getUnpackedValueOrDefault(STATEPROP_FACTORYURL , ::rtl::OUString());
512 aNew.TemplateURL = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPLATEURL, ::rtl::OUString());
513 aNew.DisplayName = lInfo.getUnpackedValueOrDefault(STATEPROP_TITLE , ::rtl::OUString());
514 aNew.Module = lInfo.getUnpackedValueOrDefault(STATEPROP_MODULE , ::rtl::OUString());
515
516 // search for already existing items and update her nState value ...
517 TURLList::iterator pIt;
518 for ( pIt = m_lURLs.begin();
519 pIt != m_lURLs.end() ;
520 ++pIt )
521 {
522 TURLInfo& aOld = *pIt;
523 if (aOld.ID == aNew.ID)
524 {
525 // change existing
526 aOld.DocState = aNew.DocState;
527 aOld.RecoveryState = RecoveryCore::mapDocState2RecoverState(aOld.DocState);
528 if (m_pListener)
529 {
530 m_pListener->updateItems();
531 m_pListener->stepNext(&aOld);
532 }
533 return;
534 }
535 }
536
537 // append as new one
538 // TODO think about mmatching Module name to a corresponding icon
539 String sURL = aNew.OrgURL;
540 if (!sURL.Len())
541 sURL = aNew.FactoryURL;
542 if (!sURL.Len())
543 sURL = aNew.TempURL;
544 if (!sURL.Len())
545 sURL = aNew.TemplateURL;
546 INetURLObject aURL(sURL);
547 aNew.StandardImage = SvFileInformationManager::GetFileImage(aURL, false, false);
548 aNew.HCImage = SvFileInformationManager::GetFileImage(aURL, false, true );
549
550 /* set the right UI state for this item to NOT_RECOVERED_YET ... because nDocState shows the state of
551 the last emergency save operation before and is interessting for the used recovery core service only ...
552 for now! But if there is a further notification for this item (see lines above!) we must
553 map the doc state to an UI state. */
554 aNew.RecoveryState = E_NOT_RECOVERED_YET;
555
556 // patch DisplayName! Because the document title contain more then the file name ...
557 sal_Int32 i = aNew.DisplayName.indexOf(::rtl::OUString::createFromAscii(" - "));
558 if (i > 0)
559 aNew.DisplayName = aNew.DisplayName.copy(0, i);
560
561 m_lURLs.push_back(aNew);
562
563 if (m_pListener)
564 m_pListener->updateItems();
565 }
566
567 //===============================================
disposing(const css::lang::EventObject &)568 void SAL_CALL RecoveryCore::disposing(const css::lang::EventObject& /*aEvent*/)
569 {
570 m_xRealCore.clear();
571 }
572
573 //===============================================
impl_startListening()574 void RecoveryCore::impl_startListening()
575 {
576 // listening already initialized ?
577 if (m_xRealCore.is())
578 return;
579 m_xRealCore = css::uno::Reference< css::frame::XDispatch >(m_xSMGR->createInstance(SERVICENAME_RECOVERYCORE), css::uno::UNO_QUERY_THROW);
580
581 css::util::URL aURL;
582 if (m_bListenForSaving)
583 aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE;
584 else
585 aURL.Complete = RECOVERY_CMD_DO_RECOVERY;
586 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
587 xParser->parseStrict(aURL);
588
589 /* Note: addStatusListener() call us synchronous back ... so we
590 will get the complete list of currently open documents! */
591 m_xRealCore->addStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL);
592 }
593
594 //===============================================
impl_stopListening()595 void RecoveryCore::impl_stopListening()
596 {
597 // Ignore it, if this instance doesn't listen currently
598 if (!m_xRealCore.is())
599 return;
600
601 css::util::URL aURL;
602 if (m_bListenForSaving)
603 aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE;
604 else
605 aURL.Complete = RECOVERY_CMD_DO_RECOVERY;
606 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
607 xParser->parseStrict(aURL);
608
609 m_xRealCore->removeStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL);
610 m_xRealCore.clear();
611 }
612
613 //===============================================
impl_getParsedURL(const::rtl::OUString & sURL)614 css::util::URL RecoveryCore::impl_getParsedURL(const ::rtl::OUString& sURL)
615 {
616 css::util::URL aURL;
617 aURL.Complete = sURL;
618
619 css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
620 xParser->parseStrict(aURL);
621
622 return aURL;
623 }
624
625 //===============================================
PluginProgressWindow(Window * pParent,const css::uno::Reference<css::lang::XComponent> & xProgress)626 PluginProgressWindow::PluginProgressWindow( Window* pParent ,
627 const css::uno::Reference< css::lang::XComponent >& xProgress)
628 : Window (pParent )
629 , m_xProgress(xProgress)
630 {
631 Show();
632 Size aParentSize = pParent->GetSizePixel();
633 // align the progressbar to its parent
634 SetPosSizePixel( -9, 0, aParentSize.Width() + 15, aParentSize.Height() - 4 );
635 }
636
637 //===============================================
~PluginProgressWindow()638 PluginProgressWindow::~PluginProgressWindow()
639 {
640 if (m_xProgress.is())
641 m_xProgress->dispose();
642 }
643
644 //===============================================
PluginProgress(Window * pParent,const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)645 PluginProgress::PluginProgress( Window* pParent,
646 const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
647 {
648 m_pPlugProgressWindow = new PluginProgressWindow(pParent, static_cast< css::lang::XComponent* >(this));
649 css::uno::Reference< css::awt::XWindow > xProgressWindow = VCLUnoHelper::GetInterface(m_pPlugProgressWindow);
650 m_xProgressFactory = css::uno::Reference< css::task::XStatusIndicatorFactory >(xSMGR->createInstance(SERVICENAME_PROGRESSFACTORY), css::uno::UNO_QUERY_THROW);
651 css::uno::Reference< css::lang::XInitialization > xInit(m_xProgressFactory, css::uno::UNO_QUERY_THROW);
652
653 css::uno::Sequence< css::uno::Any > lArgs(2);
654 css::beans::NamedValue aProp;
655 aProp.Name = PROP_PARENTWINDOW;
656 aProp.Value <<= xProgressWindow;
657 lArgs[0] <<= aProp;
658 aProp.Name = PROP_ALLOWPARENTSHOW;
659 aProp.Value <<= sal_True;
660 lArgs[1] <<= aProp;
661
662 xInit->initialize(lArgs);
663
664 m_xProgress = m_xProgressFactory->createStatusIndicator();
665 }
666
667 //===============================================
~PluginProgress()668 PluginProgress::~PluginProgress()
669 {
670 }
671
672 //===============================================
getPlugWindow()673 Window* PluginProgress::getPlugWindow()
674 {
675 return m_pPlugProgressWindow;
676 }
677
678 //===============================================
dispose()679 void SAL_CALL PluginProgress::dispose()
680 {
681 // m_pPluginProgressWindow was deleted ...
682 // So the internal pointer of this progress
683 // weill be dead!
684 m_xProgress.clear();
685 }
686
687 //===============================================
addEventListener(const css::uno::Reference<css::lang::XEventListener> &)688 void SAL_CALL PluginProgress::addEventListener(const css::uno::Reference< css::lang::XEventListener >& )
689 {
690 }
691
692 //===============================================
removeEventListener(const css::uno::Reference<css::lang::XEventListener> &)693 void SAL_CALL PluginProgress::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& )
694 {
695 }
696
697 //===============================================
start(const::rtl::OUString &,sal_Int32 nRange)698 void SAL_CALL PluginProgress::start(const ::rtl::OUString&,
699 sal_Int32 nRange)
700 {
701 if (m_xProgress.is())
702 m_xProgress->start(::rtl::OUString(), nRange);
703 }
704
705 //===============================================
end()706 void SAL_CALL PluginProgress::end()
707 {
708 if (m_xProgress.is())
709 m_xProgress->end();
710 }
711
712 //===============================================
setText(const::rtl::OUString & sText)713 void SAL_CALL PluginProgress::setText(const ::rtl::OUString& sText)
714 {
715 if (m_xProgress.is())
716 m_xProgress->setText(sText);
717 }
718
719 //===============================================
setValue(sal_Int32 nValue)720 void SAL_CALL PluginProgress::setValue(sal_Int32 nValue)
721 {
722 if (m_xProgress.is())
723 m_xProgress->setValue(nValue);
724 }
725
726 //===============================================
reset()727 void SAL_CALL PluginProgress::reset()
728 {
729 if (m_xProgress.is())
730 m_xProgress->reset();
731 }
732
733 //===============================================
SaveDialog(Window * pParent,RecoveryCore * pCore)734 SaveDialog::SaveDialog(Window* pParent,
735 RecoveryCore* pCore )
736 : IExtendedTabPage( pParent, SVX_RES( RID_SVXPAGE_DOCRECOVERY_SAVE ) )
737 , m_aTitleWin ( this , SVX_RES ( WIN_SAVE_TITLE ) )
738 , m_aTitleFT ( this , SVX_RES ( FT_SAVE_TITLE ) )
739 , m_aTitleFL ( this , SVX_RES ( FL_SAVE_TITLE ) )
740 , m_aDescrFT ( this , SVX_RES ( FT_SAVE_DESCR ) )
741 , m_aFileListFT ( this , SVX_RES ( FT_SAVE_FILELIST ) )
742 , m_aFileListLB ( this , SVX_RES ( LB_SAVE_FILELIST ) )
743 , m_aBottomFL ( this , SVX_RES ( FL_SAVE_BOTTOM ) )
744 , m_aOkBtn ( this , SVX_RES ( BT_SAVE_OK ) )
745 , m_pCore ( pCore )
746 {
747 FreeResource();
748
749 // Prepare the office for the following crash save step.
750 // E.g. hide all open widows so the user can't influence our
751 // operation .-)
752 m_pCore->doEmergencySavePrepare();
753
754 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
755 Wallpaper aBackground(rStyleSettings.GetWindowColor());
756 m_aTitleWin.SetBackground(aBackground);
757 m_aTitleFT.SetBackground (aBackground);
758
759 Font aFont(m_aTitleFT.GetFont());
760 aFont.SetWeight(WEIGHT_BOLD);
761 m_aTitleFT.SetFont(aFont);
762
763 m_aOkBtn.SetClickHdl( LINK( this, SaveDialog, OKButtonHdl ) );
764 // m_aFileListLB.EnableInput( sal_False );
765 m_aFileListLB.SetControlBackground( rStyleSettings.GetDialogColor() );
766
767 // fill listbox with current open documents
768 m_aFileListLB.Clear();
769
770 TURLList* pURLs = m_pCore->getURLListAccess();
771 TURLList::const_iterator pIt;
772
773 for ( pIt = pURLs->begin();
774 pIt != pURLs->end() ;
775 ++pIt )
776 {
777 const TURLInfo& rInfo = *pIt;
778 m_aFileListLB.InsertEntry( rInfo.DisplayName, rInfo.StandardImage );
779 }
780 }
781
782 //===============================================
~SaveDialog()783 SaveDialog::~SaveDialog()
784 {
785 }
786
787 //===============================================
IMPL_LINK(SaveDialog,OKButtonHdl,void *,EMPTYARG)788 IMPL_LINK( SaveDialog, OKButtonHdl, void*, EMPTYARG )
789 {
790 m_nResult = DLG_RET_OK;
791 return 0;
792 }
793
794 //===============================================
execute()795 short SaveDialog::execute()
796 {
797 ::vos::OGuard aLock(Application::GetSolarMutex());
798
799 // wait for user input "OK"
800 m_nResult = DLG_RET_UNKNOWN;
801 while(m_nResult == DLG_RET_UNKNOWN)
802 Application::Yield();
803
804 // start crash-save with progress
805 if (m_nResult == DLG_RET_OK)
806 {
807 SaveProgressDialog* pProgress = new SaveProgressDialog(this, m_pCore);
808 m_nResult = pProgress->Execute();
809 delete pProgress;
810 }
811 // if "CANCEL" => return "CANCEL"
812 // if "OK" => "AUTOLUNCH" always !
813 if (m_nResult == DLG_RET_OK)
814 m_nResult = DLG_RET_OK_AUTOLUNCH;
815
816 return m_nResult;
817 }
818
819 //===============================================
setDefButton()820 void SaveDialog::setDefButton()
821 {
822 m_aOkBtn.GrabFocus();
823 }
824
825 //===============================================
SaveProgressDialog(Window * pParent,RecoveryCore * pCore)826 SaveProgressDialog::SaveProgressDialog(Window* pParent,
827 RecoveryCore* pCore )
828 : ModalDialog ( pParent , SVX_RES( RID_SVX_MDLG_DOCRECOVERY_PROGR ) )
829 , m_aHintFT ( this , SVX_RES ( FT_SAVEPROGR_HINT ) )
830 , m_aProgrFT ( this , SVX_RES ( FT_SAVEPROGR_PROGR ) )
831 , m_aProgrParent( this , SVX_RES ( WIN_SAVEPROGR_PROGR ) )
832 , m_pCore ( pCore )
833 {
834 FreeResource();
835 PluginProgress* pProgress = new PluginProgress( &m_aProgrParent, pCore->getSMGR() );
836 m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW);
837 // m_aProgrBaseTxt = m_aProgrFT.GetText();
838 }
839
840 //===============================================
~SaveProgressDialog()841 SaveProgressDialog::~SaveProgressDialog()
842 {
843 }
844
845 //===============================================
Execute()846 short SaveProgressDialog::Execute()
847 {
848 ::vos::OGuard aLock(Application::GetSolarMutex());
849
850 m_pCore->setProgressHandler(m_xProgress);
851 m_pCore->setUpdateListener(this);
852 m_pCore->doEmergencySave();
853 short nRet = ModalDialog::Execute();
854 m_pCore->setUpdateListener(0);
855 return nRet;
856 }
857
858 //===============================================
updateItems()859 void SaveProgressDialog::updateItems()
860 {
861 }
862
863 //===============================================
stepNext(TURLInfo *)864 void SaveProgressDialog::stepNext(TURLInfo* )
865 {
866 /* TODO
867
868 wenn die m_pCore noch ein Member m_nCurrentItem haette
869 koennte man dort erkennen, wer gerade drann war, wer demnaechst
870 dran ist ... Diese Info kann man dann in unserem Progress FixText anzeigen ...
871 */
872 }
873
874 //===============================================
start()875 void SaveProgressDialog::start()
876 {
877 }
878
879 //===============================================
end()880 void SaveProgressDialog::end()
881 {
882 EndDialog(DLG_RET_OK);
883 }
884
885 //===============================================
RecovDocListEntry(SvLBoxEntry * pEntry,sal_uInt16 nFlags,const String & sText)886 RecovDocListEntry::RecovDocListEntry( SvLBoxEntry* pEntry,
887 sal_uInt16 nFlags,
888 const String& sText )
889 : SvLBoxString( pEntry, nFlags, sText )
890 {
891 }
892
893 //===============================================
Paint(const Point & aPos,SvLBox & aDevice,sal_uInt16,SvLBoxEntry * pEntry)894 void RecovDocListEntry::Paint(const Point& aPos ,
895 SvLBox& aDevice,
896 sal_uInt16 /*nFlags */,
897 SvLBoxEntry* pEntry )
898 {
899 const Image* pImg = 0;
900 const String* pTxt = 0;
901 RecovDocList* pList = static_cast< RecovDocList* >(&aDevice);
902
903 sal_Bool bHC = aDevice.GetSettings().GetStyleSettings().GetHighContrastMode();
904
905 TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData();
906 switch(pInfo->RecoveryState)
907 {
908 case E_SUCCESSFULLY_RECOVERED :
909 {
910 pImg = &pList->m_aGreenCheckImg;
911 if (bHC)
912 pImg = &pList->m_aGreenCheckImgHC;
913 pTxt = &pList->m_aSuccessRecovStr;
914 }
915 break;
916
917 case E_ORIGINAL_DOCUMENT_RECOVERED : // TODO must be renamed into ORIGINAL DOCUMENT recovered! Because its marked as yellow
918 {
919 pImg = &pList->m_aYellowCheckImg;
920 if (bHC)
921 pImg = &pList->m_aYellowCheckImgHC;
922 pTxt = &pList->m_aOrigDocRecovStr;
923 }
924 break;
925
926 case E_RECOVERY_FAILED :
927 {
928 pImg = &pList->m_aRedCrossImg;
929 if (bHC)
930 pImg = &pList->m_aRedCrossImgHC;
931 pTxt = &pList->m_aRecovFailedStr;
932 }
933 break;
934
935 case E_RECOVERY_IS_IN_PROGRESS :
936 {
937 pImg = 0;
938 pTxt = &pList->m_aRecovInProgrStr;
939 }
940 break;
941
942 case E_NOT_RECOVERED_YET :
943 {
944 pImg = 0;
945 pTxt = &pList->m_aNotRecovYetStr;
946 }
947 break;
948 }
949
950 if (pImg)
951 aDevice.DrawImage(aPos, *pImg);
952
953 if (pTxt)
954 {
955 ::rtl::OUString sT1(*pTxt);
956
957 Point aPnt(aPos);
958 aPnt.X() += pList->m_aGreenCheckImg.GetSizePixel().Width();
959 aPnt.X() += 10;
960 aDevice.DrawText(aPnt, *pTxt);
961 }
962 }
963 //===============================================
RecovDocList(Window * pParent,const ResId & rResId)964 RecovDocList::RecovDocList( Window* pParent,
965 const ResId& rResId )
966 : SvxSimpleTable ( pParent, rResId )
967 , m_aGreenCheckImg ( ResId(IMG_GREENCHECK,*rResId.GetResMgr() ) )
968 , m_aYellowCheckImg ( ResId(IMG_YELLOWCHECK,*rResId.GetResMgr() ) )
969 , m_aRedCrossImg ( ResId(IMG_REDCROSS,*rResId.GetResMgr() ) )
970 , m_aGreenCheckImgHC ( ResId(IMG_GREENCHECK_HC,*rResId.GetResMgr() ) )
971 , m_aYellowCheckImgHC ( ResId(IMG_YELLOWCHECK_HC,*rResId.GetResMgr() ) )
972 , m_aRedCrossImgHC ( ResId(IMG_REDCROSS_HC,*rResId.GetResMgr() ) )
973 , m_aSuccessRecovStr ( ResId(STR_SUCCESSRECOV,*rResId.GetResMgr() ) )
974 , m_aOrigDocRecovStr ( ResId(STR_ORIGDOCRECOV,*rResId.GetResMgr() ) )
975 , m_aRecovFailedStr ( ResId(STR_RECOVFAILED,*rResId.GetResMgr() ) )
976 , m_aRecovInProgrStr ( ResId(STR_RECOVINPROGR,*rResId.GetResMgr() ) )
977 , m_aNotRecovYetStr ( ResId(STR_NOTRECOVYET,*rResId.GetResMgr() ) )
978 {
979 //SetEntryHeight( short( maGreenCheckImg.GetSizePixel().Height() ) );
980 }
981
982 //===============================================
~RecovDocList()983 RecovDocList::~RecovDocList()
984 {
985 }
986
987 //===============================================
InitEntry(SvLBoxEntry * pEntry,const XubString & sText,const Image & aImage1,const Image & aImage2,SvLBoxButtonKind eButtonKind)988 void RecovDocList::InitEntry( SvLBoxEntry* pEntry ,
989 const XubString& sText ,
990 const Image& aImage1,
991 const Image& aImage2,
992 SvLBoxButtonKind eButtonKind)
993 {
994 SvTabListBox::InitEntry(pEntry, sText, aImage1, aImage2, eButtonKind);
995 DBG_ASSERT( TabCount() == 2, "*RecovDocList::InitEntry(): structure missmatch" );
996
997 SvLBoxString* pCol = (SvLBoxString*)pEntry->GetItem(2);
998 RecovDocListEntry* p = new RecovDocListEntry(pEntry, 0, pCol->GetText());
999 pEntry->ReplaceItem(p, 2);
1000 }
1001
1002 //===============================================
impl_askUserForWizardCancel(Window * pParent,sal_Int16 nRes)1003 short impl_askUserForWizardCancel(Window* pParent, sal_Int16 nRes)
1004 {
1005 QueryBox aQuery(pParent, SVX_RES(nRes));
1006 if (aQuery.Execute() == RET_YES)
1007 return DLG_RET_OK;
1008 else
1009 return DLG_RET_CANCEL;
1010 }
1011
1012 //===============================================
RecoveryDialog(Window * pParent,RecoveryCore * pCore)1013 RecoveryDialog::RecoveryDialog(Window* pParent,
1014 RecoveryCore* pCore )
1015 : IExtendedTabPage( pParent , SVX_RES( RID_SVXPAGE_DOCRECOVERY_RECOVER ) )
1016 , m_aTitleWin ( this , SVX_RES ( WIN_RECOV_TITLE ) )
1017 , m_aTitleFT ( this , SVX_RES ( FT_RECOV_TITLE ) )
1018 , m_aTitleFL ( this , SVX_RES ( FL_RECOV_TITLE ) )
1019 , m_aDescrFT ( this , SVX_RES ( FT_RECOV_DESCR ) )
1020 , m_aProgressFT ( this , SVX_RES ( FT_RECOV_PROGR ) )
1021 , m_aProgrParent ( this , SVX_RES ( WIN_RECOV_PROGR ) )
1022 , m_aFileListFT ( this , SVX_RES ( FT_RECOV_FILELIST ) )
1023 , m_aFileListLB ( this , SVX_RES ( LB_RECOV_FILELIST ) )
1024 , m_aBottomFL ( this , SVX_RES ( FL_RECOV_BOTTOM ) )
1025 , m_aNextBtn ( this , SVX_RES ( BTN_RECOV_NEXT ) )
1026 , m_aCancelBtn ( this , SVX_RES ( BTN_RECOV_CANCEL ) )
1027 , m_aNextStr ( SVX_RES ( STR_RECOVERY_NEXT ) )
1028 , m_aTitleRecoveryInProgress( SVX_RES ( STR_RECOVERY_INPROGRESS ) )
1029 , m_aTitleRecoveryReport( SVX_RES ( STR_RECOVERY_REPORT ) )
1030 , m_aRecoveryOnlyFinish ( SVX_RES ( STR_RECOVERYONLY_FINISH ) )
1031 , m_aRecoveryOnlyFinishDescr( SVX_RES ( STR_RECOVERYONLY_FINISH_DESCR ) )
1032 , m_pDefButton ( NULL )
1033 , m_pCore ( pCore )
1034 , m_eRecoveryState (RecoveryDialog::E_RECOVERY_PREPARED)
1035 , m_bWaitForUser (sal_False)
1036 , m_bWaitForCore (sal_False)
1037 , m_bUserDecideNext (sal_False)
1038 , m_bWasRecoveryStarted (sal_False)
1039 , m_bRecoveryOnly (sal_False)
1040 {
1041 static long nTabs[] = { 2, 0, 40*RECOV_CONTROLWIDTH/100 };
1042 m_aFileListLB.SetTabs( &nTabs[0] );
1043 m_aFileListLB.InsertHeaderEntry( String( SVX_RES( STR_HEADERBAR ) ) );
1044
1045 FreeResource();
1046
1047 ::rtl::OUString CFG_PACKAGE_RECOVERY( RTL_CONSTASCII_USTRINGPARAM ( "org.openoffice.Office.Recovery/" ));
1048 ::rtl::OUString CFG_PATH_CRASHREPORTER( RTL_CONSTASCII_USTRINGPARAM( "CrashReporter" ));
1049 ::rtl::OUString CFG_ENTRY_ENABLED( RTL_CONSTASCII_USTRINGPARAM ( "Enabled" ));
1050
1051 sal_Bool bCrashRepEnabled( sal_True );
1052 css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1053 pCore->getSMGR(),
1054 CFG_PACKAGE_RECOVERY,
1055 CFG_PATH_CRASHREPORTER,
1056 CFG_ENTRY_ENABLED,
1057 ::comphelper::ConfigurationHelper::E_READONLY);
1058 aVal >>= bCrashRepEnabled;
1059 m_bRecoveryOnly = !bCrashRepEnabled;
1060
1061 PluginProgress* pProgress = new PluginProgress( &m_aProgrParent, pCore->getSMGR() );
1062 m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW);
1063
1064 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1065 Wallpaper aBackground( rStyleSettings.GetWindowColor() );
1066 m_aTitleWin.SetBackground(aBackground);
1067 m_aTitleFT.SetBackground (aBackground);
1068
1069 Font aFont(m_aTitleFT.GetFont());
1070 aFont.SetWeight(WEIGHT_BOLD);
1071 m_aTitleFT.SetFont(aFont);
1072
1073 m_aFileListLB.SetBackground( rStyleSettings.GetDialogColor() );
1074
1075 m_aNextBtn.Enable(sal_True);
1076 m_aNextBtn.SetClickHdl( LINK( this, RecoveryDialog, NextButtonHdl ) );
1077 m_aCancelBtn.SetClickHdl( LINK( this, RecoveryDialog, CancelButtonHdl ) );
1078
1079 // fill list box first time
1080 TURLList* pURLList = m_pCore->getURLListAccess();
1081 TURLList::const_iterator pIt;
1082 for ( pIt = pURLList->begin();
1083 pIt != pURLList->end() ;
1084 ++pIt )
1085 {
1086 const TURLInfo& rInfo = *pIt;
1087
1088 String sName( rInfo.DisplayName );
1089 sName += '\t';
1090 sName += impl_getStatusString( rInfo );
1091 SvLBoxEntry* pEntry = m_aFileListLB.InsertEntry(sName, rInfo.StandardImage, rInfo.StandardImage);
1092 pEntry->SetUserData((void*)&rInfo);
1093 m_aFileListLB.SetExpandedEntryBmp (pEntry, rInfo.HCImage, BMP_COLOR_HIGHCONTRAST);
1094 m_aFileListLB.SetCollapsedEntryBmp(pEntry, rInfo.HCImage, BMP_COLOR_HIGHCONTRAST);
1095 }
1096
1097 // mark first item
1098 SvLBoxEntry* pFirst = m_aFileListLB.First();
1099 if (pFirst)
1100 m_aFileListLB.SetCursor(pFirst, sal_True);
1101 }
1102
1103 //===============================================
~RecoveryDialog()1104 RecoveryDialog::~RecoveryDialog()
1105 {
1106 }
1107
1108 //===============================================
execute()1109 short RecoveryDialog::execute()
1110 {
1111 ::vos::OGuard aSolarLock(Application::GetSolarMutex());
1112
1113 switch(m_eRecoveryState)
1114 {
1115 case RecoveryDialog::E_RECOVERY_PREPARED :
1116 {
1117 // Dialog was started first time ...
1118 // wait for user decision ("start" or "cancel" recovery)
1119 // This decision will be made inside the NextBtn handler.
1120 m_aNextBtn.Enable(sal_True);
1121 m_aCancelBtn.Enable(sal_True);
1122 m_bWaitForUser = sal_True;
1123 while(m_bWaitForUser)
1124 Application::Yield();
1125 if (m_bUserDecideNext)
1126 m_eRecoveryState = RecoveryDialog::E_RECOVERY_IN_PROGRESS;
1127 else
1128 m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED;
1129 return execute();
1130 }
1131
1132 case RecoveryDialog::E_RECOVERY_IN_PROGRESS :
1133 {
1134 // user decided to start recovery ...
1135 m_bWasRecoveryStarted = sal_True;
1136 // do it asynchronous (to allow repaints)
1137 // and wait for this asynchronous operation.
1138 m_aDescrFT.SetText( m_aTitleRecoveryInProgress );
1139 m_aNextBtn.Enable(sal_False);
1140 m_aCancelBtn.Enable(sal_False);
1141 m_pCore->setProgressHandler(m_xProgress);
1142 m_pCore->setUpdateListener(this);
1143 m_pCore->doRecovery();
1144
1145 m_bWaitForCore = sal_True;
1146 while(m_bWaitForCore)
1147 Application::Yield();
1148
1149 m_pCore->setUpdateListener(0);
1150 m_eRecoveryState = RecoveryDialog::E_RECOVERY_CORE_DONE;
1151 return execute();
1152 }
1153
1154 case RecoveryDialog::E_RECOVERY_CORE_DONE :
1155 {
1156 // the core finished it's task.
1157 // let the user decide the next step.
1158 if ( m_bRecoveryOnly )
1159 {
1160 m_aDescrFT.SetText(m_aRecoveryOnlyFinishDescr);
1161 m_aNextBtn.SetText(m_aRecoveryOnlyFinish);
1162 m_aNextBtn.Enable(sal_True);
1163 m_aCancelBtn.Enable(sal_False);
1164 }
1165 else
1166 {
1167 m_aDescrFT.SetText(m_aTitleRecoveryReport);
1168 m_aNextBtn.SetText(m_aNextStr);
1169 m_aNextBtn.Enable(sal_True);
1170 m_aCancelBtn.Enable(sal_True);
1171 }
1172
1173 m_bWaitForUser = sal_True;
1174 while(m_bWaitForUser)
1175 Application::Yield();
1176
1177 if (m_bUserDecideNext)
1178 m_eRecoveryState = RecoveryDialog::E_RECOVERY_DONE;
1179 else
1180 m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED;
1181 return execute();
1182 }
1183
1184 case RecoveryDialog::E_RECOVERY_DONE :
1185 {
1186 // All documents was reovered.
1187 // User decided to step to the "next" wizard page.
1188 // Do it ... but check first, if there exist some
1189 // failed recovery documents. They must be saved to
1190 // a user selected directrory.
1191 short nRet = DLG_RET_UNKNOWN;
1192 BrokenRecoveryDialog* pBrokenRecoveryDialog = new BrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted);
1193 String sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); // get the default dir
1194 if (pBrokenRecoveryDialog->isExecutionNeeded())
1195 {
1196 nRet = pBrokenRecoveryDialog->Execute();
1197 sSaveDir = pBrokenRecoveryDialog->getSaveDirURL();
1198 }
1199 delete pBrokenRecoveryDialog;
1200
1201 switch(nRet)
1202 {
1203 // no broken temp files exists
1204 // step to the next wizard page
1205 case DLG_RET_UNKNOWN :
1206 {
1207 m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
1208 return DLG_RET_OK;
1209 }
1210
1211 // user decided to save the broken temp files
1212 // do and forget it
1213 // step to the next wizard page
1214 case DLG_RET_OK :
1215 {
1216 m_pCore->saveBrokenTempEntries(sSaveDir);
1217 m_pCore->forgetBrokenTempEntries();
1218 m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
1219 return DLG_RET_OK;
1220 }
1221
1222 // user decided to ignore broken temp files.
1223 // Ask it again ... may be this decision was wrong.
1224 // Results:
1225 // IGNORE => remove broken temp files
1226 // => step to the next wizard page
1227 // CANCEL => step back to the recovery page
1228 case DLG_RET_CANCEL :
1229 {
1230 // TODO ask user ...
1231 m_pCore->forgetBrokenTempEntries();
1232 m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
1233 return DLG_RET_OK;
1234 }
1235 }
1236
1237 m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
1238 return DLG_RET_OK;
1239 }
1240
1241 case RecoveryDialog::E_RECOVERY_CANCELED :
1242 {
1243 // "YES" => break recovery
1244 // But there exist different states, where "cancel" can be called.
1245 // Handle it different.
1246 if (m_bWasRecoveryStarted)
1247 m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS;
1248 else
1249 m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_BEFORE;
1250 return execute();
1251 }
1252
1253 case RecoveryDialog::E_RECOVERY_CANCELED_BEFORE :
1254 case RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS :
1255 {
1256 // We have to check if there exists some temp. files.
1257 // They should be saved to a user defined location.
1258 // If no temp files exists or user decided to ignore it ...
1259 // we have to remove all recovery/session data anyway!
1260 short nRet = DLG_RET_UNKNOWN;
1261 BrokenRecoveryDialog* pBrokenRecoveryDialog = new BrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted);
1262 String sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); // get the default save location
1263
1264 // dialog itself checks if there is a need to copy files for this mode.
1265 // It uses the information m_bWasRecoveryStarted doing so.
1266 if (pBrokenRecoveryDialog->isExecutionNeeded())
1267 {
1268 nRet = pBrokenRecoveryDialog->Execute();
1269 sSaveDir = pBrokenRecoveryDialog->getSaveDirURL();
1270 }
1271 delete pBrokenRecoveryDialog;
1272
1273 // Possible states:
1274 // a) nRet == DLG_RET_UNKNOWN
1275 // dialog was not shown ...
1276 // because there exists no temp file for copy.
1277 // => remove all recovery data
1278 // b) nRet == DLG_RET_OK
1279 // dialog was shown ...
1280 // user decided to save temp files
1281 // => save all OR broken temp files (depends from the time, where cancel was called)
1282 // => remove all recovery data
1283 // c) nRet == DLG_RET_CANCEL
1284 // dialog was shown ...
1285 // user decided to ignore temp files
1286 // => remove all recovery data
1287 // => a)/c) are the same ... b) has one additional operation
1288
1289 // b)
1290 if (nRet == DLG_RET_OK)
1291 {
1292 if (m_bWasRecoveryStarted)
1293 m_pCore->saveBrokenTempEntries(sSaveDir);
1294 else
1295 m_pCore->saveAllTempEntries(sSaveDir);
1296 }
1297
1298 // a,b,c)
1299 if (m_bWasRecoveryStarted)
1300 m_pCore->forgetBrokenRecoveryEntries();
1301 else
1302 m_pCore->forgetAllRecoveryEntries();
1303 m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
1304
1305 // THERE IS NO WAY BACK. see impl_askUserForWizardCancel()!
1306 return DLG_RET_CANCEL;
1307 }
1308
1309 case RecoveryDialog::E_RECOVERY_HANDLED :
1310 {
1311 m_bWaitForUser = sal_True;
1312 while(m_bWaitForUser)
1313 Application::Yield();
1314
1315 // TODO: show BrokenRecoveryDialog again, ift he user
1316 // doesn't accepted it last time.
1317
1318 if (m_bUserDecideNext)
1319 return DLG_RET_OK;
1320 else
1321 return DLG_RET_CANCEL;
1322 }
1323 }
1324
1325 // should never be reached .-)
1326 DBG_ERROR("Should never be reached!");
1327 return DLG_RET_OK;
1328 }
1329
1330 //===============================================
setDefButton()1331 void RecoveryDialog::setDefButton()
1332 {
1333 if ( m_aNextBtn.IsEnabled() )
1334 m_aNextBtn.GrabFocus();
1335 else
1336 m_pDefButton = &m_aNextBtn;
1337 }
1338
1339 //===============================================
start()1340 void RecoveryDialog::start()
1341 {
1342 }
1343
1344 //===============================================
updateItems()1345 void RecoveryDialog::updateItems()
1346 {
1347 sal_uIntPtr c = m_aFileListLB.GetEntryCount();
1348 sal_uIntPtr i = 0;
1349 for ( i=0; i<c; ++i )
1350 {
1351 SvLBoxEntry* pEntry = m_aFileListLB.GetEntry(i);
1352 if ( !pEntry )
1353 continue;
1354
1355 TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData();
1356 if ( !pInfo )
1357 continue;
1358
1359 String sStatus = impl_getStatusString( *pInfo );
1360 if ( sStatus.Len() > 0 )
1361 m_aFileListLB.SetEntryText( sStatus, pEntry, 1 );
1362 }
1363
1364 m_aFileListLB.Invalidate();
1365 m_aFileListLB.Update();
1366 }
1367
1368 //===============================================
stepNext(TURLInfo * pItem)1369 void RecoveryDialog::stepNext(TURLInfo* pItem)
1370 {
1371 sal_uIntPtr c = m_aFileListLB.GetEntryCount();
1372 sal_uIntPtr i = 0;
1373 for (i=0; i<c; ++i)
1374 {
1375 SvLBoxEntry* pEntry = m_aFileListLB.GetEntry(i);
1376 if (!pEntry)
1377 continue;
1378
1379 TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData();
1380 if (pInfo->ID != pItem->ID)
1381 continue;
1382
1383 m_aFileListLB.SetCursor(pEntry, sal_True);
1384 m_aFileListLB.MakeVisible(pEntry);
1385 m_aFileListLB.Invalidate();
1386 m_aFileListLB.Update();
1387 break;
1388 }
1389 }
1390
1391 //===============================================
end()1392 void RecoveryDialog::end()
1393 {
1394 if ( m_pDefButton )
1395 {
1396 m_pDefButton->GrabFocus();
1397 m_pDefButton = NULL;
1398 }
1399 m_bWaitForCore = sal_False;
1400 }
1401
1402 //===============================================
IMPL_LINK(RecoveryDialog,NextButtonHdl,void *,EMPTYARG)1403 IMPL_LINK( RecoveryDialog, NextButtonHdl, void*, EMPTYARG )
1404 {
1405 m_bUserDecideNext = sal_True;
1406 m_bWaitForUser = sal_False;
1407 return 0;
1408 }
1409
1410 //===============================================
IMPL_LINK(RecoveryDialog,CancelButtonHdl,void *,EMPTYARG)1411 IMPL_LINK( RecoveryDialog, CancelButtonHdl, void*, EMPTYARG )
1412 {
1413 if (m_eRecoveryState == RecoveryDialog::E_RECOVERY_PREPARED)
1414 {
1415 if (impl_askUserForWizardCancel(this, RID_SVXQB_EXIT_RECOVERY) == DLG_RET_CANCEL)
1416 return 0;
1417 }
1418 m_bUserDecideNext = sal_False;
1419 m_bWaitForUser = sal_False;
1420 return 0;
1421 }
1422
1423 //===============================================
impl_refreshDocList()1424 void RecoveryDialog::impl_refreshDocList()
1425 {
1426 }
1427
1428 //===============================================
impl_getStatusString(const TURLInfo & rInfo) const1429 String RecoveryDialog::impl_getStatusString( const TURLInfo& rInfo ) const
1430 {
1431 String sStatus;
1432 switch ( rInfo.RecoveryState )
1433 {
1434 case E_SUCCESSFULLY_RECOVERED :
1435 sStatus = m_aFileListLB.m_aSuccessRecovStr;
1436 break;
1437 case E_ORIGINAL_DOCUMENT_RECOVERED :
1438 sStatus = m_aFileListLB.m_aOrigDocRecovStr;
1439 break;
1440 case E_RECOVERY_FAILED :
1441 sStatus = m_aFileListLB.m_aRecovFailedStr;
1442 break;
1443 case E_RECOVERY_IS_IN_PROGRESS :
1444 sStatus = m_aFileListLB.m_aRecovInProgrStr;
1445 break;
1446 case E_NOT_RECOVERED_YET :
1447 sStatus = m_aFileListLB.m_aNotRecovYetStr;
1448 break;
1449 default:
1450 break;
1451 }
1452 return sStatus;
1453 }
1454
1455 //===============================================
BrokenRecoveryDialog(Window * pParent,RecoveryCore * pCore,sal_Bool bBeforeRecovery)1456 BrokenRecoveryDialog::BrokenRecoveryDialog(Window* pParent ,
1457 RecoveryCore* pCore ,
1458 sal_Bool bBeforeRecovery)
1459 : ModalDialog ( pParent, SVX_RES( RID_SVX_MDLG_DOCRECOVERY_BROKEN ) )
1460 , m_aDescrFT ( this , SVX_RES( FT_BROKEN_DESCR ) )
1461 , m_aFileListFT ( this , SVX_RES( FT_BROKEN_FILELIST ) )
1462 , m_aFileListLB ( this , SVX_RES( LB_BROKEN_FILELIST ) )
1463 , m_aSaveDirFT ( this , SVX_RES( FT_BROKEN_SAVEDIR ) )
1464 , m_aSaveDirED ( this , SVX_RES( ED_BROKEN_SAVEDIR ) )
1465 , m_aSaveDirBtn ( this , SVX_RES( BTN_BROKEN_SAVEDIR ) )
1466 , m_aBottomFL ( this , SVX_RES( FL_BROKEN_BOTTOM ) )
1467 , m_aOkBtn ( this , SVX_RES( BTN_BROKEN_OK ) )
1468 , m_aCancelBtn ( this , SVX_RES( BTN_BROKEN_CANCEL ) )
1469 , m_pCore ( pCore )
1470 , m_bBeforeRecovery (bBeforeRecovery)
1471 , m_bExecutionNeeded(sal_False)
1472 {
1473 FreeResource();
1474
1475 m_aSaveDirBtn.SetClickHdl( LINK( this, BrokenRecoveryDialog, SaveButtonHdl ) );
1476 m_aOkBtn.SetClickHdl( LINK( this, BrokenRecoveryDialog, OkButtonHdl ) );
1477 m_aCancelBtn.SetClickHdl( LINK( this, BrokenRecoveryDialog, CancelButtonHdl ) );
1478
1479 m_sSavePath = SvtPathOptions().GetWorkPath();
1480 INetURLObject aObj( m_sSavePath );
1481 String sPath;
1482 ::utl::LocalFileHelper::ConvertURLToSystemPath( aObj.GetMainURL( INetURLObject::NO_DECODE ), sPath );
1483 m_aSaveDirED.SetText( sPath );
1484
1485 impl_refresh();
1486 }
1487
1488 //===============================================
~BrokenRecoveryDialog()1489 BrokenRecoveryDialog::~BrokenRecoveryDialog()
1490 {
1491 }
1492
1493 //===============================================
impl_refresh()1494 void BrokenRecoveryDialog::impl_refresh()
1495 {
1496 m_bExecutionNeeded = sal_False;
1497 TURLList* pURLList = m_pCore->getURLListAccess();
1498 TURLList::const_iterator pIt;
1499 for ( pIt = pURLList->begin();
1500 pIt != pURLList->end() ;
1501 ++pIt )
1502 {
1503 const TURLInfo& rInfo = *pIt;
1504
1505 if (m_bBeforeRecovery)
1506 {
1507 // "Cancel" before recovery ->
1508 // search for any temp files!
1509 if (!rInfo.TempURL.getLength())
1510 continue;
1511 }
1512 else
1513 {
1514 // "Cancel" after recovery ->
1515 // search for broken temp files
1516 if (!RecoveryCore::isBrokenTempEntry(rInfo))
1517 continue;
1518 }
1519
1520 m_bExecutionNeeded = sal_True;
1521
1522 sal_uInt16 nPos = m_aFileListLB.InsertEntry(rInfo.DisplayName, rInfo.StandardImage );
1523 m_aFileListLB.SetEntryData( nPos, (void*)&rInfo );
1524 }
1525 m_sSavePath = ::rtl::OUString();
1526 m_aOkBtn.GrabFocus();
1527 }
1528
1529 //===============================================
isExecutionNeeded()1530 sal_Bool BrokenRecoveryDialog::isExecutionNeeded()
1531 {
1532 return m_bExecutionNeeded;
1533 }
1534
1535 //===============================================
getSaveDirURL()1536 ::rtl::OUString BrokenRecoveryDialog::getSaveDirURL()
1537 {
1538 return m_sSavePath;
1539 }
1540
1541 //===============================================
IMPL_LINK(BrokenRecoveryDialog,OkButtonHdl,void *,EMPTYARG)1542 IMPL_LINK( BrokenRecoveryDialog, OkButtonHdl, void*, EMPTYARG )
1543 {
1544 String sPhysicalPath = m_aSaveDirED.GetText().EraseLeadingChars().EraseTrailingChars();
1545 String sURL;
1546 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPhysicalPath, sURL );
1547 m_sSavePath = sURL;
1548 while (!m_sSavePath.getLength())
1549 impl_askForSavePath();
1550
1551 EndDialog(DLG_RET_OK);
1552 return 0;
1553 }
1554
1555 //===============================================
IMPL_LINK(BrokenRecoveryDialog,CancelButtonHdl,void *,EMPTYARG)1556 IMPL_LINK( BrokenRecoveryDialog, CancelButtonHdl, void*, EMPTYARG )
1557 {
1558 EndDialog(DLG_RET_CANCEL);
1559 return 0;
1560 }
1561
1562 //===============================================
IMPL_LINK(BrokenRecoveryDialog,SaveButtonHdl,void *,EMPTYARG)1563 IMPL_LINK( BrokenRecoveryDialog, SaveButtonHdl, void*, EMPTYARG )
1564 {
1565 impl_askForSavePath();
1566 return 0;
1567 }
1568
1569 //===============================================
impl_askForSavePath()1570 void BrokenRecoveryDialog::impl_askForSavePath()
1571 {
1572 css::uno::Reference< css::ui::dialogs::XFolderPicker > xFolderPicker(
1573 m_pCore->getSMGR()->createInstance(SERVICENAME_FOLDERPICKER), css::uno::UNO_QUERY_THROW);
1574
1575 INetURLObject aURL(m_sSavePath, INET_PROT_FILE);
1576 xFolderPicker->setDisplayDirectory(aURL.GetMainURL(INetURLObject::NO_DECODE));
1577 short nRet = xFolderPicker->execute();
1578 if (nRet == css::ui::dialogs::ExecutableDialogResults::OK)
1579 {
1580 m_sSavePath = xFolderPicker->getDirectory();
1581 String sPath;
1582 ::utl::LocalFileHelper::ConvertURLToSystemPath( m_sSavePath, sPath );
1583 m_aSaveDirED.SetText( sPath );
1584 }
1585 }
1586
1587 //===============================================
1588 ///////////////////////////////////////////////////////////////////////
1589 // Error Report Welcome Dialog
1590 ///////////////////////////////////////////////////////////////////////
1591
ErrorRepWelcomeDialog(Window * _pParent,sal_Bool _bAllowBack)1592 ErrorRepWelcomeDialog::ErrorRepWelcomeDialog( Window* _pParent, sal_Bool _bAllowBack )
1593 :IExtendedTabPage ( _pParent, SVX_RES( RID_SVXPAGE_ERR_REP_WELCOME ) )
1594 ,maTitleWin ( this, SVX_RES( WIN_RECOV_TITLE ) )
1595 ,maTitleFT ( this, SVX_RES( FT_RECOV_TITLE ) )
1596 ,maTitleFL ( this, SVX_RES( FL_RECOV_TITLE ) )
1597 ,maDescrFT ( this, SVX_RES( FT_RECOV_DESCR ) )
1598 ,maBottomFL ( this, SVX_RES( FL_RECOV_BOTTOM ) )
1599 ,maPrevBtn ( this, SVX_RES( BTN_RECOV_PREV ) )
1600 ,maNextBtn ( this, SVX_RES( BTN_RECOV_NEXT ) )
1601 ,maCancelBtn ( this, SVX_RES( BTN_RECOV_CANCEL ) )
1602 {
1603 FreeResource();
1604
1605 Wallpaper aBack( GetSettings().GetStyleSettings().GetWindowColor() );
1606 maTitleWin.SetBackground( aBack );
1607 maTitleFT.SetBackground( aBack );
1608
1609 Font aFnt( maTitleFT.GetFont() );
1610 aFnt.SetWeight( WEIGHT_BOLD );
1611 maTitleFT.SetFont( aFnt );
1612
1613 maPrevBtn.SetClickHdl( LINK( this, ErrorRepWelcomeDialog, PrevBtnHdl ) );
1614 maPrevBtn.Enable( _bAllowBack );
1615
1616 maNextBtn.SetClickHdl( LINK( this, ErrorRepWelcomeDialog, NextBtnHdl ) );
1617 maNextBtn.Enable( sal_True );
1618
1619 maCancelBtn.SetClickHdl( LINK( this, ErrorRepWelcomeDialog, CancelBtnHdl ) );
1620 maCancelBtn.Enable( sal_True );
1621 }
1622
~ErrorRepWelcomeDialog()1623 ErrorRepWelcomeDialog::~ErrorRepWelcomeDialog()
1624 {
1625 }
1626
IMPL_LINK(ErrorRepWelcomeDialog,PrevBtnHdl,void *,EMPTYARG)1627 IMPL_LINK( ErrorRepWelcomeDialog, PrevBtnHdl, void*, EMPTYARG )
1628 {
1629 m_nResult = DLG_RET_BACK;
1630 return 0;
1631 }
1632
IMPL_LINK(ErrorRepWelcomeDialog,NextBtnHdl,void *,EMPTYARG)1633 IMPL_LINK( ErrorRepWelcomeDialog, NextBtnHdl, void*, EMPTYARG )
1634 {
1635 m_nResult = DLG_RET_OK;
1636 return 0;
1637 }
1638
IMPL_LINK(ErrorRepWelcomeDialog,CancelBtnHdl,void *,EMPTYARG)1639 IMPL_LINK( ErrorRepWelcomeDialog, CancelBtnHdl, void*, EMPTYARG )
1640 {
1641 m_nResult = DLG_RET_CANCEL;
1642 return 0;
1643 }
1644
execute()1645 short ErrorRepWelcomeDialog::execute()
1646 {
1647 ::vos::OGuard aLock(Application::GetSolarMutex());
1648 Show();
1649 m_nResult = DLG_RET_UNKNOWN;
1650 while(m_nResult == DLG_RET_UNKNOWN)
1651 Application::Yield();
1652 return m_nResult;
1653 }
1654
setDefButton()1655 void ErrorRepWelcomeDialog::setDefButton()
1656 {
1657 maNextBtn.GrabFocus();
1658 }
1659
1660 ///////////////////////////////////////////////////////////////////////
1661 // Error Report Send Dialog and its MultiLineEdit
1662 ///////////////////////////////////////////////////////////////////////
1663
ErrorDescriptionEdit(Window * pParent,const ResId & rResId)1664 ErrorDescriptionEdit::ErrorDescriptionEdit( Window* pParent, const ResId& rResId ) :
1665
1666 MultiLineEdit( pParent, rResId )
1667
1668 {
1669 SetModifyHdl( LINK( this, ErrorDescriptionEdit, ModifyHdl ) );
1670 if ( GetVScrollBar() )
1671 GetVScrollBar()->Hide();
1672 }
1673
~ErrorDescriptionEdit()1674 ErrorDescriptionEdit::~ErrorDescriptionEdit()
1675 {
1676 }
1677
IMPL_LINK(ErrorDescriptionEdit,ModifyHdl,void *,EMPTYARG)1678 IMPL_LINK( ErrorDescriptionEdit, ModifyHdl, void*, EMPTYARG )
1679 {
1680 if ( !GetVScrollBar() )
1681 return 0;
1682
1683 ExtTextEngine* pTextEngine = GetTextEngine();
1684 DBG_ASSERT( pTextEngine, "no text engine" );
1685
1686 sal_uIntPtr i, nParaCount = pTextEngine->GetParagraphCount();
1687 sal_uInt16 nLineCount = 0;
1688
1689 for ( i = 0; i < nParaCount; ++i )
1690 nLineCount = nLineCount + pTextEngine->GetLineCount(i);
1691
1692 sal_uInt16 nVisCols = 0, nVisLines = 0;
1693 GetMaxVisColumnsAndLines( nVisCols, nVisLines );
1694 GetVScrollBar()->Show( nLineCount > nVisLines );
1695
1696 return 0;
1697 }
1698
ErrorRepSendDialog(Window * _pParent)1699 ErrorRepSendDialog::ErrorRepSendDialog( Window* _pParent )
1700 :IExtendedTabPage ( _pParent, SVX_RES( RID_SVXPAGE_ERR_REP_SEND ) )
1701 ,maTitleWin ( this, SVX_RES( WIN_RECOV_TITLE ) )
1702 ,maTitleFT ( this, SVX_RES( FT_RECOV_TITLE ) )
1703 ,maTitleFL ( this, SVX_RES( FL_RECOV_TITLE ) )
1704 ,maDescrFT ( this, SVX_RES( FT_RECOV_DESCR ) )
1705
1706 ,maDocTypeFT ( this, SVX_RES( FT_ERRSEND_DOCTYPE ) )
1707 ,maDocTypeED ( this, SVX_RES( ED_ERRSEND_DOCTYPE ) )
1708 ,maUsingFT ( this, SVX_RES( FT_ERRSEND_USING ) )
1709 ,maUsingML ( this, SVX_RES( ML_ERRSEND_USING ) )
1710 ,maShowRepBtn ( this, SVX_RES( BTN_ERRSEND_SHOWREP ) )
1711 ,maOptBtn ( this, SVX_RES( BTN_ERRSEND_OPT ) )
1712 ,maContactCB ( this, SVX_RES( CB_ERRSEND_CONTACT ) )
1713 ,maEMailAddrFT ( this, SVX_RES( FT_ERRSEND_EMAILADDR ) )
1714 ,maEMailAddrED ( this, SVX_RES( ED_ERRSEND_EMAILADDR ) )
1715
1716 ,maBottomFL ( this, SVX_RES( FL_RECOV_BOTTOM ) )
1717 ,maPrevBtn ( this, SVX_RES( BTN_RECOV_PREV ) )
1718 ,maNextBtn ( this, SVX_RES( BTN_RECOV_NEXT ) )
1719 ,maCancelBtn ( this, SVX_RES( BTN_RECOV_CANCEL ) )
1720 {
1721 FreeResource();
1722
1723 initControls();
1724
1725 Wallpaper aBack( GetSettings().GetStyleSettings().GetWindowColor() );
1726 maTitleWin.SetBackground( aBack );
1727 maTitleFT.SetBackground( aBack );
1728
1729 Font aFnt( maTitleFT.GetFont() );
1730 aFnt.SetWeight( WEIGHT_BOLD );
1731 maTitleFT.SetFont( aFnt );
1732
1733 maShowRepBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, ShowRepBtnHdl ) );
1734 maOptBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, OptBtnHdl ) );
1735 maContactCB.SetClickHdl( LINK( this, ErrorRepSendDialog, ContactCBHdl ) );
1736 maPrevBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, PrevBtnHdl ) );
1737 maNextBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, SendBtnHdl ) );
1738 maCancelBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, CancelBtnHdl ) );
1739
1740 ReadParams();
1741
1742 /*
1743 maDocTypeED.SetText( maParams.maSubject );
1744 maUsingML.SetText( maParams.maBody );
1745 maContactCB.Check( maParams.mbAllowContact );
1746 maEMailAddrED.SetText( maParams.maReturnAddress );
1747 */
1748 ContactCBHdl( 0 );
1749 }
1750
~ErrorRepSendDialog()1751 ErrorRepSendDialog::~ErrorRepSendDialog()
1752 {
1753 }
1754
execute()1755 short ErrorRepSendDialog::execute()
1756 {
1757 ::vos::OGuard aLock(Application::GetSolarMutex());
1758 Show();
1759 m_nResult = DLG_RET_UNKNOWN;
1760 while(m_nResult == DLG_RET_UNKNOWN)
1761 Application::Yield();
1762 return m_nResult;
1763 }
1764
setDefButton()1765 void ErrorRepSendDialog::setDefButton()
1766 {
1767 // set first focus
1768 maDocTypeED.GrabFocus();
1769 }
1770
IMPL_LINK(ErrorRepSendDialog,PrevBtnHdl,void *,EMPTYARG)1771 IMPL_LINK( ErrorRepSendDialog, PrevBtnHdl, void*, EMPTYARG )
1772 {
1773 m_nResult = DLG_RET_BACK;
1774 return 0;
1775 }
1776
IMPL_LINK(ErrorRepSendDialog,CancelBtnHdl,void *,EMPTYARG)1777 IMPL_LINK( ErrorRepSendDialog, CancelBtnHdl, void*, EMPTYARG )
1778 {
1779 m_nResult = DLG_RET_CANCEL;
1780 return 0;
1781 }
1782
IMPL_LINK(ErrorRepSendDialog,SendBtnHdl,void *,EMPTYARG)1783 IMPL_LINK( ErrorRepSendDialog, SendBtnHdl, void*, EMPTYARG )
1784 {
1785
1786 SaveParams();
1787 SendReport();
1788
1789 m_nResult = DLG_RET_OK;
1790 return 0;
1791 }
1792
IMPL_LINK(ErrorRepSendDialog,ShowRepBtnHdl,void *,EMPTYARG)1793 IMPL_LINK( ErrorRepSendDialog, ShowRepBtnHdl, void*, EMPTYARG )
1794 {
1795 ErrorRepPreviewDialog aDlg( this );
1796 aDlg.Execute();
1797 return 0;
1798 }
1799
IMPL_LINK(ErrorRepSendDialog,OptBtnHdl,void *,EMPTYARG)1800 IMPL_LINK( ErrorRepSendDialog, OptBtnHdl, void*, EMPTYARG )
1801 {
1802 ErrorRepOptionsDialog aDlg( this, maParams );
1803 aDlg.Execute();
1804 return 0;
1805 }
1806
IMPL_LINK(ErrorRepSendDialog,ContactCBHdl,void *,EMPTYARG)1807 IMPL_LINK( ErrorRepSendDialog, ContactCBHdl, void*, EMPTYARG )
1808 {
1809 bool bCheck = maContactCB.IsChecked();
1810 maEMailAddrFT.Enable( bCheck );
1811 maEMailAddrED.Enable( bCheck );
1812 return 0;
1813 }
1814
initControls()1815 void ErrorRepSendDialog::initControls()
1816 {
1817 // if the text is too short for two lines, insert a newline
1818 String sText = maDocTypeFT.GetText();
1819 if ( maDocTypeFT.GetCtrlTextWidth( sText ) <= maDocTypeFT.GetSizePixel().Width() )
1820 {
1821 sText.Insert( '\n', 0 );
1822 maDocTypeFT.SetText( sText );
1823 }
1824
1825 // if the button text is too wide, then broaden the button
1826 sText = maShowRepBtn.GetText();
1827 long nTxtW = maShowRepBtn.GetCtrlTextWidth( sText );
1828 long nBtnW = maShowRepBtn.GetSizePixel().Width();
1829 if ( nTxtW >= nBtnW )
1830 {
1831 const long nMinDelta = 10;
1832 long nDelta = Max( nTxtW - nBtnW, nMinDelta );
1833 sal_uInt32 i = 0;
1834 Window* pWins[] =
1835 {
1836 &maShowRepBtn, &maOptBtn,
1837 &maDescrFT, &maDocTypeFT, &maDocTypeED, &maUsingFT,
1838 &maUsingML, &maContactCB, &maEMailAddrFT, &maEMailAddrED
1839 };
1840 // the first two buttons need a new size (wider) and position (more left)
1841 Window** pCurrent = pWins;
1842 const sal_uInt32 nBtnCount = 2;
1843 for ( ; i < nBtnCount; ++i, ++pCurrent )
1844 {
1845 Size aNewSize = (*pCurrent)->GetSizePixel();
1846 aNewSize.Width() += nDelta;
1847 (*pCurrent)->SetSizePixel( aNewSize );
1848 Point aNewPos = (*pCurrent)->GetPosPixel();
1849 aNewPos.X() -= nDelta;
1850 (*pCurrent)->SetPosPixel( aNewPos );
1851 }
1852
1853 // loop through all the other windows and adjust their size
1854 for ( ; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent )
1855 {
1856 Size aSize = (*pCurrent)->GetSizePixel();
1857 aSize.Width() -= nDelta;
1858 (*pCurrent)->SetSizePixel( aSize );
1859 }
1860 }
1861 }
1862
GetDocType(void) const1863 String ErrorRepSendDialog::GetDocType( void ) const
1864 {
1865 return maDocTypeED.GetText();
1866 }
1867
GetUsing(void) const1868 String ErrorRepSendDialog::GetUsing( void ) const
1869 {
1870 return maUsingML.GetText();
1871 }
1872
IsContactAllowed(void) const1873 bool ErrorRepSendDialog::IsContactAllowed( void ) const
1874 {
1875 return maContactCB.IsChecked();
1876 }
1877
GetEMailAddress(void) const1878 String ErrorRepSendDialog::GetEMailAddress( void ) const
1879 {
1880 return maEMailAddrED.GetText();
1881 }
1882
1883
1884 ///////////////////////////////////////////////////////////////////////
1885 // Error Report Options Dialog
1886 ///////////////////////////////////////////////////////////////////////
1887
ErrorRepOptionsDialog(Window * _pParent,ErrorRepParams & _rParams)1888 ErrorRepOptionsDialog::ErrorRepOptionsDialog( Window* _pParent, ErrorRepParams& _rParams )
1889 :ModalDialog ( _pParent, SVX_RES( RID_SVX_MDLG_ERR_REP_OPTIONS ) )
1890 ,maProxyFL( this, SVX_RES( FL_ERROPT_PROXY ) )
1891 ,maSystemBtn( this, SVX_RES( BTN_ERROPT_SYSTEM ) )
1892 ,maDirectBtn( this, SVX_RES( BTN_ERROPT_DIRECT ) )
1893 ,maManualBtn( this, SVX_RES( BTN_ERROPT_MANUAL ) )
1894 ,maProxyServerFT( this, SVX_RES( FT_ERROPT_PROXYSERVER ) )
1895 ,maProxyServerEd( this, SVX_RES( ED_ERROPT_PROXYSERVER ) )
1896 ,maProxyPortFT( this, SVX_RES( FT_ERROPT_PROXYPORT ) )
1897 ,maProxyPortEd( this, SVX_RES( ED_ERROPT_PROXYPORT ) )
1898 ,maDescriptionFT( this, SVX_RES( FT_ERROPT_DESCRIPTION ) )
1899 ,maButtonsFL( this, SVX_RES( FL_ERROPT_BUTTONS ) )
1900 ,maOKBtn( this, SVX_RES( BTN_ERROPT_OK ) )
1901 ,maCancelBtn( this, SVX_RES( BTN_ERROPT_CANCEL ) )
1902 ,mrParams( _rParams )
1903 {
1904 FreeResource();
1905
1906 maManualBtn.SetToggleHdl( LINK( this, ErrorRepOptionsDialog, ManualBtnHdl ) );
1907 maCancelBtn.SetClickHdl( LINK( this, ErrorRepOptionsDialog, CancelBtnHdl ) );
1908 maOKBtn.SetClickHdl( LINK( this, ErrorRepOptionsDialog, OKBtnHdl ) );
1909
1910 maProxyServerEd.SetText( mrParams.maHTTPProxyServer );
1911 maProxyPortEd.SetText( mrParams.maHTTPProxyPort );
1912
1913 #ifndef WNT
1914 // no "Use system settings" button on non windows systems
1915 // so hide this button
1916 maSystemBtn.Hide();
1917 long nDelta = maDirectBtn.GetPosPixel().Y() - maSystemBtn.GetPosPixel().Y();
1918 // and loop through all these controls and adjust their position
1919 Window* pWins[] =
1920 {
1921 &maDirectBtn, &maManualBtn, &maProxyServerFT,
1922 &maProxyServerEd, &maProxyPortFT, &maProxyPortEd, &maDescriptionFT
1923 };
1924 Window** pCurrent = pWins;
1925 for ( sal_uInt32 i = 0; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent )
1926 {
1927 Point aPos = (*pCurrent)->GetPosPixel();
1928 aPos.Y() -= nDelta;
1929 (*pCurrent)->SetPosPixel( aPos );
1930 }
1931 #endif
1932
1933
1934 switch ( mrParams.miHTTPConnectionType )
1935 {
1936 default:
1937 #ifdef WNT
1938 case 0:
1939 maSystemBtn.Check( sal_True );
1940 break;
1941 #endif
1942 case 1:
1943 maDirectBtn.Check( sal_True );
1944 break;
1945 case 2:
1946 maManualBtn.Check( sal_True );
1947 break;
1948 }
1949
1950 ManualBtnHdl( 0 );
1951 }
1952
~ErrorRepOptionsDialog()1953 ErrorRepOptionsDialog::~ErrorRepOptionsDialog()
1954 {
1955 }
1956
IMPL_LINK(ErrorRepOptionsDialog,ManualBtnHdl,void *,EMPTYARG)1957 IMPL_LINK( ErrorRepOptionsDialog, ManualBtnHdl, void*, EMPTYARG )
1958 {
1959 bool bCheck = maManualBtn.IsChecked();
1960 maProxyServerFT.Enable( bCheck );
1961 maProxyServerEd.Enable( bCheck );
1962 maProxyPortFT.Enable( bCheck );
1963 maProxyPortEd.Enable( bCheck );
1964 return 0;
1965 }
1966
IMPL_LINK(ErrorRepOptionsDialog,OKBtnHdl,void *,EMPTYARG)1967 IMPL_LINK( ErrorRepOptionsDialog, OKBtnHdl, void*, EMPTYARG )
1968 {
1969 if ( maManualBtn.IsChecked() )
1970 mrParams.miHTTPConnectionType = 2;
1971 else if ( maDirectBtn.IsChecked() )
1972 mrParams.miHTTPConnectionType = 1;
1973 else if ( maSystemBtn.IsChecked() )
1974 mrParams.miHTTPConnectionType = 0;
1975
1976 mrParams.maHTTPProxyServer = maProxyServerEd.GetText();
1977 mrParams.maHTTPProxyPort = maProxyPortEd.GetText();
1978
1979 EndDialog(DLG_RET_OK);
1980 return 0;
1981 }
1982
IMPL_LINK(ErrorRepOptionsDialog,CancelBtnHdl,void *,EMPTYARG)1983 IMPL_LINK( ErrorRepOptionsDialog, CancelBtnHdl, void*, EMPTYARG )
1984 {
1985 EndDialog(DLG_RET_CANCEL);
1986 return 0;
1987 }
1988
1989 ///////////////////////////////////////////////////////////////////////
1990 // Error Report Edit (MultiLineEdit with fixed font)
1991 ///////////////////////////////////////////////////////////////////////
1992
ErrorRepEdit(Window * pParent,const ResId & rResId)1993 ErrorRepEdit::ErrorRepEdit( Window* pParent, const ResId& rResId ) :
1994 ExtMultiLineEdit( pParent, rResId )
1995 {
1996 // fixed font for error report
1997 Color aColor = GetTextColor();
1998
1999 Font aFont = OutputDevice::GetDefaultFont(
2000 DEFAULTFONT_FIXED, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE );
2001
2002 // Set font color because the default font color is transparent !!!
2003 aFont.SetColor( aColor );
2004
2005 GetTextEngine()->SetFont( aFont );
2006
2007 // no blinking cursor and a little left margin
2008 EnableCursor( sal_False );
2009 SetLeftMargin( 4 );
2010 }
2011
~ErrorRepEdit()2012 ErrorRepEdit::~ErrorRepEdit()
2013 {
2014 }
2015
2016 ///////////////////////////////////////////////////////////////////////
2017 // Error Report Preview Dialog
2018 ///////////////////////////////////////////////////////////////////////
2019
2020
GetCrashConfigDir()2021 static ::rtl::OUString GetCrashConfigDir()
2022 {
2023
2024 #if defined(WNT) || defined(OS2)
2025 OUString ustrValue = OUString::createFromAscii("${$OOO_BASE_DIR/program/bootstrap.ini:UserInstallation}");
2026 #elif defined( MACOSX )
2027 OUString ustrValue = OUString::createFromAscii("~");
2028 #else
2029 OUString ustrValue = OUString::createFromAscii("$SYSUSERCONFIG");
2030 #endif
2031 Bootstrap::expandMacros( ustrValue );
2032
2033 #if defined(WNT) || defined(OS2)
2034 ustrValue += OUString::createFromAscii("/user/crashdata");
2035 #endif
2036 return ustrValue;
2037 }
2038
2039 #if defined(WNT) || defined(OS2)
2040 #define CHKFILE "crashdat.chk"
2041 #define STKFILE "crashdat.stk"
2042 #define PRVFILE "crashdat.prv"
2043 #else
2044 #define CHKFILE ".crash_report_checksum"
2045 #define STKFILE ".crash_report_frames"
2046 #define PRVFILE ".crash_report_preview"
2047 #endif
2048
2049 // static ::rtl::OUString GetChecksumURL()
2050 // {
2051 // ::rtl::OUString aURL = GetCrashConfigDir();
2052
2053 // aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
2054 // aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CHKFILE ) );
2055
2056 // return aURL;
2057 // }
2058
2059 // static ::rtl::OUString GetStackURL()
2060 // {
2061 // ::rtl::OUString aURL = GetCrashConfigDir();
2062
2063 // aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
2064 // aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STKFILE ) );
2065
2066 // return aURL;
2067 // }
2068
GetPreviewURL()2069 static ::rtl::OUString GetPreviewURL()
2070 {
2071 ::rtl::OUString aURL = GetCrashConfigDir();
2072
2073 aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
2074 aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PRVFILE ) );
2075
2076 return aURL;
2077 }
2078
LoadCrashFile(const::rtl::OUString & rURL)2079 static String LoadCrashFile( const ::rtl::OUString &rURL )
2080 {
2081 String aFileContent;
2082 ::osl::File aFile( rURL );
2083
2084 printf( "Loading %s:", OString( rURL.getStr(), rURL.getLength(), osl_getThreadTextEncoding() ).getStr() );
2085 if ( ::osl::FileBase::E_None == aFile.open( OpenFlag_Read ) )
2086 {
2087 ::rtl::OString aContent;
2088 ::osl::FileBase::RC result;
2089 sal_uInt64 aBytesRead;
2090
2091 do
2092 {
2093 sal_Char aBuffer[256];
2094
2095 result = aFile.read( aBuffer, sizeof(aBuffer), aBytesRead );
2096
2097 if ( ::osl::FileBase::E_None == result )
2098 {
2099 ::rtl::OString aTemp( aBuffer, static_cast< xub_StrLen >( aBytesRead ) );
2100 aContent += aTemp;
2101 }
2102 } while ( ::osl::FileBase::E_None == result && aBytesRead );
2103
2104 ::rtl::OUString ustrContent( aContent.getStr(), aContent.getLength(), RTL_TEXTENCODING_UTF8 );
2105 aFileContent = ustrContent;
2106
2107 aFile.close();
2108
2109 printf( "SUCCEEDED\n" );
2110 }
2111 else
2112 printf( "FAILED\n" );
2113
2114 return aFileContent;
2115 }
2116
2117
2118
ErrorRepPreviewDialog(Window * _pParent)2119 ErrorRepPreviewDialog::ErrorRepPreviewDialog( Window* _pParent )
2120 :ModalDialog ( _pParent, SVX_RES( RID_SVX_MDLG_ERR_REP_PREVIEW ) )
2121 ,maContentML( this, SVX_RES( ML_ERRPREVIEW_CONTENT ) )
2122 ,maOKBtn( this, SVX_RES( BTN_ERRPREVIEW_OK ) )
2123
2124 {
2125 FreeResource();
2126
2127 mnMinHeight = ( maContentML.GetSizePixel().Height() / 2 );
2128
2129 String aPreview = LoadCrashFile( GetPreviewURL() );
2130 ErrorRepSendDialog *pMainDlg = (ErrorRepSendDialog *)_pParent;
2131
2132 String aSeperator = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\r\n\r\n================\r\n\r\n" ) );
2133
2134 String aContent = pMainDlg->GetDocType();
2135 if ( aContent.Len() > 0 )
2136 aContent += aSeperator;
2137 aContent += pMainDlg->GetUsing();
2138 if ( aContent.Len() > 0 )
2139 aContent += aSeperator;
2140 aContent += aPreview;
2141
2142 maContentML.SetText( aContent );
2143 }
2144
~ErrorRepPreviewDialog()2145 ErrorRepPreviewDialog::~ErrorRepPreviewDialog()
2146 {
2147 }
2148
Resize()2149 void ErrorRepPreviewDialog::Resize()
2150 {
2151 Size a3Sz = LogicToPixel( Size( 3, 3 ), MAP_APPFONT );
2152 Size aWinSz = GetSizePixel();
2153 Size aBtnSz = maOKBtn.GetSizePixel();
2154 Point aEditPnt = maContentML.GetPosPixel();
2155
2156 long nNewHeight = Max( aWinSz.Height() - aEditPnt.Y() - 3 * a3Sz.Height() - aBtnSz.Height(), mnMinHeight );
2157 long nNewWidth = aWinSz.Width() - 4 * a3Sz.Width();
2158
2159 Size aNewSize( nNewWidth, nNewHeight );
2160 maContentML.SetSizePixel( aNewSize );
2161 Point aNewPoint( Max( aEditPnt.X() + aNewSize.Width() - aBtnSz.Width(), aEditPnt.X() ),
2162 aEditPnt.Y() + aNewSize.Height() + a3Sz.Height() );
2163 maOKBtn.SetPosPixel( aNewPoint );
2164 }
2165 } // namespace DocRecovery
2166 } // namespace svx
2167