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