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 rtl::OUString sYear( RTL_CONSTASCII_USTRINGPARAM("2018") ); 315 if (vendor.EqualsAscii("Apache Software Foundation")) { 316 sbcopyright.append(sYear); 317 sbcopyright.appendAscii(" The Apache Software Foundation.\n\n"); 318 } else { 319 #ifdef COPYRIGHT_YEAR 320 const rtl::OUString sDefYear( RTL_CONSTASCII_USTRINGPARAM( STRINGIFY( COPYRIGHT_YEAR ) ) ); 321 if ( sDefYear.getLength() > 0 ) 322 { 323 sYear = sDefYear; 324 } 325 #endif 326 sbcopyright.append(sYear); 327 sbcopyright.appendAscii(" "); 328 sbcopyright.append(vendor); 329 sbcopyright.appendAscii(".\nPortion copyright The Apache Software Foundation.\n\n"); 330 } 331 sbcopyright.append( createdRes ); 332 sbcopyright.appendAscii("\n\n"); 333 sbcopyright.append( copyrightAcknowledge ); 334 maCopyrightTextStr = sbcopyright.makeStringAndClear(); 335 336 InitControls(); 337 338 // set links 339 maReadmeButton.SetClickHdl( LINK( this, AboutDialog, ShowReadme_Impl ) ); 340 maCreditsLink.SetClickHdl( LINK( this, AboutDialog, OpenLinkHdl_Impl ) ); 341 342 FreeResource(); 343 344 SetHelpId( CMD_SID_ABOUT ); 345 } 346 347 // ----------------------------------------------------------------------- 348 349 AboutDialog::~AboutDialog() 350 { 351 } 352 353 // ----------------------------------------------------------------------- 354 355 void AboutDialog::InitControls() 356 { 357 // apply font, background et al. 358 ApplyStyleSettings(); 359 360 // set strings 361 maCopyrightEdit.SetText( maCopyrightTextStr ); 362 maBuildInfoEdit.SetText( GetBuildVersionString() ); 363 maCreditsLink.SetURL( maCreditsLink.GetText() ); 364 365 // determine size and position of the dialog & elements 366 Size aDlgSize; 367 LayoutControls( aDlgSize ); 368 369 // Change the width of the dialog 370 SetOutputSizePixel( aDlgSize ); 371 } 372 373 // ----------------------------------------------------------------------- 374 375 void AboutDialog::ApplyStyleSettings() 376 { 377 // Transparenter Font 378 Font aFont = GetFont(); 379 aFont.SetTransparent( sal_True ); 380 SetFont( aFont ); 381 382 // set for background and text the correct system color 383 const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 384 Color aWindowColor( rSettings.GetWindowColor() ); 385 Wallpaper aWall( aWindowColor ); 386 SetBackground( aWall ); 387 388 Font aNewFont( maCopyrightEdit.GetFont() ); 389 aNewFont.SetTransparent( sal_True ); 390 391 maVersionText.SetFont( aNewFont ); 392 maCopyrightEdit.SetFont( aNewFont ); 393 394 maVersionText.SetBackground(aWall); 395 maCopyrightEdit.SetBackground(aWall); 396 maBuildInfoEdit.SetBackground(aWall); 397 maCreditsLink.SetBackground(aWall); 398 399 Color aTextColor( rSettings.GetWindowTextColor() ); 400 maVersionText.SetControlForeground( aTextColor ); 401 maCopyrightEdit.SetControlForeground( aTextColor ); 402 maBuildInfoEdit.SetControlForeground( aTextColor ); 403 maCreditsLink.SetControlForeground(); 404 405 Size aSmaller = aNewFont.GetSize(); 406 aSmaller.Width() = (long) (aSmaller.Width() * 0.75); 407 aSmaller.Height() = (long) (aSmaller.Height() * 0.75); 408 aNewFont.SetSize( aSmaller ); 409 410 maBuildInfoEdit.SetFont( aNewFont ); 411 412 // the following is a hack to force the MultiLineEdit update its settings 413 // in order to reflect the Font 414 // See 415 // Window::SetControlFont 416 // MultiLineEdit::StateChanged 417 // MultiLineEdit::ImplInitSettings 418 // TODO Override SetFont in MultiLineEdit and do the following, 419 // otherwise SetFont has no effect at all! 420 aSmaller = PixelToLogic( aSmaller, MAP_POINT ); 421 aNewFont.SetSize( aSmaller ); 422 maBuildInfoEdit.SetControlFont( aNewFont ); 423 } 424 425 // ----------------------------------------------------------------------- 426 427 void AboutDialog::LayoutControls( Size& aDlgSize ) 428 { 429 Size aMainLogoSz = maMainLogo.GetSizePixel(); 430 Size aAppLogoSiz = maAppLogo.GetSizePixel(); 431 432 aDlgSize = GetOutputSizePixel(); 433 long nCol1 = aMainLogoSz.Width(); 434 long nCol2 = aAppLogoSiz.Width() ? aAppLogoSiz.Width() : aDlgSize.Width(); 435 436 Size a6Size = maVersionText.LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); 437 long nDlgMargin = a6Size.Width() * 2; 438 long nCtrlMargin = a6Size.Height() * 2; 439 long nTextWidth = nCol2 - nDlgMargin; 440 long nY = aAppLogoSiz.Height() + a6Size.Height(); 441 442 aDlgSize.Width() = nCol1 + a6Size.Width() + nCol2; 443 444 Point aPos( nCol1 + a6Size.Width(), nY ); 445 Size aSize; 446 // layout fixed text control 447 lcl_layoutFixedText( maVersionText, aPos, aSize, nTextWidth ); 448 nY += aSize.Height() + a6Size.Height(); 449 450 // Multiline edit with Build info 451 aPos.Y() = nY; 452 lcl_layoutEdit( maBuildInfoEdit, aPos, aSize, nTextWidth ); 453 nY += aSize.Height() + a6Size.Height(); 454 455 // Multiline edit with Copyright-Text 456 aPos.Y() = nY; 457 lcl_layoutEdit( maCopyrightEdit, aPos, aSize, nTextWidth ); 458 nY += aSize.Height() + a6Size.Height(); 459 460 // Hyperlink 461 aPos.Y() = nY; 462 lcl_layoutFixedText( maCreditsLink, aPos, aSize, nTextWidth ); 463 nY += aSize.Height(); 464 465 nY = std::max( nY, aMainLogoSz.Height() ); 466 nY += nCtrlMargin; 467 468 // logos position 469 maMainLogoPos = Point( 0, nY / 2 - aMainLogoSz.Height() / 2 ); 470 maAppLogoPos = Point( nCol1 + a6Size.Width(), 0 ); 471 472 // OK-Button-Position (at the bottom and centered) 473 Size aOKSiz = maOKButton.GetSizePixel(); 474 Point aOKPnt( ( aDlgSize.Width() - aOKSiz.Width() ) - a6Size.Width(), nY ); 475 maOKButton.SetPosPixel( aOKPnt ); 476 477 maReadmeButton.SetPosPixel( Point(a6Size.Width(), nY) ); 478 479 aDlgSize.Height() = aOKPnt.Y() + aOKSiz.Height() + a6Size.Width(); 480 } 481 482 // ----------------------------------------------------------------------- 483 484 const rtl::OUString AboutDialog::GetBuildId() const 485 { 486 rtl::OUString sDefault; 487 488 // Get buildid from version[rc|.ini] 489 rtl::OUString sBuildId( utl::Bootstrap::getBuildIdData( sDefault ) ); 490 OSL_ENSURE( sBuildId.getLength() > 0, "No BUILDID in bootstrap file" ); 491 rtl::OUStringBuffer sBuildIdBuff( sBuildId ); 492 493 // Get ProductSource from version[rc|.ini] 494 rtl::OUString sProductSource( utl::Bootstrap::getProductSource( sDefault ) ); 495 OSL_ENSURE( sProductSource.getLength() > 0, "No ProductSource in bootstrap file" ); 496 497 // the product source is something like "AOO340", 498 // while the build id is something like "340m1(Build:9590)" 499 // For better readability, strip the duplicate ProductMajor ("340"). 500 if ( sProductSource.getLength() ) 501 { 502 bool bMatchingUPD = 503 ( sProductSource.getLength() >= 3 ) 504 && ( sBuildId.getLength() >= 3 ) 505 && ( sProductSource.copy( sProductSource.getLength() - 3 ) == sBuildId.copy( 0, 3 ) ); 506 OSL_ENSURE( bMatchingUPD, "BUILDID and ProductSource do not match in their UPD" ); 507 if ( bMatchingUPD ) 508 sProductSource = sProductSource.copy( 0, sProductSource.getLength() - 3 ); 509 510 // prepend the product source 511 sBuildIdBuff.insert( 0, sProductSource ); 512 } 513 514 return sBuildIdBuff.makeStringAndClear(); 515 } 516 517 // ----------------------------------------------------------------------- 518 519 const rtl::OUString AboutDialog::GetBuildVersionString() const 520 { 521 rtl::OUStringBuffer aBuildString( GetBuildId() ); 522 rtl::OUString sRevision( utl::Bootstrap::getRevisionInfo() ); 523 524 if ( sRevision.getLength() > 0 ) 525 { 526 aBuildString.appendAscii( RTL_CONSTASCII_STRINGPARAM( " - Rev. " ) ); 527 aBuildString.append( sRevision ); 528 } 529 530 #ifdef BUILD_VER_STRING 531 rtl::OUString sBuildVer( RTL_CONSTASCII_USTRINGPARAM( STRINGIFY( BUILD_VER_STRING ) ) ); 532 if ( sBuildVer.getLength() > 0 ) 533 { 534 aBuildString.append( sal_Unicode( '\n' ) ); 535 aBuildString.append( sBuildVer ); 536 } 537 #endif 538 539 return aBuildString.makeStringAndClear(); 540 } 541 542 // ----------------------------------------------------------------------- 543 544 sal_Bool AboutDialog::Close() 545 { 546 EndDialog( RET_OK ); 547 return( sal_False ); 548 } 549 550 // ----------------------------------------------------------------------- 551 552 void AboutDialog::Paint( const Rectangle& rRect ) 553 { 554 SetClipRegion( rRect ); 555 556 // workaround to ensure that the background is painted correct 557 // on MacOS for example the background was grey and the image and other controls white 558 SetFillColor(GetSettings().GetStyleSettings().GetWindowColor()); 559 SetLineColor(); 560 DrawRect(rRect); 561 562 DrawImage( maMainLogoPos, maMainLogo ); 563 DrawImage( maAppLogoPos, maAppLogo ); 564 565 return; 566 } 567 568 // ----------------------------------------------------------------------- 569 570 IMPL_LINK ( AboutDialog, OpenLinkHdl_Impl, svt::FixedHyperlink*, EMPTYARG ) 571 { 572 ::rtl::OUString sURL( maCreditsLink.GetURL() ); 573 if ( sURL.getLength() > 0 ) 574 { 575 try 576 { 577 uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShell( 578 com::sun::star::system::SystemShellExecute::create( 579 ::comphelper::getProcessComponentContext() ) ); 580 if ( xSystemShell.is() ) 581 xSystemShell->execute( sURL, rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::DEFAULTS ); 582 } 583 catch( const uno::Exception& e ) 584 { 585 OSL_TRACE( "Caught exception: %s\n thread terminated.\n", 586 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); 587 } 588 } 589 590 return 0; 591 } 592 593 IMPL_LINK ( AboutDialog, ShowReadme_Impl, PushButton*, EMPTYARG ) 594 { 595 ReadmeDialog aDlg( this ); 596 aDlg.Execute(); 597 598 return 0; 599 } 600