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