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