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