xref: /aoo41x/main/cui/source/dialogs/about.cxx (revision 8bd5297c)
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 ---------------------------------------------------------------
28 
29 #include <vcl/svapp.hxx>
30 #include <vcl/msgbox.hxx>
31 #include <tools/stream.hxx>
32 #include <tools/urlobj.hxx>
33 #include <rtl/bootstrap.hxx>
34 #include <unotools/configmgr.hxx>
35 #include <unotools/bootstrap.hxx>
36 #include <com/sun/star/uno/Any.h>
37 #include <vcl/graph.hxx>
38 #include <svtools/filter.hxx>
39 #include <sfx2/sfxuno.hxx>
40 #include "about.hxx"
41 #include <sfx2/sfxdefs.hxx>
42 #include <sfx2/app.hxx>
43 #include <sfx2/sfxcommands.h>
44 #include "about.hrc"
45 #include <dialmgr.hxx>
46 #include <svtools/svtools.hrc>
47 
48 // defines ---------------------------------------------------------------
49 
50 #define SCROLL_OFFSET	1
51 #define SPACE_OFFSET	5
52 #define SCROLL_TIMER	30
53 
54 #define WELCOME_URL     DEFINE_CONST_UNICODE( "http://www.openoffice.org/welcome/credits.html" )
55 
56 // class AboutDialog -----------------------------------------------------
57 static void layoutText( FixedInfo &rText, long &nY, long nTextWidth, Size a6Size )
58 {
59 	Point aTextPos = rText.GetPosPixel();
60 	aTextPos.X() = a6Size.Width() * 2;
61 	aTextPos.Y() = nY;
62 	rText.SetPosPixel( aTextPos );
63 
64 	Size aTxtSiz = rText.GetSizePixel();
65 	aTxtSiz.Width() = nTextWidth;
66     Size aCalcSize = rText.CalcMinimumSize( nTextWidth );
67     aTxtSiz.Height() = aCalcSize.Height();
68 	rText.SetSizePixel( aTxtSiz );
69 
70 	nY += aTxtSiz.Height();
71 }
72 
73 String InitDevVersionStr()
74 {
75     String sDefault;
76     String sBuildId( utl::Bootstrap::getBuildIdData( sDefault ) );
77     OSL_ENSURE( sBuildId.Len() > 0, "No BUILDID in bootstrap file" );
78 
79     String sProductSource( utl::Bootstrap::getProductSource( sDefault ) );
80     OSL_ENSURE( sProductSource.Len() > 0, "No ProductSource in bootstrap file" );
81 
82     // the product source is something like "DEV300", where the
83     // build id is something like "300m12(Build:12345)". For better readability,
84     // strip the duplicate UPD ("300").
85     if ( sProductSource.Len() )
86     {
87         bool bMatchingUPD =
88                 ( sProductSource.Len() >= 3 )
89             &&  ( sBuildId.Len() >= 3 )
90             &&  ( sProductSource.Copy( sProductSource.Len() - 3 ) == sBuildId.Copy( 0, 3 ) );
91         OSL_ENSURE( bMatchingUPD, "BUILDID and ProductSource do not match in their UPD" );
92         if ( bMatchingUPD )
93             sProductSource = sProductSource.Copy( 0, sProductSource.Len() - 3 );
94 
95         // prepend the product source
96         sBuildId.Insert( sProductSource, 0 );
97     }
98 
99     return sBuildId;
100 }
101 
102 AboutDialog::AboutDialog( Window* pParent, const ResId& rId ) :
103 
104 	SfxModalDialog	( pParent, 	rId ),
105 
106 	aOKButton      	( this,		ResId( ABOUT_BTN_OK, *rId.GetResMgr() ) ),
107 	aVersionText 	( this, 	ResId( ABOUT_FTXT_VERSION, *rId.GetResMgr() ) ),
108     aCopyrightText  ( this,     ResId( ABOUT_FTXT_COPYRIGHT, *rId.GetResMgr() ) ),
109 	aBuildData      ( this ),
110     pDeveloperAry(0),
111 	aAccelStr		( 			ResId( ABOUT_STR_ACCEL, *rId.GetResMgr() ) ),
112     aTimer          (),
113     nOff            ( 0 ),
114     m_nDeltaWidth   ( 0 ),
115     m_nPendingScrolls( 0 ),
116     bNormal         ( sal_True )
117 {
118     aDevVersionStr = InitDevVersionStr();
119 
120     ::com::sun::star::lang::Locale aLocale;
121     ResMgr* pResMgr = ResMgr::SearchCreateResMgr( "about", aLocale );
122     if ( pResMgr )
123     {
124         aCopyrightTextStr = String( ResId( ABOUT_STR_COPYRIGHT, *pResMgr ) );
125         pDeveloperAry = new ResStringArray( ResId( ABOUT_STR_DEVELOPER_ARY, *pResMgr ) );
126         delete pResMgr;
127     }
128 
129     rtl::OUString sProduct;
130     utl::ConfigManager::GetDirectConfigProperty(utl::ConfigManager::PRODUCTNAME) >>= sProduct;
131 
132     // load image from module path
133 	aAppLogo = SfxApplication::GetApplicationLogo();
134 
135 	// Transparenter Font
136 	Font aFont = GetFont();
137     aFont.SetTransparent( sal_True );
138 	SetFont( aFont );
139 
140     // if necessary more info
141     String sVersion = aVersionText.GetText();
142     sVersion.SearchAndReplaceAscii( "$(VER)", Application::GetDisplayName() );
143     aVersionText.SetText( sVersion );
144 
145 	// Initialisierung fuer Aufruf Entwickler
146 	if ( aAccelStr.Len() && ByteString(U2S(aAccelStr)).IsAlphaAscii() )
147 	{
148 		Accelerator	*pAccel = 0, *pPrevAccel = 0, *pFirstAccel = 0;
149 		aAccelStr.ToUpperAscii();
150 
151 		for ( sal_uInt16 i = 0; i < aAccelStr.Len(); ++i )
152 		{
153 			pPrevAccel = pAccel;
154 			pAccel = new Accelerator;
155 			aAccelList.Insert( pAccel, LIST_APPEND );
156 			sal_uInt16 nKey = aAccelStr.GetChar(i) - 'A' + KEY_A;
157 			pAccel->InsertItem( 1, KeyCode( nKey, KEY_MOD1 ) );
158 			if ( i > 0 )
159 				pPrevAccel->SetAccel( 1, pAccel );
160 			if ( i == 0 )
161 				pFirstAccel = pAccel;
162 		}
163 		pAccel->SetSelectHdl( LINK( this, AboutDialog, AccelSelectHdl ) );
164 		GetpApp()->InsertAccel( pFirstAccel );
165 	}
166 
167 	// set for background and text the correct system color
168 	const StyleSettings& rSettings = GetSettings().GetStyleSettings();
169 	Color aWhiteCol( rSettings.GetWindowColor() );
170 	Wallpaper aWall( aWhiteCol );
171 	SetBackground( aWall );
172 	Font aNewFont( aCopyrightText.GetFont() );
173 	aNewFont.SetTransparent( sal_True );
174 
175 	aVersionText.SetFont( aNewFont );
176 	aCopyrightText.SetFont( aNewFont );
177 
178 	aVersionText.SetBackground();
179 	aCopyrightText.SetBackground();
180 
181 	Color aTextColor( rSettings.GetWindowTextColor() );
182 	aVersionText.SetControlForeground( aTextColor );
183 	aCopyrightText.SetControlForeground( aTextColor );
184 	aBuildData.SetBackground( );
185 
186 	Font aSmallFont = rSettings.GetInfoFont();
187 	Size aSmaller = aNewFont.GetSize();
188 	aSmaller.Width() = (long) (aSmaller.Width() * 0.75);
189 	aSmaller.Height() = (long) (aSmaller.Height() * 0.75);
190 	aNewFont.SetSize( aSmaller );
191 	aBuildData.SetFont( aNewFont );
192 
193     String sRevision( utl::Bootstrap::getRevisionInfo() );
194 
195     String aBuildString(aDevVersionStr);
196     aBuildString += (DEFINE_CONST_UNICODE("  -  Rev. "));
197     aBuildString += sRevision;
198 
199 #ifdef BUILD_VER_STRING
200 #define _STRINGIFY(x) #x
201 #define STRINGIFY(x) _STRINGIFY(x)
202     aBuildString += '\n';
203 	aBuildString += ( DEFINE_CONST_UNICODE( STRINGIFY( BUILD_VER_STRING ) ) );
204 #endif
205 	aBuildData.SetText( aBuildString );
206 	aBuildData.Show();
207 
208     // determine size and position of the dialog & elements
209 	Size aAppLogoSiz = aAppLogo.GetSizePixel();
210 	Size aOutSiz     = GetOutputSizePixel();
211     aOutSiz.Width()  = aAppLogoSiz.Width();
212 
213     Size a6Size      = aVersionText.LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
214     long nY          = aAppLogoSiz.Height() + ( a6Size.Height() * 2 );
215     long nDlgMargin  = a6Size.Width() * 4 ;
216     long nCtrlMargin = a6Size.Height() * 2;
217     long nTextWidth  = aOutSiz.Width() - nDlgMargin;
218 
219     aCopyrightText.SetText( aCopyrightTextStr );
220 
221     // layout fixed text controls
222     layoutText( aVersionText, nY, nTextWidth, a6Size );
223     if( aBuildString.Len() > 0 )
224     {
225         nY += ( a6Size.Height() / 2 );
226         layoutText( aBuildData, nY, nTextWidth, a6Size );
227     }
228     nY += nCtrlMargin;
229 
230 	// OK-Button-Position (at the bottom and centered)
231 	Size aOKSiz = aOKButton.GetSizePixel();
232 	Point aOKPnt = aOKButton.GetPosPixel();
233 
234     // Multiline edit with Copyright-Text
235     Point aCopyPnt = aCopyrightText.GetPosPixel();
236     Size aCopySize = aCopyrightText.GetSizePixel();
237     aCopySize.Width()  = nTextWidth;
238     aCopySize.Height() = aOutSiz.Height() - nY - ( aOKSiz.Height() * 2 ) - nCtrlMargin;
239 
240     aCopyPnt.X() = ( aOutSiz.Width() - aCopySize.Width() ) / 2;
241     aCopyPnt.Y() = nY;
242     aCopyrightText.SetPosSizePixel( aCopyPnt, aCopySize );
243 
244     nY += aCopySize.Height() + nCtrlMargin;
245 	aOKPnt.X() = ( aOutSiz.Width() - aOKSiz.Width() ) / 2;
246 	aOKPnt.Y() = nY;
247 	aOKButton.SetPosPixel( aOKPnt );
248 
249     // Change the width of the dialog
250     SetOutputSizePixel( aOutSiz );
251 
252 	FreeResource();
253 
254 	SetHelpId( CMD_SID_ABOUT );
255 }
256 
257 // -----------------------------------------------------------------------
258 
259 AboutDialog::~AboutDialog()
260 {
261 	// L"oschen des Entwickleraufrufs
262     delete pDeveloperAry;
263 	if ( aAccelList.Count() )
264 	{
265 		GetpApp()->RemoveAccel( aAccelList.First() );
266 		Accelerator* pAccel = aAccelList.Last();
267 
268 		while ( pAccel )
269 		{
270 			delete pAccel;
271 			pAccel = aAccelList.Prev();
272 		}
273 	}
274 }
275 
276 // -----------------------------------------------------------------------
277 
278 IMPL_LINK( AboutDialog, TimerHdl, Timer *, pTimer )
279 {
280     (void)pTimer; //unused
281 	++m_nPendingScrolls;
282 	Invalidate( INVALIDATE_NOERASE | INVALIDATE_NOCHILDREN );
283 	return 0;
284 }
285 
286 // -----------------------------------------------------------------------
287 
288 IMPL_LINK( AboutDialog, AccelSelectHdl, Accelerator *, pAccelerator )
289 {
290 #ifdef YURI_DARIO
291 	aCopyrightText.SetHelpText( DEFINE_CONST_UNICODE("Conoscere qualcuno ovunque egli sia, con cui comprendersi nonostante le distanze\n"
292 					  "e le differenze, puo' trasformare la terra in un giardino. baci Valeria") );
293 #endif
294 
295     (void)pAccelerator; //unused
296     // init Timer
297 	aTimer.SetTimeoutHdl( LINK( this, AboutDialog, TimerHdl ) );
298 
299 	// init scroll mode
300 	nOff = GetOutputSizePixel().Height();
301 	MapMode aMapMode( MAP_PIXEL );
302 	SetMapMode( aMapMode );
303 	bNormal = sal_False;
304 
305 	// start scroll Timer
306 	aTimer.SetTimeout( SCROLL_TIMER );
307 	aTimer.Start();
308 	return 0;
309 }
310 
311 // -----------------------------------------------------------------------
312 
313 sal_Bool AboutDialog::Close()
314 {
315 	// stop Timer and finish the dialog
316 	aTimer.Stop();
317 	EndDialog( RET_OK );
318 	return( sal_False );
319 }
320 
321 // -----------------------------------------------------------------------
322 
323 void AboutDialog::Paint( const Rectangle& rRect )
324 {
325 	SetClipRegion( rRect );
326 
327     if ( bNormal ) // not in scroll mode
328 	{
329         Point aPos( m_nDeltaWidth / 2, 0 );
330         DrawImage( aPos, aAppLogo );
331 		return;
332 	}
333 
334 	// scroll the content
335 	const int nDeltaY = -SCROLL_OFFSET * m_nPendingScrolls;
336 	if( !nDeltaY )
337 		return;
338 	nOff += nDeltaY;
339 	Scroll( 0, nDeltaY, SCROLL_NOERASE );
340 	m_nPendingScrolls = 0;
341 
342 	// draw the credits text
343 	const Font aOrigFont = GetFont();
344 	const int nFullWidth = GetOutputSizePixel().Width();
345 
346 	int nY = nOff;
347 	const int nDevCnt = static_cast<int>( pDeveloperAry->Count() );
348 	for( int i = 0; i < nDevCnt; ++i )
349 	{
350 		if( nY >= rRect.Bottom() )
351 			break;
352 
353 		int nPos2 = nY + GetTextHeight() + 3;
354 		if( nPos2 >= rRect.Top() + nDeltaY )
355 		{
356 			const String aStr = pDeveloperAry->GetString(i);
357 			const long nVal = pDeveloperAry->GetValue(i);
358 
359 			if ( nVal )
360 			{
361 				// emphasize the headers
362 				Font aFont = aOrigFont;
363 				aFont.SetWeight( (FontWeight)nVal );
364 				SetFont( aFont );
365 				nPos2 = nY + GetTextHeight() + 3;
366 			}
367 
368 			// clear text background
369 			Rectangle aEraseRect( Point(0,nY), Size( nFullWidth, nPos2-nY));
370 			Erase( aEraseRect );
371 
372 			// draw centered text
373 			const long nTextWidth = GetTextWidth( aStr );
374 			long nX = (nFullWidth - 5 - nTextWidth) / 2;
375 			if( nX < 0 )
376 				nX = SPACE_OFFSET;
377 			const Point aPnt( nX, nY );
378 			DrawText( aPnt, aStr );
379 
380 			// restore the font if needed
381 			if( nVal )
382 				SetFont( aOrigFont );
383 		}
384 		nY = nPos2;
385 	}
386 
387 	// close dialog if the whole text has been scrolled
388 	if ( nY <= 0 )
389 	{
390 		bNormal = sal_True;
391 		Close();
392 	}
393 }
394