1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_folders.h>
22 #include <sal/macros.h>
24 #include <svx/dialmgr.hxx>
25 #include <svx/dialogs.hrc>
26 #include "docrecovery.hxx"
27 #include "docrecovery.hrc"
29 #include <comphelper/processfactory.hxx>
30 #include <comphelper/sequenceashashmap.hxx>
31 #include <comphelper/string.hxx>
32 #include <svtools/imagemgr.hxx>
33 #include <vcl/xtextedt.hxx>
34 #include <vcl/settings.hxx>
35 #include <tools/urlobj.hxx>
36 #include <vcl/msgbox.hxx>
37 #include <vcl/svapp.hxx>
38 #include <rtl/ustrbuf.hxx>
39 #include <vcl/scrbar.hxx>
41 #include <toolkit/helper/vclunohelper.hxx>
43 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
44 #include <com/sun/star/lang/XInitialization.hpp>
45 #include <com/sun/star/beans/NamedValue.hpp>
46 #include <com/sun/star/util/URL.hpp>
47 #include <com/sun/star/util/XURLTransformer.hpp>
48 #include <com/sun/star/frame/theAutoRecovery.hpp>
49 #include <com/sun/star/frame/XDispatch.hpp>
50 #include <com/sun/star/awt/XWindow.hpp>
51 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
52 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
53 #include <com/sun/star/util/URLTransformer.hpp>
54 #include <osl/file.hxx>
55 #include <osl/security.hxx>
56 #include <rtl/bootstrap.hxx>
57 #include <unotools/pathoptions.hxx>
58 #include <unotools/localfilehelper.hxx>
59 #include "svtools/treelistentry.hxx"
60 #include <officecfg/Office/Recovery.hxx>
63 namespace DocRecovery
{
65 using namespace ::rtl
;
66 using namespace ::osl
;
69 TabDialog4Recovery::TabDialog4Recovery(Window
* pParent
)
70 : TabDialog (pParent
, SVX_RES( RID_SVX_TABDLG_DOCRECOVERY
))
71 , m_pActualPage(m_lTabPages
.begin() )
76 TabDialog4Recovery::~TabDialog4Recovery()
82 void TabDialog4Recovery::addTabPage(IExtendedTabPage
* pPage
)
85 m_lTabPages
.push_back(pPage
);
89 short TabDialog4Recovery::Execute()
91 ::SolarMutexGuard aLock
;
94 m_pActualPage
= m_lTabPages
.begin();
97 IExtendedTabPage
* pPage
= *m_pActualPage
;
100 pPage
->setDefButton();
101 short nRet
= pPage
->execute();
109 if (m_pActualPage
== m_lTabPages
.end())
116 if (m_pActualPage
!= m_lTabPages
.begin())
121 case DLG_RET_UNKNOWN
:
122 case DLG_RET_CANCEL
:
123 case DLG_RET_OK_AUTOLUNCH
:
130 RecoveryCore::RecoveryCore(const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
132 : m_xContext ( rxContext
)
134 , m_bListenForSaving(bUsedForSaving
)
136 impl_startListening();
140 RecoveryCore::~RecoveryCore()
142 impl_stopListening();
146 css::uno::Reference
< css::uno::XComponentContext
> RecoveryCore::getComponentContext()
152 TURLList
* RecoveryCore::getURLListAccess()
158 bool RecoveryCore::isBrokenTempEntry(const TURLInfo
& rInfo
)
160 if (rInfo
.TempURL
.isEmpty())
163 // Note: If the original files was recovery ... but a temp file
164 // exists ... an error inside the temp file exists!
166 !(rInfo
.RecoveryState
== E_RECOVERY_FAILED
) &&
167 !(rInfo
.RecoveryState
== E_ORIGINAL_DOCUMENT_RECOVERED
)
175 void RecoveryCore::saveBrokenTempEntries(const OUString
& rPath
)
180 if (!m_xRealCore
.is())
183 // prepare all needed parameters for the following dispatch() request.
184 css::util::URL aCopyURL
= impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP
);
185 css::uno::Sequence
< css::beans::PropertyValue
> lCopyArgs(3);
186 lCopyArgs
[0].Name
= PROP_DISPATCHASYNCHRON
;
187 lCopyArgs
[0].Value
<<= sal_False
;
188 lCopyArgs
[1].Name
= PROP_SAVEPATH
;
189 lCopyArgs
[1].Value
<<= rPath
;
190 lCopyArgs
[2].Name
= PROP_ENTRYID
;
191 // lCopyArgs[2].Value will be changed during next loop ...
193 // work on a copied list only ...
194 // Reason: We will get notifications from the core for every
195 // changed or removed element. And that will change our m_lURLs list.
196 // That's not a good idea, if we use a stl iterator inbetween .-)
197 TURLList lURLs
= m_lURLs
;
198 TURLList::const_iterator pIt
;
199 for ( pIt
= lURLs
.begin();
203 const TURLInfo
& rInfo
= *pIt
;
204 if (!RecoveryCore::isBrokenTempEntry(rInfo
))
207 lCopyArgs
[2].Value
<<= rInfo
.ID
;
208 m_xRealCore
->dispatch(aCopyURL
, lCopyArgs
);
213 void RecoveryCore::saveAllTempEntries(const OUString
& rPath
)
218 if (!m_xRealCore
.is())
221 // prepare all needed parameters for the following dispatch() request.
222 css::util::URL aCopyURL
= impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP
);
223 css::uno::Sequence
< css::beans::PropertyValue
> lCopyArgs(3);
224 lCopyArgs
[0].Name
= PROP_DISPATCHASYNCHRON
;
225 lCopyArgs
[0].Value
<<= sal_False
;
226 lCopyArgs
[1].Name
= PROP_SAVEPATH
;
227 lCopyArgs
[1].Value
<<= rPath
;
228 lCopyArgs
[2].Name
= PROP_ENTRYID
;
229 // lCopyArgs[2].Value will be changed during next loop ...
231 // work on a copied list only ...
232 // Reason: We will get notifications from the core for every
233 // changed or removed element. And that will change our m_lURLs list.
234 // That's not a good idea, if we use a stl iterator inbetween .-)
235 TURLList lURLs
= m_lURLs
;
236 TURLList::const_iterator pIt
;
237 for ( pIt
= lURLs
.begin();
241 const TURLInfo
& rInfo
= *pIt
;
242 if (rInfo
.TempURL
.isEmpty())
245 lCopyArgs
[2].Value
<<= rInfo
.ID
;
246 m_xRealCore
->dispatch(aCopyURL
, lCopyArgs
);
251 void RecoveryCore::forgetBrokenTempEntries()
253 if (!m_xRealCore
.is())
256 css::util::URL aRemoveURL
= impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP
);
257 css::uno::Sequence
< css::beans::PropertyValue
> lRemoveArgs(2);
258 lRemoveArgs
[0].Name
= PROP_DISPATCHASYNCHRON
;
259 lRemoveArgs
[0].Value
<<= sal_False
;
260 lRemoveArgs
[1].Name
= PROP_ENTRYID
;
261 // lRemoveArgs[1].Value will be changed during next loop ...
263 // work on a copied list only ...
264 // Reason: We will get notifications from the core for every
265 // changed or removed element. And that will change our m_lURLs list.
266 // That's not a good idea, if we use a stl iterator inbetween .-)
267 TURLList lURLs
= m_lURLs
;
268 TURLList::const_iterator pIt
;
269 for ( pIt
= lURLs
.begin();
273 const TURLInfo
& rInfo
= *pIt
;
274 if (!RecoveryCore::isBrokenTempEntry(rInfo
))
277 lRemoveArgs
[1].Value
<<= rInfo
.ID
;
278 m_xRealCore
->dispatch(aRemoveURL
, lRemoveArgs
);
283 void RecoveryCore::forgetAllRecoveryEntries()
285 if (!m_xRealCore
.is())
288 css::util::URL aRemoveURL
= impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP
);
289 css::uno::Sequence
< css::beans::PropertyValue
> lRemoveArgs(2);
290 lRemoveArgs
[0].Name
= PROP_DISPATCHASYNCHRON
;
291 lRemoveArgs
[0].Value
<<= sal_False
;
292 lRemoveArgs
[1].Name
= PROP_ENTRYID
;
293 // lRemoveArgs[1].Value will be changed during next loop ...
295 // work on a copied list only ...
296 // Reason: We will get notifications from the core for every
297 // changed or removed element. And that will change our m_lURLs list.
298 // That's not a good idea, if we use a stl iterator inbetween .-)
299 TURLList lURLs
= m_lURLs
;
300 TURLList::const_iterator pIt
;
301 for ( pIt
= lURLs
.begin();
305 const TURLInfo
& rInfo
= *pIt
;
306 lRemoveArgs
[1].Value
<<= rInfo
.ID
;
307 m_xRealCore
->dispatch(aRemoveURL
, lRemoveArgs
);
312 void RecoveryCore::forgetBrokenRecoveryEntries()
314 if (!m_xRealCore
.is())
317 css::util::URL aRemoveURL
= impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP
);
318 css::uno::Sequence
< css::beans::PropertyValue
> lRemoveArgs(2);
319 lRemoveArgs
[0].Name
= PROP_DISPATCHASYNCHRON
;
320 lRemoveArgs
[0].Value
<<= sal_False
;
321 lRemoveArgs
[1].Name
= PROP_ENTRYID
;
322 // lRemoveArgs[1].Value will be changed during next loop ...
324 // work on a copied list only ...
325 // Reason: We will get notifications from the core for every
326 // changed or removed element. And that will change our m_lURLs list.
327 // That's not a good idea, if we use a stl iterator inbetween .-)
328 TURLList lURLs
= m_lURLs
;
329 TURLList::const_iterator pIt
;
330 for ( pIt
= lURLs
.begin();
334 const TURLInfo
& rInfo
= *pIt
;
335 if (!RecoveryCore::isBrokenTempEntry(rInfo
))
338 lRemoveArgs
[1].Value
<<= rInfo
.ID
;
339 m_xRealCore
->dispatch(aRemoveURL
, lRemoveArgs
);
344 void RecoveryCore::setProgressHandler(const css::uno::Reference
< css::task::XStatusIndicator
>& xProgress
)
346 m_xProgress
= xProgress
;
350 void RecoveryCore::setUpdateListener(IRecoveryUpdateListener
* pListener
)
352 m_pListener
= pListener
;
356 void RecoveryCore::doEmergencySavePrepare()
358 if (!m_xRealCore
.is())
361 css::util::URL aURL
= impl_getParsedURL(RECOVERY_CMD_DO_PREPARE_EMERGENCY_SAVE
);
363 css::uno::Sequence
< css::beans::PropertyValue
> lArgs(1);
364 lArgs
[0].Name
= PROP_DISPATCHASYNCHRON
;
365 lArgs
[0].Value
<<= sal_False
;
367 m_xRealCore
->dispatch(aURL
, lArgs
);
371 void RecoveryCore::doEmergencySave()
373 if (!m_xRealCore
.is())
376 css::util::URL aURL
= impl_getParsedURL(RECOVERY_CMD_DO_EMERGENCY_SAVE
);
378 css::uno::Sequence
< css::beans::PropertyValue
> lArgs(2);
379 lArgs
[0].Name
= PROP_STATUSINDICATOR
;
380 lArgs
[0].Value
<<= m_xProgress
;
381 lArgs
[1].Name
= PROP_DISPATCHASYNCHRON
;
382 lArgs
[1].Value
<<= sal_True
;
384 m_xRealCore
->dispatch(aURL
, lArgs
);
388 void RecoveryCore::doRecovery()
390 if (!m_xRealCore
.is())
393 css::util::URL aURL
= impl_getParsedURL(RECOVERY_CMD_DO_RECOVERY
);
395 css::uno::Sequence
< css::beans::PropertyValue
> lArgs(2);
396 lArgs
[0].Name
= PROP_STATUSINDICATOR
;
397 lArgs
[0].Value
<<= m_xProgress
;
398 lArgs
[1].Name
= PROP_DISPATCHASYNCHRON
;
399 lArgs
[1].Value
<<= sal_True
;
401 m_xRealCore
->dispatch(aURL
, lArgs
);
405 ERecoveryState
RecoveryCore::mapDocState2RecoverState(sal_Int32 eDocState
)
408 ERecoveryState eRecState
= E_NOT_RECOVERED_YET
;
411 Some of the following states can occur at the
412 same time. So we have to check for the "worst case" first!
414 DAMAGED -> INCOMPLETE -> HANDLED
419 ((eDocState
& E_TRY_LOAD_BACKUP
) == E_TRY_LOAD_BACKUP
) ||
420 ((eDocState
& E_TRY_LOAD_ORIGINAL
) == E_TRY_LOAD_ORIGINAL
)
422 eRecState
= E_RECOVERY_IS_IN_PROGRESS
;
424 else if ((eDocState
& E_DAMAGED
) == E_DAMAGED
)
425 eRecState
= E_RECOVERY_FAILED
;
427 else if ((eDocState
& E_INCOMPLETE
) == E_INCOMPLETE
)
428 eRecState
= E_ORIGINAL_DOCUMENT_RECOVERED
;
430 else if ((eDocState
& E_SUCCEDED
) == E_SUCCEDED
)
431 eRecState
= E_SUCCESSFULLY_RECOVERED
;
437 void SAL_CALL
RecoveryCore::statusChanged(const css::frame::FeatureStateEvent
& aEvent
)
438 throw(css::uno::RuntimeException
, std::exception
)
440 // a) special notification about start/stop async dispatch!
441 // FeatureDescriptor = "start" || "stop"
442 if (aEvent
.FeatureDescriptor
.equals(RECOVERY_OPERATIONSTATE_START
))
445 m_pListener
->start();
449 if (aEvent
.FeatureDescriptor
.equals(RECOVERY_OPERATIONSTATE_STOP
))
456 // b) normal notification about changed items
457 // FeatureDescriptor = "Update"
458 // State = Lits of information [seq< NamedValue >]
459 if (! aEvent
.FeatureDescriptor
.equals(RECOVERY_OPERATIONSTATE_UPDATE
))
462 ::comphelper::SequenceAsHashMap
lInfo(aEvent
.State
);
465 aNew
.ID
= lInfo
.getUnpackedValueOrDefault(STATEPROP_ID
, (sal_Int32
)0 );
466 aNew
.DocState
= lInfo
.getUnpackedValueOrDefault(STATEPROP_STATE
, (sal_Int32
)0 );
467 aNew
.OrgURL
= lInfo
.getUnpackedValueOrDefault(STATEPROP_ORGURL
, OUString());
468 aNew
.TempURL
= lInfo
.getUnpackedValueOrDefault(STATEPROP_TEMPURL
, OUString());
469 aNew
.FactoryURL
= lInfo
.getUnpackedValueOrDefault(STATEPROP_FACTORYURL
, OUString());
470 aNew
.TemplateURL
= lInfo
.getUnpackedValueOrDefault(STATEPROP_TEMPLATEURL
, OUString());
471 aNew
.DisplayName
= lInfo
.getUnpackedValueOrDefault(STATEPROP_TITLE
, OUString());
472 aNew
.Module
= lInfo
.getUnpackedValueOrDefault(STATEPROP_MODULE
, OUString());
474 // search for already existing items and update her nState value ...
475 TURLList::iterator pIt
;
476 for ( pIt
= m_lURLs
.begin();
477 pIt
!= m_lURLs
.end() ;
480 TURLInfo
& aOld
= *pIt
;
481 if (aOld
.ID
== aNew
.ID
)
484 aOld
.DocState
= aNew
.DocState
;
485 aOld
.RecoveryState
= RecoveryCore::mapDocState2RecoverState(aOld
.DocState
);
488 m_pListener
->updateItems();
489 m_pListener
->stepNext(&aOld
);
496 // TODO think about mmatching Module name to a corresponding icon
497 OUString sURL
= aNew
.OrgURL
;
499 sURL
= aNew
.FactoryURL
;
503 sURL
= aNew
.TemplateURL
;
504 INetURLObject
aURL(sURL
);
505 aNew
.StandardImage
= SvFileInformationManager::GetFileImage(aURL
, false);
507 /* set the right UI state for this item to NOT_RECOVERED_YET ... because nDocState shows the state of
508 the last emergency save operation before and is interessting for the used recovery core service only ...
509 for now! But if there is a further notification for this item (see lines above!) we must
510 map the doc state to an UI state. */
511 aNew
.RecoveryState
= E_NOT_RECOVERED_YET
;
513 // patch DisplayName! Because the document title contain more then the file name ...
514 sal_Int32 i
= aNew
.DisplayName
.indexOf(" - ");
516 aNew
.DisplayName
= aNew
.DisplayName
.copy(0, i
);
518 m_lURLs
.push_back(aNew
);
521 m_pListener
->updateItems();
525 void SAL_CALL
RecoveryCore::disposing(const css::lang::EventObject
& /*aEvent*/)
526 throw(css::uno::RuntimeException
, std::exception
)
532 void RecoveryCore::impl_startListening()
534 // listening already initialized ?
535 if (m_xRealCore
.is())
537 m_xRealCore
= css::frame::theAutoRecovery::get(m_xContext
);
540 if (m_bListenForSaving
)
541 aURL
.Complete
= RECOVERY_CMD_DO_EMERGENCY_SAVE
;
543 aURL
.Complete
= RECOVERY_CMD_DO_RECOVERY
;
544 css::uno::Reference
< css::util::XURLTransformer
> xParser(css::util::URLTransformer::create(m_xContext
));
545 xParser
->parseStrict(aURL
);
547 /* Note: addStatusListener() call us synchronous back ... so we
548 will get the complete list of currently open documents! */
549 m_xRealCore
->addStatusListener(static_cast< css::frame::XStatusListener
* >(this), aURL
);
553 void RecoveryCore::impl_stopListening()
555 // Ignore it, if this instance doesn't listen currently
556 if (!m_xRealCore
.is())
560 if (m_bListenForSaving
)
561 aURL
.Complete
= RECOVERY_CMD_DO_EMERGENCY_SAVE
;
563 aURL
.Complete
= RECOVERY_CMD_DO_RECOVERY
;
564 css::uno::Reference
< css::util::XURLTransformer
> xParser(css::util::URLTransformer::create(m_xContext
));
565 xParser
->parseStrict(aURL
);
567 m_xRealCore
->removeStatusListener(static_cast< css::frame::XStatusListener
* >(this), aURL
);
572 css::util::URL
RecoveryCore::impl_getParsedURL(const OUString
& sURL
)
575 aURL
.Complete
= sURL
;
577 css::uno::Reference
< css::util::XURLTransformer
> xParser(css::util::URLTransformer::create(m_xContext
));
578 xParser
->parseStrict(aURL
);
584 PluginProgressWindow::PluginProgressWindow( Window
* pParent
,
585 const css::uno::Reference
< css::lang::XComponent
>& xProgress
)
587 , m_xProgress(xProgress
)
590 Size aParentSize
= pParent
->GetSizePixel();
591 // align the progressbar to its parent
592 setPosSizePixel( -9, 0, aParentSize
.Width() + 15, aParentSize
.Height() - 4 );
596 PluginProgressWindow::~PluginProgressWindow()
598 if (m_xProgress
.is())
599 m_xProgress
->dispose();
603 PluginProgress::PluginProgress( Window
* pParent
,
604 const css::uno::Reference
< css::uno::XComponentContext
>& xContext
)
606 m_pPlugProgressWindow
= new PluginProgressWindow(pParent
, static_cast< css::lang::XComponent
* >(this));
607 css::uno::Reference
< css::awt::XWindow
> xProgressWindow
= VCLUnoHelper::GetInterface(m_pPlugProgressWindow
);
608 m_xProgressFactory
= css::task::StatusIndicatorFactory::createWithWindow(xContext
, xProgressWindow
, sal_False
/*DisableReschedule*/, sal_True
/*AllowParentShow*/);
609 m_xProgress
= m_xProgressFactory
->createStatusIndicator();
613 PluginProgress::~PluginProgress()
618 void SAL_CALL
PluginProgress::dispose()
619 throw(css::uno::RuntimeException
, std::exception
)
621 // m_pPluginProgressWindow was deleted ...
622 // So the internal pointer of this progress
628 void SAL_CALL
PluginProgress::addEventListener(const css::uno::Reference
< css::lang::XEventListener
>& )
629 throw(css::uno::RuntimeException
, std::exception
)
634 void SAL_CALL
PluginProgress::removeEventListener( const css::uno::Reference
< css::lang::XEventListener
>& )
635 throw(css::uno::RuntimeException
, std::exception
)
640 void SAL_CALL
PluginProgress::start(const OUString
&,
642 throw(css::uno::RuntimeException
, std::exception
)
644 if (m_xProgress
.is())
645 m_xProgress
->start(OUString(), nRange
);
649 void SAL_CALL
PluginProgress::end()
650 throw(css::uno::RuntimeException
, std::exception
)
652 if (m_xProgress
.is())
657 void SAL_CALL
PluginProgress::setText(const OUString
& sText
)
658 throw(css::uno::RuntimeException
, std::exception
)
660 if (m_xProgress
.is())
661 m_xProgress
->setText(sText
);
665 void SAL_CALL
PluginProgress::setValue(sal_Int32 nValue
)
666 throw(css::uno::RuntimeException
, std::exception
)
668 if (m_xProgress
.is())
669 m_xProgress
->setValue(nValue
);
673 void SAL_CALL
PluginProgress::reset()
674 throw(css::uno::RuntimeException
, std::exception
)
676 if (m_xProgress
.is())
677 m_xProgress
->reset();
681 SaveDialog::SaveDialog(Window
* pParent
,
682 RecoveryCore
* pCore
)
683 : IExtendedTabPage( pParent
, SVX_RES( RID_SVXPAGE_DOCRECOVERY_SAVE
) )
684 , m_aTitleFT ( this , SVX_RES ( FT_SAVE_TITLE
) )
685 , m_aTitleWin ( this , SVX_RES ( WIN_SAVE_TITLE
) )
686 , m_aTitleFL ( this , SVX_RES ( FL_SAVE_TITLE
) )
687 , m_aDescrFT ( this , SVX_RES ( FT_SAVE_DESCR
) )
688 , m_aFileListFT ( this , SVX_RES ( FT_SAVE_FILELIST
) )
689 , m_aFileListLB ( this , SVX_RES ( LB_SAVE_FILELIST
) )
690 , m_aBottomFL ( this , SVX_RES ( FL_SAVE_BOTTOM
) )
691 , m_aOkBtn ( this , SVX_RES ( BT_SAVE_OK
) )
696 // Prepare the office for the following crash save step.
697 // E.g. hide all open widows so the user can't influence our
699 m_pCore
->doEmergencySavePrepare();
701 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
702 Wallpaper
aBackground(rStyleSettings
.GetWindowColor());
703 m_aTitleWin
.SetBackground(aBackground
);
704 m_aTitleFT
.SetBackground (aBackground
);
706 Font
aFont(m_aTitleFT
.GetFont());
707 aFont
.SetWeight(WEIGHT_BOLD
);
708 m_aTitleFT
.SetFont(aFont
);
710 m_aOkBtn
.SetClickHdl( LINK( this, SaveDialog
, OKButtonHdl
) );
711 m_aFileListLB
.SetControlBackground( rStyleSettings
.GetDialogColor() );
713 // fill listbox with current open documents
714 m_aFileListLB
.Clear();
716 TURLList
* pURLs
= m_pCore
->getURLListAccess();
717 TURLList::const_iterator pIt
;
719 for ( pIt
= pURLs
->begin();
720 pIt
!= pURLs
->end() ;
723 const TURLInfo
& rInfo
= *pIt
;
724 m_aFileListLB
.InsertEntry( rInfo
.DisplayName
, rInfo
.StandardImage
);
729 SaveDialog::~SaveDialog()
734 IMPL_LINK_NOARG(SaveDialog
, OKButtonHdl
)
736 m_nResult
= DLG_RET_OK
;
741 short SaveDialog::execute()
743 ::SolarMutexGuard aLock
;
745 // wait for user input "OK"
746 m_nResult
= DLG_RET_UNKNOWN
;
747 while(m_nResult
== DLG_RET_UNKNOWN
)
748 Application::Yield();
750 // start crash-save with progress
751 if (m_nResult
== DLG_RET_OK
)
753 SaveProgressDialog
* pProgress
= new SaveProgressDialog(this, m_pCore
);
754 m_nResult
= pProgress
->Execute();
757 // if "CANCEL" => return "CANCEL"
758 // if "OK" => "AUTOLUNCH" always !
759 if (m_nResult
== DLG_RET_OK
)
760 m_nResult
= DLG_RET_OK_AUTOLUNCH
;
766 void SaveDialog::setDefButton()
768 m_aOkBtn
.GrabFocus();
772 SaveProgressDialog::SaveProgressDialog(Window
* pParent
,
773 RecoveryCore
* pCore
)
774 : ModalDialog ( pParent
, SVX_RES( RID_SVX_MDLG_DOCRECOVERY_PROGR
) )
775 , m_aHintFT ( this , SVX_RES ( FT_SAVEPROGR_HINT
) )
776 , m_aProgrFT ( this , SVX_RES ( FT_SAVEPROGR_PROGR
) )
777 , m_aProgrParent( this , SVX_RES ( WIN_SAVEPROGR_PROGR
) )
781 PluginProgress
* pProgress
= new PluginProgress( &m_aProgrParent
, pCore
->getComponentContext() );
782 m_xProgress
= css::uno::Reference
< css::task::XStatusIndicator
>(static_cast< css::task::XStatusIndicator
* >(pProgress
), css::uno::UNO_QUERY_THROW
);
786 SaveProgressDialog::~SaveProgressDialog()
791 short SaveProgressDialog::Execute()
793 ::SolarMutexGuard aLock
;
795 m_pCore
->setProgressHandler(m_xProgress
);
796 m_pCore
->setUpdateListener(this);
797 m_pCore
->doEmergencySave();
798 short nRet
= ModalDialog::Execute();
799 m_pCore
->setUpdateListener(0);
804 void SaveProgressDialog::updateItems()
809 void SaveProgressDialog::stepNext(TURLInfo
* )
813 wenn die m_pCore noch ein Member m_nCurrentItem haette
814 koennte man dort erkennen, wer gerade drann war, wer demnaechst
815 dran ist ... Diese Info kann man dann in unserem Progress FixText anzeigen ...
820 void SaveProgressDialog::start()
825 void SaveProgressDialog::end()
827 EndDialog(DLG_RET_OK
);
831 RecovDocListEntry::RecovDocListEntry( SvTreeListEntry
* pEntry
,
833 const OUString
& sText
)
834 : SvLBoxString( pEntry
, nFlags
, sText
)
839 void RecovDocListEntry::Paint(
840 const Point
& aPos
, SvTreeListBox
& aDevice
, const SvViewDataEntry
* /*pView*/, const SvTreeListEntry
* pEntry
)
842 const Image
* pImg
= 0;
843 const OUString
* pTxt
= 0;
844 RecovDocList
* pList
= static_cast< RecovDocList
* >(&aDevice
);
846 TURLInfo
* pInfo
= (TURLInfo
*)pEntry
->GetUserData();
847 switch(pInfo
->RecoveryState
)
849 case E_SUCCESSFULLY_RECOVERED
:
851 pImg
= &pList
->m_aGreenCheckImg
;
852 pTxt
= &pList
->m_aSuccessRecovStr
;
856 case E_ORIGINAL_DOCUMENT_RECOVERED
: // TODO must be renamed into ORIGINAL DOCUMENT recovered! Because its marked as yellow
858 pImg
= &pList
->m_aYellowCheckImg
;
859 pTxt
= &pList
->m_aOrigDocRecovStr
;
863 case E_RECOVERY_FAILED
:
865 pImg
= &pList
->m_aRedCrossImg
;
866 pTxt
= &pList
->m_aRecovFailedStr
;
870 case E_RECOVERY_IS_IN_PROGRESS
:
873 pTxt
= &pList
->m_aRecovInProgrStr
;
877 case E_NOT_RECOVERED_YET
:
880 pTxt
= &pList
->m_aNotRecovYetStr
;
886 aDevice
.DrawImage(aPos
, *pImg
);
891 aPnt
.X() += pList
->m_aGreenCheckImg
.GetSizePixel().Width();
893 aDevice
.DrawText(aPnt
, *pTxt
);
897 RecovDocList::RecovDocList(SvSimpleTableContainer
& rParent
, ResMgr
&rResMgr
)
898 : SvSimpleTable ( rParent
)
899 , m_aGreenCheckImg ( ResId(IMG_GREENCHECK
, rResMgr
) )
900 , m_aYellowCheckImg ( ResId(IMG_YELLOWCHECK
, rResMgr
) )
901 , m_aRedCrossImg ( ResId(IMG_REDCROSS
, rResMgr
) )
902 , m_aSuccessRecovStr ( ResId(STR_SUCCESSRECOV
, rResMgr
) )
903 , m_aOrigDocRecovStr ( ResId(STR_ORIGDOCRECOV
, rResMgr
) )
904 , m_aRecovFailedStr ( ResId(STR_RECOVFAILED
, rResMgr
) )
905 , m_aRecovInProgrStr ( ResId(STR_RECOVINPROGR
, rResMgr
) )
906 , m_aNotRecovYetStr ( ResId(STR_NOTRECOVYET
, rResMgr
) )
911 RecovDocList::~RecovDocList()
916 void RecovDocList::InitEntry(SvTreeListEntry
* pEntry
,
917 const OUString
& rText
,
918 const Image
& rImage1
,
919 const Image
& rImage2
,
920 SvLBoxButtonKind eButtonKind
)
922 SvTabListBox::InitEntry(pEntry
, rText
, rImage1
, rImage2
, eButtonKind
);
923 DBG_ASSERT( TabCount() == 2, "*RecovDocList::InitEntry(): structure missmatch" );
925 SvLBoxString
* pCol
= (SvLBoxString
*)pEntry
->GetItem(2);
926 RecovDocListEntry
* p
= new RecovDocListEntry(pEntry
, 0, pCol
->GetText());
927 pEntry
->ReplaceItem(p
, 2);
931 short impl_askUserForWizardCancel(Window
* pParent
, sal_Int16 nRes
)
933 QueryBox
aQuery(pParent
, SVX_RES(nRes
));
934 if (aQuery
.Execute() == RET_YES
)
937 return DLG_RET_CANCEL
;
941 RecoveryDialog::RecoveryDialog(Window
* pParent
,
942 RecoveryCore
* pCore
)
943 : IExtendedTabPage( pParent
, SVX_RES( RID_SVXPAGE_DOCRECOVERY_RECOVER
) )
944 , m_aTitleFT ( this , SVX_RES ( FT_RECOV_TITLE
) )
945 , m_aTitleWin ( this , SVX_RES ( WIN_RECOV_TITLE
) )
946 , m_aTitleFL ( this , SVX_RES ( FL_RECOV_TITLE
) )
947 , m_aDescrFT ( this , SVX_RES ( FT_RECOV_DESCR
) )
948 , m_aProgressFT ( this , SVX_RES ( FT_RECOV_PROGR
) )
949 , m_aProgrParent ( this , SVX_RES ( WIN_RECOV_PROGR
) )
950 , m_aFileListFT ( this , SVX_RES ( FT_RECOV_FILELIST
) )
951 , m_aFileListLBContainer( this , SVX_RES ( LB_RECOV_FILELIST
) )
952 , m_aFileListLB (m_aFileListLBContainer
, DIALOG_MGR())
953 , m_aBottomFL ( this , SVX_RES ( FL_RECOV_BOTTOM
) )
954 , m_aNextBtn ( this , SVX_RES ( BTN_RECOV_NEXT
) )
955 , m_aCancelBtn ( this , SVX_RES ( BTN_RECOV_CANCEL
) )
956 , m_aTitleRecoveryInProgress(SVX_RESSTR(STR_RECOVERY_INPROGRESS
))
957 , m_aRecoveryOnlyFinish (SVX_RESSTR(STR_RECOVERYONLY_FINISH
))
958 , m_aRecoveryOnlyFinishDescr(SVX_RESSTR(STR_RECOVERYONLY_FINISH_DESCR
))
959 , m_pDefButton ( NULL
)
961 , m_eRecoveryState (RecoveryDialog::E_RECOVERY_PREPARED
)
962 , m_bWaitForUser (false)
963 , m_bWaitForCore (false)
964 , m_bUserDecideNext (false)
965 , m_bWasRecoveryStarted (false)
967 static long nTabs
[] = { 2, 0, 40*RECOV_CONTROLWIDTH
/100 };
968 m_aFileListLB
.SetTabs( &nTabs
[0] );
969 m_aFileListLB
.InsertHeaderEntry(SVX_RESSTR(STR_HEADERBAR
));
973 PluginProgress
* pProgress
= new PluginProgress( &m_aProgrParent
, pCore
->getComponentContext() );
974 m_xProgress
= css::uno::Reference
< css::task::XStatusIndicator
>(static_cast< css::task::XStatusIndicator
* >(pProgress
), css::uno::UNO_QUERY_THROW
);
976 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
977 Wallpaper
aBackground( rStyleSettings
.GetWindowColor() );
978 m_aTitleWin
.SetBackground(aBackground
);
979 m_aTitleFT
.SetBackground (aBackground
);
981 Font
aFont(m_aTitleFT
.GetFont());
982 aFont
.SetWeight(WEIGHT_BOLD
);
983 m_aTitleFT
.SetFont(aFont
);
985 m_aFileListLB
.SetBackground( rStyleSettings
.GetDialogColor() );
987 m_aNextBtn
.Enable(true);
988 m_aNextBtn
.SetClickHdl( LINK( this, RecoveryDialog
, NextButtonHdl
) );
989 m_aCancelBtn
.SetClickHdl( LINK( this, RecoveryDialog
, CancelButtonHdl
) );
991 // fill list box first time
992 TURLList
* pURLList
= m_pCore
->getURLListAccess();
993 TURLList::const_iterator pIt
;
994 for ( pIt
= pURLList
->begin();
995 pIt
!= pURLList
->end() ;
998 const TURLInfo
& rInfo
= *pIt
;
1000 OUString
sName( rInfo
.DisplayName
);
1002 sName
+= impl_getStatusString( rInfo
);
1003 SvTreeListEntry
* pEntry
= m_aFileListLB
.InsertEntry(sName
, rInfo
.StandardImage
, rInfo
.StandardImage
);
1004 pEntry
->SetUserData((void*)&rInfo
);
1008 SvTreeListEntry
* pFirst
= m_aFileListLB
.First();
1010 m_aFileListLB
.SetCursor(pFirst
, true);
1014 RecoveryDialog::~RecoveryDialog()
1019 short RecoveryDialog::execute()
1021 ::SolarMutexGuard aSolarLock
;
1023 switch(m_eRecoveryState
)
1025 case RecoveryDialog::E_RECOVERY_PREPARED
:
1027 // Dialog was started first time ...
1028 // wait for user decision ("start" or "cancel" recovery)
1029 // This decision will be made inside the NextBtn handler.
1030 m_aNextBtn
.Enable(true);
1031 m_aCancelBtn
.Enable(true);
1032 m_bWaitForUser
= true;
1033 while(m_bWaitForUser
)
1034 Application::Yield();
1035 if (m_bUserDecideNext
)
1036 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_IN_PROGRESS
;
1038 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_CANCELED
;
1042 case RecoveryDialog::E_RECOVERY_IN_PROGRESS
:
1044 // user decided to start recovery ...
1045 m_bWasRecoveryStarted
= true;
1046 // do it asynchronous (to allow repaints)
1047 // and wait for this asynchronous operation.
1048 m_aDescrFT
.SetText( m_aTitleRecoveryInProgress
);
1049 m_aNextBtn
.Enable(false);
1050 m_aCancelBtn
.Enable(false);
1051 m_pCore
->setProgressHandler(m_xProgress
);
1052 m_pCore
->setUpdateListener(this);
1053 m_pCore
->doRecovery();
1055 m_bWaitForCore
= true;
1056 while(m_bWaitForCore
)
1057 Application::Yield();
1059 m_pCore
->setUpdateListener(0);
1060 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_CORE_DONE
;
1064 case RecoveryDialog::E_RECOVERY_CORE_DONE
:
1066 // the core finished it's task.
1067 // let the user decide the next step.
1068 m_aDescrFT
.SetText(m_aRecoveryOnlyFinishDescr
);
1069 m_aNextBtn
.SetText(m_aRecoveryOnlyFinish
);
1070 m_aNextBtn
.Enable(true);
1071 m_aCancelBtn
.Enable(false);
1073 m_bWaitForUser
= true;
1074 while(m_bWaitForUser
)
1075 Application::Yield();
1077 if (m_bUserDecideNext
)
1078 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_DONE
;
1080 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_CANCELED
;
1084 case RecoveryDialog::E_RECOVERY_DONE
:
1086 // All documents was reovered.
1087 // User decided to step to the "next" wizard page.
1088 // Do it ... but check first, if there exist some
1089 // failed recovery documents. They must be saved to
1090 // a user selected directrory.
1091 short nRet
= DLG_RET_UNKNOWN
;
1092 BrokenRecoveryDialog
* pBrokenRecoveryDialog
= new BrokenRecoveryDialog(this, m_pCore
, !m_bWasRecoveryStarted
);
1093 OUString sSaveDir
= pBrokenRecoveryDialog
->getSaveDirURL(); // get the default dir
1094 if (pBrokenRecoveryDialog
->isExecutionNeeded())
1096 nRet
= pBrokenRecoveryDialog
->Execute();
1097 sSaveDir
= pBrokenRecoveryDialog
->getSaveDirURL();
1099 delete pBrokenRecoveryDialog
;
1103 // no broken temp files exists
1104 // step to the next wizard page
1105 case DLG_RET_UNKNOWN
:
1107 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_HANDLED
;
1111 // user decided to save the broken temp files
1113 // step to the next wizard page
1116 m_pCore
->saveBrokenTempEntries(sSaveDir
);
1117 m_pCore
->forgetBrokenTempEntries();
1118 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_HANDLED
;
1122 // user decided to ignore broken temp files.
1123 // Ask it again ... may be this decision was wrong.
1125 // IGNORE => remove broken temp files
1126 // => step to the next wizard page
1127 // CANCEL => step back to the recovery page
1128 case DLG_RET_CANCEL
:
1130 // TODO ask user ...
1131 m_pCore
->forgetBrokenTempEntries();
1132 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_HANDLED
;
1137 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_HANDLED
;
1141 case RecoveryDialog::E_RECOVERY_CANCELED
:
1143 // "YES" => break recovery
1144 // But there exist different states, where "cancel" can be called.
1145 // Handle it different.
1146 if (m_bWasRecoveryStarted
)
1147 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS
;
1149 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_CANCELED_BEFORE
;
1153 case RecoveryDialog::E_RECOVERY_CANCELED_BEFORE
:
1154 case RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS
:
1156 // We have to check if there exists some temp. files.
1157 // They should be saved to a user defined location.
1158 // If no temp files exists or user decided to ignore it ...
1159 // we have to remove all recovery/session data anyway!
1160 short nRet
= DLG_RET_UNKNOWN
;
1161 BrokenRecoveryDialog
* pBrokenRecoveryDialog
= new BrokenRecoveryDialog(this, m_pCore
, !m_bWasRecoveryStarted
);
1162 OUString sSaveDir
= pBrokenRecoveryDialog
->getSaveDirURL(); // get the default save location
1164 // dialog itself checks if there is a need to copy files for this mode.
1165 // It uses the information m_bWasRecoveryStarted doing so.
1166 if (pBrokenRecoveryDialog
->isExecutionNeeded())
1168 nRet
= pBrokenRecoveryDialog
->Execute();
1169 sSaveDir
= pBrokenRecoveryDialog
->getSaveDirURL();
1171 delete pBrokenRecoveryDialog
;
1174 // a) nRet == DLG_RET_UNKNOWN
1175 // dialog was not shown ...
1176 // because there exists no temp file for copy.
1177 // => remove all recovery data
1178 // b) nRet == DLG_RET_OK
1179 // dialog was shown ...
1180 // user decided to save temp files
1181 // => save all OR broken temp files (depends from the time, where cancel was called)
1182 // => remove all recovery data
1183 // c) nRet == DLG_RET_CANCEL
1184 // dialog was shown ...
1185 // user decided to ignore temp files
1186 // => remove all recovery data
1187 // => a)/c) are the same ... b) has one additional operation
1190 if (nRet
== DLG_RET_OK
)
1192 if (m_bWasRecoveryStarted
)
1193 m_pCore
->saveBrokenTempEntries(sSaveDir
);
1195 m_pCore
->saveAllTempEntries(sSaveDir
);
1199 if (m_bWasRecoveryStarted
)
1200 m_pCore
->forgetBrokenRecoveryEntries();
1202 m_pCore
->forgetAllRecoveryEntries();
1203 m_eRecoveryState
= RecoveryDialog::E_RECOVERY_HANDLED
;
1205 // THERE IS NO WAY BACK. see impl_askUserForWizardCancel()!
1206 return DLG_RET_CANCEL
;
1209 case RecoveryDialog::E_RECOVERY_HANDLED
:
1211 m_bWaitForUser
= true;
1212 while(m_bWaitForUser
)
1213 Application::Yield();
1215 // TODO: show BrokenRecoveryDialog again, ift he user
1216 // doesn't accepted it last time.
1218 if (m_bUserDecideNext
)
1221 return DLG_RET_CANCEL
;
1225 // should never be reached .-)
1226 OSL_FAIL("Should never be reached!");
1231 void RecoveryDialog::setDefButton()
1233 if ( m_aNextBtn
.IsEnabled() )
1234 m_aNextBtn
.GrabFocus();
1236 m_pDefButton
= &m_aNextBtn
;
1240 void RecoveryDialog::start()
1245 void RecoveryDialog::updateItems()
1247 sal_uIntPtr c
= m_aFileListLB
.GetEntryCount();
1249 for ( i
=0; i
<c
; ++i
)
1251 SvTreeListEntry
* pEntry
= m_aFileListLB
.GetEntry(i
);
1255 TURLInfo
* pInfo
= (TURLInfo
*)pEntry
->GetUserData();
1259 OUString sStatus
= impl_getStatusString( *pInfo
);
1260 if ( !sStatus
.isEmpty() )
1261 m_aFileListLB
.SetEntryText( sStatus
, pEntry
, 1 );
1264 m_aFileListLB
.Invalidate();
1265 m_aFileListLB
.Update();
1269 void RecoveryDialog::stepNext(TURLInfo
* pItem
)
1271 sal_uIntPtr c
= m_aFileListLB
.GetEntryCount();
1275 SvTreeListEntry
* pEntry
= m_aFileListLB
.GetEntry(i
);
1279 TURLInfo
* pInfo
= (TURLInfo
*)pEntry
->GetUserData();
1280 if (pInfo
->ID
!= pItem
->ID
)
1283 m_aFileListLB
.SetCursor(pEntry
, true);
1284 m_aFileListLB
.MakeVisible(pEntry
);
1285 m_aFileListLB
.Invalidate();
1286 m_aFileListLB
.Update();
1292 void RecoveryDialog::end()
1296 m_pDefButton
->GrabFocus();
1297 m_pDefButton
= NULL
;
1299 m_bWaitForCore
= false;
1303 IMPL_LINK_NOARG(RecoveryDialog
, NextButtonHdl
)
1305 m_bUserDecideNext
= true;
1306 m_bWaitForUser
= false;
1311 IMPL_LINK_NOARG(RecoveryDialog
, CancelButtonHdl
)
1313 if (m_eRecoveryState
== RecoveryDialog::E_RECOVERY_PREPARED
)
1315 if (impl_askUserForWizardCancel(this, RID_SVXQB_EXIT_RECOVERY
) == DLG_RET_CANCEL
)
1318 m_bUserDecideNext
= false;
1319 m_bWaitForUser
= false;
1324 OUString
RecoveryDialog::impl_getStatusString( const TURLInfo
& rInfo
) const
1327 switch ( rInfo
.RecoveryState
)
1329 case E_SUCCESSFULLY_RECOVERED
:
1330 sStatus
= m_aFileListLB
.m_aSuccessRecovStr
;
1332 case E_ORIGINAL_DOCUMENT_RECOVERED
:
1333 sStatus
= m_aFileListLB
.m_aOrigDocRecovStr
;
1335 case E_RECOVERY_FAILED
:
1336 sStatus
= m_aFileListLB
.m_aRecovFailedStr
;
1338 case E_RECOVERY_IS_IN_PROGRESS
:
1339 sStatus
= m_aFileListLB
.m_aRecovInProgrStr
;
1341 case E_NOT_RECOVERED_YET
:
1342 sStatus
= m_aFileListLB
.m_aNotRecovYetStr
;
1351 BrokenRecoveryDialog::BrokenRecoveryDialog(Window
* pParent
,
1352 RecoveryCore
* pCore
,
1353 bool bBeforeRecovery
)
1354 : ModalDialog ( pParent
, SVX_RES( RID_SVX_MDLG_DOCRECOVERY_BROKEN
) )
1355 , m_aDescrFT ( this , SVX_RES( FT_BROKEN_DESCR
) )
1356 , m_aFileListFT ( this , SVX_RES( FT_BROKEN_FILELIST
) )
1357 , m_aFileListLB ( this , SVX_RES( LB_BROKEN_FILELIST
) )
1358 , m_aSaveDirFT ( this , SVX_RES( FT_BROKEN_SAVEDIR
) )
1359 , m_aSaveDirED ( this , SVX_RES( ED_BROKEN_SAVEDIR
) )
1360 , m_aSaveDirBtn ( this , SVX_RES( BTN_BROKEN_SAVEDIR
) )
1361 , m_aBottomFL ( this , SVX_RES( FL_BROKEN_BOTTOM
) )
1362 , m_aOkBtn ( this , SVX_RES( BTN_BROKEN_OK
) )
1363 , m_aCancelBtn ( this , SVX_RES( BTN_BROKEN_CANCEL
) )
1365 , m_bBeforeRecovery (bBeforeRecovery
)
1366 , m_bExecutionNeeded(false)
1370 m_aSaveDirBtn
.SetClickHdl( LINK( this, BrokenRecoveryDialog
, SaveButtonHdl
) );
1371 m_aOkBtn
.SetClickHdl( LINK( this, BrokenRecoveryDialog
, OkButtonHdl
) );
1372 m_aCancelBtn
.SetClickHdl( LINK( this, BrokenRecoveryDialog
, CancelButtonHdl
) );
1374 m_sSavePath
= SvtPathOptions().GetWorkPath();
1375 INetURLObject
aObj( m_sSavePath
);
1377 ::utl::LocalFileHelper::ConvertURLToSystemPath( aObj
.GetMainURL( INetURLObject::NO_DECODE
), sPath
);
1378 m_aSaveDirED
.SetText( sPath
);
1384 BrokenRecoveryDialog::~BrokenRecoveryDialog()
1389 void BrokenRecoveryDialog::impl_refresh()
1391 m_bExecutionNeeded
= false;
1392 TURLList
* pURLList
= m_pCore
->getURLListAccess();
1393 TURLList::const_iterator pIt
;
1394 for ( pIt
= pURLList
->begin();
1395 pIt
!= pURLList
->end() ;
1398 const TURLInfo
& rInfo
= *pIt
;
1400 if (m_bBeforeRecovery
)
1402 // "Cancel" before recovery ->
1403 // search for any temp files!
1404 if (rInfo
.TempURL
.isEmpty())
1409 // "Cancel" after recovery ->
1410 // search for broken temp files
1411 if (!RecoveryCore::isBrokenTempEntry(rInfo
))
1415 m_bExecutionNeeded
= true;
1417 sal_uInt16 nPos
= m_aFileListLB
.InsertEntry(rInfo
.DisplayName
, rInfo
.StandardImage
);
1418 m_aFileListLB
.SetEntryData( nPos
, (void*)&rInfo
);
1421 m_aOkBtn
.GrabFocus();
1425 bool BrokenRecoveryDialog::isExecutionNeeded()
1427 return m_bExecutionNeeded
;
1431 OUString
BrokenRecoveryDialog::getSaveDirURL()
1437 IMPL_LINK_NOARG(BrokenRecoveryDialog
, OkButtonHdl
)
1439 OUString sPhysicalPath
= comphelper::string::strip(m_aSaveDirED
.GetText(), ' ');
1441 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPhysicalPath
, sURL
);
1443 while (m_sSavePath
.isEmpty())
1444 impl_askForSavePath();
1446 EndDialog(DLG_RET_OK
);
1451 IMPL_LINK_NOARG(BrokenRecoveryDialog
, CancelButtonHdl
)
1453 EndDialog(DLG_RET_CANCEL
);
1458 IMPL_LINK_NOARG(BrokenRecoveryDialog
, SaveButtonHdl
)
1460 impl_askForSavePath();
1465 void BrokenRecoveryDialog::impl_askForSavePath()
1467 css::uno::Reference
< css::ui::dialogs::XFolderPicker2
> xFolderPicker
=
1468 css::ui::dialogs::FolderPicker::create( m_pCore
->getComponentContext() );
1470 INetURLObject
aURL(m_sSavePath
, INET_PROT_FILE
);
1471 xFolderPicker
->setDisplayDirectory(aURL
.GetMainURL(INetURLObject::NO_DECODE
));
1472 short nRet
= xFolderPicker
->execute();
1473 if (nRet
== css::ui::dialogs::ExecutableDialogResults::OK
)
1475 m_sSavePath
= xFolderPicker
->getDirectory();
1477 ::utl::LocalFileHelper::ConvertURLToSystemPath( m_sSavePath
, sPath
);
1478 m_aSaveDirED
.SetText( sPath
);
1482 } // namespace DocRecovery
1485 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */