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