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_cui.hxx" 26 27 #include <comphelper/processfactory.hxx> 28 #include <dialmgr.hxx> 29 #include <osl/file.hxx> 30 #include <rtl/bootstrap.hxx> 31 //#include <rtl/ustrbuf.hxx> 32 #include <sfx2/sfxcommands.h> 33 #include <sfx2/sfxdefs.hxx> 34 #include <sfx2/sfxuno.hxx> 35 #include <svtools/filter.hxx> 36 #include <svtools/svtools.hrc> 37 #include <tools/stream.hxx> 38 #include <tools/urlobj.hxx> 39 #include <unotools/bootstrap.hxx> 40 #include <unotools/configmgr.hxx> 41 #include <vcl/graph.hxx> 42 #include <vcl/imagerepository.hxx> 43 #include <vcl/msgbox.hxx> 44 #include <vcl/svapp.hxx> 45 #include <vcl/tabctrl.hxx> 46 #include <vcl/tabdlg.hxx> 47 #include <vcl/tabpage.hxx> 48 49 #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 50 #include <com/sun/star/system/SystemShellExecute.hpp> 51 #include <com/sun/star/uno/Any.h> 52 53 #include "about.hxx" 54 #include "about.hrc" 55 56 #define _STRINGIFY(x) #x 57 #define STRINGIFY(x) _STRINGIFY(x) 58 59 /* On Windows/OS2, all the three files have .txt extension 60 and the README file name is in lowercase 61 Readme files are localized and have the locale in their file name: 62 README_de README_en-US 63 */ 64 #if defined(WNT) || defined(OS2) 65 #define FILE_EXTENSION ".txt" 66 #define README_FILE "readme" 67 #else 68 #define FILE_EXTENSION 69 #define README_FILE "README" 70 #endif 71 #define LICENSE_FILE "LICENSE" FILE_EXTENSION 72 #define NOTICE_FILE "NOTICE" FILE_EXTENSION 73 74 // Dir where the files are located 75 #define OOO_DIR_SHARE_README "${OOO_BASE_DIR}/share/readme/" 76 77 using namespace com::sun::star; 78 79 namespace 80 { 81 82 static void lcl_layoutFixedText( FixedText &rControl, 83 const Point& aPos, 84 Size &aSize, 85 const long nTextWidth ) 86 { 87 aSize = rControl.GetSizePixel(); 88 // change the width 89 aSize.Width() = nTextWidth; 90 // set Position and Size, to calculate the minimum size 91 // this will update the Height 92 rControl.SetPosSizePixel( aPos, aSize ); 93 aSize = rControl.CalcMinimumSize(); 94 // update the size with the right Height 95 rControl.SetSizePixel( aSize ); 96 } 97 98 static void lcl_layoutEdit( Edit &rControl, 99 const Point& aPos, 100 Size &aSize, 101 const long nTextWidth ) 102 { 103 aSize = rControl.GetSizePixel(); 104 // change the width 105 aSize.Width() = nTextWidth; 106 // set Position and Size, to calculate the minimum size 107 // this will update the Height 108 rControl.SetPosSizePixel( aPos, aSize ); 109 aSize = rControl.CalcMinimumSize(); 110 // update the size with the right Height 111 rControl.SetSizePixel( aSize ); 112 } 113 114 static void lcl_readTxtFile( const rtl::OUString &rFile, rtl::OUString &sText ) 115 { 116 rtl::OUString sFile( rFile ); 117 rtl::Bootstrap::expandMacros( sFile ); 118 osl::File aFile(sFile); 119 if ( aFile.open(OpenFlag_Read) == osl::FileBase::E_None ) 120 { 121 osl::DirectoryItem aItem; 122 osl::DirectoryItem::get(sFile, aItem); 123 124 osl::FileStatus aStatus(FileStatusMask_FileSize); 125 aItem.getFileStatus(aStatus); 126 127 sal_uInt64 nBytesRead = 0; 128 sal_uInt64 nPosition = 0; 129 sal_uInt32 nBytes = (sal_uInt32)aStatus.getFileSize(); 130 131 sal_Char *pBuffer = new sal_Char[nBytes]; 132 133 while ( aFile.read( pBuffer + nPosition, 134 nBytes-nPosition, 135 nBytesRead ) == osl::FileBase::E_None 136 && nPosition + nBytesRead < nBytes) 137 { 138 nPosition += nBytesRead; 139 } 140 141 OSL_ENSURE( nBytes < STRING_MAXLEN, "Text file has too much bytes!" ); 142 if ( nBytes > STRING_MAXLEN ) 143 nBytes = STRING_MAXLEN - 1; 144 145 sText = rtl::OUString( pBuffer, 146 nBytes, 147 RTL_TEXTENCODING_UTF8, 148 OSTRING_TO_OUSTRING_CVTFLAGS 149 | RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE); 150 delete[] pBuffer; 151 } 152 } 153 154 class ReadmeDialog; 155 156 class ReadmeTabPage : public TabPage 157 { 158 private: 159 MultiLineEdit maText; 160 String msText; 161 162 public: 163 ReadmeTabPage(Window *pParent, const String &sText); 164 ~ReadmeTabPage(); 165 166 void Adjust(const Size &aSz, const Size &a6Size); 167 }; 168 169 ReadmeTabPage::ReadmeTabPage(Window *pParent, const String &sText) 170 : TabPage(pParent, CUI_RES( RID_CUI_README_TBPAGE)) 171 ,maText( this, CUI_RES( RID_CUI_README_TBPAGE_EDIT )) 172 ,msText( sText ) 173 { 174 FreeResource(); 175 176 maText.SetText(msText); 177 maText.Show(); 178 } 179 180 ReadmeTabPage::~ReadmeTabPage() 181 { 182 } 183 184 void ReadmeTabPage::Adjust(const Size &aSz, const Size &a6Size) 185 { 186 long nDlgMargin = a6Size.Width() * 2; 187 long nCtrlMargin = a6Size.Height() * 2; 188 maText.SetPosPixel( Point(a6Size.Width(), a6Size.Height()) ); 189 maText.SetSizePixel( Size(aSz.Width() - nDlgMargin, aSz.Height() - nCtrlMargin) ); 190 } 191 192 class ReadmeDialog : public ModalDialog 193 { 194 private: 195 TabControl maTabCtrl; 196 OKButton maBtnOK; 197 198 ReadmeTabPage *maReadmeTabPage; 199 ReadmeTabPage *maLicenseTabPage; 200 ReadmeTabPage *maNoticeTabPage; 201 202 DECL_LINK( ActivatePageHdl, TabControl * ); 203 DECL_LINK( DeactivatePageHdl, TabControl * ); 204 205 public: 206 ReadmeDialog( Window* ); 207 ~ReadmeDialog(); 208 }; 209 210 ReadmeDialog::ReadmeDialog( Window * pParent ) 211 : ModalDialog( pParent, CUI_RES( RID_CUI_README_DLG ) ) 212 , maTabCtrl( this, CUI_RES(RID_CUI_README_TBCTL) ) 213 , maBtnOK( this, CUI_RES(RID_CUI_README_OKBTN) ) 214 , maReadmeTabPage(0) 215 , maLicenseTabPage(0) 216 , maNoticeTabPage(0) 217 { 218 FreeResource(); 219 220 maTabCtrl.Show(); 221 222 // Notice and License are not localized 223 const rtl::OUString sLicense( RTL_CONSTASCII_USTRINGPARAM( OOO_DIR_SHARE_README LICENSE_FILE ) ); 224 const rtl::OUString sNotice( RTL_CONSTASCII_USTRINGPARAM( OOO_DIR_SHARE_README NOTICE_FILE ) ); 225 226 // get localized README 227 rtl::OUStringBuffer aBuff; 228 lang::Locale aLocale = Application::GetSettings().GetUILocale(); 229 aBuff.appendAscii( RTL_CONSTASCII_STRINGPARAM( OOO_DIR_SHARE_README README_FILE "_" ) ); 230 aBuff.append( aLocale.Language ); 231 if ( aLocale.Country.getLength() ) 232 { 233 aBuff.append( sal_Unicode( '-') ); 234 aBuff.append( aLocale.Country ); 235 if ( aLocale.Variant.getLength() ) 236 { 237 aBuff.append( sal_Unicode( '-' ) ); 238 aBuff.append( aLocale.Variant ); 239 } 240 } 241 #if defined(WNT) || defined(OS2) 242 aBuff.appendAscii( RTL_CONSTASCII_STRINGPARAM( FILE_EXTENSION ) ); 243 #endif 244 245 rtl::OUString sReadmeTxt, sLicenseTxt, sNoticeTxt; 246 lcl_readTxtFile( aBuff.makeStringAndClear(), sReadmeTxt ); 247 lcl_readTxtFile( sLicense, sLicenseTxt ); 248 lcl_readTxtFile( sNotice, sNoticeTxt ); 249 250 maReadmeTabPage = new ReadmeTabPage( &maTabCtrl, sReadmeTxt ); 251 maLicenseTabPage = new ReadmeTabPage( &maTabCtrl, sLicenseTxt ); 252 maNoticeTabPage = new ReadmeTabPage( &maTabCtrl, sNoticeTxt ); 253 254 maTabCtrl.SetTabPage( RID_CUI_READMEPAGE, maReadmeTabPage ); 255 maTabCtrl.SetTabPage( RID_CUI_LICENSEPAGE, maLicenseTabPage ); 256 maTabCtrl.SetTabPage( RID_CUI_NOTICEPAGE, maNoticeTabPage ); 257 258 maTabCtrl.SelectTabPage( RID_CUI_READMEPAGE ); 259 260 Size aTpSz = maReadmeTabPage->GetOutputSizePixel(); 261 Size a6Size = maReadmeTabPage->LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); 262 263 maReadmeTabPage->Adjust( aTpSz, a6Size ); 264 maLicenseTabPage->Adjust( aTpSz, a6Size ); 265 maNoticeTabPage->Adjust( aTpSz, a6Size ); 266 267 Size aDlgSize = GetOutputSizePixel(); 268 Size aOkBtnSz = maBtnOK.GetSizePixel(); 269 Point aOKPnt( aDlgSize.Width() / 2 - aOkBtnSz.Width() / 2 , maBtnOK.GetPosPixel().Y() ); 270 maBtnOK.SetPosPixel( aOKPnt ); 271 } 272 273 ReadmeDialog::~ReadmeDialog() 274 { 275 delete maReadmeTabPage; 276 delete maLicenseTabPage; 277 delete maNoticeTabPage; 278 } 279 } 280 281 // ----------------------------------------------------------------------- 282 283 AboutDialog::AboutDialog( Window* pParent, const ResId & rId ) : 284 SfxModalDialog( pParent, rId ), 285 maOKButton( this, ResId( RID_CUI_ABOUT_BTN_OK, *rId.GetResMgr() ) ), 286 maReadmeButton( this, ResId( RID_CUI_ABOUT_BTN_README, *rId.GetResMgr() ) ), 287 maVersionText( this, ResId( RID_CUI_ABOUT_FTXT_VERSION, *rId.GetResMgr() ) ), 288 maBuildInfoEdit( this, ResId( RID_CUI_ABOUT_FTXT_BUILDDATA, *rId.GetResMgr() ) ), 289 maCopyrightEdit( this, ResId( RID_CUI_ABOUT_FTXT_COPYRIGHT, *rId.GetResMgr() ) ), 290 maCreditsLink( this, ResId( RID_CUI_ABOUT_FTXT_WELCOME_LINK, *rId.GetResMgr() ) ) 291 // maCopyrightTextStr( ResId( RID_CUI_ABOUT_STR_COPYRIGHT, *rId.GetResMgr() ) ) 292 { 293 bool bLoad = vcl::ImageRepository::loadBrandingImage( 294 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("about")), 295 maAppLogo ); 296 OSL_ENSURE( bLoad, "Can't load about image"); 297 298 bLoad = vcl::ImageRepository::loadBrandingImage( 299 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("logo")), 300 maMainLogo ); 301 OSL_ENSURE( bLoad, "Can't load logo image"); 302 303 const String vendor( ResId( RID_CUI_ABOUT_STR_COPYRIGHT_VENDOR, *rId.GetResMgr() ) ); 304 String createdRes( ResId( RID_CUI_ABOUT_STR_CREATED, *rId.GetResMgr() ) ); 305 if ( !vendor.EqualsAscii("Apache Software Foundation") ) { 306 createdRes = String( ResId( RID_CUI_ABOUT_STR_CREATED_VENDOR, *rId.GetResMgr() )); 307 } 308 const String copyrightAcknowledge( ResId( RID_CUI_ABOUT_STR_ACKNOWLEDGE, *rId.GetResMgr() ) ); 309 310 rtl::OUStringBuffer sbcopyright(250); 311 sbcopyright.appendAscii("Copyright "); 312 sbcopyright.append((sal_Unicode)0x00a9); 313 sbcopyright.appendAscii(" "); 314 // TODO: 315 // This date needs to be updated each year... do this automagically 316 // 317 rtl::OUString sYear( RTL_CONSTASCII_USTRINGPARAM("2021") ); 318 if (vendor.EqualsAscii("Apache Software Foundation")) { 319 sbcopyright.append(sYear); 320 sbcopyright.appendAscii(" The Apache Software Foundation.\n\n"); 321 } else { 322 #ifdef COPYRIGHT_YEAR 323 const rtl::OUString sDefYear( RTL_CONSTASCII_USTRINGPARAM( STRINGIFY( COPYRIGHT_YEAR ) ) ); 324 if ( sDefYear.getLength() > 0 ) 325 { 326 sYear = sDefYear; 327 } 328 #endif 329 sbcopyright.append(sYear); 330 sbcopyright.appendAscii(" "); 331 sbcopyright.append(vendor); 332 sbcopyright.appendAscii(".\nPortion copyright The Apache Software Foundation.\n\n"); 333 } 334 sbcopyright.append( createdRes ); 335 sbcopyright.appendAscii("\n\n"); 336 sbcopyright.append( copyrightAcknowledge ); 337 maCopyrightTextStr = sbcopyright.makeStringAndClear(); 338 339 InitControls(); 340 341 // set links 342 maReadmeButton.SetClickHdl( LINK( this, AboutDialog, ShowReadme_Impl ) ); 343 maCreditsLink.SetClickHdl( LINK( this, AboutDialog, OpenLinkHdl_Impl ) ); 344 345 FreeResource(); 346 347 SetHelpId( CMD_SID_ABOUT ); 348 } 349 350 // ----------------------------------------------------------------------- 351 352 AboutDialog::~AboutDialog() 353 { 354 } 355 356 // ----------------------------------------------------------------------- 357 358 void AboutDialog::InitControls() 359 { 360 // apply font, background et al. 361 ApplyStyleSettings(); 362 363 // set strings 364 maCopyrightEdit.SetText( maCopyrightTextStr ); 365 maBuildInfoEdit.SetText( GetBuildVersionString() ); 366 maCreditsLink.SetURL( maCreditsLink.GetText() ); 367 368 // determine size and position of the dialog & elements 369 Size aDlgSize; 370 LayoutControls( aDlgSize ); 371 372 // Change the width of the dialog 373 SetOutputSizePixel( aDlgSize ); 374 } 375 376 // ----------------------------------------------------------------------- 377 378 void AboutDialog::ApplyStyleSettings() 379 { 380 // Transparenter Font 381 Font aFont = GetFont(); 382 aFont.SetTransparent( sal_True ); 383 SetFont( aFont ); 384 385 // set for background and text the correct system color 386 const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 387 Color aWindowColor( rSettings.GetWindowColor() ); 388 Wallpaper aWall( aWindowColor ); 389 SetBackground( aWall ); 390 391 Font aNewFont( maCopyrightEdit.GetFont() ); 392 aNewFont.SetTransparent( sal_True ); 393 394 maVersionText.SetFont( aNewFont ); 395 maCopyrightEdit.SetFont( aNewFont ); 396 397 maVersionText.SetBackground(aWall); 398 maCopyrightEdit.SetBackground(aWall); 399 maBuildInfoEdit.SetBackground(aWall); 400 maCreditsLink.SetBackground(aWall); 401 402 Color aTextColor( rSettings.GetWindowTextColor() ); 403 maVersionText.SetControlForeground( aTextColor ); 404 maCopyrightEdit.SetControlForeground( aTextColor ); 405 maBuildInfoEdit.SetControlForeground( aTextColor ); 406 maCreditsLink.SetControlForeground(); 407 408 Size aSmaller = aNewFont.GetSize(); 409 aSmaller.Width() = (long) (aSmaller.Width() * 0.75); 410 aSmaller.Height() = (long) (aSmaller.Height() * 0.75); 411 aNewFont.SetSize( aSmaller ); 412 413 maBuildInfoEdit.SetFont( aNewFont ); 414 415 // the following is a hack to force the MultiLineEdit update its settings 416 // in order to reflect the Font 417 // See 418 // Window::SetControlFont 419 // MultiLineEdit::StateChanged 420 // MultiLineEdit::ImplInitSettings 421 // TODO Override SetFont in MultiLineEdit and do the following, 422 // otherwise SetFont has no effect at all! 423 aSmaller = PixelToLogic( aSmaller, MAP_POINT ); 424 aNewFont.SetSize( aSmaller ); 425 maBuildInfoEdit.SetControlFont( aNewFont ); 426 } 427 428 // ----------------------------------------------------------------------- 429 430 void AboutDialog::LayoutControls( Size& aDlgSize ) 431 { 432 Size aMainLogoSz = maMainLogo.GetSizePixel(); 433 Size aAppLogoSiz = maAppLogo.GetSizePixel(); 434 435 aDlgSize = GetOutputSizePixel(); 436 long nCol1 = aMainLogoSz.Width(); 437 long nCol2 = aAppLogoSiz.Width() ? aAppLogoSiz.Width() : aDlgSize.Width(); 438 439 Size a6Size = maVersionText.LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); 440 long nDlgMargin = a6Size.Width() * 2; 441 long nCtrlMargin = a6Size.Height() * 2; 442 long nTextWidth = nCol2 - nDlgMargin; 443 long nY = aAppLogoSiz.Height() + a6Size.Height(); 444 445 aDlgSize.Width() = nCol1 + a6Size.Width() + nCol2; 446 447 Point aPos( nCol1 + a6Size.Width(), nY ); 448 Size aSize; 449 // layout fixed text control 450 lcl_layoutFixedText( maVersionText, aPos, aSize, nTextWidth ); 451 nY += aSize.Height() + a6Size.Height(); 452 453 // Multiline edit with Build info 454 aPos.Y() = nY; 455 lcl_layoutEdit( maBuildInfoEdit, aPos, aSize, nTextWidth ); 456 nY += aSize.Height() + a6Size.Height(); 457 458 // Multiline edit with Copyright-Text 459 aPos.Y() = nY; 460 lcl_layoutEdit( maCopyrightEdit, aPos, aSize, nTextWidth ); 461 nY += aSize.Height() + a6Size.Height(); 462 463 // Hyperlink 464 aPos.Y() = nY; 465 lcl_layoutFixedText( maCreditsLink, aPos, aSize, nTextWidth ); 466 nY += aSize.Height(); 467 468 nY = std::max( nY, aMainLogoSz.Height() ); 469 nY += nCtrlMargin; 470 471 // logos position 472 maMainLogoPos = Point( 0, nY / 2 - aMainLogoSz.Height() / 2 ); 473 maAppLogoPos = Point( nCol1 + a6Size.Width(), 0 ); 474 475 // OK-Button-Position (at the bottom and centered) 476 Size aOKSiz = maOKButton.GetSizePixel(); 477 Point aOKPnt( ( aDlgSize.Width() - aOKSiz.Width() ) - a6Size.Width(), nY ); 478 maOKButton.SetPosPixel( aOKPnt ); 479 480 maReadmeButton.SetPosPixel( Point(a6Size.Width(), nY) ); 481 482 aDlgSize.Height() = aOKPnt.Y() + aOKSiz.Height() + a6Size.Width(); 483 } 484 485 // ----------------------------------------------------------------------- 486 487 const rtl::OUString AboutDialog::GetBuildId() const 488 { 489 rtl::OUString sDefault; 490 491 // Get buildid from version[rc|.ini] 492 rtl::OUString sBuildId( utl::Bootstrap::getBuildIdData( sDefault ) ); 493 OSL_ENSURE( sBuildId.getLength() > 0, "No BUILDID in bootstrap file" ); 494 rtl::OUStringBuffer sBuildIdBuff( sBuildId ); 495 496 // Get ProductSource from version[rc|.ini] 497 rtl::OUString sProductSource( utl::Bootstrap::getProductSource( sDefault ) ); 498 OSL_ENSURE( sProductSource.getLength() > 0, "No ProductSource in bootstrap file" ); 499 500 // the product source is something like "AOO340", 501 // while the build id is something like "340m1(Build:9590)" 502 // For better readability, strip the duplicate ProductMajor ("340"). 503 if ( sProductSource.getLength() ) 504 { 505 bool bMatchingUPD = 506 ( sProductSource.getLength() >= 3 ) 507 && ( sBuildId.getLength() >= 3 ) 508 && ( sProductSource.copy( sProductSource.getLength() - 3 ) == sBuildId.copy( 0, 3 ) ); 509 OSL_ENSURE( bMatchingUPD, "BUILDID and ProductSource do not match in their UPD" ); 510 if ( bMatchingUPD ) 511 sProductSource = sProductSource.copy( 0, sProductSource.getLength() - 3 ); 512 513 // prepend the product source 514 sBuildIdBuff.insert( 0, sProductSource ); 515 } 516 517 return sBuildIdBuff.makeStringAndClear(); 518 } 519 520 // ----------------------------------------------------------------------- 521 522 const rtl::OUString AboutDialog::GetBuildVersionString() const 523 { 524 rtl::OUStringBuffer aBuildString( GetBuildId() ); 525 rtl::OUString sRevision( utl::Bootstrap::getRevisionInfo() ); 526 527 if ( sRevision.getLength() > 0 ) 528 { 529 aBuildString.appendAscii( RTL_CONSTASCII_STRINGPARAM( " - Rev. " ) ); 530 aBuildString.append( sRevision ); 531 } 532 533 #ifdef BUILD_VER_STRING 534 rtl::OUString sBuildVer( RTL_CONSTASCII_USTRINGPARAM( STRINGIFY( BUILD_VER_STRING ) ) ); 535 if ( sBuildVer.getLength() > 0 ) 536 { 537 aBuildString.append( sal_Unicode( '\n' ) ); 538 aBuildString.append( sBuildVer ); 539 } 540 #endif 541 542 return aBuildString.makeStringAndClear(); 543 } 544 545 // ----------------------------------------------------------------------- 546 547 sal_Bool AboutDialog::Close() 548 { 549 EndDialog( RET_OK ); 550 return( sal_False ); 551 } 552 553 // ----------------------------------------------------------------------- 554 555 void AboutDialog::Paint( const Rectangle& rRect ) 556 { 557 SetClipRegion( rRect ); 558 559 // workaround to ensure that the background is painted correct 560 // on MacOS for exmaple the background was grey and the image and other controls white 561 SetFillColor(GetSettings().GetStyleSettings().GetWindowColor()); 562 SetLineColor(); 563 DrawRect(rRect); 564 565 DrawImage( maMainLogoPos, maMainLogo ); 566 DrawImage( maAppLogoPos, maAppLogo ); 567 568 return; 569 } 570 571 // ----------------------------------------------------------------------- 572 573 IMPL_LINK ( AboutDialog, OpenLinkHdl_Impl, svt::FixedHyperlink*, EMPTYARG ) 574 { 575 ::rtl::OUString sURL( maCreditsLink.GetURL() ); 576 if ( sURL.getLength() > 0 ) 577 { 578 try 579 { 580 uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShell( 581 com::sun::star::system::SystemShellExecute::create( 582 ::comphelper::getProcessComponentContext() ) ); 583 if ( xSystemShell.is() ) 584 xSystemShell->execute( sURL, rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS ); 585 } 586 catch( const uno::Exception& e ) 587 { 588 OSL_TRACE( "Caught exception: %s\n thread terminated.\n", 589 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); 590 } 591 } 592 593 return 0; 594 } 595 596 IMPL_LINK ( AboutDialog, ShowReadme_Impl, PushButton*, EMPTYARG ) 597 { 598 ReadmeDialog aDlg( this ); 599 aDlg.Execute(); 600 601 return 0; 602 } 603