xref: /trunk/main/cui/source/dialogs/about.cxx (revision e07a3880)
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 
lcl_layoutFixedText(FixedText & rControl,const Point & aPos,Size & aSize,const long nTextWidth)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 
lcl_layoutEdit(Edit & rControl,const Point & aPos,Size & aSize,const long nTextWidth)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 
lcl_readTxtFile(const rtl::OUString & rFile,rtl::OUString & sText)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 
ReadmeTabPage(Window * pParent,const String & sText)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 
~ReadmeTabPage()178 	ReadmeTabPage::~ReadmeTabPage()
179 	{
180 	}
181 
Adjust(const Size & aSz,const Size & a6Size)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 
ReadmeDialog(Window * pParent)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 
~ReadmeDialog()271 	ReadmeDialog::~ReadmeDialog()
272 	{
273 		delete maReadmeTabPage;
274 		delete maLicenseTabPage;
275 		delete maNoticeTabPage;
276 	}
277 }
278 
279 // -----------------------------------------------------------------------
280 
AboutDialog(Window * pParent,const ResId & rId)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("2024") );
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 
~AboutDialog()347 AboutDialog::~AboutDialog()
348 {
349 }
350 
351 // -----------------------------------------------------------------------
352 
InitControls()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 
ApplyStyleSettings()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 
LayoutControls(Size & aDlgSize)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 
GetBuildId() const482 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 
GetBuildVersionString() const518 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 
Close()543 sal_Bool AboutDialog::Close()
544 {
545 	EndDialog( RET_OK );
546 	return( sal_False );
547 }
548 
549 // -----------------------------------------------------------------------
550 
Paint(const Rectangle & rRect)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 
IMPL_LINK(AboutDialog,OpenLinkHdl_Impl,svt::FixedHyperlink *,EMPTYARG)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 
IMPL_LINK(AboutDialog,ShowReadme_Impl,PushButton *,EMPTYARG)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