xref: /haiku/src/kits/interface/AboutWindow.cpp (revision 9ce450b9c2f42501d4aff202b0819f96a15b66d1)
1*9ce450b9SJohn Scipione /*
2*9ce450b9SJohn Scipione  * Copyright 2007-2012 Haiku, Inc.
3*9ce450b9SJohn Scipione  * Distributed under the terms of the MIT License.
4*9ce450b9SJohn Scipione  *
5*9ce450b9SJohn Scipione  * Authors:
6*9ce450b9SJohn Scipione  *		Ryan Leavengood <leavengood@gmail.com>
7*9ce450b9SJohn Scipione  *		John Scipione <jscipione@gmail.com>
8*9ce450b9SJohn Scipione  */
9*9ce450b9SJohn Scipione 
10*9ce450b9SJohn Scipione 
11*9ce450b9SJohn Scipione #include <AboutWindow.h>
12*9ce450b9SJohn Scipione 
13*9ce450b9SJohn Scipione #include <stdarg.h>
14*9ce450b9SJohn Scipione #include <time.h>
15*9ce450b9SJohn Scipione 
16*9ce450b9SJohn Scipione #include <Alert.h>
17*9ce450b9SJohn Scipione #include <AppFileInfo.h>
18*9ce450b9SJohn Scipione #include <Bitmap.h>
19*9ce450b9SJohn Scipione #include <Button.h>
20*9ce450b9SJohn Scipione #include <File.h>
21*9ce450b9SJohn Scipione #include <Font.h>
22*9ce450b9SJohn Scipione #include <GroupLayoutBuilder.h>
23*9ce450b9SJohn Scipione #include <GroupView.h>
24*9ce450b9SJohn Scipione #include <InterfaceDefs.h>
25*9ce450b9SJohn Scipione #include <LayoutBuilder.h>
26*9ce450b9SJohn Scipione #include <Message.h>
27*9ce450b9SJohn Scipione #include <MessageFilter.h>
28*9ce450b9SJohn Scipione #include <Point.h>
29*9ce450b9SJohn Scipione #include <Roster.h>
30*9ce450b9SJohn Scipione #include <Screen.h>
31*9ce450b9SJohn Scipione #include <ScrollView.h>
32*9ce450b9SJohn Scipione #include <Size.h>
33*9ce450b9SJohn Scipione #include <String.h>
34*9ce450b9SJohn Scipione #include <StringView.h>
35*9ce450b9SJohn Scipione #include <SystemCatalog.h>
36*9ce450b9SJohn Scipione #include <TextView.h>
37*9ce450b9SJohn Scipione #include <View.h>
38*9ce450b9SJohn Scipione #include <Window.h>
39*9ce450b9SJohn Scipione 
40*9ce450b9SJohn Scipione 
41*9ce450b9SJohn Scipione static const float kStripeWidth = 30.0;
42*9ce450b9SJohn Scipione 
43*9ce450b9SJohn Scipione using BPrivate::gSystemCatalog;
44*9ce450b9SJohn Scipione 
45*9ce450b9SJohn Scipione 
46*9ce450b9SJohn Scipione #undef B_TRANSLATION_CONTEXT
47*9ce450b9SJohn Scipione #define B_TRANSLATION_CONTEXT "AboutWindow"
48*9ce450b9SJohn Scipione 
49*9ce450b9SJohn Scipione 
50*9ce450b9SJohn Scipione class StripeView : public BView {
51*9ce450b9SJohn Scipione public:
52*9ce450b9SJohn Scipione 							StripeView(BBitmap* icon);
53*9ce450b9SJohn Scipione 	virtual					~StripeView();
54*9ce450b9SJohn Scipione 
55*9ce450b9SJohn Scipione 	virtual	void			Draw(BRect updateRect);
56*9ce450b9SJohn Scipione 
57*9ce450b9SJohn Scipione 			BBitmap*		Icon() const { return fIcon; };
58*9ce450b9SJohn Scipione 			void			SetIcon(BBitmap* icon);
59*9ce450b9SJohn Scipione 
60*9ce450b9SJohn Scipione private:
61*9ce450b9SJohn Scipione 			BBitmap*		fIcon;
62*9ce450b9SJohn Scipione };
63*9ce450b9SJohn Scipione 
64*9ce450b9SJohn Scipione 
65*9ce450b9SJohn Scipione class AboutView : public BGroupView {
66*9ce450b9SJohn Scipione public:
67*9ce450b9SJohn Scipione 							AboutView(const char* name,
68*9ce450b9SJohn Scipione 								const char* signature);
69*9ce450b9SJohn Scipione 	virtual					~AboutView();
70*9ce450b9SJohn Scipione 
71*9ce450b9SJohn Scipione 			BTextView*		InfoView() const { return fInfoView; };
72*9ce450b9SJohn Scipione 
73*9ce450b9SJohn Scipione 			BBitmap*		Icon();
74*9ce450b9SJohn Scipione 			status_t		SetIcon(BBitmap* icon);
75*9ce450b9SJohn Scipione 
76*9ce450b9SJohn Scipione 			const char*		Name();
77*9ce450b9SJohn Scipione 			status_t		SetName(const char* name);
78*9ce450b9SJohn Scipione 
79*9ce450b9SJohn Scipione 			const char*		Version();
80*9ce450b9SJohn Scipione 			status_t		SetVersion(const char* version);
81*9ce450b9SJohn Scipione 
82*9ce450b9SJohn Scipione private:
83*9ce450b9SJohn Scipione 			const char*		_GetVersionFromSignature(const char* signature);
84*9ce450b9SJohn Scipione 			BBitmap*		_GetIconFromSignature(const char* signature);
85*9ce450b9SJohn Scipione 
86*9ce450b9SJohn Scipione private:
87*9ce450b9SJohn Scipione 			BStringView*	fNameView;
88*9ce450b9SJohn Scipione 			BStringView*	fVersionView;
89*9ce450b9SJohn Scipione 			BTextView*		fInfoView;
90*9ce450b9SJohn Scipione 			StripeView*		fStripeView;
91*9ce450b9SJohn Scipione };
92*9ce450b9SJohn Scipione 
93*9ce450b9SJohn Scipione 
94*9ce450b9SJohn Scipione //	#pragma mark - StripeView
95*9ce450b9SJohn Scipione 
96*9ce450b9SJohn Scipione 
97*9ce450b9SJohn Scipione StripeView::StripeView(BBitmap* icon)
98*9ce450b9SJohn Scipione 	:
99*9ce450b9SJohn Scipione 	BView("StripeView", B_WILL_DRAW),
100*9ce450b9SJohn Scipione 	fIcon(icon)
101*9ce450b9SJohn Scipione {
102*9ce450b9SJohn Scipione 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
103*9ce450b9SJohn Scipione 
104*9ce450b9SJohn Scipione 	float width = 0.0f;
105*9ce450b9SJohn Scipione 	if (icon != NULL)
106*9ce450b9SJohn Scipione 		width += icon->Bounds().Width() + 32.0f;
107*9ce450b9SJohn Scipione 
108*9ce450b9SJohn Scipione 	SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
109*9ce450b9SJohn Scipione 	SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
110*9ce450b9SJohn Scipione }
111*9ce450b9SJohn Scipione 
112*9ce450b9SJohn Scipione 
113*9ce450b9SJohn Scipione StripeView::~StripeView()
114*9ce450b9SJohn Scipione {
115*9ce450b9SJohn Scipione }
116*9ce450b9SJohn Scipione 
117*9ce450b9SJohn Scipione 
118*9ce450b9SJohn Scipione void
119*9ce450b9SJohn Scipione StripeView::Draw(BRect updateRect)
120*9ce450b9SJohn Scipione {
121*9ce450b9SJohn Scipione 	if (fIcon == NULL)
122*9ce450b9SJohn Scipione 		return;
123*9ce450b9SJohn Scipione 
124*9ce450b9SJohn Scipione 	SetHighColor(ViewColor());
125*9ce450b9SJohn Scipione 	FillRect(updateRect);
126*9ce450b9SJohn Scipione 
127*9ce450b9SJohn Scipione 	BRect stripeRect = Bounds();
128*9ce450b9SJohn Scipione 	stripeRect.right = kStripeWidth;
129*9ce450b9SJohn Scipione 	SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
130*9ce450b9SJohn Scipione 	FillRect(stripeRect);
131*9ce450b9SJohn Scipione 
132*9ce450b9SJohn Scipione 	SetDrawingMode(B_OP_ALPHA);
133*9ce450b9SJohn Scipione 	SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
134*9ce450b9SJohn Scipione 	DrawBitmapAsync(fIcon, BPoint(15.0f, 10.0f));
135*9ce450b9SJohn Scipione }
136*9ce450b9SJohn Scipione 
137*9ce450b9SJohn Scipione 
138*9ce450b9SJohn Scipione void
139*9ce450b9SJohn Scipione StripeView::SetIcon(BBitmap* icon)
140*9ce450b9SJohn Scipione {
141*9ce450b9SJohn Scipione 	if (fIcon != NULL)
142*9ce450b9SJohn Scipione 		delete fIcon;
143*9ce450b9SJohn Scipione 
144*9ce450b9SJohn Scipione 	fIcon = icon;
145*9ce450b9SJohn Scipione 
146*9ce450b9SJohn Scipione 	float width = 0.0f;
147*9ce450b9SJohn Scipione 	if (icon != NULL)
148*9ce450b9SJohn Scipione 		width += icon->Bounds().Width() + 32.0f;
149*9ce450b9SJohn Scipione 
150*9ce450b9SJohn Scipione 	SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
151*9ce450b9SJohn Scipione 	SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
152*9ce450b9SJohn Scipione };
153*9ce450b9SJohn Scipione 
154*9ce450b9SJohn Scipione 
155*9ce450b9SJohn Scipione //	#pragma mark - AboutView
156*9ce450b9SJohn Scipione 
157*9ce450b9SJohn Scipione 
158*9ce450b9SJohn Scipione AboutView::AboutView(const char* appName, const char* signature)
159*9ce450b9SJohn Scipione 	:
160*9ce450b9SJohn Scipione 	BGroupView("AboutView", B_VERTICAL)
161*9ce450b9SJohn Scipione {
162*9ce450b9SJohn Scipione 	fNameView = new BStringView("name", appName);
163*9ce450b9SJohn Scipione 	BFont font;
164*9ce450b9SJohn Scipione 	fNameView->GetFont(&font);
165*9ce450b9SJohn Scipione 	font.SetFace(B_BOLD_FACE);
166*9ce450b9SJohn Scipione 	font.SetSize(font.Size() * 2.0);
167*9ce450b9SJohn Scipione 	fNameView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
168*9ce450b9SJohn Scipione 		| B_FONT_FLAGS);
169*9ce450b9SJohn Scipione 
170*9ce450b9SJohn Scipione 	fVersionView = new BStringView("version",
171*9ce450b9SJohn Scipione 		_GetVersionFromSignature(signature));
172*9ce450b9SJohn Scipione 
173*9ce450b9SJohn Scipione 	fInfoView = new BTextView("info", B_WILL_DRAW);
174*9ce450b9SJohn Scipione 	fInfoView->SetExplicitMinSize(BSize(210.0, 160.0));
175*9ce450b9SJohn Scipione 	fInfoView->MakeEditable(false);
176*9ce450b9SJohn Scipione 	fInfoView->SetWordWrap(true);
177*9ce450b9SJohn Scipione 	fInfoView->SetInsets(5.0, 5.0, 5.0, 5.0);
178*9ce450b9SJohn Scipione 	fInfoView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
179*9ce450b9SJohn Scipione 	fInfoView->SetHighColor(ui_color(B_DOCUMENT_TEXT_COLOR));
180*9ce450b9SJohn Scipione 	fInfoView->SetStylable(true);
181*9ce450b9SJohn Scipione 
182*9ce450b9SJohn Scipione 	BScrollView* infoViewScroller = new BScrollView(
183*9ce450b9SJohn Scipione 		"infoViewScroller", fInfoView, B_WILL_DRAW | B_FRAME_EVENTS,
184*9ce450b9SJohn Scipione 		false, true, B_PLAIN_BORDER);
185*9ce450b9SJohn Scipione 
186*9ce450b9SJohn Scipione 	fStripeView = new StripeView(_GetIconFromSignature(signature));
187*9ce450b9SJohn Scipione 
188*9ce450b9SJohn Scipione 	const char* ok = B_TRANSLATE_MARK("Ok");
189*9ce450b9SJohn Scipione 	BButton* closeButton = new BButton("ok",
190*9ce450b9SJohn Scipione 		gSystemCatalog.GetString(ok, "AboutWindow"),
191*9ce450b9SJohn Scipione 		new BMessage(B_QUIT_REQUESTED));
192*9ce450b9SJohn Scipione 
193*9ce450b9SJohn Scipione 	GroupLayout()->SetSpacing(0);
194*9ce450b9SJohn Scipione 	BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0)
195*9ce450b9SJohn Scipione 		.Add(fStripeView)
196*9ce450b9SJohn Scipione 		.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
197*9ce450b9SJohn Scipione 			.SetInsets(0, B_USE_DEFAULT_SPACING,
198*9ce450b9SJohn Scipione 				B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
199*9ce450b9SJohn Scipione 			.Add(fNameView)
200*9ce450b9SJohn Scipione 			.Add(fVersionView)
201*9ce450b9SJohn Scipione 			.Add(infoViewScroller)
202*9ce450b9SJohn Scipione 			.AddGroup(B_HORIZONTAL, 0)
203*9ce450b9SJohn Scipione 				.AddGlue()
204*9ce450b9SJohn Scipione 				.Add(closeButton)
205*9ce450b9SJohn Scipione 				.End()
206*9ce450b9SJohn Scipione 			.End()
207*9ce450b9SJohn Scipione 		.AddGlue()
208*9ce450b9SJohn Scipione 		.End();
209*9ce450b9SJohn Scipione }
210*9ce450b9SJohn Scipione 
211*9ce450b9SJohn Scipione 
212*9ce450b9SJohn Scipione AboutView::~AboutView()
213*9ce450b9SJohn Scipione {
214*9ce450b9SJohn Scipione }
215*9ce450b9SJohn Scipione 
216*9ce450b9SJohn Scipione 
217*9ce450b9SJohn Scipione //	#pragma mark - AboutView private methods
218*9ce450b9SJohn Scipione 
219*9ce450b9SJohn Scipione 
220*9ce450b9SJohn Scipione const char*
221*9ce450b9SJohn Scipione AboutView::_GetVersionFromSignature(const char* signature)
222*9ce450b9SJohn Scipione {
223*9ce450b9SJohn Scipione 	if (signature == NULL)
224*9ce450b9SJohn Scipione 		return NULL;
225*9ce450b9SJohn Scipione 
226*9ce450b9SJohn Scipione 	entry_ref ref;
227*9ce450b9SJohn Scipione 	if (be_roster->FindApp(signature, &ref) != B_OK)
228*9ce450b9SJohn Scipione 		return NULL;
229*9ce450b9SJohn Scipione 
230*9ce450b9SJohn Scipione 	BFile file(&ref, B_READ_ONLY);
231*9ce450b9SJohn Scipione 	BAppFileInfo appMime(&file);
232*9ce450b9SJohn Scipione 	if (appMime.InitCheck() != B_OK)
233*9ce450b9SJohn Scipione 		return NULL;
234*9ce450b9SJohn Scipione 
235*9ce450b9SJohn Scipione 	version_info versionInfo;
236*9ce450b9SJohn Scipione 	if (appMime.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK) {
237*9ce450b9SJohn Scipione 		if (versionInfo.major == 0 && versionInfo.middle == 0
238*9ce450b9SJohn Scipione 			&& versionInfo.minor == 0) {
239*9ce450b9SJohn Scipione 			return NULL;
240*9ce450b9SJohn Scipione 		}
241*9ce450b9SJohn Scipione 
242*9ce450b9SJohn Scipione 		const char* version = B_TRANSLATE_MARK("Version");
243*9ce450b9SJohn Scipione 		version = gSystemCatalog.GetString(version, "AboutWindow");
244*9ce450b9SJohn Scipione 		BString appVersion(version);
245*9ce450b9SJohn Scipione 		appVersion << " " << versionInfo.major << "." << versionInfo.middle;
246*9ce450b9SJohn Scipione 		if (versionInfo.minor > 0)
247*9ce450b9SJohn Scipione 			appVersion << "." << versionInfo.minor;
248*9ce450b9SJohn Scipione 
249*9ce450b9SJohn Scipione 		// Add the version variety
250*9ce450b9SJohn Scipione 		const char* variety = NULL;
251*9ce450b9SJohn Scipione 		switch (versionInfo.variety) {
252*9ce450b9SJohn Scipione 			case B_DEVELOPMENT_VERSION:
253*9ce450b9SJohn Scipione 				variety = B_TRANSLATE_MARK("development");
254*9ce450b9SJohn Scipione 				break;
255*9ce450b9SJohn Scipione 			case B_ALPHA_VERSION:
256*9ce450b9SJohn Scipione 				variety = B_TRANSLATE_MARK("alpha");
257*9ce450b9SJohn Scipione 				break;
258*9ce450b9SJohn Scipione 			case B_BETA_VERSION:
259*9ce450b9SJohn Scipione 				variety = B_TRANSLATE_MARK("beta");
260*9ce450b9SJohn Scipione 				break;
261*9ce450b9SJohn Scipione 			case B_GAMMA_VERSION:
262*9ce450b9SJohn Scipione 				variety = B_TRANSLATE_MARK("gamma");
263*9ce450b9SJohn Scipione 				break;
264*9ce450b9SJohn Scipione 			case B_GOLDEN_MASTER_VERSION:
265*9ce450b9SJohn Scipione 				variety = B_TRANSLATE_MARK("gold master");
266*9ce450b9SJohn Scipione 				break;
267*9ce450b9SJohn Scipione 		}
268*9ce450b9SJohn Scipione 
269*9ce450b9SJohn Scipione 		if (variety != NULL) {
270*9ce450b9SJohn Scipione 			variety = gSystemCatalog.GetString(variety, "AboutWindow");
271*9ce450b9SJohn Scipione 			appVersion << "-" << variety;
272*9ce450b9SJohn Scipione 		}
273*9ce450b9SJohn Scipione 
274*9ce450b9SJohn Scipione 		return appVersion.String();
275*9ce450b9SJohn Scipione 	}
276*9ce450b9SJohn Scipione 
277*9ce450b9SJohn Scipione 	return NULL;
278*9ce450b9SJohn Scipione }
279*9ce450b9SJohn Scipione 
280*9ce450b9SJohn Scipione 
281*9ce450b9SJohn Scipione BBitmap*
282*9ce450b9SJohn Scipione AboutView::_GetIconFromSignature(const char* signature)
283*9ce450b9SJohn Scipione {
284*9ce450b9SJohn Scipione 	if (signature == NULL)
285*9ce450b9SJohn Scipione 		return NULL;
286*9ce450b9SJohn Scipione 
287*9ce450b9SJohn Scipione 	entry_ref ref;
288*9ce450b9SJohn Scipione 	if (be_roster->FindApp(signature, &ref) != B_OK)
289*9ce450b9SJohn Scipione 		return NULL;
290*9ce450b9SJohn Scipione 
291*9ce450b9SJohn Scipione 	BFile file(&ref, B_READ_ONLY);
292*9ce450b9SJohn Scipione 	BAppFileInfo appMime(&file);
293*9ce450b9SJohn Scipione 	if (appMime.InitCheck() != B_OK)
294*9ce450b9SJohn Scipione 		return NULL;
295*9ce450b9SJohn Scipione 
296*9ce450b9SJohn Scipione 	BBitmap* icon = new BBitmap(BRect(0.0, 0.0, 127.0, 127.0), B_RGBA32);
297*9ce450b9SJohn Scipione 	if (appMime.GetIcon(icon, (icon_size)128) == B_OK)
298*9ce450b9SJohn Scipione 		return icon;
299*9ce450b9SJohn Scipione 
300*9ce450b9SJohn Scipione 	delete icon;
301*9ce450b9SJohn Scipione 	return NULL;
302*9ce450b9SJohn Scipione }
303*9ce450b9SJohn Scipione 
304*9ce450b9SJohn Scipione 
305*9ce450b9SJohn Scipione //	#pragma mark - AboutView public methods
306*9ce450b9SJohn Scipione 
307*9ce450b9SJohn Scipione 
308*9ce450b9SJohn Scipione BBitmap*
309*9ce450b9SJohn Scipione AboutView::Icon()
310*9ce450b9SJohn Scipione {
311*9ce450b9SJohn Scipione 	if (fStripeView == NULL)
312*9ce450b9SJohn Scipione 		return NULL;
313*9ce450b9SJohn Scipione 
314*9ce450b9SJohn Scipione 	return fStripeView->Icon();
315*9ce450b9SJohn Scipione }
316*9ce450b9SJohn Scipione 
317*9ce450b9SJohn Scipione 
318*9ce450b9SJohn Scipione status_t
319*9ce450b9SJohn Scipione AboutView::SetIcon(BBitmap* icon)
320*9ce450b9SJohn Scipione {
321*9ce450b9SJohn Scipione 	if (fStripeView == NULL)
322*9ce450b9SJohn Scipione 		return B_NO_INIT;
323*9ce450b9SJohn Scipione 
324*9ce450b9SJohn Scipione 	fStripeView->SetIcon(icon);
325*9ce450b9SJohn Scipione 
326*9ce450b9SJohn Scipione 	return B_OK;
327*9ce450b9SJohn Scipione }
328*9ce450b9SJohn Scipione 
329*9ce450b9SJohn Scipione 
330*9ce450b9SJohn Scipione const char*
331*9ce450b9SJohn Scipione AboutView::Name()
332*9ce450b9SJohn Scipione {
333*9ce450b9SJohn Scipione 	return fNameView->Text();
334*9ce450b9SJohn Scipione }
335*9ce450b9SJohn Scipione 
336*9ce450b9SJohn Scipione 
337*9ce450b9SJohn Scipione status_t
338*9ce450b9SJohn Scipione AboutView::SetName(const char* name)
339*9ce450b9SJohn Scipione {
340*9ce450b9SJohn Scipione 	fNameView->SetText(name);
341*9ce450b9SJohn Scipione 
342*9ce450b9SJohn Scipione 	return B_OK;
343*9ce450b9SJohn Scipione }
344*9ce450b9SJohn Scipione 
345*9ce450b9SJohn Scipione 
346*9ce450b9SJohn Scipione const char*
347*9ce450b9SJohn Scipione AboutView::Version()
348*9ce450b9SJohn Scipione {
349*9ce450b9SJohn Scipione 	return fVersionView->Text();
350*9ce450b9SJohn Scipione }
351*9ce450b9SJohn Scipione 
352*9ce450b9SJohn Scipione 
353*9ce450b9SJohn Scipione status_t
354*9ce450b9SJohn Scipione AboutView::SetVersion(const char* version)
355*9ce450b9SJohn Scipione {
356*9ce450b9SJohn Scipione 	fVersionView->SetText(version);
357*9ce450b9SJohn Scipione 
358*9ce450b9SJohn Scipione 	return B_OK;
359*9ce450b9SJohn Scipione }
360*9ce450b9SJohn Scipione 
361*9ce450b9SJohn Scipione 
362*9ce450b9SJohn Scipione //	#pragma mark - BAboutWindow
363*9ce450b9SJohn Scipione 
364*9ce450b9SJohn Scipione 
365*9ce450b9SJohn Scipione BAboutWindow::BAboutWindow(const char* appName, const char* signature)
366*9ce450b9SJohn Scipione 	:
367*9ce450b9SJohn Scipione 	BWindow(BRect(0.0, 0.0, 200.0, 200.0), appName, B_MODAL_WINDOW,
368*9ce450b9SJohn Scipione 		B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE
369*9ce450b9SJohn Scipione 			| B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE)
370*9ce450b9SJohn Scipione {
371*9ce450b9SJohn Scipione 	SetLayout(new BGroupLayout(B_VERTICAL));
372*9ce450b9SJohn Scipione 
373*9ce450b9SJohn Scipione 	const char* about = B_TRANSLATE_MARK("About %app%");
374*9ce450b9SJohn Scipione 	about = gSystemCatalog.GetString(about, "AboutWindow");
375*9ce450b9SJohn Scipione 
376*9ce450b9SJohn Scipione 	BString title(about);
377*9ce450b9SJohn Scipione 	title.ReplaceFirst("%app%", appName);
378*9ce450b9SJohn Scipione 	SetTitle(title.String());
379*9ce450b9SJohn Scipione 
380*9ce450b9SJohn Scipione 	fAboutView = new AboutView(appName, signature);
381*9ce450b9SJohn Scipione 	AddChild(fAboutView);
382*9ce450b9SJohn Scipione 
383*9ce450b9SJohn Scipione 	MoveTo(AboutPosition(Frame().Width(), Frame().Height()));
384*9ce450b9SJohn Scipione }
385*9ce450b9SJohn Scipione 
386*9ce450b9SJohn Scipione 
387*9ce450b9SJohn Scipione BAboutWindow::~BAboutWindow()
388*9ce450b9SJohn Scipione {
389*9ce450b9SJohn Scipione 	fAboutView->RemoveSelf();
390*9ce450b9SJohn Scipione 	delete fAboutView;
391*9ce450b9SJohn Scipione 	fAboutView = NULL;
392*9ce450b9SJohn Scipione }
393*9ce450b9SJohn Scipione 
394*9ce450b9SJohn Scipione 
395*9ce450b9SJohn Scipione //	#pragma mark - BAboutWindow virtual methods
396*9ce450b9SJohn Scipione 
397*9ce450b9SJohn Scipione 
398*9ce450b9SJohn Scipione void
399*9ce450b9SJohn Scipione BAboutWindow::Show()
400*9ce450b9SJohn Scipione {
401*9ce450b9SJohn Scipione 	if (IsHidden()) {
402*9ce450b9SJohn Scipione 		// move to current workspace
403*9ce450b9SJohn Scipione 		SetWorkspaces(B_CURRENT_WORKSPACE);
404*9ce450b9SJohn Scipione 	}
405*9ce450b9SJohn Scipione 
406*9ce450b9SJohn Scipione 	BWindow::Show();
407*9ce450b9SJohn Scipione }
408*9ce450b9SJohn Scipione 
409*9ce450b9SJohn Scipione 
410*9ce450b9SJohn Scipione //	#pragma mark - BAboutWindow public methods
411*9ce450b9SJohn Scipione 
412*9ce450b9SJohn Scipione 
413*9ce450b9SJohn Scipione BPoint
414*9ce450b9SJohn Scipione BAboutWindow::AboutPosition(float width, float height)
415*9ce450b9SJohn Scipione {
416*9ce450b9SJohn Scipione 	BPoint result(100, 100);
417*9ce450b9SJohn Scipione 
418*9ce450b9SJohn Scipione 	BWindow* window =
419*9ce450b9SJohn Scipione 		dynamic_cast<BWindow*>(BLooper::LooperForThread(find_thread(NULL)));
420*9ce450b9SJohn Scipione 
421*9ce450b9SJohn Scipione 	BScreen screen(window);
422*9ce450b9SJohn Scipione 	BRect screenFrame(0, 0, 640, 480);
423*9ce450b9SJohn Scipione 	if (screen.IsValid())
424*9ce450b9SJohn Scipione 		screenFrame = screen.Frame();
425*9ce450b9SJohn Scipione 
426*9ce450b9SJohn Scipione 	// Horizontally, we're smack in the middle
427*9ce450b9SJohn Scipione 	result.x = screenFrame.left + (screenFrame.Width() / 2.0) - (width / 2.0);
428*9ce450b9SJohn Scipione 
429*9ce450b9SJohn Scipione 	// This is probably sooo wrong, but it looks right on 1024 x 768
430*9ce450b9SJohn Scipione 	result.y = screenFrame.top + (screenFrame.Height() / 4.0)
431*9ce450b9SJohn Scipione 		- ceil(height / 3.0);
432*9ce450b9SJohn Scipione 
433*9ce450b9SJohn Scipione 	return result;
434*9ce450b9SJohn Scipione }
435*9ce450b9SJohn Scipione 
436*9ce450b9SJohn Scipione 
437*9ce450b9SJohn Scipione void
438*9ce450b9SJohn Scipione BAboutWindow::AddDescription(const char* description)
439*9ce450b9SJohn Scipione {
440*9ce450b9SJohn Scipione 	if (description == NULL)
441*9ce450b9SJohn Scipione 		return;
442*9ce450b9SJohn Scipione 
443*9ce450b9SJohn Scipione 	AddText(description);
444*9ce450b9SJohn Scipione }
445*9ce450b9SJohn Scipione 
446*9ce450b9SJohn Scipione 
447*9ce450b9SJohn Scipione void
448*9ce450b9SJohn Scipione BAboutWindow::AddCopyright(int32 firstCopyrightYear,
449*9ce450b9SJohn Scipione 	const char* copyrightHolder, const char** extraCopyrights)
450*9ce450b9SJohn Scipione {
451*9ce450b9SJohn Scipione 	BString copyright(B_UTF8_COPYRIGHT " %years% %holder%");
452*9ce450b9SJohn Scipione 
453*9ce450b9SJohn Scipione 	// Get current year
454*9ce450b9SJohn Scipione 	time_t tp;
455*9ce450b9SJohn Scipione 	time(&tp);
456*9ce450b9SJohn Scipione 	char currentYear[5];
457*9ce450b9SJohn Scipione 	strftime(currentYear, 5, "%Y", localtime(&tp));
458*9ce450b9SJohn Scipione 	BString copyrightYears;
459*9ce450b9SJohn Scipione 	copyrightYears << firstCopyrightYear;
460*9ce450b9SJohn Scipione 	if (copyrightYears != currentYear)
461*9ce450b9SJohn Scipione 		copyrightYears << "-" << currentYear;
462*9ce450b9SJohn Scipione 
463*9ce450b9SJohn Scipione 	BString text("");
464*9ce450b9SJohn Scipione 	if (fAboutView->InfoView()->TextLength() > 0)
465*9ce450b9SJohn Scipione 		text << "\n\n";
466*9ce450b9SJohn Scipione 
467*9ce450b9SJohn Scipione 	text << copyright;
468*9ce450b9SJohn Scipione 
469*9ce450b9SJohn Scipione 	// Fill out the copyright year placeholder
470*9ce450b9SJohn Scipione 	text.ReplaceAll("%years%", copyrightYears.String());
471*9ce450b9SJohn Scipione 
472*9ce450b9SJohn Scipione 	// Fill in the copyright holder placeholder
473*9ce450b9SJohn Scipione 	text.ReplaceAll("%holder%", copyrightHolder);
474*9ce450b9SJohn Scipione 
475*9ce450b9SJohn Scipione 	// Add extra copyright strings
476*9ce450b9SJohn Scipione 	if (extraCopyrights != NULL) {
477*9ce450b9SJohn Scipione 		// Add optional extra copyright information
478*9ce450b9SJohn Scipione 		for (int32 i = 0; extraCopyrights[i]; i++)
479*9ce450b9SJohn Scipione 			text << "\n" << B_UTF8_COPYRIGHT << " " << extraCopyrights[i];
480*9ce450b9SJohn Scipione 	}
481*9ce450b9SJohn Scipione 
482*9ce450b9SJohn Scipione 	const char* allRightsReserved = B_TRANSLATE_MARK("All Rights Reserved.");
483*9ce450b9SJohn Scipione 	allRightsReserved = gSystemCatalog.GetString(allRightsReserved,
484*9ce450b9SJohn Scipione 		"AboutWindow");
485*9ce450b9SJohn Scipione 	text << "\n    " << allRightsReserved;
486*9ce450b9SJohn Scipione 
487*9ce450b9SJohn Scipione 	fAboutView->InfoView()->Insert(text.String());
488*9ce450b9SJohn Scipione }
489*9ce450b9SJohn Scipione 
490*9ce450b9SJohn Scipione 
491*9ce450b9SJohn Scipione void
492*9ce450b9SJohn Scipione BAboutWindow::AddAuthors(const char** authors)
493*9ce450b9SJohn Scipione {
494*9ce450b9SJohn Scipione 	if (authors == NULL)
495*9ce450b9SJohn Scipione 		return;
496*9ce450b9SJohn Scipione 
497*9ce450b9SJohn Scipione 	const char* writtenBy = B_TRANSLATE_MARK("Written by:");
498*9ce450b9SJohn Scipione 	writtenBy = gSystemCatalog.GetString(writtenBy, "AboutWindow");
499*9ce450b9SJohn Scipione 
500*9ce450b9SJohn Scipione 	AddText(writtenBy, authors);
501*9ce450b9SJohn Scipione }
502*9ce450b9SJohn Scipione 
503*9ce450b9SJohn Scipione 
504*9ce450b9SJohn Scipione void
505*9ce450b9SJohn Scipione BAboutWindow::AddSpecialThanks(const char** thanks)
506*9ce450b9SJohn Scipione {
507*9ce450b9SJohn Scipione 	if (thanks == NULL)
508*9ce450b9SJohn Scipione 		return;
509*9ce450b9SJohn Scipione 
510*9ce450b9SJohn Scipione 	const char* specialThanks = B_TRANSLATE_MARK("Special Thanks:");
511*9ce450b9SJohn Scipione 	specialThanks = gSystemCatalog.GetString(specialThanks, "AboutWindow");
512*9ce450b9SJohn Scipione 
513*9ce450b9SJohn Scipione 	AddText(specialThanks, thanks);
514*9ce450b9SJohn Scipione }
515*9ce450b9SJohn Scipione 
516*9ce450b9SJohn Scipione 
517*9ce450b9SJohn Scipione void
518*9ce450b9SJohn Scipione BAboutWindow::AddVersionHistory(const char** history)
519*9ce450b9SJohn Scipione {
520*9ce450b9SJohn Scipione 	if (history == NULL)
521*9ce450b9SJohn Scipione 		return;
522*9ce450b9SJohn Scipione 
523*9ce450b9SJohn Scipione 	const char* versionHistory = B_TRANSLATE_MARK("Version history:");
524*9ce450b9SJohn Scipione 	versionHistory = gSystemCatalog.GetString(versionHistory, "AboutWindow");
525*9ce450b9SJohn Scipione 
526*9ce450b9SJohn Scipione 	AddText(versionHistory, history);
527*9ce450b9SJohn Scipione }
528*9ce450b9SJohn Scipione 
529*9ce450b9SJohn Scipione 
530*9ce450b9SJohn Scipione void
531*9ce450b9SJohn Scipione BAboutWindow::AddExtraInfo(const char* extraInfo)
532*9ce450b9SJohn Scipione {
533*9ce450b9SJohn Scipione 	if (extraInfo == NULL)
534*9ce450b9SJohn Scipione 		return;
535*9ce450b9SJohn Scipione 
536*9ce450b9SJohn Scipione 	const char* appExtraInfo = B_TRANSLATE_MARK(extraInfo);
537*9ce450b9SJohn Scipione 	appExtraInfo = gSystemCatalog.GetString(extraInfo, "AboutWindow");
538*9ce450b9SJohn Scipione 
539*9ce450b9SJohn Scipione 	BString extra("");
540*9ce450b9SJohn Scipione 	if (fAboutView->InfoView()->TextLength() > 0)
541*9ce450b9SJohn Scipione 		extra << "\n\n";
542*9ce450b9SJohn Scipione 
543*9ce450b9SJohn Scipione 	extra << appExtraInfo;
544*9ce450b9SJohn Scipione 
545*9ce450b9SJohn Scipione 	fAboutView->InfoView()->Insert(extra.String());
546*9ce450b9SJohn Scipione }
547*9ce450b9SJohn Scipione 
548*9ce450b9SJohn Scipione 
549*9ce450b9SJohn Scipione void
550*9ce450b9SJohn Scipione BAboutWindow::AddText(const char* header, const char** contents)
551*9ce450b9SJohn Scipione {
552*9ce450b9SJohn Scipione 	BTextView* infoView = fAboutView->InfoView();
553*9ce450b9SJohn Scipione 	int32 textLength = infoView->TextLength();
554*9ce450b9SJohn Scipione 	BString text("");
555*9ce450b9SJohn Scipione 
556*9ce450b9SJohn Scipione 	if (textLength > 0) {
557*9ce450b9SJohn Scipione 		text << "\n\n";
558*9ce450b9SJohn Scipione 		textLength += 2;
559*9ce450b9SJohn Scipione 	}
560*9ce450b9SJohn Scipione 
561*9ce450b9SJohn Scipione 	const char* indent = "";
562*9ce450b9SJohn Scipione 	if (header != NULL) {
563*9ce450b9SJohn Scipione 		indent = "    ";
564*9ce450b9SJohn Scipione 		text << header;
565*9ce450b9SJohn Scipione 	}
566*9ce450b9SJohn Scipione 
567*9ce450b9SJohn Scipione 	if (contents != NULL) {
568*9ce450b9SJohn Scipione 		text << "\n";
569*9ce450b9SJohn Scipione 		for (int32 i = 0; contents[i]; i++)
570*9ce450b9SJohn Scipione 			text << indent << contents[i] << "\n";
571*9ce450b9SJohn Scipione 	}
572*9ce450b9SJohn Scipione 
573*9ce450b9SJohn Scipione 	infoView->Insert(text.String());
574*9ce450b9SJohn Scipione 
575*9ce450b9SJohn Scipione 	if (contents != NULL && header != NULL) {
576*9ce450b9SJohn Scipione 		infoView->SetFontAndColor(textLength, textLength + strlen(header),
577*9ce450b9SJohn Scipione 			be_bold_font);
578*9ce450b9SJohn Scipione 	}
579*9ce450b9SJohn Scipione }
580*9ce450b9SJohn Scipione 
581*9ce450b9SJohn Scipione 
582*9ce450b9SJohn Scipione BBitmap*
583*9ce450b9SJohn Scipione BAboutWindow::Icon()
584*9ce450b9SJohn Scipione {
585*9ce450b9SJohn Scipione 	return fAboutView->Icon();
586*9ce450b9SJohn Scipione }
587*9ce450b9SJohn Scipione 
588*9ce450b9SJohn Scipione 
589*9ce450b9SJohn Scipione void
590*9ce450b9SJohn Scipione BAboutWindow::SetIcon(BBitmap* icon)
591*9ce450b9SJohn Scipione {
592*9ce450b9SJohn Scipione 	fAboutView->SetIcon(icon);
593*9ce450b9SJohn Scipione }
594*9ce450b9SJohn Scipione 
595*9ce450b9SJohn Scipione 
596*9ce450b9SJohn Scipione const char*
597*9ce450b9SJohn Scipione BAboutWindow::Name()
598*9ce450b9SJohn Scipione {
599*9ce450b9SJohn Scipione 	return fAboutView->Name();
600*9ce450b9SJohn Scipione }
601*9ce450b9SJohn Scipione 
602*9ce450b9SJohn Scipione 
603*9ce450b9SJohn Scipione void
604*9ce450b9SJohn Scipione BAboutWindow::SetName(const char* name)
605*9ce450b9SJohn Scipione {
606*9ce450b9SJohn Scipione 	fAboutView->SetName(name);
607*9ce450b9SJohn Scipione }
608*9ce450b9SJohn Scipione 
609*9ce450b9SJohn Scipione 
610*9ce450b9SJohn Scipione const char*
611*9ce450b9SJohn Scipione BAboutWindow::Version()
612*9ce450b9SJohn Scipione {
613*9ce450b9SJohn Scipione 	return fAboutView->Version();
614*9ce450b9SJohn Scipione }
615*9ce450b9SJohn Scipione 
616*9ce450b9SJohn Scipione 
617*9ce450b9SJohn Scipione void
618*9ce450b9SJohn Scipione BAboutWindow::SetVersion(const char* version)
619*9ce450b9SJohn Scipione {
620*9ce450b9SJohn Scipione 	fAboutView->SetVersion(version);
621*9ce450b9SJohn Scipione }
622*9ce450b9SJohn Scipione 
623*9ce450b9SJohn Scipione 
624*9ce450b9SJohn Scipione // FBC padding
625*9ce450b9SJohn Scipione 
626*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow20() {}
627*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow19() {}
628*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow18() {}
629*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow17() {}
630*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow16() {}
631*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow15() {}
632*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow14() {}
633*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow13() {}
634*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow12() {}
635*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow11() {}
636*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow10() {}
637*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow9() {}
638*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow8() {}
639*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow7() {}
640*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow6() {}
641*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow5() {}
642*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow4() {}
643*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow3() {}
644*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow2() {}
645*9ce450b9SJohn Scipione void BAboutWindow::_ReservedAboutWindow1() {}
646