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