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