xref: /trunk/main/svx/source/dialog/docrecovery.cxx (revision 86e1cf34)
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 //===============================================
77 TabDialog4Recovery::TabDialog4Recovery(Window* pParent)
78     : TabDialog    (pParent, SVX_RES( RID_SVX_TABDLG_DOCRECOVERY ))
79     , m_pActualPage(m_lTabPages.begin()                           )
80 {
81 }
82 
83 //===============================================
84 TabDialog4Recovery::~TabDialog4Recovery()
85 {
86     m_lTabPages.clear();
87 }
88 
89 //===============================================
90 void TabDialog4Recovery::addTabPage(IExtendedTabPage* pPage)
91 {
92     if (pPage)
93         m_lTabPages.push_back(pPage);
94 }
95 
96 //===============================================
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 //===============================================
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 //===============================================
148 RecoveryCore::~RecoveryCore()
149 {
150     impl_stopListening();
151 }
152 
153 //===============================================
154 css::uno::Reference< css::lang::XMultiServiceFactory > RecoveryCore::getSMGR()
155 {
156     return m_xSMGR;
157 }
158 
159 //===============================================
160 TURLList* RecoveryCore::getURLListAccess()
161 {
162     return &m_lURLs;
163 }
164 
165 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
384 void RecoveryCore::setProgressHandler(const css::uno::Reference< css::task::XStatusIndicator >& xProgress)
385 {
386     m_xProgress = xProgress;
387 }
388 
389 //===============================================
390 void RecoveryCore::setUpdateListener(IRecoveryUpdateListener* pListener)
391 {
392     m_pListener = pListener;
393 }
394 
395 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
445 ERecoveryState RecoveryCore::mapDocState2RecoverState(sal_Int32 eDocState)
446 {
447     // ???
448     ERecoveryState eRecState = E_NOT_RECOVERED_YET;
449 
450     /* Attention:
451         Some of the following states can occur at the
452         same time. So we have to check for the "worst case" first!
453 
454         DAMAGED -> INCOMPLETE -> HANDLED
455      */
456 
457     // running ...
458     if (
459         ((eDocState & E_TRY_LOAD_BACKUP  ) == E_TRY_LOAD_BACKUP  ) ||
460         ((eDocState & E_TRY_LOAD_ORIGINAL) == E_TRY_LOAD_ORIGINAL)
461        )
462         eRecState = E_RECOVERY_IS_IN_PROGRESS;
463     // red
464     else
465     if ((eDocState & E_DAMAGED) == E_DAMAGED)
466         eRecState = E_RECOVERY_FAILED;
467     // yellow
468     else
469     if ((eDocState & E_INCOMPLETE) == E_INCOMPLETE)
470         eRecState = E_ORIGINAL_DOCUMENT_RECOVERED;
471     // green
472     else
473     if ((eDocState & E_SUCCEDED) == E_SUCCEDED)
474         eRecState = E_SUCCESSFULLY_RECOVERED;
475 
476     return eRecState;
477 }
478 
479 //===============================================
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 //===============================================
569 void SAL_CALL RecoveryCore::disposing(const css::lang::EventObject& /*aEvent*/)
570     throw(css::uno::RuntimeException)
571 {
572     m_xRealCore.clear();
573 }
574 
575 //===============================================
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 //===============================================
597 void RecoveryCore::impl_stopListening()
598 {
599     // Ignore it, if this instance doesn't 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 //===============================================
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 //===============================================
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 //===============================================
640 PluginProgressWindow::~PluginProgressWindow()
641 {
642     if (m_xProgress.is())
643         m_xProgress->dispose();
644 }
645 
646 //===============================================
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 //===============================================
670 PluginProgress::~PluginProgress()
671 {
672 }
673 
674 //===============================================
675 Window* PluginProgress::getPlugWindow()
676 {
677     return m_pPlugProgressWindow;
678 }
679 
680 //===============================================
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 //===============================================
691 void SAL_CALL PluginProgress::addEventListener(const css::uno::Reference< css::lang::XEventListener >& )
692     throw(css::uno::RuntimeException)
693 {
694 }
695 
696 //===============================================
697 void SAL_CALL PluginProgress::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& )
698     throw(css::uno::RuntimeException)
699 {
700 }
701 
702 //===============================================
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 //===============================================
712 void SAL_CALL PluginProgress::end()
713     throw(css::uno::RuntimeException)
714 {
715     if (m_xProgress.is())
716         m_xProgress->end();
717 }
718 
719 //===============================================
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 //===============================================
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 //===============================================
736 void SAL_CALL PluginProgress::reset()
737     throw(css::uno::RuntimeException)
738 {
739     if (m_xProgress.is())
740         m_xProgress->reset();
741 }
742 
743 //===============================================
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 can't 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 //===============================================
793 SaveDialog::~SaveDialog()
794 {
795 }
796 
797 //===============================================
798 IMPL_LINK( SaveDialog, OKButtonHdl, void*, EMPTYARG )
799 {
800     m_nResult = DLG_RET_OK;
801     return 0;
802 }
803 
804 //===============================================
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 //===============================================
830 void SaveDialog::setDefButton()
831 {
832     m_aOkBtn.GrabFocus();
833 }
834 
835 //===============================================
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 //===============================================
851 SaveProgressDialog::~SaveProgressDialog()
852 {
853 }
854 
855 //===============================================
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 //===============================================
869 void SaveProgressDialog::updateItems()
870 {
871 }
872 
873 //===============================================
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 //===============================================
885 void SaveProgressDialog::start()
886 {
887 }
888 
889 //===============================================
890 void SaveProgressDialog::end()
891 {
892     EndDialog(DLG_RET_OK);
893 }
894 
895 //===============================================
896 RecovDocListEntry::RecovDocListEntry(      SvLBoxEntry* pEntry,
897                                            sal_uInt16       nFlags,
898                                      const String&      sText )
899     : SvLBoxString( pEntry, nFlags, sText )
900 {
901 }
902 
903 //===============================================
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 //===============================================
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 //===============================================
993 RecovDocList::~RecovDocList()
994 {
995 }
996 
997 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
1114 RecoveryDialog::~RecoveryDialog()
1115 {
1116 }
1117 
1118 //===============================================
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                  // doesn't 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 //===============================================
1341 void RecoveryDialog::setDefButton()
1342 {
1343     if ( m_aNextBtn.IsEnabled() )
1344         m_aNextBtn.GrabFocus();
1345     else
1346         m_pDefButton = &m_aNextBtn;
1347 }
1348 
1349 //===============================================
1350 void RecoveryDialog::start()
1351 {
1352 }
1353 
1354 //===============================================
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 //===============================================
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 //===============================================
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 //===============================================
1413 IMPL_LINK( RecoveryDialog, NextButtonHdl, void*, EMPTYARG )
1414 {
1415     m_bUserDecideNext = sal_True;
1416     m_bWaitForUser    = sal_False;
1417     return 0;
1418 }
1419 
1420 //===============================================
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 //===============================================
1434 void RecoveryDialog::impl_refreshDocList()
1435 {
1436 }
1437 
1438 //===============================================
1439 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 //===============================================
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 //===============================================
1499 BrokenRecoveryDialog::~BrokenRecoveryDialog()
1500 {
1501 }
1502 
1503 //===============================================
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 //===============================================
1540 sal_Bool BrokenRecoveryDialog::isExecutionNeeded()
1541 {
1542     return m_bExecutionNeeded;
1543 }
1544 
1545 //===============================================
1546 ::rtl::OUString BrokenRecoveryDialog::getSaveDirURL()
1547 {
1548     return m_sSavePath;
1549 }
1550 
1551 //===============================================
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 //===============================================
1566 IMPL_LINK( BrokenRecoveryDialog, CancelButtonHdl, void*, EMPTYARG )
1567 {
1568     EndDialog(DLG_RET_CANCEL);
1569     return 0;
1570 }
1571 
1572 //===============================================
1573 IMPL_LINK( BrokenRecoveryDialog, SaveButtonHdl, void*, EMPTYARG )
1574 {
1575     impl_askForSavePath();
1576     return 0;
1577 }
1578 
1579 //===============================================
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 
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 
1633 		ErrorRepWelcomeDialog::~ErrorRepWelcomeDialog()
1634 		{
1635 		}
1636 
1637 		IMPL_LINK( ErrorRepWelcomeDialog, PrevBtnHdl, void*, EMPTYARG )
1638 		{
1639 			m_nResult = DLG_RET_BACK;
1640 			return 0;
1641 		}
1642 
1643 		IMPL_LINK( ErrorRepWelcomeDialog, NextBtnHdl, void*, EMPTYARG )
1644 		{
1645 			m_nResult = DLG_RET_OK;
1646 			return 0;
1647 		}
1648 
1649 		IMPL_LINK( ErrorRepWelcomeDialog, CancelBtnHdl, void*, EMPTYARG )
1650 		{
1651 			m_nResult = DLG_RET_CANCEL;
1652 			return 0;
1653 		}
1654 
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 
1665         void ErrorRepWelcomeDialog::setDefButton()
1666         {
1667             maNextBtn.GrabFocus();
1668         }
1669 
1670 	///////////////////////////////////////////////////////////////////////
1671     // Error Report Send Dialog and its MultiLineEdit
1672 	///////////////////////////////////////////////////////////////////////
1673 
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 
1684         ErrorDescriptionEdit::~ErrorDescriptionEdit()
1685         {
1686         }
1687 
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 
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 
1761 		ErrorRepSendDialog::~ErrorRepSendDialog()
1762 		{
1763 		}
1764 
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 
1775         void ErrorRepSendDialog::setDefButton()
1776         {
1777             // set first focus
1778             maDocTypeED.GrabFocus();
1779         }
1780 
1781 		IMPL_LINK( ErrorRepSendDialog, PrevBtnHdl, void*, EMPTYARG )
1782 		{
1783 			m_nResult = DLG_RET_BACK;
1784 			return 0;
1785 		}
1786 
1787 		IMPL_LINK( ErrorRepSendDialog, CancelBtnHdl, void*, EMPTYARG )
1788 		{
1789 			m_nResult = DLG_RET_CANCEL;
1790 			return 0;
1791 		}
1792 
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 
1803 		IMPL_LINK( ErrorRepSendDialog, ShowRepBtnHdl, void*, EMPTYARG )
1804 		{
1805             ErrorRepPreviewDialog aDlg( this );
1806 			aDlg.Execute();
1807 			return 0;
1808 		}
1809 
1810 		IMPL_LINK( ErrorRepSendDialog, OptBtnHdl, void*, EMPTYARG )
1811 		{
1812             ErrorRepOptionsDialog aDlg( this, maParams );
1813 			aDlg.Execute();
1814 			return 0;
1815 		}
1816 
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 
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 
1873 		String ErrorRepSendDialog::GetDocType( void ) const
1874 		{
1875 			return maDocTypeED.GetText();
1876 		}
1877 
1878 		String ErrorRepSendDialog::GetUsing( void ) const
1879 		{
1880 			return maUsingML.GetText();
1881 		}
1882 
1883 		bool ErrorRepSendDialog::IsContactAllowed( void ) const
1884 		{
1885 			return maContactCB.IsChecked();
1886 		}
1887 
1888 		String ErrorRepSendDialog::GetEMailAddress( void ) const
1889 		{
1890 			return maEMailAddrED.GetText();
1891 		}
1892 
1893 
1894 	///////////////////////////////////////////////////////////////////////
1895 	// Error Report Options Dialog
1896 	///////////////////////////////////////////////////////////////////////
1897 
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 
1963 		ErrorRepOptionsDialog::~ErrorRepOptionsDialog()
1964 		{
1965 		}
1966 
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 
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 
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 
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 
2022         ErrorRepEdit::~ErrorRepEdit()
2023         {
2024         }
2025 
2026 	///////////////////////////////////////////////////////////////////////
2027 	// Error Report Preview Dialog
2028 	///////////////////////////////////////////////////////////////////////
2029 
2030 
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 
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 
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 
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 
2155         ErrorRepPreviewDialog::~ErrorRepPreviewDialog()
2156         {
2157         }
2158 
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