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