1 /* 2 * Copyright 2005-2014, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Augustin Cavalier <waddlesplash> 7 * DarkWyrm <bpmagic@columbus.rr.com> 8 * René Gollent 9 * Wim van der Meer <WPJvanderMeer@gmail.com> 10 */ 11 12 13 #include <ctype.h> 14 #include <stdio.h> 15 #include <time.h> 16 #include <unistd.h> 17 18 #include <algorithm> 19 #include <map> 20 #include <string> 21 22 #include <AppFileInfo.h> 23 #include <Application.h> 24 #include <Bitmap.h> 25 #include <DateTimeFormat.h> 26 #include <DurationFormat.h> 27 #include <File.h> 28 #include <FindDirectory.h> 29 #include <Font.h> 30 #include <fs_attr.h> 31 #include <LayoutBuilder.h> 32 #include <MessageFormat.h> 33 #include <MessageRunner.h> 34 #include <Messenger.h> 35 #include <OS.h> 36 #include <Path.h> 37 #include <PathFinder.h> 38 #include <Resources.h> 39 #include <Screen.h> 40 #include <ScrollView.h> 41 #include <String.h> 42 #include <StringList.h> 43 #include <StringView.h> 44 #include <TranslationUtils.h> 45 #include <TranslatorFormats.h> 46 #include <View.h> 47 #include <Volume.h> 48 #include <VolumeRoster.h> 49 #include <Window.h> 50 51 #include <AppMisc.h> 52 #include <AutoDeleter.h> 53 #include <cpu_type.h> 54 #include <parsedate.h> 55 #include <system_revision.h> 56 57 #include <Catalog.h> 58 #include <Language.h> 59 #include <Locale.h> 60 #include <LocaleRoster.h> 61 62 #include "HyperTextActions.h" 63 #include "HyperTextView.h" 64 #include "Utilities.h" 65 66 #include "Credits.h" 67 68 #ifndef LINE_MAX 69 #define LINE_MAX 2048 70 #endif 71 72 #define SCROLL_CREDITS_VIEW 'mviv' 73 74 #undef B_TRANSLATION_CONTEXT 75 #define B_TRANSLATION_CONTEXT "AboutWindow" 76 77 78 79 static const char* UptimeToString(char string[], size_t size); 80 static const char* MemSizeToString(char string[], size_t size, 81 system_info* info); 82 static const char* MemUsageToString(char string[], size_t size, 83 system_info* info); 84 85 86 static const rgb_color kDarkGrey = { 100, 100, 100, 255 }; 87 static const rgb_color kHaikuGreen = { 42, 131, 36, 255 }; 88 static const rgb_color kHaikuOrange = { 255, 69, 0, 255 }; 89 static const rgb_color kHaikuYellow = { 255, 176, 0, 255 }; 90 static const rgb_color kLinkBlue = { 80, 80, 200, 255 }; 91 static const rgb_color kBeOSBlue = { 0, 0, 200, 255 }; 92 static const rgb_color kBeOSRed = { 200, 0, 0, 255 }; 93 94 static const char* kBSDTwoClause = B_TRANSLATE_MARK("BSD (2-clause)"); 95 static const char* kBSDThreeClause = B_TRANSLATE_MARK("BSD (3-clause)"); 96 static const char* kBSDFourClause = B_TRANSLATE_MARK("BSD (4-clause)"); 97 static const char* kGPLv2 = B_TRANSLATE_MARK("GNU GPL v2"); 98 static const char* kGPLv3 = B_TRANSLATE_MARK("GNU GPL v3"); 99 static const char* kLGPLv2 = B_TRANSLATE_MARK("GNU LGPL v2"); 100 static const char* kLGPLv21 = B_TRANSLATE_MARK("GNU LGPL v2.1"); 101 static const char* kPublicDomain = B_TRANSLATE_MARK("Public Domain"); 102 #ifdef __INTEL__ 103 static const char* kIntel2xxxFirmware = B_TRANSLATE_MARK("Intel (2xxx firmware)"); 104 static const char* kIntelFirmware = B_TRANSLATE_MARK("Intel (firmware)"); 105 static const char* kMarvellFirmware = B_TRANSLATE_MARK("Marvell (firmware)"); 106 static const char* kRalinkFirmware = B_TRANSLATE_MARK("Ralink (firmware)"); 107 #endif 108 109 110 static int 111 TranslationComparator(const void* left, const void* right) 112 { 113 const Translation* leftTranslation = *(const Translation**)left; 114 const Translation* rightTranslation = *(const Translation**)right; 115 116 BLanguage* language; 117 BString leftName; 118 if (BLocaleRoster::Default()->GetLanguage(leftTranslation->languageCode, 119 &language) == B_OK) { 120 language->GetName(leftName); 121 delete language; 122 } else 123 leftName = leftTranslation->languageCode; 124 125 BString rightName; 126 if (BLocaleRoster::Default()->GetLanguage(rightTranslation->languageCode, 127 &language) == B_OK) { 128 language->GetName(rightName); 129 delete language; 130 } else 131 rightName = rightTranslation->languageCode; 132 133 BCollator collator; 134 BLocale::Default()->GetCollator(&collator); 135 return collator.Compare(leftName.String(), rightName.String()); 136 } 137 138 139 class AboutApp : public BApplication { 140 public: 141 AboutApp(); 142 void MessageReceived(BMessage* message); 143 }; 144 145 146 class AboutWindow : public BWindow { 147 public: 148 AboutWindow(); 149 150 virtual bool QuitRequested(); 151 }; 152 153 154 class LogoView : public BView { 155 public: 156 LogoView(); 157 virtual ~LogoView(); 158 159 virtual BSize MinSize(); 160 virtual BSize MaxSize(); 161 162 virtual void Draw(BRect updateRect); 163 164 private: 165 BBitmap* fLogo; 166 }; 167 168 169 class CropView : public BView { 170 public: 171 CropView(BView* target, int32 left, int32 top, 172 int32 right, int32 bottom); 173 virtual ~CropView(); 174 175 virtual BSize MinSize(); 176 virtual BSize MaxSize(); 177 178 virtual void DoLayout(); 179 180 private: 181 BView* fTarget; 182 int32 fCropLeft; 183 int32 fCropTop; 184 int32 fCropRight; 185 int32 fCropBottom; 186 }; 187 188 189 class AboutView : public BView { 190 public: 191 AboutView(); 192 ~AboutView(); 193 194 virtual void AttachedToWindow(); 195 virtual void Pulse(); 196 197 virtual void MessageReceived(BMessage* msg); 198 virtual void MouseDown(BPoint point); 199 200 void AddCopyrightEntry(const char* name, 201 const char* text, 202 const StringVector& licenses, 203 const StringVector& sources, 204 const char* url); 205 void AddCopyrightEntry(const char* name, 206 const char* text, const char* url = NULL); 207 void PickRandomHaiku(); 208 209 210 private: 211 typedef std::map<std::string, PackageCredit*> PackageCreditMap; 212 213 private: 214 BView* _CreateLabel(const char* name, const char* label); 215 BView* _CreateCreditsView(); 216 status_t _GetLicensePath(const char* license, 217 BPath& path); 218 void _AddCopyrightsFromAttribute(); 219 void _AddPackageCredit(const PackageCredit& package); 220 void _AddPackageCreditEntries(); 221 222 BStringView* fMemView; 223 BTextView* fUptimeView; 224 BView* fInfoView; 225 HyperTextView* fCreditsView; 226 227 BBitmap* fLogo; 228 229 bigtime_t fLastActionTime; 230 BMessageRunner* fScrollRunner; 231 PackageCreditMap fPackageCredits; 232 }; 233 234 235 // #pragma mark - 236 237 238 AboutApp::AboutApp() 239 : BApplication("application/x-vnd.Haiku-About") 240 { 241 B_TRANSLATE_MARK_SYSTEM_NAME_VOID("AboutSystem"); 242 243 AboutWindow *window = new(std::nothrow) AboutWindow(); 244 if (window) 245 window->Show(); 246 } 247 248 249 void 250 AboutApp::MessageReceived(BMessage* message) 251 { 252 switch (message->what) { 253 case B_SILENT_RELAUNCH: 254 WindowAt(0)->Activate(); 255 break; 256 } 257 258 BApplication::MessageReceived(message); 259 } 260 261 262 // #pragma mark - 263 264 265 AboutWindow::AboutWindow() 266 : BWindow(BRect(0, 0, 500, 300), B_TRANSLATE("About this system"), 267 B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE) 268 { 269 SetLayout(new BGroupLayout(B_VERTICAL)); 270 AddChild(new AboutView()); 271 272 // Make sure we take the minimal window size into account when centering 273 BSize size = GetLayout()->MinSize(); 274 ResizeTo(max_c(size.width, Bounds().Width()), 275 max_c(size.height, Bounds().Height())); 276 277 CenterOnScreen(); 278 } 279 280 281 bool 282 AboutWindow::QuitRequested() 283 { 284 be_app->PostMessage(B_QUIT_REQUESTED); 285 return true; 286 } 287 288 289 // #pragma mark - LogoView 290 291 292 LogoView::LogoView() 293 : BView("logo", B_WILL_DRAW) 294 { 295 fLogo = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "logo.png"); 296 SetViewColor(255, 255, 255); 297 } 298 299 300 LogoView::~LogoView() 301 { 302 delete fLogo; 303 } 304 305 306 BSize 307 LogoView::MinSize() 308 { 309 if (fLogo == NULL) 310 return BSize(0, 0); 311 312 return BSize(fLogo->Bounds().Width(), fLogo->Bounds().Height()); 313 } 314 315 316 BSize 317 LogoView::MaxSize() 318 { 319 if (fLogo == NULL) 320 return BSize(0, 0); 321 322 return BSize(B_SIZE_UNLIMITED, fLogo->Bounds().Height()); 323 } 324 325 326 void 327 LogoView::Draw(BRect updateRect) 328 { 329 if (fLogo != NULL) { 330 DrawBitmap(fLogo, 331 BPoint((Bounds().Width() - fLogo->Bounds().Width()) / 2, 0)); 332 } 333 } 334 335 336 // #pragma mark - CropView 337 338 339 CropView::CropView(BView* target, int32 left, int32 top, int32 right, 340 int32 bottom) 341 : BView("crop view", 0), 342 fTarget(target), 343 fCropLeft(left), 344 fCropTop(top), 345 fCropRight(right), 346 fCropBottom(bottom) 347 { 348 AddChild(target); 349 } 350 351 352 CropView::~CropView() 353 { 354 } 355 356 357 BSize 358 CropView::MinSize() 359 { 360 if (fTarget == NULL) 361 return BSize(); 362 363 BSize size = fTarget->MinSize(); 364 if (size.width != B_SIZE_UNSET) 365 size.width -= fCropLeft + fCropRight; 366 if (size.height != B_SIZE_UNSET) 367 size.height -= fCropTop + fCropBottom; 368 369 return size; 370 } 371 372 373 BSize 374 CropView::MaxSize() 375 { 376 if (fTarget == NULL) 377 return BSize(); 378 379 BSize size = fTarget->MaxSize(); 380 if (size.width != B_SIZE_UNSET) 381 size.width -= fCropLeft + fCropRight; 382 if (size.height != B_SIZE_UNSET) 383 size.height -= fCropTop + fCropBottom; 384 385 return size; 386 } 387 388 389 void 390 CropView::DoLayout() 391 { 392 BView::DoLayout(); 393 394 if (fTarget == NULL) 395 return; 396 397 fTarget->MoveTo(-fCropLeft, -fCropTop); 398 fTarget->ResizeTo(Bounds().Width() + fCropLeft + fCropRight, 399 Bounds().Height() + fCropTop + fCropBottom); 400 } 401 402 403 // #pragma mark - AboutView 404 405 #undef B_TRANSLATION_CONTEXT 406 #define B_TRANSLATION_CONTEXT "AboutView" 407 408 AboutView::AboutView() 409 : BView("aboutview", B_WILL_DRAW | B_PULSE_NEEDED), 410 fLastActionTime(system_time()), 411 fScrollRunner(NULL) 412 { 413 // Begin Construction of System Information controls 414 415 system_info systemInfo; 416 get_system_info(&systemInfo); 417 418 // Create all the various labels for system infomation 419 420 // OS Version 421 422 char string[1024]; 423 strlcpy(string, B_TRANSLATE("Unknown"), sizeof(string)); 424 425 // the version is stored in the BEOS:APP_VERSION attribute of libbe.so 426 BPath path; 427 if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) { 428 path.Append("libbe.so"); 429 430 BAppFileInfo appFileInfo; 431 version_info versionInfo; 432 BFile file; 433 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK 434 && appFileInfo.SetTo(&file) == B_OK 435 && appFileInfo.GetVersionInfo(&versionInfo, 436 B_APP_VERSION_KIND) == B_OK 437 && versionInfo.short_info[0] != '\0') 438 strlcpy(string, versionInfo.short_info, sizeof(string)); 439 } 440 441 // Add system revision 442 const char* haikuRevision = __get_haiku_revision(); 443 if (haikuRevision != NULL) { 444 strlcat(string, " (", sizeof(string)); 445 strlcat(string, B_TRANSLATE("Revision"), sizeof(string)); 446 strlcat(string, " ", sizeof(string)); 447 strlcat(string, haikuRevision, sizeof(string)); 448 strlcat(string, ")", sizeof(string)); 449 } 450 451 BStringView* versionView = new BStringView("ostext", string); 452 versionView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 453 B_ALIGN_VERTICAL_UNSET)); 454 455 BStringView* abiView = new BStringView("abitext", B_HAIKU_ABI_NAME); 456 abiView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 457 B_ALIGN_VERTICAL_UNSET)); 458 459 // CPU count, type and clock speed 460 static BMessageFormat format(B_TRANSLATE_COMMENT( 461 "{0, plural, one{Processor:} other{# Processors:}}", 462 "\"Processor:\" or \"2 Processors:\"")); 463 464 BString processorLabel; 465 format.Format(processorLabel, systemInfo.cpu_count); 466 467 uint32 topologyNodeCount = 0; 468 cpu_topology_node_info* topology = NULL; 469 get_cpu_topology_info(NULL, &topologyNodeCount); 470 if (topologyNodeCount != 0) 471 topology = new cpu_topology_node_info[topologyNodeCount]; 472 get_cpu_topology_info(topology, &topologyNodeCount); 473 474 enum cpu_platform platform = B_CPU_UNKNOWN; 475 enum cpu_vendor cpuVendor = B_CPU_VENDOR_UNKNOWN; 476 uint32 cpuModel = 0; 477 for (uint32 i = 0; i < topologyNodeCount; i++) { 478 switch (topology[i].type) { 479 case B_TOPOLOGY_ROOT: 480 platform = topology[i].data.root.platform; 481 break; 482 483 case B_TOPOLOGY_PACKAGE: 484 cpuVendor = topology[i].data.package.vendor; 485 break; 486 487 case B_TOPOLOGY_CORE: 488 cpuModel = topology[i].data.core.model; 489 break; 490 491 default: 492 break; 493 } 494 } 495 496 delete[] topology; 497 498 BString cpuType; 499 cpuType << get_cpu_vendor_string(cpuVendor) 500 << " " << get_cpu_model_string(platform, cpuVendor, cpuModel); 501 502 BStringView* cpuView = new BStringView("cputext", cpuType.String()); 503 cpuView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 504 B_ALIGN_VERTICAL_UNSET)); 505 506 int32 clockSpeed = get_rounded_cpu_speed(); 507 if (clockSpeed < 1000) 508 snprintf(string, sizeof(string), B_TRANSLATE("%ld MHz"), clockSpeed); 509 else 510 snprintf(string, sizeof(string), B_TRANSLATE("%.2f GHz"), 511 clockSpeed / 1000.0f); 512 513 BStringView* frequencyView = new BStringView("frequencytext", string); 514 frequencyView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 515 B_ALIGN_VERTICAL_UNSET)); 516 517 // RAM 518 BStringView *memSizeView = new BStringView("ramsizetext", 519 MemSizeToString(string, sizeof(string), &systemInfo)); 520 memSizeView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 521 B_ALIGN_VERTICAL_UNSET)); 522 fMemView = new BStringView("ramtext", 523 MemUsageToString(string, sizeof(string), &systemInfo)); 524 fMemView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 525 B_ALIGN_VERTICAL_UNSET)); 526 527 // Kernel build time/date 528 BString kernelTimeDate; 529 kernelTimeDate << systemInfo.kernel_build_date 530 << " " << systemInfo.kernel_build_time; 531 BString buildTimeDate; 532 533 time_t buildTimeDateStamp = parsedate(kernelTimeDate, -1); 534 if (buildTimeDateStamp > 0) { 535 if (BDateTimeFormat().Format(buildTimeDate, buildTimeDateStamp, 536 B_LONG_DATE_FORMAT, B_MEDIUM_TIME_FORMAT) != B_OK) 537 buildTimeDate.SetTo(kernelTimeDate); 538 } else 539 buildTimeDate.SetTo(kernelTimeDate); 540 541 BStringView* kernelView = new BStringView("kerneltext", buildTimeDate); 542 kernelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 543 B_ALIGN_VERTICAL_UNSET)); 544 545 // Uptime 546 fUptimeView = new BTextView("uptimetext"); 547 fUptimeView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 548 fUptimeView->MakeEditable(false); 549 fUptimeView->MakeSelectable(false); 550 fUptimeView->SetWordWrap(true); 551 552 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 553 554 const float offset = 5; 555 556 SetLayout(new BGroupLayout(B_HORIZONTAL, 0)); 557 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 558 559 BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) 560 .AddGroup(B_VERTICAL, 0) 561 .Add(new LogoView()) 562 .AddGroup(B_VERTICAL, 0) 563 .Add(_CreateLabel("oslabel", B_TRANSLATE("Version:"))) 564 .Add(versionView) 565 .Add(abiView) 566 .AddStrut(offset) 567 .Add(_CreateLabel("cpulabel", processorLabel.String())) 568 .Add(cpuView) 569 .Add(frequencyView) 570 .AddStrut(offset) 571 .Add(_CreateLabel("memlabel", B_TRANSLATE("Memory:"))) 572 .Add(memSizeView) 573 .Add(fMemView) 574 .AddStrut(offset) 575 .Add(_CreateLabel("kernellabel", B_TRANSLATE("Kernel:"))) 576 .Add(kernelView) 577 .AddStrut(offset) 578 .Add(_CreateLabel("uptimelabel", 579 B_TRANSLATE("Time running:"))) 580 .Add(fUptimeView) 581 .SetInsets(5, 5, 5, 5) 582 .End() 583 // TODO: investigate: adding this causes the time to be cut 584 //.AddGlue() 585 .End() 586 .Add(_CreateCreditsView()); 587 588 float min = fMemView->MinSize().width * 1.1f; 589 fCreditsView->SetExplicitMinSize(BSize(min, min)); 590 } 591 592 593 AboutView::~AboutView() 594 { 595 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 596 it != fPackageCredits.end(); it++) { 597 598 delete it->second; 599 } 600 601 delete fScrollRunner; 602 } 603 604 605 void 606 AboutView::AttachedToWindow() 607 { 608 BView::AttachedToWindow(); 609 Window()->SetPulseRate(500000); 610 SetEventMask(B_POINTER_EVENTS); 611 } 612 613 614 void 615 AboutView::MouseDown(BPoint point) 616 { 617 BRect r(92, 26, 105, 31); 618 if (r.Contains(point)) 619 BMessenger(this).SendMessage('eegg'); 620 621 if (Bounds().Contains(point)) { 622 fLastActionTime = system_time(); 623 delete fScrollRunner; 624 fScrollRunner = NULL; 625 } 626 } 627 628 629 void 630 AboutView::Pulse() 631 { 632 char string[255]; 633 system_info info; 634 get_system_info(&info); 635 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 636 fMemView->SetText(MemUsageToString(string, sizeof(string), &info)); 637 638 if (fScrollRunner == NULL 639 && system_time() > fLastActionTime + 10000000) { 640 BMessage message(SCROLL_CREDITS_VIEW); 641 //fScrollRunner = new BMessageRunner(this, &message, 25000, -1); 642 } 643 } 644 645 646 void 647 AboutView::MessageReceived(BMessage* msg) 648 { 649 switch (msg->what) { 650 case SCROLL_CREDITS_VIEW: 651 { 652 BScrollBar* scrollBar = 653 fCreditsView->ScrollBar(B_VERTICAL); 654 if (scrollBar == NULL) 655 break; 656 float max, min; 657 scrollBar->GetRange(&min, &max); 658 if (scrollBar->Value() < max) 659 fCreditsView->ScrollBy(0, 1); 660 661 break; 662 } 663 664 case 'eegg': 665 { 666 printf("Easter egg\n"); 667 PickRandomHaiku(); 668 break; 669 } 670 671 default: 672 BView::MessageReceived(msg); 673 break; 674 } 675 } 676 677 678 void 679 AboutView::AddCopyrightEntry(const char* name, const char* text, 680 const char* url) 681 { 682 AddCopyrightEntry(name, text, StringVector(), StringVector(), url); 683 } 684 685 686 void 687 AboutView::AddCopyrightEntry(const char* name, const char* text, 688 const StringVector& licenses, const StringVector& sources, 689 const char* url) 690 { 691 BFont font(be_bold_font); 692 //font.SetSize(be_bold_font->Size()); 693 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 694 695 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuYellow); 696 fCreditsView->Insert(name); 697 fCreditsView->Insert("\n"); 698 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 699 fCreditsView->Insert(text); 700 fCreditsView->Insert("\n"); 701 702 if (licenses.CountStrings() > 0) { 703 if (licenses.CountStrings() > 1) 704 fCreditsView->Insert(B_TRANSLATE("Licenses: ")); 705 else 706 fCreditsView->Insert(B_TRANSLATE("License: ")); 707 708 for (int32 i = 0; i < licenses.CountStrings(); i++) { 709 const char* license = licenses.StringAt(i); 710 711 if (i > 0) 712 fCreditsView->Insert(", "); 713 714 BString licenseName; 715 BString licenseURL; 716 parse_named_url(license, licenseName, licenseURL); 717 718 BPath licensePath; 719 if (_GetLicensePath(licenseURL, licensePath) == B_OK) { 720 fCreditsView->InsertHyperText(B_TRANSLATE_NOCOLLECT(licenseName), 721 new OpenFileAction(licensePath.Path())); 722 } else 723 fCreditsView->Insert(licenseName); 724 } 725 726 fCreditsView->Insert("\n"); 727 } 728 729 if (sources.CountStrings() > 0) { 730 fCreditsView->Insert(B_TRANSLATE("Source Code: ")); 731 732 for (int32 i = 0; i < sources.CountStrings(); i++) { 733 const char* source = sources.StringAt(i); 734 735 if (i > 0) 736 fCreditsView->Insert(", "); 737 738 BString urlName; 739 BString urlAddress; 740 parse_named_url(source, urlName, urlAddress); 741 742 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 743 &kLinkBlue); 744 fCreditsView->InsertHyperText(urlName, 745 new URLAction(urlAddress)); 746 } 747 748 fCreditsView->Insert("\n"); 749 } 750 751 if (url) { 752 BString urlName; 753 BString urlAddress; 754 parse_named_url(url, urlName, urlAddress); 755 756 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 757 &kLinkBlue); 758 fCreditsView->InsertHyperText(urlName, 759 new URLAction(urlAddress)); 760 fCreditsView->Insert("\n"); 761 } 762 fCreditsView->Insert("\n"); 763 } 764 765 766 void 767 AboutView::PickRandomHaiku() 768 { 769 BPath path; 770 if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK) 771 path = "/system/data"; 772 path.Append("fortunes"); 773 path.Append("Haiku"); 774 775 BFile fortunes(path.Path(), B_READ_ONLY); 776 struct stat st; 777 if (fortunes.InitCheck() < B_OK) 778 return; 779 if (fortunes.GetStat(&st) < B_OK) 780 return; 781 782 char* buff = (char*)malloc((size_t)st.st_size + 1); 783 if (!buff) 784 return; 785 buff[(size_t)st.st_size] = '\0'; 786 BList haikuList; 787 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 788 char* p = buff; 789 while (p && *p) { 790 char* e = strchr(p, '%'); 791 BString* s = new BString(p, e ? (e - p) : -1); 792 haikuList.AddItem(s); 793 p = e; 794 if (p && (*p == '%')) 795 p++; 796 if (p && (*p == '\n')) 797 p++; 798 } 799 } 800 free(buff); 801 if (haikuList.CountItems() < 1) 802 return; 803 804 BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems()); 805 BFont font(be_bold_font); 806 font.SetSize(be_bold_font->Size()); 807 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 808 fCreditsView->SelectAll(); 809 fCreditsView->Delete(); 810 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey); 811 fCreditsView->Insert(s->String()); 812 fCreditsView->Insert("\n"); 813 while ((s = (BString*)haikuList.RemoveItem((int32)0))) { 814 delete s; 815 } 816 } 817 818 819 BView* 820 AboutView::_CreateLabel(const char* name, const char* label) 821 { 822 BStringView* labelView = new BStringView(name, label); 823 labelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 824 B_ALIGN_VERTICAL_UNSET)); 825 labelView->SetFont(be_bold_font); 826 return labelView; 827 } 828 829 830 BView* 831 AboutView::_CreateCreditsView() 832 { 833 // Begin construction of the credits view 834 fCreditsView = new HyperTextView("credits"); 835 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS); 836 fCreditsView->SetStylable(true); 837 fCreditsView->MakeEditable(false); 838 fCreditsView->SetWordWrap(true); 839 fCreditsView->SetInsets(5, 5, 5, 5); 840 fCreditsView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); 841 842 BScrollView* creditsScroller = new BScrollView("creditsScroller", 843 fCreditsView, B_WILL_DRAW | B_FRAME_EVENTS, false, true, 844 B_PLAIN_BORDER); 845 846 // Haiku copyright 847 BFont font(be_bold_font); 848 font.SetSize(font.Size() + 4); 849 850 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 851 fCreditsView->Insert("Haiku\n"); 852 853 char string[1024]; 854 time_t time = ::time(NULL); 855 struct tm* tm = localtime(&time); 856 int32 year = tm->tm_year + 1900; 857 if (year < 2008) 858 year = 2008; 859 snprintf(string, sizeof(string), 860 COPYRIGHT_STRING "2001-%" B_PRId32 " The Haiku project. ", year); 861 862 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 863 fCreditsView->Insert(string); 864 865 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 866 fCreditsView->Insert(B_TRANSLATE("The copyright to the Haiku code is " 867 "property of Haiku, Inc. or of the respective authors where expressly " 868 "noted in the source. Haiku" B_UTF8_REGISTERED 869 " and the HAIKU logo" B_UTF8_REGISTERED 870 " are registered trademarks of Haiku, Inc." 871 "\n\n")); 872 873 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 874 fCreditsView->InsertHyperText("https://www.haiku-os.org", 875 new URLAction("https://www.haiku-os.org")); 876 fCreditsView->Insert("\n\n"); 877 878 font.SetSize(be_bold_font->Size()); 879 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 880 881 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 882 fCreditsView->Insert(B_TRANSLATE("Current maintainers:\n")); 883 884 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 885 fCreditsView->Insert(kCurrentMaintainers); 886 887 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 888 fCreditsView->Insert(B_TRANSLATE("Past maintainers:\n")); 889 890 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 891 fCreditsView->Insert(kPastMaintainers); 892 893 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 894 fCreditsView->Insert(B_TRANSLATE("Website & marketing:\n")); 895 896 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 897 fCreditsView->Insert(kWebsiteTeam); 898 899 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 900 fCreditsView->Insert(B_TRANSLATE("Past website & marketing:\n")); 901 902 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 903 fCreditsView->Insert(kPastWebsiteTeam); 904 905 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 906 fCreditsView->Insert(B_TRANSLATE("Contributors:\n")); 907 908 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 909 fCreditsView->Insert(kContributors); 910 fCreditsView->Insert( 911 B_TRANSLATE("\n" B_UTF8_ELLIPSIS 912 "and probably some more we forgot to mention (sorry!)" 913 "\n\n")); 914 915 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 916 fCreditsView->Insert(B_TRANSLATE("Translations:\n")); 917 918 BLanguage* lang; 919 BString langName; 920 921 BList sortedTranslations; 922 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 923 const Translation* translation = &kTranslations[i]; 924 sortedTranslations.AddItem((void*)translation); 925 } 926 sortedTranslations.SortItems(TranslationComparator); 927 928 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 929 const Translation& translation 930 = *(const Translation*)sortedTranslations.ItemAt(i); 931 932 langName.Truncate(0); 933 if (BLocaleRoster::Default()->GetLanguage(translation.languageCode, 934 &lang) == B_OK) { 935 lang->GetName(langName); 936 delete lang; 937 } else { 938 // We failed to get the localized readable name, 939 // go with what we have. 940 langName.Append(translation.languageCode); 941 } 942 943 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 944 fCreditsView->Insert("\n"); 945 fCreditsView->Insert(langName); 946 fCreditsView->Insert("\n"); 947 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 948 fCreditsView->Insert(translation.names); 949 } 950 951 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 952 fCreditsView->Insert(B_TRANSLATE("\n\nSpecial thanks to:\n")); 953 954 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 955 BString beosCredits(B_TRANSLATE( 956 "Be Inc. and its developer team, for having created BeOS!\n\n")); 957 int32 beosOffset = beosCredits.FindFirst("BeOS"); 958 fCreditsView->Insert(beosCredits.String(), 959 (beosOffset < 0) ? beosCredits.Length() : beosOffset); 960 if (beosOffset > -1) { 961 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBeOSBlue); 962 fCreditsView->Insert("B"); 963 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBeOSRed); 964 fCreditsView->Insert("e"); 965 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 966 beosCredits.Remove(0, beosOffset + 2); 967 fCreditsView->Insert(beosCredits.String(), beosCredits.Length()); 968 } 969 fCreditsView->Insert( 970 B_TRANSLATE("Travis Geiselbrecht (and his NewOS kernel)\n")); 971 fCreditsView->Insert( 972 B_TRANSLATE("Michael Phipps (project founder)\n\n")); 973 fCreditsView->Insert( 974 B_TRANSLATE("The HaikuPorts team\n")); 975 fCreditsView->Insert( 976 B_TRANSLATE("The Haikuware team and their bounty program\n")); 977 fCreditsView->Insert( 978 B_TRANSLATE("The BeGeistert team\n")); 979 fCreditsView->Insert( 980 B_TRANSLATE("Google and their Google Summer of Code and Google Code In " 981 "programs\n")); 982 fCreditsView->Insert( 983 B_TRANSLATE("The University of Auckland and Christof Lutteroth\n\n")); 984 fCreditsView->Insert( 985 B_TRANSLATE(B_UTF8_ELLIPSIS "and the many people making donations!\n\n")); 986 987 // copyrights for various projects we use 988 989 BPath mitPath; 990 _GetLicensePath("MIT", mitPath); 991 BPath lgplPath; 992 _GetLicensePath("GNU LGPL v2.1", lgplPath); 993 994 font.SetSize(be_bold_font->Size() + 4); 995 font.SetFace(B_BOLD_FACE); 996 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 997 fCreditsView->Insert(B_TRANSLATE("\nCopyrights\n\n")); 998 999 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1000 fCreditsView->Insert(B_TRANSLATE("[Click a license name to read the " 1001 "respective license.]\n\n")); 1002 1003 // Haiku license 1004 BString haikuLicense = B_TRANSLATE_COMMENT("The code that is unique to " 1005 "Haiku, especially the kernel and all code that applications may link " 1006 "against, is distributed under the terms of the <MIT license>. " 1007 "Some system libraries contain third party code distributed under the " 1008 "<LGPL license>. You can find the copyrights to third party code below." 1009 "\n\n", "<MIT license> and <LGPL license> aren't variables and can be " 1010 "translated. However, please, don't remove < and > as they're needed " 1011 "as placeholders for proper hypertext functionality."); 1012 int32 licensePart1 = haikuLicense.FindFirst("<"); 1013 int32 licensePart2 = haikuLicense.FindFirst(">"); 1014 int32 licensePart3 = haikuLicense.FindLast("<"); 1015 int32 licensePart4 = haikuLicense.FindLast(">"); 1016 BString part; 1017 haikuLicense.CopyInto(part, 0, licensePart1); 1018 fCreditsView->Insert(part); 1019 1020 part.Truncate(0); 1021 haikuLicense.CopyInto(part, licensePart1 + 1, licensePart2 - 1 1022 - licensePart1); 1023 fCreditsView->InsertHyperText(part, new OpenFileAction(mitPath.Path())); 1024 1025 part.Truncate(0); 1026 haikuLicense.CopyInto(part, licensePart2 + 1, licensePart3 - 1 1027 - licensePart2); 1028 fCreditsView->Insert(part); 1029 1030 part.Truncate(0); 1031 haikuLicense.CopyInto(part, licensePart3 + 1, licensePart4 - 1 1032 - licensePart3); 1033 fCreditsView->InsertHyperText(part, new OpenFileAction(lgplPath.Path())); 1034 1035 part.Truncate(0); 1036 haikuLicense.CopyInto(part, licensePart4 + 1, haikuLicense.Length() - 1 1037 - licensePart4); 1038 fCreditsView->Insert(part); 1039 1040 // GNU copyrights 1041 AddCopyrightEntry("The GNU Project", 1042 B_TRANSLATE("Contains software from the GNU Project, " 1043 "released under the GPL and LGPL licenses:\n" 1044 "GNU C Library, " 1045 "GNU coretools, diffutils, findutils, " 1046 "sharutils, gawk, bison, m4, make, " 1047 "wget, ncurses, termcap, " 1048 "Bourne Again Shell.\n" 1049 COPYRIGHT_STRING "The Free Software Foundation."), 1050 StringVector(kLGPLv21, kGPLv2, kGPLv3, NULL), 1051 StringVector(), 1052 "https://www.gnu.org"); 1053 1054 // FreeBSD copyrights 1055 AddCopyrightEntry("The FreeBSD Project", 1056 B_TRANSLATE("Contains software from the FreeBSD Project, " 1057 "released under the BSD license:\n" 1058 "ftpd, ping, telnet, telnetd, traceroute\n" 1059 COPYRIGHT_STRING "1994-2008 The FreeBSD Project. " 1060 "All rights reserved."), 1061 StringVector(kBSDTwoClause, kBSDThreeClause, kBSDFourClause, 1062 NULL), 1063 StringVector(), 1064 "https://www.freebsd.org"); 1065 1066 // NetBSD copyrights 1067 AddCopyrightEntry("The NetBSD Project", 1068 B_TRANSLATE("Contains software developed by the NetBSD " 1069 "Foundation, Inc. and its contributors:\n" 1070 "ftp, tput\n" 1071 COPYRIGHT_STRING "1996-2008 The NetBSD Foundation, Inc. " 1072 "All rights reserved."), 1073 "https://www.netbsd.org"); 1074 // TODO: License! 1075 1076 // FFmpeg copyrights 1077 _AddPackageCredit(PackageCredit("FFmpeg") 1078 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2000-2014 Fabrice " 1079 "Bellard, et al.")) 1080 .SetLicenses(kLGPLv21, kLGPLv2, NULL) 1081 .SetURL("https://www.ffmpeg.org")); 1082 1083 // AGG copyrights 1084 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 1085 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2006 Maxim " 1086 "Shemanarev (McSeem).")) 1087 .SetLicenses("Anti-Grain Geometry", kBSDThreeClause, "GPC", NULL) 1088 .SetURL("http://www.antigrain.com")); 1089 1090 // PDFLib copyrights 1091 _AddPackageCredit(PackageCredit("PDFLib") 1092 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1997-2006 PDFlib GmbH and " 1093 "Thomas Merz. All rights reserved.\n" 1094 "PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.")) 1095 .SetLicense("PDFlib Lite") 1096 .SetURL("http://www.pdflib.com")); 1097 1098 // FreeType copyrights 1099 _AddPackageCredit(PackageCredit("FreeType2") 1100 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1996-2002, 2006 " 1101 "David Turner, Robert Wilhelm and Werner Lemberg."), 1102 COPYRIGHT_STRING "2014 The FreeType Project. " 1103 "All rights reserved.", 1104 NULL) 1105 .SetLicense("FreeType") 1106 .SetURL("http://www.freetype.org")); 1107 1108 // Mesa3D (http://www.mesa3d.org) copyrights 1109 _AddPackageCredit(PackageCredit("Mesa") 1110 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2006 Brian Paul. " 1111 "Mesa3D Project. All rights reserved.")) 1112 .SetLicense("MIT") 1113 .SetURL("http://www.mesa3d.org")); 1114 1115 // SGI's GLU implementation copyrights 1116 _AddPackageCredit(PackageCredit("GLU") 1117 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1991-2000 " 1118 "Silicon Graphics, Inc. All rights reserved.")) 1119 .SetLicense("SGI Free B") 1120 .SetURL("http://www.sgi.com/products/software/opengl")); 1121 1122 // GLUT implementation copyrights 1123 _AddPackageCredit(PackageCredit("GLUT") 1124 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1125 "All rights reserved."), 1126 COPYRIGHT_STRING "1997 Be Inc.", 1127 COPYRIGHT_STRING "1999 Jake Hamby.", 1128 NULL) 1129 .SetLicense("GLUT (Mark Kilgard)") 1130 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1131 1132 // OpenGroup & DEC (BRegion backend) copyright 1133 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1134 .SetCopyrights(COPYRIGHT_STRING "1987-1988, 1998 The Open Group.", 1135 B_TRANSLATE(COPYRIGHT_STRING "1987-1988 Digital Equipment " 1136 "Corporation, Maynard, Massachusetts.\n" 1137 "All rights reserved."), 1138 NULL) 1139 .SetLicenses("OpenGroup", "DEC", NULL)); 1140 // TODO: URL 1141 1142 // VL-Gothic font 1143 _AddPackageCredit(PackageCredit("VL-Gothic font") 1144 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1990-2003 Wada Laboratory," 1145 " the University of Tokyo."), COPYRIGHT_STRING 1146 "2003-2004 Electronic Font Open Laboratory (/efont/).", 1147 COPYRIGHT_STRING "2003-2012 M+ FONTS PROJECT.", 1148 COPYRIGHT_STRING "2006-2012 Daisuke SUZUKI.", 1149 COPYRIGHT_STRING "2006-2012 Project Vine.", 1150 B_TRANSLATE("MIT license. All rights reserved."), 1151 NULL) 1152 .SetLicense(kBSDThreeClause) 1153 .SetURL("http://vlgothic.dicey.org/")); 1154 1155 // expat copyrights 1156 _AddPackageCredit(PackageCredit("expat") 1157 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1998-2000 Thai " 1158 "Open Source Software Center Ltd and Clark Cooper."), 1159 B_TRANSLATE(COPYRIGHT_STRING "2001-2003 Expat maintainers."), 1160 NULL) 1161 .SetLicense("Expat") 1162 .SetURL("http://expat.sourceforge.net")); 1163 1164 // zlib copyrights 1165 _AddPackageCredit(PackageCredit("zlib") 1166 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2004 Jean-loup " 1167 "Gailly and Mark Adler.")) 1168 .SetLicense("Zlib") 1169 .SetURL("http://www.zlib.net")); 1170 1171 // zip copyrights 1172 _AddPackageCredit(PackageCredit("Info-ZIP") 1173 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1990-2002 Info-ZIP. " 1174 "All rights reserved.")) 1175 .SetLicense("Info-ZIP") 1176 .SetURL("http://www.info-zip.org")); 1177 1178 // bzip2 copyrights 1179 _AddPackageCredit(PackageCredit("bzip2") 1180 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-2005 Julian R " 1181 "Seward. All rights reserved.")) 1182 .SetLicense(kBSDFourClause) 1183 .SetURL("http://bzip.org")); 1184 1185 // OpenEXR copyrights 1186 _AddPackageCredit(PackageCredit("OpenEXR") 1187 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2005 Industrial " 1188 "Light & Magic, a division of Lucas Digital Ltd. LLC.")) 1189 .SetLicense(kBSDThreeClause) 1190 .SetURL("http://www.openexr.com")); 1191 1192 // Bullet copyrights 1193 _AddPackageCredit(PackageCredit("Bullet") 1194 .SetCopyright(COPYRIGHT_STRING "2003-2008 Erwin Coumans") 1195 .SetLicense("Bullet") 1196 .SetURL("http://www.bulletphysics.com")); 1197 1198 // Netcat copyrights 1199 _AddPackageCredit(PackageCredit("Netcat") 1200 .SetCopyright(COPYRIGHT_STRING "1996 Hobbit.") 1201 .SetLicense(kPublicDomain) 1202 .SetURL("http://nc110.sourceforge.net/")); 1203 1204 // acpica copyrights 1205 _AddPackageCredit(PackageCredit("acpica") 1206 .SetCopyright(COPYRIGHT_STRING "1999-2014 Intel Corp.") 1207 .SetLicense("Intel (ACPICA)") 1208 .SetURL("https://www.acpica.org")); 1209 1210 // libpng copyrights 1211 _AddPackageCredit(PackageCredit("libpng") 1212 .SetCopyright(COPYRIGHT_STRING "2004, 2006-2008 Glenn " 1213 "Randers-Pehrson.") 1214 .SetLicense("LibPNG") 1215 .SetURL("http://www.libpng.org")); 1216 1217 // libjpeg copyrights 1218 _AddPackageCredit(PackageCredit("libjpeg") 1219 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1994-2009, Thomas G. " 1220 "Lane, Guido Vollbeding. This software is based in part on the " 1221 "work of the Independent JPEG Group.")) 1222 .SetLicense("LibJPEG") 1223 .SetURL("http://www.ijg.org")); 1224 1225 // libprint copyrights 1226 _AddPackageCredit(PackageCredit("libprint") 1227 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2000 Y.Takagi. " 1228 "All rights reserved."))); 1229 // TODO: License! 1230 1231 // cortex copyrights 1232 _AddPackageCredit(PackageCredit("Cortex") 1233 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1234 .SetLicense(kBSDThreeClause) 1235 .SetURL("http://cortex.sourceforge.net/documentation")); 1236 1237 // FluidSynth copyrights 1238 _AddPackageCredit(PackageCredit("FluidSynth") 1239 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003 Peter Hanappe " 1240 "and others.")) 1241 .SetLicense(kLGPLv2) 1242 .SetURL("http://www.fluidsynth.org")); 1243 1244 // Xiph.org Foundation copyrights 1245 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1246 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1247 B_TRANSLATE(COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1248 "All rights reserved."), NULL) 1249 .SetLicense(kBSDThreeClause) 1250 .SetURL("http://www.xiph.org")); 1251 1252 // The Tcpdump Group 1253 _AddPackageCredit(PackageCredit("The Tcpdump Group") 1254 .SetCopyright("tcpdump, libpcap") 1255 .SetLicense(kBSDThreeClause) 1256 .SetURL("http://www.tcpdump.org")); 1257 1258 // Matroska 1259 _AddPackageCredit(PackageCredit("libmatroska") 1260 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1261 "All rights reserved.")) 1262 .SetLicense(kLGPLv21) 1263 .SetURL("http://www.matroska.org")); 1264 1265 // BColorQuantizer (originally CQuantizer code) 1266 _AddPackageCredit(PackageCredit("CQuantizer") 1267 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1268 "All rights reserved.")) 1269 .SetLicense("CQuantizer") 1270 .SetURL("http://www.xdp.it")); 1271 1272 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1273 _AddPackageCredit(PackageCredit("MAPM") 1274 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2007 Michael C. " 1275 "Ring. All rights reserved.")) 1276 .SetLicense("MAPM") 1277 .SetURL("http://tc.umn.edu/~ringx004")); 1278 1279 // MkDepend 1.7 copyright (Makefile dependency generator) 1280 _AddPackageCredit(PackageCredit("MkDepend") 1281 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1282 "All rights reserved.")) 1283 .SetLicense("MkDepend") 1284 .SetURL("http://bearnip.com/lars/be")); 1285 1286 // libhttpd copyright (used as Poorman backend) 1287 _AddPackageCredit(PackageCredit("libhttpd") 1288 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995, 1998-2001 " 1289 "Jef Poskanzer. All rights reserved.")) 1290 .SetLicense("LibHTTPd") 1291 .SetURL("http://www.acme.com/software/thttpd/")); 1292 1293 #ifdef __INTEL__ 1294 // Udis86 copyrights 1295 _AddPackageCredit(PackageCredit("Udis86") 1296 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2004 " 1297 "Vivek Mohan. All rights reserved.")) 1298 .SetLicense(kBSDTwoClause) 1299 .SetURL("http://udis86.sourceforge.net")); 1300 1301 // Intel PRO/Wireless 2100 Firmware 1302 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 Firmware") 1303 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003-2006 " 1304 "Intel Corporation. All rights reserved.")) 1305 .SetLicense(kIntel2xxxFirmware) 1306 .SetURL("http://ipw2100.sourceforge.net/")); 1307 1308 // Intel PRO/Wireless 2200BG Firmware 1309 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2200BG Firmware") 1310 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2004-2005 " 1311 "Intel Corporation. All rights reserved.")) 1312 .SetLicense(kIntel2xxxFirmware) 1313 .SetURL("http://ipw2200.sourceforge.net/")); 1314 1315 // Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware 1316 _AddPackageCredit( 1317 PackageCredit( 1318 "Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware") 1319 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2007 " 1320 "Intel Corporation. All rights reserved.")) 1321 .SetLicense(kIntelFirmware) 1322 .SetURL("http://www.intellinuxwireless.org/")); 1323 1324 // Intel Wireless WiFi Link 4965AGN Adapter Firmware 1325 _AddPackageCredit( 1326 PackageCredit("Intel Wireless WiFi Link 4965AGN Adapter Firmware") 1327 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2007 " 1328 "Intel Corporation. All rights reserved.")) 1329 .SetLicense(kIntelFirmware) 1330 .SetURL("http://www.intellinuxwireless.org/")); 1331 1332 // Marvell 88w8363 1333 _AddPackageCredit(PackageCredit("Marvell 88w8363") 1334 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007-2009 " 1335 "Marvell Semiconductor, Inc. All rights reserved.")) 1336 .SetLicense(kMarvellFirmware) 1337 .SetURL("http://www.marvell.com/")); 1338 1339 // Ralink Firmware RT2501/RT2561/RT2661 1340 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 1341 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007 " 1342 "Ralink Technology Corporation. All rights reserved.")) 1343 .SetLicense(kRalinkFirmware) 1344 .SetURL("http://www.ralinktech.com/")); 1345 #endif 1346 1347 // Gutenprint 1348 _AddPackageCredit(PackageCredit("Gutenprint") 1349 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1350 "1999-2010 by the authors of Gutenprint. All rights reserved.")) 1351 .SetLicense(kGPLv2) 1352 .SetURL("http://gutenprint.sourceforge.net/")); 1353 1354 // libwebp 1355 _AddPackageCredit(PackageCredit("libwebp") 1356 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1357 "2010-2011 Google Inc. All rights reserved.")) 1358 .SetLicense(kBSDThreeClause) 1359 .SetURL("http://www.webmproject.org/code/#libwebp_webp_image_library")); 1360 1361 // GTF 1362 _AddPackageCredit(PackageCredit("GTF") 1363 .SetCopyright(B_TRANSLATE("2001 by Andy Ritger based on the " 1364 "Generalized Timing Formula")) 1365 .SetLicense(kBSDThreeClause) 1366 .SetURL("http://gtf.sourceforge.net/")); 1367 1368 // libqrencode 1369 _AddPackageCredit(PackageCredit("libqrencode") 1370 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2012 Kentaro Fukuchi")) 1371 .SetLicense(kLGPLv21) 1372 .SetURL("http://fukuchi.org/works/qrencode/")); 1373 1374 _AddCopyrightsFromAttribute(); 1375 _AddPackageCreditEntries(); 1376 1377 return new CropView(creditsScroller, 0, 1, 1, 1); 1378 } 1379 1380 1381 status_t 1382 AboutView::_GetLicensePath(const char* license, BPath& path) 1383 { 1384 BPathFinder pathFinder; 1385 BStringList paths; 1386 struct stat st; 1387 1388 status_t error = pathFinder.FindPaths(B_FIND_PATH_DATA_DIRECTORY, 1389 "licenses", paths); 1390 1391 for (int i = 0; i < paths.CountStrings(); ++i) { 1392 if (error == B_OK && path.SetTo(paths.StringAt(i)) == B_OK 1393 && path.Append(license) == B_OK 1394 && lstat(path.Path(), &st) == 0) { 1395 return B_OK; 1396 } 1397 } 1398 1399 path.Unset(); 1400 return B_ENTRY_NOT_FOUND; 1401 } 1402 1403 1404 void 1405 AboutView::_AddCopyrightsFromAttribute() 1406 { 1407 #ifdef __HAIKU__ 1408 // open the app executable file 1409 char appPath[B_PATH_NAME_LENGTH]; 1410 int appFD; 1411 if (BPrivate::get_app_path(appPath) != B_OK 1412 || (appFD = open(appPath, O_RDONLY)) < 0) { 1413 return; 1414 } 1415 1416 // open the attribute 1417 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 1418 close(appFD); 1419 if (attrFD < 0) 1420 return; 1421 1422 // attach it to a FILE 1423 FILE* attrFile = fdopen(attrFD, "r"); 1424 if (attrFile == NULL) { 1425 close(attrFD); 1426 return; 1427 } 1428 CObjectDeleter<FILE, int> _(attrFile, fclose); 1429 1430 // read and parse the copyrights 1431 BMessage package; 1432 BString fieldName; 1433 BString fieldValue; 1434 char lineBuffer[LINE_MAX]; 1435 while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) { 1436 // chop off line break 1437 size_t lineLen = strlen(line); 1438 if (lineLen > 0 && line[lineLen - 1] == '\n') 1439 line[--lineLen] = '\0'; 1440 1441 // flush previous field, if a new field begins, otherwise append 1442 if (lineLen == 0 || !isspace(line[0])) { 1443 // new field -- flush the previous one 1444 if (fieldName.Length() > 0) { 1445 fieldValue = trim_string(fieldValue.String(), 1446 fieldValue.Length()); 1447 package.AddString(fieldName.String(), fieldValue); 1448 fieldName = ""; 1449 } 1450 } else if (fieldName.Length() > 0) { 1451 // append to current field 1452 fieldValue += line; 1453 continue; 1454 } else { 1455 // bogus line -- ignore 1456 continue; 1457 } 1458 1459 if (lineLen == 0) 1460 continue; 1461 1462 // parse new field 1463 char* colon = strchr(line, ':'); 1464 if (colon == NULL) { 1465 // bogus line -- ignore 1466 continue; 1467 } 1468 1469 fieldName.SetTo(line, colon - line); 1470 fieldName = trim_string(line, colon - line); 1471 if (fieldName.Length() == 0) { 1472 // invalid field name 1473 continue; 1474 } 1475 1476 fieldValue = colon + 1; 1477 1478 if (fieldName == "Package") { 1479 // flush the current package 1480 _AddPackageCredit(PackageCredit(package)); 1481 package.MakeEmpty(); 1482 } 1483 } 1484 1485 // flush current package 1486 _AddPackageCredit(PackageCredit(package)); 1487 #endif 1488 } 1489 1490 1491 void 1492 AboutView::_AddPackageCreditEntries() 1493 { 1494 // sort the packages case-insensitively 1495 PackageCredit* packages[fPackageCredits.size()]; 1496 int32 count = 0; 1497 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1498 it != fPackageCredits.end(); ++it) { 1499 packages[count++] = it->second; 1500 } 1501 1502 if (count > 1) { 1503 std::sort(packages, packages + count, 1504 &PackageCredit::NameLessInsensitive); 1505 } 1506 1507 // add the credits 1508 for (int32 i = 0; i < count; i++) { 1509 PackageCredit* package = packages[i]; 1510 1511 BString text(package->CopyrightAt(0)); 1512 int32 count = package->CountCopyrights(); 1513 for (int32 i = 1; i < count; i++) 1514 text << "\n" << package->CopyrightAt(i); 1515 1516 AddCopyrightEntry(package->PackageName(), text.String(), 1517 package->Licenses(), package->Sources(), package->URL()); 1518 } 1519 } 1520 1521 1522 void 1523 AboutView::_AddPackageCredit(const PackageCredit& package) 1524 { 1525 if (!package.IsValid()) 1526 return; 1527 1528 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 1529 if (it != fPackageCredits.end()) { 1530 // If the new package credit isn't "better" than the old one, ignore it. 1531 PackageCredit* oldPackage = it->second; 1532 if (!package.IsBetterThan(*oldPackage)) 1533 return; 1534 1535 // replace the old credit 1536 fPackageCredits.erase(it); 1537 delete oldPackage; 1538 } 1539 1540 fPackageCredits[package.PackageName()] = new PackageCredit(package); 1541 } 1542 1543 1544 // #pragma mark - 1545 1546 1547 static const char* 1548 MemSizeToString(char string[], size_t size, system_info* info) 1549 { 1550 int inaccessibleMemory = int(info->ignored_pages 1551 * (B_PAGE_SIZE / 1048576.0f) + 0.5f); 1552 if (inaccessibleMemory > 0) { 1553 BString message(B_TRANSLATE("%total MiB total, %inaccessible MiB " 1554 "inaccessible")); 1555 1556 snprintf(string, size, "%d", int((info->max_pages 1557 + info->ignored_pages) * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1558 message.ReplaceFirst("%total", string); 1559 1560 snprintf(string, size, "%d", inaccessibleMemory); 1561 message.ReplaceFirst("%inaccessible", string); 1562 strncpy(string, message.String(), size); 1563 } else { 1564 snprintf(string, size, B_TRANSLATE("%d MiB total"), 1565 int(info->max_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1566 } 1567 1568 return string; 1569 } 1570 1571 1572 static const char* 1573 MemUsageToString(char string[], size_t size, system_info* info) 1574 { 1575 snprintf(string, size, B_TRANSLATE("%d MiB used (%d%%)"), 1576 int(info->used_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f), 1577 int(100 * info->used_pages / info->max_pages)); 1578 1579 return string; 1580 } 1581 1582 1583 static const char* 1584 UptimeToString(char string[], size_t size) 1585 { 1586 BDurationFormat formatter; 1587 BString str; 1588 1589 bigtime_t uptime = system_time(); 1590 bigtime_t now = (bigtime_t)time(NULL) * 1000000; 1591 formatter.Format(str, now - uptime, now); 1592 str.CopyInto(string, 0, size); 1593 string[std::min((size_t)str.Length(), size)] = '\0'; 1594 1595 return string; 1596 } 1597 1598 1599 int 1600 main() 1601 { 1602 AboutApp app; 1603 app.Run(); 1604 return 0; 1605 } 1606 1607