tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / interface / AboutWindow.cpp
blobfa84cf5c985895501737c4a27f5e5d10b8de064d
1 /*
2 * Copyright 2007-2012 Haiku, Inc.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Ryan Leavengood <leavengood@gmail.com>
7 * John Scipione <jscipione@gmail.com>
8 */
11 #include <AboutWindow.h>
13 #include <stdarg.h>
14 #include <time.h>
16 #include <Alert.h>
17 #include <AppFileInfo.h>
18 #include <Bitmap.h>
19 #include <Button.h>
20 #include <File.h>
21 #include <Font.h>
22 #include <GroupLayoutBuilder.h>
23 #include <GroupView.h>
24 #include <InterfaceDefs.h>
25 #include <LayoutBuilder.h>
26 #include <Message.h>
27 #include <MessageFilter.h>
28 #include <Point.h>
29 #include <Roster.h>
30 #include <Screen.h>
31 #include <ScrollView.h>
32 #include <Size.h>
33 #include <String.h>
34 #include <StringView.h>
35 #include <SystemCatalog.h>
36 #include <TextView.h>
37 #include <View.h>
38 #include <Window.h>
41 static const float kStripeWidth = 30.0;
43 using BPrivate::gSystemCatalog;
46 #undef B_TRANSLATION_CONTEXT
47 #define B_TRANSLATION_CONTEXT "AboutWindow"
50 class StripeView : public BView {
51 public:
52 StripeView(BBitmap* icon);
53 virtual ~StripeView();
55 virtual void Draw(BRect updateRect);
57 BBitmap* Icon() const { return fIcon; };
58 void SetIcon(BBitmap* icon);
60 private:
61 BBitmap* fIcon;
65 class AboutView : public BGroupView {
66 public:
67 AboutView(const char* name,
68 const char* signature);
69 virtual ~AboutView();
71 BTextView* InfoView() const { return fInfoView; };
73 BBitmap* Icon();
74 status_t SetIcon(BBitmap* icon);
76 const char* Name();
77 status_t SetName(const char* name);
79 const char* Version();
80 status_t SetVersion(const char* version);
82 private:
83 const char* _GetVersionFromSignature(const char* signature);
84 BBitmap* _GetIconFromSignature(const char* signature);
86 private:
87 BStringView* fNameView;
88 BStringView* fVersionView;
89 BTextView* fInfoView;
90 StripeView* fStripeView;
94 // #pragma mark - StripeView
97 StripeView::StripeView(BBitmap* icon)
99 BView("StripeView", B_WILL_DRAW),
100 fIcon(icon)
102 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
104 float width = 0.0f;
105 if (icon != NULL)
106 width += icon->Bounds().Width() + 32.0f;
108 SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
109 SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
113 StripeView::~StripeView()
118 void
119 StripeView::Draw(BRect updateRect)
121 if (fIcon == NULL)
122 return;
124 SetHighColor(ViewColor());
125 FillRect(updateRect);
127 BRect stripeRect = Bounds();
128 stripeRect.right = kStripeWidth;
129 SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
130 FillRect(stripeRect);
132 SetDrawingMode(B_OP_ALPHA);
133 SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
134 DrawBitmapAsync(fIcon, BPoint(15.0f, 10.0f));
138 void
139 StripeView::SetIcon(BBitmap* icon)
141 if (fIcon != NULL)
142 delete fIcon;
144 fIcon = icon;
146 float width = 0.0f;
147 if (icon != NULL)
148 width += icon->Bounds().Width() + 32.0f;
150 SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
151 SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
155 // #pragma mark - AboutView
158 AboutView::AboutView(const char* appName, const char* signature)
160 BGroupView("AboutView", B_VERTICAL)
162 fNameView = new BStringView("name", appName);
163 BFont font;
164 fNameView->GetFont(&font);
165 font.SetFace(B_BOLD_FACE);
166 font.SetSize(font.Size() * 2.0);
167 fNameView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
168 | B_FONT_FLAGS);
170 fVersionView = new BStringView("version",
171 _GetVersionFromSignature(signature));
173 rgb_color documentColor = ui_color(B_DOCUMENT_TEXT_COLOR);
174 fInfoView = new BTextView("info", NULL, &documentColor, B_WILL_DRAW);
175 fInfoView->SetExplicitMinSize(BSize(210.0, 160.0));
176 fInfoView->MakeEditable(false);
177 fInfoView->SetWordWrap(true);
178 fInfoView->SetInsets(5.0, 5.0, 5.0, 5.0);
179 fInfoView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
180 fInfoView->SetStylable(true);
182 BScrollView* infoViewScroller = new BScrollView(
183 "infoViewScroller", fInfoView, B_WILL_DRAW | B_FRAME_EVENTS,
184 false, true, B_PLAIN_BORDER);
186 fStripeView = new StripeView(_GetIconFromSignature(signature));
188 const char* ok = B_TRANSLATE_MARK("OK");
189 BButton* closeButton = new BButton("ok",
190 gSystemCatalog.GetString(ok, "AboutWindow"),
191 new BMessage(B_QUIT_REQUESTED));
193 GroupLayout()->SetSpacing(0);
194 BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0)
195 .Add(fStripeView)
196 .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
197 .SetInsets(0, B_USE_DEFAULT_SPACING,
198 B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
199 .Add(fNameView)
200 .Add(fVersionView)
201 .Add(infoViewScroller)
202 .AddGroup(B_HORIZONTAL, 0)
203 .AddGlue()
204 .Add(closeButton)
205 .End()
206 .End()
207 .AddGlue()
208 .End();
212 AboutView::~AboutView()
217 // #pragma mark - AboutView private methods
220 const char*
221 AboutView::_GetVersionFromSignature(const char* signature)
223 if (signature == NULL)
224 return NULL;
226 entry_ref ref;
227 if (be_roster->FindApp(signature, &ref) != B_OK)
228 return NULL;
230 BFile file(&ref, B_READ_ONLY);
231 BAppFileInfo appMime(&file);
232 if (appMime.InitCheck() != B_OK)
233 return NULL;
235 version_info versionInfo;
236 if (appMime.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK) {
237 if (versionInfo.major == 0 && versionInfo.middle == 0
238 && versionInfo.minor == 0) {
239 return NULL;
242 const char* version = B_TRANSLATE_MARK("Version");
243 version = gSystemCatalog.GetString(version, "AboutWindow");
244 BString appVersion(version);
245 appVersion << " " << versionInfo.major << "." << versionInfo.middle;
246 if (versionInfo.minor > 0)
247 appVersion << "." << versionInfo.minor;
249 // Add the version variety
250 const char* variety = NULL;
251 switch (versionInfo.variety) {
252 case B_DEVELOPMENT_VERSION:
253 variety = B_TRANSLATE_MARK("development");
254 break;
255 case B_ALPHA_VERSION:
256 variety = B_TRANSLATE_MARK("alpha");
257 break;
258 case B_BETA_VERSION:
259 variety = B_TRANSLATE_MARK("beta");
260 break;
261 case B_GAMMA_VERSION:
262 variety = B_TRANSLATE_MARK("gamma");
263 break;
264 case B_GOLDEN_MASTER_VERSION:
265 variety = B_TRANSLATE_MARK("gold master");
266 break;
269 if (variety != NULL) {
270 variety = gSystemCatalog.GetString(variety, "AboutWindow");
271 appVersion << "-" << variety;
274 return appVersion.String();
277 return NULL;
281 BBitmap*
282 AboutView::_GetIconFromSignature(const char* signature)
284 if (signature == NULL)
285 return NULL;
287 entry_ref ref;
288 if (be_roster->FindApp(signature, &ref) != B_OK)
289 return NULL;
291 BFile file(&ref, B_READ_ONLY);
292 BAppFileInfo appMime(&file);
293 if (appMime.InitCheck() != B_OK)
294 return NULL;
296 BBitmap* icon = new BBitmap(BRect(0.0, 0.0, 127.0, 127.0), B_RGBA32);
297 if (appMime.GetIcon(icon, (icon_size)128) == B_OK)
298 return icon;
300 delete icon;
301 return NULL;
305 // #pragma mark - AboutView public methods
308 BBitmap*
309 AboutView::Icon()
311 if (fStripeView == NULL)
312 return NULL;
314 return fStripeView->Icon();
318 status_t
319 AboutView::SetIcon(BBitmap* icon)
321 if (fStripeView == NULL)
322 return B_NO_INIT;
324 fStripeView->SetIcon(icon);
326 return B_OK;
330 const char*
331 AboutView::Name()
333 return fNameView->Text();
337 status_t
338 AboutView::SetName(const char* name)
340 fNameView->SetText(name);
342 return B_OK;
346 const char*
347 AboutView::Version()
349 return fVersionView->Text();
353 status_t
354 AboutView::SetVersion(const char* version)
356 fVersionView->SetText(version);
358 return B_OK;
362 // #pragma mark - BAboutWindow
365 BAboutWindow::BAboutWindow(const char* appName, const char* signature)
367 BWindow(BRect(0.0, 0.0, 200.0, 200.0), appName, B_MODAL_WINDOW,
368 B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE
369 | B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE)
371 SetLayout(new BGroupLayout(B_VERTICAL));
373 const char* about = B_TRANSLATE_MARK("About %app%");
374 about = gSystemCatalog.GetString(about, "AboutWindow");
376 BString title(about);
377 title.ReplaceFirst("%app%", appName);
378 SetTitle(title.String());
380 fAboutView = new AboutView(appName, signature);
381 AddChild(fAboutView);
383 MoveTo(AboutPosition(Frame().Width(), Frame().Height()));
387 BAboutWindow::~BAboutWindow()
389 fAboutView->RemoveSelf();
390 delete fAboutView;
391 fAboutView = NULL;
395 // #pragma mark - BAboutWindow virtual methods
398 void
399 BAboutWindow::Show()
401 if (IsHidden()) {
402 // move to current workspace
403 SetWorkspaces(B_CURRENT_WORKSPACE);
406 BWindow::Show();
410 // #pragma mark - BAboutWindow public methods
413 BPoint
414 BAboutWindow::AboutPosition(float width, float height)
416 BPoint result(100, 100);
418 BWindow* window =
419 dynamic_cast<BWindow*>(BLooper::LooperForThread(find_thread(NULL)));
421 BScreen screen(window);
422 BRect screenFrame(0, 0, 640, 480);
423 if (screen.IsValid())
424 screenFrame = screen.Frame();
426 // Horizontally, we're smack in the middle
427 result.x = screenFrame.left + (screenFrame.Width() / 2.0) - (width / 2.0);
429 // This is probably sooo wrong, but it looks right on 1024 x 768
430 result.y = screenFrame.top + (screenFrame.Height() / 4.0)
431 - ceil(height / 3.0);
433 return result;
437 void
438 BAboutWindow::AddDescription(const char* description)
440 if (description == NULL)
441 return;
443 AddText(description);
447 void
448 BAboutWindow::AddCopyright(int32 firstCopyrightYear,
449 const char* copyrightHolder, const char** extraCopyrights)
451 BString copyright(B_UTF8_COPYRIGHT " %years% %holder%");
453 // Get current year
454 time_t tp;
455 time(&tp);
456 char currentYear[5];
457 strftime(currentYear, 5, "%Y", localtime(&tp));
458 BString copyrightYears;
459 copyrightYears << firstCopyrightYear;
460 if (copyrightYears != currentYear)
461 copyrightYears << "-" << currentYear;
463 BString text("");
464 if (fAboutView->InfoView()->TextLength() > 0)
465 text << "\n\n";
467 text << copyright;
469 // Fill out the copyright year placeholder
470 text.ReplaceAll("%years%", copyrightYears.String());
472 // Fill in the copyright holder placeholder
473 text.ReplaceAll("%holder%", copyrightHolder);
475 // Add extra copyright strings
476 if (extraCopyrights != NULL) {
477 // Add optional extra copyright information
478 for (int32 i = 0; extraCopyrights[i]; i++)
479 text << "\n" << B_UTF8_COPYRIGHT << " " << extraCopyrights[i];
482 const char* allRightsReserved = B_TRANSLATE_MARK("All Rights Reserved.");
483 allRightsReserved = gSystemCatalog.GetString(allRightsReserved,
484 "AboutWindow");
485 text << "\n " << allRightsReserved;
487 fAboutView->InfoView()->Insert(text.String());
491 void
492 BAboutWindow::AddAuthors(const char** authors)
494 if (authors == NULL)
495 return;
497 const char* writtenBy = B_TRANSLATE_MARK("Written by:");
498 writtenBy = gSystemCatalog.GetString(writtenBy, "AboutWindow");
500 AddText(writtenBy, authors);
504 void
505 BAboutWindow::AddSpecialThanks(const char** thanks)
507 if (thanks == NULL)
508 return;
510 const char* specialThanks = B_TRANSLATE_MARK("Special Thanks:");
511 specialThanks = gSystemCatalog.GetString(specialThanks, "AboutWindow");
513 AddText(specialThanks, thanks);
517 void
518 BAboutWindow::AddVersionHistory(const char** history)
520 if (history == NULL)
521 return;
523 const char* versionHistory = B_TRANSLATE_MARK("Version history:");
524 versionHistory = gSystemCatalog.GetString(versionHistory, "AboutWindow");
526 AddText(versionHistory, history);
530 void
531 BAboutWindow::AddExtraInfo(const char* extraInfo)
533 if (extraInfo == NULL)
534 return;
536 const char* appExtraInfo = B_TRANSLATE_MARK(extraInfo);
537 appExtraInfo = gSystemCatalog.GetString(extraInfo, "AboutWindow");
539 BString extra("");
540 if (fAboutView->InfoView()->TextLength() > 0)
541 extra << "\n\n";
543 extra << appExtraInfo;
545 fAboutView->InfoView()->Insert(extra.String());
549 void
550 BAboutWindow::AddText(const char* header, const char** contents)
552 BTextView* infoView = fAboutView->InfoView();
553 int32 textLength = infoView->TextLength();
554 BString text("");
556 if (textLength > 0) {
557 text << "\n\n";
558 textLength += 2;
561 const char* indent = "";
562 if (header != NULL) {
563 indent = " ";
564 text << header;
567 if (contents != NULL) {
568 text << "\n";
569 for (int32 i = 0; contents[i]; i++)
570 text << indent << contents[i] << "\n";
573 infoView->Insert(text.String());
575 if (contents != NULL && header != NULL) {
576 infoView->SetFontAndColor(textLength, textLength + strlen(header),
577 be_bold_font);
582 BBitmap*
583 BAboutWindow::Icon()
585 return fAboutView->Icon();
589 void
590 BAboutWindow::SetIcon(BBitmap* icon)
592 fAboutView->SetIcon(icon);
596 const char*
597 BAboutWindow::Name()
599 return fAboutView->Name();
603 void
604 BAboutWindow::SetName(const char* name)
606 fAboutView->SetName(name);
610 const char*
611 BAboutWindow::Version()
613 return fAboutView->Version();
617 void
618 BAboutWindow::SetVersion(const char* version)
620 fAboutView->SetVersion(version);
624 // FBC padding
626 void BAboutWindow::_ReservedAboutWindow20() {}
627 void BAboutWindow::_ReservedAboutWindow19() {}
628 void BAboutWindow::_ReservedAboutWindow18() {}
629 void BAboutWindow::_ReservedAboutWindow17() {}
630 void BAboutWindow::_ReservedAboutWindow16() {}
631 void BAboutWindow::_ReservedAboutWindow15() {}
632 void BAboutWindow::_ReservedAboutWindow14() {}
633 void BAboutWindow::_ReservedAboutWindow13() {}
634 void BAboutWindow::_ReservedAboutWindow12() {}
635 void BAboutWindow::_ReservedAboutWindow11() {}
636 void BAboutWindow::_ReservedAboutWindow10() {}
637 void BAboutWindow::_ReservedAboutWindow9() {}
638 void BAboutWindow::_ReservedAboutWindow8() {}
639 void BAboutWindow::_ReservedAboutWindow7() {}
640 void BAboutWindow::_ReservedAboutWindow6() {}
641 void BAboutWindow::_ReservedAboutWindow5() {}
642 void BAboutWindow::_ReservedAboutWindow4() {}
643 void BAboutWindow::_ReservedAboutWindow3() {}
644 void BAboutWindow::_ReservedAboutWindow2() {}
645 void BAboutWindow::_ReservedAboutWindow1() {}