Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <config_folders.h>
21 :
22 : #include <sal/macros.h>
23 :
24 : #include <svx/dialmgr.hxx>
25 : #include <svx/dialogs.hrc>
26 : #include "docrecovery.hxx"
27 : #include "docrecovery.hrc"
28 :
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/layout.hxx>
37 : #include <vcl/svapp.hxx>
38 : #include <rtl/ustrbuf.hxx>
39 : #include <vcl/scrbar.hxx>
40 :
41 : #include <toolkit/helper/vclunohelper.hxx>
42 :
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>
61 : #include <boost/scoped_ptr.hpp>
62 :
63 : namespace svx{
64 : namespace DocRecovery{
65 :
66 : using namespace ::osl;
67 :
68 0 : RecoveryCore::RecoveryCore(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
69 : bool bUsedForSaving)
70 : : m_xContext ( rxContext )
71 : , m_pListener ( 0 )
72 0 : , m_bListenForSaving(bUsedForSaving)
73 : {
74 0 : impl_startListening();
75 0 : }
76 :
77 :
78 0 : RecoveryCore::~RecoveryCore()
79 : {
80 0 : impl_stopListening();
81 0 : }
82 :
83 :
84 0 : css::uno::Reference< css::uno::XComponentContext > RecoveryCore::getComponentContext()
85 : {
86 0 : return m_xContext;
87 : }
88 :
89 :
90 0 : TURLList* RecoveryCore::getURLListAccess()
91 : {
92 0 : return &m_lURLs;
93 : }
94 :
95 :
96 0 : bool RecoveryCore::isBrokenTempEntry(const TURLInfo& rInfo)
97 : {
98 0 : if (rInfo.TempURL.isEmpty())
99 0 : return false;
100 :
101 : // Note: If the original files was recovery ... but a temp file
102 : // exists ... an error inside the temp file exists!
103 0 : if (
104 0 : !(rInfo.RecoveryState == E_RECOVERY_FAILED ) &&
105 0 : !(rInfo.RecoveryState == E_ORIGINAL_DOCUMENT_RECOVERED)
106 : )
107 0 : return false;
108 :
109 0 : return true;
110 : }
111 :
112 :
113 0 : void RecoveryCore::saveBrokenTempEntries(const OUString& rPath)
114 : {
115 0 : if (rPath.isEmpty())
116 0 : return;
117 :
118 0 : if (!m_xRealCore.is())
119 0 : return;
120 :
121 : // prepare all needed parameters for the following dispatch() request.
122 0 : css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP);
123 0 : css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3);
124 0 : lCopyArgs[0].Name = PROP_DISPATCHASYNCHRON;
125 0 : lCopyArgs[0].Value <<= sal_False;
126 0 : lCopyArgs[1].Name = PROP_SAVEPATH;
127 0 : lCopyArgs[1].Value <<= rPath;
128 0 : lCopyArgs[2].Name = PROP_ENTRYID;
129 : // lCopyArgs[2].Value will be changed during next loop ...
130 :
131 : // work on a copied list only ...
132 : // Reason: We will get notifications from the core for every
133 : // changed or removed element. And that will change our m_lURLs list.
134 : // That's not a good idea, if we use a stl iterator inbetween .-)
135 0 : TURLList lURLs = m_lURLs;
136 0 : TURLList::const_iterator pIt;
137 0 : for ( pIt = lURLs.begin();
138 0 : pIt != lURLs.end() ;
139 : ++pIt )
140 : {
141 0 : const TURLInfo& rInfo = *pIt;
142 0 : if (!RecoveryCore::isBrokenTempEntry(rInfo))
143 0 : continue;
144 :
145 0 : lCopyArgs[2].Value <<= rInfo.ID;
146 0 : m_xRealCore->dispatch(aCopyURL, lCopyArgs);
147 0 : }
148 : }
149 :
150 :
151 0 : void RecoveryCore::saveAllTempEntries(const OUString& rPath)
152 : {
153 0 : if (rPath.isEmpty())
154 0 : return;
155 :
156 0 : if (!m_xRealCore.is())
157 0 : return;
158 :
159 : // prepare all needed parameters for the following dispatch() request.
160 0 : css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP);
161 0 : css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3);
162 0 : lCopyArgs[0].Name = PROP_DISPATCHASYNCHRON;
163 0 : lCopyArgs[0].Value <<= sal_False;
164 0 : lCopyArgs[1].Name = PROP_SAVEPATH;
165 0 : lCopyArgs[1].Value <<= rPath;
166 0 : lCopyArgs[2].Name = PROP_ENTRYID;
167 : // lCopyArgs[2].Value will be changed during next loop ...
168 :
169 : // work on a copied list only ...
170 : // Reason: We will get notifications from the core for every
171 : // changed or removed element. And that will change our m_lURLs list.
172 : // That's not a good idea, if we use a stl iterator inbetween .-)
173 0 : TURLList lURLs = m_lURLs;
174 0 : TURLList::const_iterator pIt;
175 0 : for ( pIt = lURLs.begin();
176 0 : pIt != lURLs.end() ;
177 : ++pIt )
178 : {
179 0 : const TURLInfo& rInfo = *pIt;
180 0 : if (rInfo.TempURL.isEmpty())
181 0 : continue;
182 :
183 0 : lCopyArgs[2].Value <<= rInfo.ID;
184 0 : m_xRealCore->dispatch(aCopyURL, lCopyArgs);
185 0 : }
186 : }
187 :
188 :
189 0 : void RecoveryCore::forgetBrokenTempEntries()
190 : {
191 0 : if (!m_xRealCore.is())
192 0 : return;
193 :
194 0 : css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
195 0 : css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
196 0 : lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON;
197 0 : lRemoveArgs[0].Value <<= sal_False;
198 0 : lRemoveArgs[1].Name = PROP_ENTRYID;
199 : // lRemoveArgs[1].Value will be changed during next loop ...
200 :
201 : // work on a copied list only ...
202 : // Reason: We will get notifications from the core for every
203 : // changed or removed element. And that will change our m_lURLs list.
204 : // That's not a good idea, if we use a stl iterator inbetween .-)
205 0 : TURLList lURLs = m_lURLs;
206 0 : TURLList::const_iterator pIt;
207 0 : for ( pIt = lURLs.begin();
208 0 : pIt != lURLs.end() ;
209 : ++pIt )
210 : {
211 0 : const TURLInfo& rInfo = *pIt;
212 0 : if (!RecoveryCore::isBrokenTempEntry(rInfo))
213 0 : continue;
214 :
215 0 : lRemoveArgs[1].Value <<= rInfo.ID;
216 0 : m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
217 0 : }
218 : }
219 :
220 :
221 0 : void RecoveryCore::forgetAllRecoveryEntries()
222 : {
223 0 : if (!m_xRealCore.is())
224 0 : return;
225 :
226 0 : css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
227 0 : css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
228 0 : lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON;
229 0 : lRemoveArgs[0].Value <<= sal_False;
230 0 : lRemoveArgs[1].Name = PROP_ENTRYID;
231 : // lRemoveArgs[1].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 0 : TURLList lURLs = m_lURLs;
238 0 : TURLList::const_iterator pIt;
239 0 : for ( pIt = lURLs.begin();
240 0 : pIt != lURLs.end() ;
241 : ++pIt )
242 : {
243 0 : const TURLInfo& rInfo = *pIt;
244 0 : lRemoveArgs[1].Value <<= rInfo.ID;
245 0 : m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
246 0 : }
247 : }
248 :
249 :
250 0 : void RecoveryCore::forgetBrokenRecoveryEntries()
251 : {
252 0 : if (!m_xRealCore.is())
253 0 : return;
254 :
255 0 : css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
256 0 : css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
257 0 : lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON;
258 0 : lRemoveArgs[0].Value <<= sal_False;
259 0 : lRemoveArgs[1].Name = PROP_ENTRYID;
260 : // lRemoveArgs[1].Value will be changed during next loop ...
261 :
262 : // work on a copied list only ...
263 : // Reason: We will get notifications from the core for every
264 : // changed or removed element. And that will change our m_lURLs list.
265 : // That's not a good idea, if we use a stl iterator inbetween .-)
266 0 : TURLList lURLs = m_lURLs;
267 0 : TURLList::const_iterator pIt;
268 0 : for ( pIt = lURLs.begin();
269 0 : pIt != lURLs.end() ;
270 : ++pIt )
271 : {
272 0 : const TURLInfo& rInfo = *pIt;
273 0 : if (!RecoveryCore::isBrokenTempEntry(rInfo))
274 0 : continue;
275 :
276 0 : lRemoveArgs[1].Value <<= rInfo.ID;
277 0 : m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
278 0 : }
279 : }
280 :
281 :
282 0 : void RecoveryCore::setProgressHandler(const css::uno::Reference< css::task::XStatusIndicator >& xProgress)
283 : {
284 0 : m_xProgress = xProgress;
285 0 : }
286 :
287 :
288 0 : void RecoveryCore::setUpdateListener(IRecoveryUpdateListener* pListener)
289 : {
290 0 : m_pListener = pListener;
291 0 : }
292 :
293 :
294 0 : void RecoveryCore::doEmergencySavePrepare()
295 : {
296 0 : if (!m_xRealCore.is())
297 0 : return;
298 :
299 0 : css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_PREPARE_EMERGENCY_SAVE);
300 :
301 0 : css::uno::Sequence< css::beans::PropertyValue > lArgs(1);
302 0 : lArgs[0].Name = PROP_DISPATCHASYNCHRON;
303 0 : lArgs[0].Value <<= sal_False;
304 :
305 0 : m_xRealCore->dispatch(aURL, lArgs);
306 : }
307 :
308 :
309 0 : void RecoveryCore::doEmergencySave()
310 : {
311 0 : if (!m_xRealCore.is())
312 0 : return;
313 :
314 0 : css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_EMERGENCY_SAVE);
315 :
316 0 : css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
317 0 : lArgs[0].Name = PROP_STATUSINDICATOR;
318 0 : lArgs[0].Value <<= m_xProgress;
319 0 : lArgs[1].Name = PROP_DISPATCHASYNCHRON;
320 0 : lArgs[1].Value <<= sal_True;
321 :
322 0 : m_xRealCore->dispatch(aURL, lArgs);
323 : }
324 :
325 :
326 0 : void RecoveryCore::doRecovery()
327 : {
328 0 : if (!m_xRealCore.is())
329 0 : return;
330 :
331 0 : css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_RECOVERY);
332 :
333 0 : css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
334 0 : lArgs[0].Name = PROP_STATUSINDICATOR;
335 0 : lArgs[0].Value <<= m_xProgress;
336 0 : lArgs[1].Name = PROP_DISPATCHASYNCHRON;
337 0 : lArgs[1].Value <<= sal_True;
338 :
339 0 : m_xRealCore->dispatch(aURL, lArgs);
340 : }
341 :
342 :
343 0 : ERecoveryState RecoveryCore::mapDocState2RecoverState(sal_Int32 eDocState)
344 : {
345 : // ???
346 0 : ERecoveryState eRecState = E_NOT_RECOVERED_YET;
347 :
348 : /* Attention:
349 : Some of the following states can occur at the
350 : same time. So we have to check for the "worst case" first!
351 :
352 : DAMAGED -> INCOMPLETE -> HANDLED
353 : */
354 :
355 : // running ...
356 0 : if (
357 0 : ((eDocState & E_TRY_LOAD_BACKUP ) == E_TRY_LOAD_BACKUP ) ||
358 0 : ((eDocState & E_TRY_LOAD_ORIGINAL) == E_TRY_LOAD_ORIGINAL)
359 : )
360 0 : eRecState = E_RECOVERY_IS_IN_PROGRESS;
361 : // red
362 0 : else if ((eDocState & E_DAMAGED) == E_DAMAGED)
363 0 : eRecState = E_RECOVERY_FAILED;
364 : // yellow
365 0 : else if ((eDocState & E_INCOMPLETE) == E_INCOMPLETE)
366 0 : eRecState = E_ORIGINAL_DOCUMENT_RECOVERED;
367 : // green
368 0 : else if ((eDocState & E_SUCCEDED) == E_SUCCEDED)
369 0 : eRecState = E_SUCCESSFULLY_RECOVERED;
370 :
371 0 : return eRecState;
372 : }
373 :
374 :
375 0 : void SAL_CALL RecoveryCore::statusChanged(const css::frame::FeatureStateEvent& aEvent)
376 : throw(css::uno::RuntimeException, std::exception)
377 : {
378 : // a) special notification about start/stop async dispatch!
379 : // FeatureDescriptor = "start" || "stop"
380 0 : if (aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_START))
381 : {
382 0 : if (m_pListener)
383 0 : m_pListener->start();
384 0 : return;
385 : }
386 :
387 0 : if (aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_STOP))
388 : {
389 0 : if (m_pListener)
390 0 : m_pListener->end();
391 0 : return;
392 : }
393 :
394 : // b) normal notification about changed items
395 : // FeatureDescriptor = "Update"
396 : // State = Lits of information [seq< NamedValue >]
397 0 : if (! aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_UPDATE))
398 0 : return;
399 :
400 0 : ::comphelper::SequenceAsHashMap lInfo(aEvent.State);
401 0 : TURLInfo aNew;
402 :
403 0 : aNew.ID = lInfo.getUnpackedValueOrDefault(STATEPROP_ID , (sal_Int32)0 );
404 0 : aNew.DocState = lInfo.getUnpackedValueOrDefault(STATEPROP_STATE , (sal_Int32)0 );
405 0 : aNew.OrgURL = lInfo.getUnpackedValueOrDefault(STATEPROP_ORGURL , OUString());
406 0 : aNew.TempURL = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPURL , OUString());
407 0 : aNew.FactoryURL = lInfo.getUnpackedValueOrDefault(STATEPROP_FACTORYURL , OUString());
408 0 : aNew.TemplateURL = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPLATEURL, OUString());
409 0 : aNew.DisplayName = lInfo.getUnpackedValueOrDefault(STATEPROP_TITLE , OUString());
410 0 : aNew.Module = lInfo.getUnpackedValueOrDefault(STATEPROP_MODULE , OUString());
411 :
412 0 : if (aNew.OrgURL.isEmpty()) {
413 : // If there is no file URL, the window title is used for the display name.
414 : // Remove any unwanted elements such as " - LibreOffice Writer".
415 0 : sal_Int32 i = aNew.DisplayName.indexOf(" - ");
416 0 : if (i > 0)
417 0 : aNew.DisplayName = aNew.DisplayName.copy(0, i);
418 : } else {
419 : // If there is a file URL, parse out the filename part as the display name.
420 0 : INetURLObject aOrgURL(aNew.OrgURL);
421 0 : aNew.DisplayName = aOrgURL.getName(INetURLObject::LAST_SEGMENT, true,
422 0 : INetURLObject::DECODE_WITH_CHARSET);
423 : }
424 :
425 : // search for already existing items and update her nState value ...
426 0 : TURLList::iterator pIt;
427 0 : for ( pIt = m_lURLs.begin();
428 0 : pIt != m_lURLs.end() ;
429 : ++pIt )
430 : {
431 0 : TURLInfo& aOld = *pIt;
432 0 : if (aOld.ID == aNew.ID)
433 : {
434 : // change existing
435 0 : aOld.DocState = aNew.DocState;
436 0 : aOld.RecoveryState = RecoveryCore::mapDocState2RecoverState(aOld.DocState);
437 0 : if (m_pListener)
438 : {
439 0 : m_pListener->updateItems();
440 0 : m_pListener->stepNext(&aOld);
441 : }
442 0 : return;
443 : }
444 : }
445 :
446 : // append as new one
447 : // TODO think about mmatching Module name to a corresponding icon
448 0 : OUString sURL = aNew.OrgURL;
449 0 : if (sURL.isEmpty())
450 0 : sURL = aNew.FactoryURL;
451 0 : if (sURL.isEmpty())
452 0 : sURL = aNew.TempURL;
453 0 : if (sURL.isEmpty())
454 0 : sURL = aNew.TemplateURL;
455 0 : INetURLObject aURL(sURL);
456 0 : aNew.StandardImage = SvFileInformationManager::GetFileImage(aURL, false);
457 :
458 : /* set the right UI state for this item to NOT_RECOVERED_YET ... because nDocState shows the state of
459 : the last emergency save operation before and is interessting for the used recovery core service only ...
460 : for now! But if there is a further notification for this item (see lines above!) we must
461 : map the doc state to an UI state. */
462 0 : aNew.RecoveryState = E_NOT_RECOVERED_YET;
463 :
464 0 : m_lURLs.push_back(aNew);
465 :
466 0 : if (m_pListener)
467 0 : m_pListener->updateItems();
468 : }
469 :
470 :
471 0 : void SAL_CALL RecoveryCore::disposing(const css::lang::EventObject& /*aEvent*/)
472 : throw(css::uno::RuntimeException, std::exception)
473 : {
474 0 : m_xRealCore.clear();
475 0 : }
476 :
477 :
478 0 : void RecoveryCore::impl_startListening()
479 : {
480 : // listening already initialized ?
481 0 : if (m_xRealCore.is())
482 0 : return;
483 0 : m_xRealCore = css::frame::theAutoRecovery::get(m_xContext);
484 :
485 0 : css::util::URL aURL;
486 0 : if (m_bListenForSaving)
487 0 : aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE;
488 : else
489 0 : aURL.Complete = RECOVERY_CMD_DO_RECOVERY;
490 0 : css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(m_xContext));
491 0 : xParser->parseStrict(aURL);
492 :
493 : /* Note: addStatusListener() call us synchronous back ... so we
494 : will get the complete list of currently open documents! */
495 0 : m_xRealCore->addStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL);
496 : }
497 :
498 :
499 0 : void RecoveryCore::impl_stopListening()
500 : {
501 : // Ignore it, if this instance doesn't listen currently
502 0 : if (!m_xRealCore.is())
503 0 : return;
504 :
505 0 : css::util::URL aURL;
506 0 : if (m_bListenForSaving)
507 0 : aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE;
508 : else
509 0 : aURL.Complete = RECOVERY_CMD_DO_RECOVERY;
510 0 : css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(m_xContext));
511 0 : xParser->parseStrict(aURL);
512 :
513 0 : m_xRealCore->removeStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL);
514 0 : m_xRealCore.clear();
515 : }
516 :
517 :
518 0 : css::util::URL RecoveryCore::impl_getParsedURL(const OUString& sURL)
519 : {
520 0 : css::util::URL aURL;
521 0 : aURL.Complete = sURL;
522 :
523 0 : css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(m_xContext));
524 0 : xParser->parseStrict(aURL);
525 :
526 0 : return aURL;
527 : }
528 :
529 0 : PluginProgressWindow::PluginProgressWindow( vcl::Window* pParent ,
530 : const css::uno::Reference< css::lang::XComponent >& xProgress)
531 : : Window (pParent )
532 0 : , m_xProgress(xProgress)
533 : {
534 0 : Show();
535 0 : Size aParentSize = pParent->GetSizePixel();
536 : // align the progressbar to its parent
537 0 : setPosSizePixel( -9, 0, aParentSize.Width() + 15, aParentSize.Height() - 4 );
538 0 : }
539 :
540 0 : PluginProgressWindow::~PluginProgressWindow()
541 : {
542 0 : if (m_xProgress.is())
543 0 : m_xProgress->dispose();
544 0 : }
545 :
546 :
547 0 : PluginProgress::PluginProgress( vcl::Window* pParent,
548 0 : const css::uno::Reference< css::uno::XComponentContext >& xContext )
549 : {
550 0 : m_pPlugProgressWindow = new PluginProgressWindow(pParent, static_cast< css::lang::XComponent* >(this));
551 0 : css::uno::Reference< css::awt::XWindow > xProgressWindow = VCLUnoHelper::GetInterface(m_pPlugProgressWindow);
552 0 : m_xProgressFactory = css::task::StatusIndicatorFactory::createWithWindow(xContext, xProgressWindow, sal_False/*DisableReschedule*/, sal_True/*AllowParentShow*/);
553 0 : m_xProgress = m_xProgressFactory->createStatusIndicator();
554 0 : }
555 :
556 :
557 0 : PluginProgress::~PluginProgress()
558 : {
559 0 : }
560 :
561 :
562 0 : void SAL_CALL PluginProgress::dispose()
563 : throw(css::uno::RuntimeException, std::exception)
564 : {
565 : // m_pPluginProgressWindow was deleted ...
566 : // So the internal pointer of this progress
567 : // weill be dead!
568 0 : m_xProgress.clear();
569 0 : }
570 :
571 :
572 0 : void SAL_CALL PluginProgress::addEventListener(const css::uno::Reference< css::lang::XEventListener >& )
573 : throw(css::uno::RuntimeException, std::exception)
574 : {
575 0 : }
576 :
577 :
578 0 : void SAL_CALL PluginProgress::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& )
579 : throw(css::uno::RuntimeException, std::exception)
580 : {
581 0 : }
582 :
583 :
584 0 : void SAL_CALL PluginProgress::start(const OUString&,
585 : sal_Int32 nRange)
586 : throw(css::uno::RuntimeException, std::exception)
587 : {
588 0 : if (m_xProgress.is())
589 0 : m_xProgress->start(OUString(), nRange);
590 0 : }
591 :
592 :
593 0 : void SAL_CALL PluginProgress::end()
594 : throw(css::uno::RuntimeException, std::exception)
595 : {
596 0 : if (m_xProgress.is())
597 0 : m_xProgress->end();
598 0 : }
599 :
600 :
601 0 : void SAL_CALL PluginProgress::setText(const OUString& sText)
602 : throw(css::uno::RuntimeException, std::exception)
603 : {
604 0 : if (m_xProgress.is())
605 0 : m_xProgress->setText(sText);
606 0 : }
607 :
608 :
609 0 : void SAL_CALL PluginProgress::setValue(sal_Int32 nValue)
610 : throw(css::uno::RuntimeException, std::exception)
611 : {
612 0 : if (m_xProgress.is())
613 0 : m_xProgress->setValue(nValue);
614 0 : }
615 :
616 :
617 0 : void SAL_CALL PluginProgress::reset()
618 : throw(css::uno::RuntimeException, std::exception)
619 : {
620 0 : if (m_xProgress.is())
621 0 : m_xProgress->reset();
622 0 : }
623 :
624 :
625 0 : SaveDialog::SaveDialog(vcl::Window* pParent, RecoveryCore* pCore)
626 : : Dialog(pParent, "DocRecoverySaveDialog",
627 : "svx/ui/docrecoverysavedialog.ui")
628 0 : , m_pCore(pCore)
629 : {
630 0 : get(m_pTitleFT, "title");
631 0 : get(m_pFileListLB, "filelist");
632 0 : m_pFileListLB->set_height_request(m_pFileListLB->GetTextHeight() * 10);
633 0 : m_pFileListLB->set_width_request(m_pFileListLB->approximate_char_width() * 72);
634 0 : get(m_pOkBtn, "ok");
635 :
636 : // Prepare the office for the following crash save step.
637 : // E.g. hide all open widows so the user can't influence our
638 : // operation .-)
639 0 : m_pCore->doEmergencySavePrepare();
640 :
641 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
642 0 : m_pTitleFT->SetBackground(rStyleSettings.GetWindowColor());
643 0 : m_pTitleFT->set_height_request(m_pTitleFT->get_preferred_size().Height() + 48);
644 :
645 0 : m_pOkBtn->SetClickHdl( LINK( this, SaveDialog, OKButtonHdl ) );
646 0 : m_pFileListLB->SetControlBackground( rStyleSettings.GetDialogColor() );
647 :
648 : // fill listbox with current open documents
649 0 : m_pFileListLB->Clear();
650 :
651 0 : TURLList* pURLs = m_pCore->getURLListAccess();
652 0 : TURLList::const_iterator pIt;
653 :
654 0 : for ( pIt = pURLs->begin();
655 0 : pIt != pURLs->end() ;
656 : ++pIt )
657 : {
658 0 : const TURLInfo& rInfo = *pIt;
659 0 : m_pFileListLB->InsertEntry( rInfo.DisplayName, rInfo.StandardImage );
660 : }
661 0 : }
662 :
663 0 : IMPL_LINK_NOARG(SaveDialog, OKButtonHdl)
664 : {
665 : // start crash-save with progress
666 0 : boost::scoped_ptr<SaveProgressDialog> pProgress(new SaveProgressDialog(this, m_pCore));
667 0 : short nResult = pProgress->Execute();
668 0 : pProgress.reset();
669 :
670 : // if "CANCEL" => return "CANCEL"
671 : // if "OK" => "AUTOLUNCH" always !
672 0 : if (nResult == DLG_RET_OK)
673 0 : nResult = DLG_RET_OK_AUTOLUNCH;
674 :
675 0 : EndDialog(nResult);
676 0 : return 0;
677 : }
678 :
679 0 : SaveProgressDialog::SaveProgressDialog(vcl::Window* pParent, RecoveryCore* pCore)
680 : : ModalDialog(pParent, "DocRecoveryProgressDialog",
681 : "svx/ui/docrecoveryprogressdialog.ui")
682 0 : , m_pCore(pCore)
683 : {
684 0 : get(m_pProgrParent, "progress");
685 0 : Size aSize(LogicToPixel(Size(SAVEPROGR_CONTROLWIDTH, PROGR_HEIGHT)));
686 0 : m_pProgrParent->set_width_request(aSize.Width());
687 0 : m_pProgrParent->set_height_request(aSize.Height());
688 :
689 0 : PluginProgress* pProgress = new PluginProgress(m_pProgrParent, pCore->getComponentContext());
690 0 : m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW);
691 0 : }
692 :
693 0 : short SaveProgressDialog::Execute()
694 : {
695 0 : ::SolarMutexGuard aLock;
696 :
697 0 : m_pCore->setProgressHandler(m_xProgress);
698 0 : m_pCore->setUpdateListener(this);
699 0 : m_pCore->doEmergencySave();
700 0 : short nRet = ModalDialog::Execute();
701 0 : m_pCore->setUpdateListener(0);
702 0 : return nRet;
703 : }
704 :
705 0 : void SaveProgressDialog::updateItems()
706 : {
707 0 : }
708 :
709 :
710 0 : void SaveProgressDialog::stepNext(TURLInfo* )
711 : {
712 : /* TODO
713 :
714 : wenn die m_pCore noch ein Member m_nCurrentItem haette
715 : koennte man dort erkennen, wer gerade drann war, wer demnaechst
716 : dran ist ... Diese Info kann man dann in unserem Progress FixText anzeigen ...
717 : */
718 0 : }
719 :
720 :
721 0 : void SaveProgressDialog::start()
722 : {
723 0 : }
724 :
725 :
726 0 : void SaveProgressDialog::end()
727 : {
728 0 : EndDialog(DLG_RET_OK);
729 0 : }
730 :
731 :
732 0 : RecovDocListEntry::RecovDocListEntry( SvTreeListEntry* pEntry,
733 : sal_uInt16 nFlags,
734 : const OUString& sText )
735 0 : : SvLBoxString( pEntry, nFlags, sText )
736 : {
737 0 : }
738 :
739 :
740 0 : void RecovDocListEntry::Paint(
741 : const Point& aPos, SvTreeListBox& aDevice, const SvViewDataEntry* /*pView*/, const SvTreeListEntry* pEntry)
742 : {
743 0 : const Image* pImg = 0;
744 0 : const OUString* pTxt = 0;
745 0 : RecovDocList* pList = static_cast< RecovDocList* >(&aDevice);
746 :
747 0 : TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData();
748 0 : switch(pInfo->RecoveryState)
749 : {
750 : case E_SUCCESSFULLY_RECOVERED :
751 : {
752 0 : pImg = &pList->m_aGreenCheckImg;
753 0 : pTxt = &pList->m_aSuccessRecovStr;
754 : }
755 0 : break;
756 :
757 : case E_ORIGINAL_DOCUMENT_RECOVERED : // TODO must be renamed into ORIGINAL DOCUMENT recovered! Because its marked as yellow
758 : {
759 0 : pImg = &pList->m_aYellowCheckImg;
760 0 : pTxt = &pList->m_aOrigDocRecovStr;
761 : }
762 0 : break;
763 :
764 : case E_RECOVERY_FAILED :
765 : {
766 0 : pImg = &pList->m_aRedCrossImg;
767 0 : pTxt = &pList->m_aRecovFailedStr;
768 : }
769 0 : break;
770 :
771 : case E_RECOVERY_IS_IN_PROGRESS :
772 : {
773 0 : pImg = 0;
774 0 : pTxt = &pList->m_aRecovInProgrStr;
775 : }
776 0 : break;
777 :
778 : case E_NOT_RECOVERED_YET :
779 : {
780 0 : pImg = 0;
781 0 : pTxt = &pList->m_aNotRecovYetStr;
782 : }
783 0 : break;
784 : }
785 :
786 0 : if (pImg)
787 0 : aDevice.DrawImage(aPos, *pImg);
788 :
789 0 : if (pTxt)
790 : {
791 0 : Point aPnt(aPos);
792 0 : aPnt.X() += pList->m_aGreenCheckImg.GetSizePixel().Width();
793 0 : aPnt.X() += 10;
794 0 : aDevice.DrawText(aPnt, *pTxt);
795 : }
796 0 : }
797 :
798 0 : RecovDocList::RecovDocList(SvSimpleTableContainer& rParent, ResMgr &rResMgr)
799 : : SvSimpleTable ( rParent )
800 : , m_aGreenCheckImg ( ResId(RID_SVXIMG_GREENCHECK, rResMgr ) )
801 : , m_aYellowCheckImg ( ResId(RID_SVXIMG_YELLOWCHECK, rResMgr ) )
802 : , m_aRedCrossImg ( ResId(RID_SVXIMG_REDCROSS, rResMgr ) )
803 : , m_aSuccessRecovStr ( ResId(RID_SVXSTR_SUCCESSRECOV, rResMgr ) )
804 : , m_aOrigDocRecovStr ( ResId(RID_SVXSTR_ORIGDOCRECOV, rResMgr ) )
805 : , m_aRecovFailedStr ( ResId(RID_SVXSTR_RECOVFAILED, rResMgr ) )
806 : , m_aRecovInProgrStr ( ResId(RID_SVXSTR_RECOVINPROGR, rResMgr ) )
807 0 : , m_aNotRecovYetStr ( ResId(RID_SVXSTR_NOTRECOVYET, rResMgr ) )
808 : {
809 0 : }
810 :
811 0 : RecovDocList::~RecovDocList()
812 : {
813 0 : }
814 :
815 0 : void RecovDocList::InitEntry(SvTreeListEntry* pEntry,
816 : const OUString& rText,
817 : const Image& rImage1,
818 : const Image& rImage2,
819 : SvLBoxButtonKind eButtonKind)
820 : {
821 0 : SvTabListBox::InitEntry(pEntry, rText, rImage1, rImage2, eButtonKind);
822 : DBG_ASSERT( TabCount() == 2, "*RecovDocList::InitEntry(): structure missmatch" );
823 :
824 0 : SvLBoxString* pCol = static_cast<SvLBoxString*>(pEntry->GetItem(2));
825 0 : RecovDocListEntry* p = new RecovDocListEntry(pEntry, 0, pCol->GetText());
826 0 : pEntry->ReplaceItem(p, 2);
827 0 : }
828 :
829 :
830 0 : short impl_askUserForWizardCancel(vcl::Window* pParent, sal_Int16 nRes)
831 : {
832 0 : MessageDialog aQuery(pParent, SVX_RES(nRes), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
833 0 : if (aQuery.Execute() == RET_YES)
834 0 : return DLG_RET_OK;
835 : else
836 0 : return DLG_RET_CANCEL;
837 : }
838 :
839 0 : RecoveryDialog::RecoveryDialog(vcl::Window* pParent, RecoveryCore* pCore)
840 : : Dialog(pParent, "DocRecoveryRecoverDialog",
841 : "svx/ui/docrecoveryrecoverdialog.ui")
842 0 : , m_aTitleRecoveryInProgress(SVX_RESSTR(RID_SVXSTR_RECOVERY_INPROGRESS))
843 0 : , m_aRecoveryOnlyFinish (SVX_RESSTR(RID_SVXSTR_RECOVERYONLY_FINISH))
844 0 : , m_aRecoveryOnlyFinishDescr(SVX_RESSTR(RID_SVXSTR_RECOVERYONLY_FINISH_DESCR))
845 : , m_pCore(pCore)
846 : , m_eRecoveryState(RecoveryDialog::E_RECOVERY_PREPARED)
847 : , m_bWaitForCore(false)
848 0 : , m_bWasRecoveryStarted(false)
849 : {
850 0 : get(m_pTitleFT, "title");
851 0 : get(m_pDescrFT, "desc");
852 0 : get(m_pProgrParent, "progress");
853 0 : m_pProgrParent->set_height_request(LogicToPixel(Size(0, PROGR_HEIGHT), MAP_APPFONT).Height());
854 0 : get(m_pNextBtn, "next");
855 0 : get(m_pCancelBtn, "cancel");
856 :
857 0 : SvSimpleTableContainer* pFileListLBContainer = get<SvSimpleTableContainer>("filelist");
858 0 : Size aSize(LogicToPixel(Size(RECOV_CONTROLWIDTH, RECOV_FILELISTHEIGHT), MAP_APPFONT));
859 0 : pFileListLBContainer->set_width_request(aSize.Width());
860 0 : pFileListLBContainer->set_height_request(aSize.Height());
861 0 : m_pFileListLB = new RecovDocList(*pFileListLBContainer, DIALOG_MGR());
862 :
863 : static long nTabs[] = { 2, 0, 40*RECOV_CONTROLWIDTH/100 };
864 0 : m_pFileListLB->SetTabs( &nTabs[0] );
865 0 : m_pFileListLB->InsertHeaderEntry(get<FixedText>("nameft")->GetText() + "\t" + get<FixedText>("statusft")->GetText());
866 :
867 0 : PluginProgress* pProgress = new PluginProgress(m_pProgrParent, pCore->getComponentContext());
868 0 : m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW);
869 :
870 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
871 0 : m_pTitleFT->SetBackground(rStyleSettings.GetWindowColor());
872 0 : m_pTitleFT->set_height_request(m_pTitleFT->get_preferred_size().Height() + 48);
873 :
874 0 : m_pFileListLB->SetBackground( rStyleSettings.GetDialogColor() );
875 :
876 0 : m_pNextBtn->Enable(true);
877 0 : m_pNextBtn->SetClickHdl( LINK( this, RecoveryDialog, NextButtonHdl ) );
878 0 : m_pCancelBtn->SetClickHdl( LINK( this, RecoveryDialog, CancelButtonHdl ) );
879 :
880 : // fill list box first time
881 0 : TURLList* pURLList = m_pCore->getURLListAccess();
882 0 : TURLList::const_iterator pIt;
883 0 : for ( pIt = pURLList->begin();
884 0 : pIt != pURLList->end() ;
885 : ++pIt )
886 : {
887 0 : const TURLInfo& rInfo = *pIt;
888 :
889 0 : OUString sName( rInfo.DisplayName );
890 0 : sName += "\t";
891 0 : sName += impl_getStatusString( rInfo );
892 0 : SvTreeListEntry* pEntry = m_pFileListLB->InsertEntry(sName, rInfo.StandardImage, rInfo.StandardImage);
893 0 : pEntry->SetUserData((void*)&rInfo);
894 0 : }
895 :
896 : // mark first item
897 0 : SvTreeListEntry* pFirst = m_pFileListLB->First();
898 0 : if (pFirst)
899 0 : m_pFileListLB->SetCursor(pFirst, true);
900 0 : }
901 :
902 0 : RecoveryDialog::~RecoveryDialog()
903 : {
904 0 : delete m_pFileListLB;
905 0 : }
906 :
907 0 : short RecoveryDialog::execute()
908 : {
909 0 : ::SolarMutexGuard aSolarLock;
910 :
911 0 : switch (m_eRecoveryState)
912 : {
913 : case RecoveryDialog::E_RECOVERY_IN_PROGRESS :
914 : {
915 : // user decided to start recovery ...
916 0 : m_bWasRecoveryStarted = true;
917 : // do it asynchronous (to allow repaints)
918 : // and wait for this asynchronous operation.
919 0 : m_pDescrFT->SetText( m_aTitleRecoveryInProgress );
920 0 : m_pNextBtn->Enable(false);
921 0 : m_pCancelBtn->Enable(false);
922 0 : m_pCore->setProgressHandler(m_xProgress);
923 0 : m_pCore->setUpdateListener(this);
924 0 : m_pCore->doRecovery();
925 :
926 0 : m_bWaitForCore = true;
927 0 : while(m_bWaitForCore)
928 0 : Application::Yield();
929 :
930 0 : m_pCore->setUpdateListener(0);
931 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_CORE_DONE;
932 0 : return execute();
933 : }
934 :
935 : case RecoveryDialog::E_RECOVERY_CORE_DONE :
936 : {
937 : // the core finished it's task.
938 : // let the user decide the next step.
939 0 : m_pDescrFT->SetText(m_aRecoveryOnlyFinishDescr);
940 0 : m_pNextBtn->SetText(m_aRecoveryOnlyFinish);
941 0 : m_pNextBtn->Enable(true);
942 0 : m_pCancelBtn->Enable(false);
943 0 : return 0;
944 : }
945 :
946 : case RecoveryDialog::E_RECOVERY_DONE :
947 : {
948 : // All documents was reovered.
949 : // User decided to step to the "next" wizard page.
950 : // Do it ... but check first, if there exist some
951 : // failed recovery documents. They must be saved to
952 : // a user selected directrory.
953 0 : short nRet = DLG_RET_UNKNOWN;
954 0 : boost::scoped_ptr<BrokenRecoveryDialog> pBrokenRecoveryDialog(new BrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted));
955 0 : OUString sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); // get the default dir
956 0 : if (pBrokenRecoveryDialog->isExecutionNeeded())
957 : {
958 0 : nRet = pBrokenRecoveryDialog->Execute();
959 0 : sSaveDir = pBrokenRecoveryDialog->getSaveDirURL();
960 : }
961 0 : pBrokenRecoveryDialog.reset();
962 :
963 0 : switch(nRet)
964 : {
965 : // no broken temp files exists
966 : // step to the next wizard page
967 : case DLG_RET_UNKNOWN :
968 : {
969 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
970 0 : return DLG_RET_OK;
971 : }
972 :
973 : // user decided to save the broken temp files
974 : // do and forget it
975 : // step to the next wizard page
976 : case DLG_RET_OK :
977 : {
978 0 : m_pCore->saveBrokenTempEntries(sSaveDir);
979 0 : m_pCore->forgetBrokenTempEntries();
980 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
981 0 : return DLG_RET_OK;
982 : }
983 :
984 : // user decided to ignore broken temp files.
985 : // Ask it again ... may be this decision was wrong.
986 : // Results:
987 : // IGNORE => remove broken temp files
988 : // => step to the next wizard page
989 : // CANCEL => step back to the recovery page
990 : case DLG_RET_CANCEL :
991 : {
992 : // TODO ask user ...
993 0 : m_pCore->forgetBrokenTempEntries();
994 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
995 0 : return DLG_RET_OK;
996 : }
997 : }
998 :
999 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
1000 0 : return DLG_RET_OK;
1001 : }
1002 :
1003 : case RecoveryDialog::E_RECOVERY_CANCELED :
1004 : {
1005 : // "YES" => break recovery
1006 : // But there exist different states, where "cancel" can be called.
1007 : // Handle it different.
1008 0 : if (m_bWasRecoveryStarted)
1009 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS;
1010 : else
1011 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_BEFORE;
1012 0 : return execute();
1013 : }
1014 :
1015 : case RecoveryDialog::E_RECOVERY_CANCELED_BEFORE :
1016 : case RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS :
1017 : {
1018 : // We have to check if there exists some temp. files.
1019 : // They should be saved to a user defined location.
1020 : // If no temp files exists or user decided to ignore it ...
1021 : // we have to remove all recovery/session data anyway!
1022 0 : short nRet = DLG_RET_UNKNOWN;
1023 0 : boost::scoped_ptr<BrokenRecoveryDialog> pBrokenRecoveryDialog(new BrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted));
1024 0 : OUString sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); // get the default save location
1025 :
1026 : // dialog itself checks if there is a need to copy files for this mode.
1027 : // It uses the information m_bWasRecoveryStarted doing so.
1028 0 : if (pBrokenRecoveryDialog->isExecutionNeeded())
1029 : {
1030 0 : nRet = pBrokenRecoveryDialog->Execute();
1031 0 : sSaveDir = pBrokenRecoveryDialog->getSaveDirURL();
1032 : }
1033 0 : pBrokenRecoveryDialog.reset();
1034 :
1035 : // Possible states:
1036 : // a) nRet == DLG_RET_UNKNOWN
1037 : // dialog was not shown ...
1038 : // because there exists no temp file for copy.
1039 : // => remove all recovery data
1040 : // b) nRet == DLG_RET_OK
1041 : // dialog was shown ...
1042 : // user decided to save temp files
1043 : // => save all OR broken temp files (depends from the time, where cancel was called)
1044 : // => remove all recovery data
1045 : // c) nRet == DLG_RET_CANCEL
1046 : // dialog was shown ...
1047 : // user decided to ignore temp files
1048 : // => remove all recovery data
1049 : // => a)/c) are the same ... b) has one additional operation
1050 :
1051 : // b)
1052 0 : if (nRet == DLG_RET_OK)
1053 : {
1054 0 : if (m_bWasRecoveryStarted)
1055 0 : m_pCore->saveBrokenTempEntries(sSaveDir);
1056 : else
1057 0 : m_pCore->saveAllTempEntries(sSaveDir);
1058 : }
1059 :
1060 : // a,b,c)
1061 0 : if (m_bWasRecoveryStarted)
1062 0 : m_pCore->forgetBrokenRecoveryEntries();
1063 : else
1064 0 : m_pCore->forgetAllRecoveryEntries();
1065 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
1066 :
1067 : // THERE IS NO WAY BACK. see impl_askUserForWizardCancel()!
1068 0 : return DLG_RET_CANCEL;
1069 : }
1070 : }
1071 :
1072 : // should never be reached .-)
1073 : OSL_FAIL("Should never be reached!");
1074 0 : return DLG_RET_OK;
1075 : }
1076 :
1077 0 : void RecoveryDialog::start()
1078 : {
1079 0 : }
1080 :
1081 0 : void RecoveryDialog::updateItems()
1082 : {
1083 0 : sal_uIntPtr c = m_pFileListLB->GetEntryCount();
1084 0 : sal_uIntPtr i = 0;
1085 0 : for ( i=0; i<c; ++i )
1086 : {
1087 0 : SvTreeListEntry* pEntry = m_pFileListLB->GetEntry(i);
1088 0 : if ( !pEntry )
1089 0 : continue;
1090 :
1091 0 : TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData();
1092 0 : if ( !pInfo )
1093 0 : continue;
1094 :
1095 0 : OUString sStatus = impl_getStatusString( *pInfo );
1096 0 : if ( !sStatus.isEmpty() )
1097 0 : m_pFileListLB->SetEntryText( sStatus, pEntry, 1 );
1098 0 : }
1099 :
1100 0 : m_pFileListLB->Invalidate();
1101 0 : m_pFileListLB->Update();
1102 0 : }
1103 :
1104 :
1105 0 : void RecoveryDialog::stepNext(TURLInfo* pItem)
1106 : {
1107 0 : sal_uIntPtr c = m_pFileListLB->GetEntryCount();
1108 0 : sal_uIntPtr i = 0;
1109 0 : for (i=0; i<c; ++i)
1110 : {
1111 0 : SvTreeListEntry* pEntry = m_pFileListLB->GetEntry(i);
1112 0 : if (!pEntry)
1113 0 : continue;
1114 :
1115 0 : TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData();
1116 0 : if (pInfo->ID != pItem->ID)
1117 0 : continue;
1118 :
1119 0 : m_pFileListLB->SetCursor(pEntry, true);
1120 0 : m_pFileListLB->MakeVisible(pEntry);
1121 0 : m_pFileListLB->Invalidate();
1122 0 : m_pFileListLB->Update();
1123 0 : break;
1124 : }
1125 0 : }
1126 :
1127 0 : void RecoveryDialog::end()
1128 : {
1129 0 : m_bWaitForCore = false;
1130 0 : }
1131 :
1132 0 : IMPL_LINK_NOARG(RecoveryDialog, NextButtonHdl)
1133 : {
1134 0 : switch (m_eRecoveryState)
1135 : {
1136 : case RecoveryDialog::E_RECOVERY_PREPARED:
1137 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_IN_PROGRESS;
1138 0 : execute();
1139 0 : break;
1140 : case RecoveryDialog::E_RECOVERY_CORE_DONE:
1141 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_DONE;
1142 0 : execute();
1143 0 : break;
1144 : }
1145 :
1146 0 : if (m_eRecoveryState == RecoveryDialog::E_RECOVERY_HANDLED)
1147 : {
1148 0 : EndDialog(DLG_RET_OK);
1149 0 : return DLG_RET_OK;
1150 : }
1151 :
1152 0 : return 0;
1153 : }
1154 :
1155 0 : IMPL_LINK_NOARG(RecoveryDialog, CancelButtonHdl)
1156 : {
1157 0 : switch (m_eRecoveryState)
1158 : {
1159 : case RecoveryDialog::E_RECOVERY_PREPARED:
1160 0 : if (impl_askUserForWizardCancel(this, RID_SVXSTR_QUERY_EXIT_RECOVERY) != DLG_RET_CANCEL)
1161 : {
1162 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED;
1163 0 : execute();
1164 : }
1165 0 : break;
1166 : case RecoveryDialog::E_RECOVERY_CORE_DONE:
1167 0 : m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED;
1168 0 : execute();
1169 0 : break;
1170 : }
1171 :
1172 0 : if (m_eRecoveryState == RecoveryDialog::E_RECOVERY_HANDLED)
1173 : {
1174 0 : EndDialog(DLG_RET_CANCEL);
1175 0 : return DLG_RET_CANCEL;
1176 : }
1177 :
1178 0 : return 0;
1179 : }
1180 :
1181 0 : OUString RecoveryDialog::impl_getStatusString( const TURLInfo& rInfo ) const
1182 : {
1183 0 : OUString sStatus;
1184 0 : switch ( rInfo.RecoveryState )
1185 : {
1186 : case E_SUCCESSFULLY_RECOVERED :
1187 0 : sStatus = m_pFileListLB->m_aSuccessRecovStr;
1188 0 : break;
1189 : case E_ORIGINAL_DOCUMENT_RECOVERED :
1190 0 : sStatus = m_pFileListLB->m_aOrigDocRecovStr;
1191 0 : break;
1192 : case E_RECOVERY_FAILED :
1193 0 : sStatus = m_pFileListLB->m_aRecovFailedStr;
1194 0 : break;
1195 : case E_RECOVERY_IS_IN_PROGRESS :
1196 0 : sStatus = m_pFileListLB->m_aRecovInProgrStr;
1197 0 : break;
1198 : case E_NOT_RECOVERED_YET :
1199 0 : sStatus = m_pFileListLB->m_aNotRecovYetStr;
1200 0 : break;
1201 : default:
1202 0 : break;
1203 : }
1204 0 : return sStatus;
1205 : }
1206 :
1207 0 : BrokenRecoveryDialog::BrokenRecoveryDialog(vcl::Window* pParent ,
1208 : RecoveryCore* pCore ,
1209 : bool bBeforeRecovery)
1210 : : ModalDialog ( pParent, "DocRecoveryBrokenDialog", "svx/ui/docrecoverybrokendialog.ui" )
1211 : , m_pCore ( pCore )
1212 : , m_bBeforeRecovery (bBeforeRecovery)
1213 0 : , m_bExecutionNeeded(false)
1214 : {
1215 0 : get(m_pFileListLB, "filelist");
1216 0 : get(m_pSaveDirED, "savedir");
1217 0 : get(m_pSaveDirBtn, "change");
1218 0 : get(m_pOkBtn, "save");
1219 0 : get(m_pCancelBtn, "cancel");
1220 :
1221 0 : m_pSaveDirBtn->SetClickHdl( LINK( this, BrokenRecoveryDialog, SaveButtonHdl ) );
1222 0 : m_pOkBtn->SetClickHdl( LINK( this, BrokenRecoveryDialog, OkButtonHdl ) );
1223 0 : m_pCancelBtn->SetClickHdl( LINK( this, BrokenRecoveryDialog, CancelButtonHdl ) );
1224 :
1225 0 : m_sSavePath = SvtPathOptions().GetWorkPath();
1226 0 : INetURLObject aObj( m_sSavePath );
1227 0 : OUString sPath;
1228 0 : ::utl::LocalFileHelper::ConvertURLToSystemPath( aObj.GetMainURL( INetURLObject::NO_DECODE ), sPath );
1229 0 : m_pSaveDirED->SetText( sPath );
1230 :
1231 0 : impl_refresh();
1232 0 : }
1233 :
1234 :
1235 0 : BrokenRecoveryDialog::~BrokenRecoveryDialog()
1236 : {
1237 0 : }
1238 :
1239 :
1240 0 : void BrokenRecoveryDialog::impl_refresh()
1241 : {
1242 0 : m_bExecutionNeeded = false;
1243 0 : TURLList* pURLList = m_pCore->getURLListAccess();
1244 0 : TURLList::const_iterator pIt;
1245 0 : for ( pIt = pURLList->begin();
1246 0 : pIt != pURLList->end() ;
1247 : ++pIt )
1248 : {
1249 0 : const TURLInfo& rInfo = *pIt;
1250 :
1251 0 : if (m_bBeforeRecovery)
1252 : {
1253 : // "Cancel" before recovery ->
1254 : // search for any temp files!
1255 0 : if (rInfo.TempURL.isEmpty())
1256 0 : continue;
1257 : }
1258 : else
1259 : {
1260 : // "Cancel" after recovery ->
1261 : // search for broken temp files
1262 0 : if (!RecoveryCore::isBrokenTempEntry(rInfo))
1263 0 : continue;
1264 : }
1265 :
1266 0 : m_bExecutionNeeded = true;
1267 :
1268 0 : sal_uInt16 nPos = m_pFileListLB->InsertEntry(rInfo.DisplayName, rInfo.StandardImage );
1269 0 : m_pFileListLB->SetEntryData( nPos, (void*)&rInfo );
1270 : }
1271 0 : m_sSavePath = "";
1272 0 : m_pOkBtn->GrabFocus();
1273 0 : }
1274 :
1275 :
1276 0 : bool BrokenRecoveryDialog::isExecutionNeeded()
1277 : {
1278 0 : return m_bExecutionNeeded;
1279 : }
1280 :
1281 :
1282 0 : OUString BrokenRecoveryDialog::getSaveDirURL()
1283 : {
1284 0 : return m_sSavePath;
1285 : }
1286 :
1287 :
1288 0 : IMPL_LINK_NOARG(BrokenRecoveryDialog, OkButtonHdl)
1289 : {
1290 0 : OUString sPhysicalPath = comphelper::string::strip(m_pSaveDirED->GetText(), ' ');
1291 0 : OUString sURL;
1292 0 : ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPhysicalPath, sURL );
1293 0 : m_sSavePath = sURL;
1294 0 : while (m_sSavePath.isEmpty())
1295 0 : impl_askForSavePath();
1296 :
1297 0 : EndDialog(DLG_RET_OK);
1298 0 : return 0;
1299 : }
1300 :
1301 :
1302 0 : IMPL_LINK_NOARG(BrokenRecoveryDialog, CancelButtonHdl)
1303 : {
1304 0 : EndDialog(DLG_RET_CANCEL);
1305 0 : return 0;
1306 : }
1307 :
1308 :
1309 0 : IMPL_LINK_NOARG(BrokenRecoveryDialog, SaveButtonHdl)
1310 : {
1311 0 : impl_askForSavePath();
1312 0 : return 0;
1313 : }
1314 :
1315 :
1316 0 : void BrokenRecoveryDialog::impl_askForSavePath()
1317 : {
1318 : css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker =
1319 0 : css::ui::dialogs::FolderPicker::create( m_pCore->getComponentContext() );
1320 :
1321 0 : INetURLObject aURL(m_sSavePath, INET_PROT_FILE);
1322 0 : xFolderPicker->setDisplayDirectory(aURL.GetMainURL(INetURLObject::NO_DECODE));
1323 0 : short nRet = xFolderPicker->execute();
1324 0 : if (nRet == css::ui::dialogs::ExecutableDialogResults::OK)
1325 : {
1326 0 : m_sSavePath = xFolderPicker->getDirectory();
1327 0 : OUString sPath;
1328 0 : ::utl::LocalFileHelper::ConvertURLToSystemPath( m_sSavePath, sPath );
1329 0 : m_pSaveDirED->SetText( sPath );
1330 0 : }
1331 0 : }
1332 :
1333 : } // namespace DocRecovery
1334 594 : } // namespace svx
1335 :
1336 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|