1 /* 2 * Copyright 2005-2011, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * René Gollent 8 * Wim van der Meer <WPJvanderMeer@gmail.com> 9 */ 10 11 12 #include <ctype.h> 13 #include <stdio.h> 14 #include <time.h> 15 #include <unistd.h> 16 17 #include <algorithm> 18 #include <map> 19 #include <string> 20 21 #include <AppFileInfo.h> 22 #include <Application.h> 23 #include <Bitmap.h> 24 #include <DurationFormat.h> 25 #include <File.h> 26 #include <FindDirectory.h> 27 #include <Font.h> 28 #include <fs_attr.h> 29 #include <LayoutBuilder.h> 30 #include <MessageRunner.h> 31 #include <Messenger.h> 32 #include <OS.h> 33 #include <Path.h> 34 #include <Resources.h> 35 #include <Screen.h> 36 #include <ScrollView.h> 37 #include <String.h> 38 #include <StringView.h> 39 #include <TranslationUtils.h> 40 #include <TranslatorFormats.h> 41 #include <View.h> 42 #include <Volume.h> 43 #include <VolumeRoster.h> 44 #include <Window.h> 45 46 #include <AppMisc.h> 47 #include <AutoDeleter.h> 48 #include <cpu_type.h> 49 #include <system_revision.h> 50 51 #include <Catalog.h> 52 #include <Language.h> 53 #include <Locale.h> 54 #include <LocaleRoster.h> 55 56 #include "HyperTextActions.h" 57 #include "HyperTextView.h" 58 #include "Utilities.h" 59 60 61 #ifndef LINE_MAX 62 #define LINE_MAX 2048 63 #endif 64 65 #define SCROLL_CREDITS_VIEW 'mviv' 66 67 68 static const char* UptimeToString(char string[], size_t size); 69 static const char* MemSizeToString(char string[], size_t size, 70 system_info* info); 71 static const char* MemUsageToString(char string[], size_t size, 72 system_info* info); 73 74 75 static const rgb_color kDarkGrey = { 100, 100, 100, 255 }; 76 static const rgb_color kHaikuGreen = { 42, 131, 36, 255 }; 77 static const rgb_color kHaikuOrange = { 255, 69, 0, 255 }; 78 static const rgb_color kHaikuYellow = { 255, 176, 0, 255 }; 79 static const rgb_color kLinkBlue = { 80, 80, 200, 255 }; 80 static const rgb_color kBeOSBlue = { 0, 0, 200, 255 }; 81 static const rgb_color kBeOSRed = { 200, 0, 0, 255 }; 82 83 typedef struct 84 { 85 const char* languageCode; 86 const char* names; 87 } Translation; 88 89 static const Translation gTranslations[] = 90 { 91 { "ar", 92 "Khaled Berraoui (khallebal)\n" 93 }, 94 { "be", 95 "Michael Bulash\n" 96 }, 97 { "bg", 98 "Ognyan Valeri Angelov\n" 99 "cssvb94\n" 100 }, 101 { "cs", 102 "Pavel Drotár\n" 103 "Matěj Kocián\n" 104 }, 105 { "nl", 106 "Floris Kint\n" 107 "Meanwhile\n" 108 }, 109 { "eo", 110 "Travis D. Reed (Dancxjo)\n" 111 }, 112 { "fi", 113 "Jorma Karvonen (Karvjorm)\n" 114 "Jaakko Leikas (Garjala)\n" 115 }, 116 { "fr", 117 "Jean-Loïc Charroud\n" 118 "Adrien Destugues (PulkoMandy)\n" 119 "Florent Revest\n" 120 }, 121 { "da", 122 "Brian Matzon\n" 123 }, 124 { "de", 125 "Colin Günther\n" 126 "Mirko Israel\n" 127 "leszek\n" 128 "Christian Morgenroth\n" 129 "Joachim Seemer (Humdinger)\n" 130 "Matthias Spreiter\n" 131 "svend\n" 132 }, 133 { "hi", 134 "Abhishek Arora\n" 135 "Jayneil Dalal\n" 136 "Atharva Lath\n" 137 }, 138 { "hr", 139 "zvacet\n" 140 }, 141 { "hu", 142 "Zoltán Mizsei (miqlas)\n" 143 "Zoltán Szabó (Bird)\n" 144 }, 145 { "it", 146 "Andrea Bernardi\n" 147 "Dario Casalinuovo\n" 148 "Francesco Franchina\n" 149 "Lorenzo Frezza\n" 150 "Mometto Nicola\n" 151 "Michael Peppers\n" 152 }, 153 { "ja", 154 "Satoshi Eguchi\n" 155 "Shota Fukumori\n" 156 "Hironori Ichimiya\n" 157 "Jorge G. Mare (Koki)\n" 158 "Takashi Murai\n" 159 "SHINTA\n" 160 "Hiroyuki Tsutsumi\n" 161 "Hiromu Yakura\n" 162 "The JPBE.net user group\n" 163 }, 164 { "lt", 165 "Algirdas Buckus\n" 166 }, 167 { "pl", 168 "Szymon Barczak\n" 169 "Grzegorz Dąbrowski\n" 170 "Hubert Hareńczyk\n" 171 "Krzysztof Miemiec\n" 172 "Artur Wyszyński\n" 173 }, 174 { "pt", 175 "Marcos Alves (Xeon3D)\n" 176 "Vasco Costa (gluon)\n" 177 "Michael Vinícius de Oliveira (michaelvo)\n" 178 }, 179 { "ro", 180 "Victor Carbune\n" 181 "Florentina Mușat\n" 182 }, 183 { "ru", 184 "Tatyana Fursic (iceid)\n" 185 "StoroZ Gneva\n" 186 "Rodastahm Islamov (RISC)\n" 187 "Eugene Katashov (mrNoisy)\n" 188 "Reznikov Sergei (Diver)\n" 189 "Michael Smirnov\n" 190 "Vladimir Vasilenko\n" 191 }, 192 { "es", 193 "Pedro Arregui\n" 194 "Zola Bridges\n" 195 "Nicolás C (CapitanPico)\n" 196 "Oscar Carballal (oscarcp)\n" 197 "Miguel Zúñiga González (miguel~1.mx)\n" 198 "Luis Gustavo Lira\n" 199 "Victor Madariaga\n" 200 "César Ortiz Pantoja (ccortiz)\n" 201 }, 202 { "sv", 203 "Patrik Gissberg\n" 204 "Johan Holmberg\n" 205 "Jimmy Olsson (phalax)\n" 206 "Jonas Sundström\n" 207 "Victor Widell\n" 208 }, 209 { "tr", 210 "Aras Ergus\n" 211 }, 212 { "uk", 213 "Alex Rudyk (totish)\n" 214 "Oleg Varunok\n" 215 }, 216 { "zh", 217 "Pengfei Han (kurain)\n" 218 } 219 }; 220 221 #define kNumberOfTranslations (sizeof(gTranslations) / sizeof(Translation)) 222 223 224 static int 225 TranslationComparator(const void* left, const void* right) 226 { 227 const Translation* leftTranslation = *(const Translation**)left; 228 const Translation* rightTranslation = *(const Translation**)right; 229 230 BLanguage* language; 231 BString leftName; 232 if (BLocaleRoster::Default()->GetLanguage(leftTranslation->languageCode, 233 &language) == B_OK) { 234 language->GetName(leftName); 235 delete language; 236 } else 237 leftName = leftTranslation->languageCode; 238 239 BString rightName; 240 if (BLocaleRoster::Default()->GetLanguage(rightTranslation->languageCode, 241 &language) == B_OK) { 242 language->GetName(rightName); 243 delete language; 244 } else 245 rightName = rightTranslation->languageCode; 246 247 BCollator collator; 248 BLocale::Default()->GetCollator(&collator); 249 return collator.Compare(leftName.String(), rightName.String()); 250 } 251 252 253 class AboutApp : public BApplication { 254 public: 255 AboutApp(); 256 }; 257 258 259 class AboutWindow : public BWindow { 260 public: 261 AboutWindow(); 262 263 virtual bool QuitRequested(); 264 }; 265 266 267 class LogoView : public BView { 268 public: 269 LogoView(); 270 virtual ~LogoView(); 271 272 virtual BSize MinSize(); 273 virtual BSize MaxSize(); 274 275 virtual void Draw(BRect updateRect); 276 277 private: 278 BBitmap* fLogo; 279 }; 280 281 282 class CropView : public BView { 283 public: 284 CropView(BView* target, int32 left, int32 top, 285 int32 right, int32 bottom); 286 virtual ~CropView(); 287 288 virtual BSize MinSize(); 289 virtual BSize MaxSize(); 290 291 virtual void DoLayout(); 292 293 private: 294 BView* fTarget; 295 int32 fCropLeft; 296 int32 fCropTop; 297 int32 fCropRight; 298 int32 fCropBottom; 299 }; 300 301 302 class AboutView : public BView { 303 public: 304 AboutView(); 305 ~AboutView(); 306 307 virtual void AttachedToWindow(); 308 virtual void Pulse(); 309 310 virtual void MessageReceived(BMessage* msg); 311 virtual void MouseDown(BPoint point); 312 313 void AddCopyrightEntry(const char* name, 314 const char* text, 315 const StringVector& licenses, 316 const StringVector& sources, 317 const char* url); 318 void AddCopyrightEntry(const char* name, 319 const char* text, const char* url = NULL); 320 void PickRandomHaiku(); 321 322 323 private: 324 typedef std::map<std::string, PackageCredit*> PackageCreditMap; 325 326 private: 327 BView* _CreateLabel(const char* name, const char* label); 328 BView* _CreateCreditsView(); 329 status_t _GetLicensePath(const char* license, 330 BPath& path); 331 void _AddCopyrightsFromAttribute(); 332 void _AddPackageCredit(const PackageCredit& package); 333 void _AddPackageCreditEntries(); 334 335 BStringView* fMemView; 336 BTextView* fUptimeView; 337 BView* fInfoView; 338 HyperTextView* fCreditsView; 339 340 BBitmap* fLogo; 341 342 bigtime_t fLastActionTime; 343 BMessageRunner* fScrollRunner; 344 PackageCreditMap fPackageCredits; 345 }; 346 347 348 // #pragma mark - 349 350 351 AboutApp::AboutApp() 352 : BApplication("application/x-vnd.Haiku-About") 353 { 354 B_TRANSLATE_MARK_SYSTEM_NAME("AboutSystem"); 355 356 AboutWindow *window = new(std::nothrow) AboutWindow(); 357 if (window) 358 window->Show(); 359 } 360 361 362 // #pragma mark - 363 364 365 #undef B_TRANSLATE_CONTEXT 366 #define B_TRANSLATE_CONTEXT "AboutWindow" 367 368 AboutWindow::AboutWindow() 369 : BWindow(BRect(0, 0, 500, 300), B_TRANSLATE("About this system"), 370 B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE) 371 { 372 SetLayout(new BGroupLayout(B_VERTICAL)); 373 AddChild(new AboutView()); 374 375 // Make sure we take the minimal window size into account when centering 376 BSize size = GetLayout()->MinSize(); 377 ResizeTo(max_c(size.width, Bounds().Width()), 378 max_c(size.height, Bounds().Height())); 379 380 CenterOnScreen(); 381 } 382 383 384 bool 385 AboutWindow::QuitRequested() 386 { 387 be_app->PostMessage(B_QUIT_REQUESTED); 388 return true; 389 } 390 391 392 // #pragma mark - LogoView 393 394 395 LogoView::LogoView() 396 : BView("logo", B_WILL_DRAW) 397 { 398 fLogo = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "logo.png"); 399 SetViewColor(255, 255, 255); 400 } 401 402 403 LogoView::~LogoView() 404 { 405 delete fLogo; 406 } 407 408 409 BSize 410 LogoView::MinSize() 411 { 412 if (fLogo == NULL) 413 return BSize(0, 0); 414 415 return BSize(fLogo->Bounds().Width(), fLogo->Bounds().Height()); 416 } 417 418 419 BSize 420 LogoView::MaxSize() 421 { 422 if (fLogo == NULL) 423 return BSize(0, 0); 424 425 return BSize(B_SIZE_UNLIMITED, fLogo->Bounds().Height()); 426 } 427 428 429 void 430 LogoView::Draw(BRect updateRect) 431 { 432 if (fLogo != NULL) { 433 DrawBitmap(fLogo, 434 BPoint((Bounds().Width() - fLogo->Bounds().Width()) / 2, 0)); 435 } 436 } 437 438 439 // #pragma mark - CropView 440 441 442 CropView::CropView(BView* target, int32 left, int32 top, int32 right, 443 int32 bottom) 444 : BView("crop view", 0), 445 fTarget(target), 446 fCropLeft(left), 447 fCropTop(top), 448 fCropRight(right), 449 fCropBottom(bottom) 450 { 451 AddChild(target); 452 } 453 454 455 CropView::~CropView() 456 { 457 } 458 459 460 BSize 461 CropView::MinSize() 462 { 463 if (fTarget == NULL) 464 return BSize(); 465 466 BSize size = fTarget->MinSize(); 467 if (size.width != B_SIZE_UNSET) 468 size.width -= fCropLeft + fCropRight; 469 if (size.height != B_SIZE_UNSET) 470 size.height -= fCropTop + fCropBottom; 471 472 return size; 473 } 474 475 476 BSize 477 CropView::MaxSize() 478 { 479 if (fTarget == NULL) 480 return BSize(); 481 482 BSize size = fTarget->MaxSize(); 483 if (size.width != B_SIZE_UNSET) 484 size.width -= fCropLeft + fCropRight; 485 if (size.height != B_SIZE_UNSET) 486 size.height -= fCropTop + fCropBottom; 487 488 return size; 489 } 490 491 492 void 493 CropView::DoLayout() 494 { 495 BView::DoLayout(); 496 497 if (fTarget == NULL) 498 return; 499 500 fTarget->MoveTo(-fCropLeft, -fCropTop); 501 fTarget->ResizeTo(Bounds().Width() + fCropLeft + fCropRight, 502 Bounds().Height() + fCropTop + fCropBottom); 503 } 504 505 506 // #pragma mark - AboutView 507 508 #undef B_TRANSLATE_CONTEXT 509 #define B_TRANSLATE_CONTEXT "AboutView" 510 511 AboutView::AboutView() 512 : BView("aboutview", B_WILL_DRAW | B_PULSE_NEEDED), 513 fLastActionTime(system_time()), 514 fScrollRunner(NULL) 515 { 516 // Begin Construction of System Information controls 517 518 system_info systemInfo; 519 get_system_info(&systemInfo); 520 521 // Create all the various labels for system infomation 522 523 // OS Version 524 525 char string[1024]; 526 strlcpy(string, B_TRANSLATE("Unknown"), sizeof(string)); 527 528 // the version is stored in the BEOS:APP_VERSION attribute of libbe.so 529 BPath path; 530 if (find_directory(B_BEOS_LIB_DIRECTORY, &path) == B_OK) { 531 path.Append("libbe.so"); 532 533 BAppFileInfo appFileInfo; 534 version_info versionInfo; 535 BFile file; 536 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK 537 && appFileInfo.SetTo(&file) == B_OK 538 && appFileInfo.GetVersionInfo(&versionInfo, 539 B_APP_VERSION_KIND) == B_OK 540 && versionInfo.short_info[0] != '\0') 541 strlcpy(string, versionInfo.short_info, sizeof(string)); 542 } 543 544 // Add system revision 545 const char* haikuRevision = __get_haiku_revision(); 546 if (haikuRevision != NULL) { 547 strlcat(string, " (", sizeof(string)); 548 strlcat(string, B_TRANSLATE("Revision"), sizeof(string)); 549 strlcat(string, " ", sizeof(string)); 550 strlcat(string, haikuRevision, sizeof(string)); 551 strlcat(string, ")", sizeof(string)); 552 } 553 554 BStringView* versionView = new BStringView("ostext", string); 555 versionView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 556 B_ALIGN_VERTICAL_UNSET)); 557 558 // GCC version 559 BEntry gccFourHybrid("/boot/system/lib/gcc2/libstdc++.r4.so"); 560 BEntry gccTwoHybrid("/boot/system/lib/gcc4/libsupc++.so"); 561 bool isHybrid = gccFourHybrid.Exists() || gccTwoHybrid.Exists(); 562 563 if (isHybrid) { 564 snprintf(string, sizeof(string), B_TRANSLATE("GCC %d Hybrid"), 565 __GNUC__); 566 } else 567 snprintf(string, sizeof(string), "GCC %d", __GNUC__); 568 569 BStringView* gccView = new BStringView("gcctext", string); 570 gccView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 571 B_ALIGN_VERTICAL_UNSET)); 572 573 #if __GNUC__ == 2 574 if (isHybrid) { 575 // do now show the GCC version if it's the default 576 gccView->Hide(); 577 } 578 #endif 579 580 // CPU count, type and clock speed 581 char processorLabel[256]; 582 if (systemInfo.cpu_count > 1) { 583 snprintf(processorLabel, sizeof(processorLabel), 584 B_TRANSLATE("%ld Processors:"), systemInfo.cpu_count); 585 } else 586 strlcpy(processorLabel, B_TRANSLATE("Processor:"), 587 sizeof(processorLabel)); 588 589 BString cpuType; 590 cpuType << get_cpu_vendor_string(systemInfo.cpu_type) 591 << " " << get_cpu_model_string(&systemInfo); 592 593 BStringView* cpuView = new BStringView("cputext", cpuType.String()); 594 cpuView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 595 B_ALIGN_VERTICAL_UNSET)); 596 597 int32 clockSpeed = get_rounded_cpu_speed(); 598 if (clockSpeed < 1000) 599 snprintf(string, sizeof(string), B_TRANSLATE("%ld MHz"), clockSpeed); 600 else 601 snprintf(string, sizeof(string), B_TRANSLATE("%.2f GHz"), 602 clockSpeed / 1000.0f); 603 604 BStringView* frequencyView = new BStringView("frequencytext", string); 605 frequencyView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 606 B_ALIGN_VERTICAL_UNSET)); 607 608 // RAM 609 BStringView *memSizeView = new BStringView("ramsizetext", 610 MemSizeToString(string, sizeof(string), &systemInfo)); 611 memSizeView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 612 B_ALIGN_VERTICAL_UNSET)); 613 fMemView = new BStringView("ramtext", 614 MemUsageToString(string, sizeof(string), &systemInfo)); 615 fMemView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 616 B_ALIGN_VERTICAL_UNSET)); 617 618 // Kernel build time/date 619 snprintf(string, sizeof(string), "%s %s", 620 systemInfo.kernel_build_date, systemInfo.kernel_build_time); 621 622 BStringView* kernelView = new BStringView("kerneltext", string); 623 kernelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 624 B_ALIGN_VERTICAL_UNSET)); 625 626 // Uptime 627 fUptimeView = new BTextView("uptimetext"); 628 fUptimeView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 629 fUptimeView->MakeEditable(false); 630 fUptimeView->MakeSelectable(false); 631 fUptimeView->SetWordWrap(true); 632 633 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 634 635 const float offset = 5; 636 637 SetLayout(new BGroupLayout(B_HORIZONTAL, 0)); 638 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 639 640 BLayoutBuilder::Group<>((BGroupLayout*)GetLayout()) 641 .AddGroup(B_VERTICAL, 0) 642 .Add(new LogoView()) 643 .AddGroup(B_VERTICAL, 0) 644 .Add(_CreateLabel("oslabel", B_TRANSLATE("Version:"))) 645 .Add(versionView) 646 .Add(gccView) 647 .AddStrut(offset) 648 .Add(_CreateLabel("cpulabel", processorLabel)) 649 .Add(cpuView) 650 .Add(frequencyView) 651 .AddStrut(offset) 652 .Add(_CreateLabel("memlabel", B_TRANSLATE("Memory:"))) 653 .Add(memSizeView) 654 .Add(fMemView) 655 .AddStrut(offset) 656 .Add(_CreateLabel("kernellabel", B_TRANSLATE("Kernel:"))) 657 .Add(kernelView) 658 .AddStrut(offset) 659 .Add(_CreateLabel("uptimelabel", 660 B_TRANSLATE("Time running:"))) 661 .Add(fUptimeView) 662 .SetInsets(5, 5, 5, 5) 663 .End() 664 // TODO: investigate: adding this causes the time to be cut 665 //.AddGlue() 666 .End() 667 .Add(_CreateCreditsView()); 668 669 float min = fMemView->MinSize().width * 1.1f; 670 fCreditsView->SetExplicitMinSize(BSize(min, min)); 671 } 672 673 674 AboutView::~AboutView() 675 { 676 delete fScrollRunner; 677 } 678 679 680 void 681 AboutView::AttachedToWindow() 682 { 683 BView::AttachedToWindow(); 684 Window()->SetPulseRate(500000); 685 SetEventMask(B_POINTER_EVENTS); 686 } 687 688 689 void 690 AboutView::MouseDown(BPoint point) 691 { 692 BRect r(92, 26, 105, 31); 693 if (r.Contains(point)) 694 BMessenger(this).SendMessage('eegg'); 695 696 if (Bounds().Contains(point)) { 697 fLastActionTime = system_time(); 698 delete fScrollRunner; 699 fScrollRunner = NULL; 700 } 701 } 702 703 704 void 705 AboutView::Pulse() 706 { 707 char string[255]; 708 system_info info; 709 get_system_info(&info); 710 fUptimeView->SetText(UptimeToString(string, sizeof(string))); 711 fMemView->SetText(MemUsageToString(string, sizeof(string), &info)); 712 713 if (fScrollRunner == NULL 714 && system_time() > fLastActionTime + 10000000) { 715 BMessage message(SCROLL_CREDITS_VIEW); 716 //fScrollRunner = new BMessageRunner(this, &message, 25000, -1); 717 } 718 } 719 720 721 void 722 AboutView::MessageReceived(BMessage* msg) 723 { 724 switch (msg->what) { 725 case SCROLL_CREDITS_VIEW: 726 { 727 BScrollBar* scrollBar = 728 fCreditsView->ScrollBar(B_VERTICAL); 729 if (scrollBar == NULL) 730 break; 731 float max, min; 732 scrollBar->GetRange(&min, &max); 733 if (scrollBar->Value() < max) 734 fCreditsView->ScrollBy(0, 1); 735 736 break; 737 } 738 739 case 'eegg': 740 { 741 printf("Easter egg\n"); 742 PickRandomHaiku(); 743 break; 744 } 745 746 default: 747 BView::MessageReceived(msg); 748 break; 749 } 750 } 751 752 753 void 754 AboutView::AddCopyrightEntry(const char* name, const char* text, 755 const char* url) 756 { 757 AddCopyrightEntry(name, text, StringVector(), StringVector(), url); 758 } 759 760 761 void 762 AboutView::AddCopyrightEntry(const char* name, const char* text, 763 const StringVector& licenses, const StringVector& sources, 764 const char* url) 765 { 766 BFont font(be_bold_font); 767 //font.SetSize(be_bold_font->Size()); 768 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 769 770 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuYellow); 771 fCreditsView->Insert(name); 772 fCreditsView->Insert("\n"); 773 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 774 fCreditsView->Insert(text); 775 fCreditsView->Insert("\n"); 776 777 if (licenses.CountStrings() > 0) { 778 if (licenses.CountStrings() > 1) 779 fCreditsView->Insert(B_TRANSLATE("Licenses: ")); 780 else 781 fCreditsView->Insert(B_TRANSLATE("License: ")); 782 783 for (int32 i = 0; i < licenses.CountStrings(); i++) { 784 const char* license = licenses.StringAt(i); 785 786 if (i > 0) 787 fCreditsView->Insert(", "); 788 789 BString licenseName; 790 BString licenseURL; 791 parse_named_url(license, licenseName, licenseURL); 792 793 BPath licensePath; 794 if (_GetLicensePath(licenseURL, licensePath) == B_OK) { 795 fCreditsView->InsertHyperText(licenseName, 796 new OpenFileAction(licensePath.Path())); 797 } else 798 fCreditsView->Insert(licenseName); 799 } 800 801 fCreditsView->Insert("\n"); 802 } 803 804 if (sources.CountStrings() > 0) { 805 fCreditsView->Insert(B_TRANSLATE("Source Code: ")); 806 807 for (int32 i = 0; i < sources.CountStrings(); i++) { 808 const char* source = sources.StringAt(i); 809 810 if (i > 0) 811 fCreditsView->Insert(", "); 812 813 BString urlName; 814 BString urlAddress; 815 parse_named_url(source, urlName, urlAddress); 816 817 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 818 &kLinkBlue); 819 fCreditsView->InsertHyperText(urlName, 820 new URLAction(urlAddress)); 821 } 822 823 fCreditsView->Insert("\n"); 824 } 825 826 if (url) { 827 BString urlName; 828 BString urlAddress; 829 parse_named_url(url, urlName, urlAddress); 830 831 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, 832 &kLinkBlue); 833 fCreditsView->InsertHyperText(urlName, 834 new URLAction(urlAddress)); 835 fCreditsView->Insert("\n"); 836 } 837 fCreditsView->Insert("\n"); 838 } 839 840 841 void 842 AboutView::PickRandomHaiku() 843 { 844 BPath path; 845 if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK) 846 path = "/system/data"; 847 path.Append("fortunes"); 848 path.Append("Haiku"); 849 850 BFile fortunes(path.Path(), B_READ_ONLY); 851 struct stat st; 852 if (fortunes.InitCheck() < B_OK) 853 return; 854 if (fortunes.GetStat(&st) < B_OK) 855 return; 856 857 char* buff = (char*)malloc((size_t)st.st_size + 1); 858 if (!buff) 859 return; 860 buff[(size_t)st.st_size] = '\0'; 861 BList haikuList; 862 if (fortunes.Read(buff, (size_t)st.st_size) == (ssize_t)st.st_size) { 863 char* p = buff; 864 while (p && *p) { 865 char* e = strchr(p, '%'); 866 BString* s = new BString(p, e ? (e - p) : -1); 867 haikuList.AddItem(s); 868 p = e; 869 if (p && (*p == '%')) 870 p++; 871 if (p && (*p == '\n')) 872 p++; 873 } 874 } 875 free(buff); 876 if (haikuList.CountItems() < 1) 877 return; 878 879 BString* s = (BString*)haikuList.ItemAt(rand() % haikuList.CountItems()); 880 BFont font(be_bold_font); 881 font.SetSize(be_bold_font->Size()); 882 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 883 fCreditsView->SelectAll(); 884 fCreditsView->Delete(); 885 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kDarkGrey); 886 fCreditsView->Insert(s->String()); 887 fCreditsView->Insert("\n"); 888 while ((s = (BString*)haikuList.RemoveItem((int32)0))) { 889 delete s; 890 } 891 } 892 893 894 BView* 895 AboutView::_CreateLabel(const char* name, const char* label) 896 { 897 BStringView* labelView = new BStringView(name, label); 898 labelView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 899 B_ALIGN_VERTICAL_UNSET)); 900 labelView->SetFont(be_bold_font); 901 return labelView; 902 } 903 904 905 BView* 906 AboutView::_CreateCreditsView() 907 { 908 // Begin construction of the credits view 909 fCreditsView = new HyperTextView("credits"); 910 fCreditsView->SetFlags(fCreditsView->Flags() | B_FRAME_EVENTS); 911 fCreditsView->SetStylable(true); 912 fCreditsView->MakeEditable(false); 913 fCreditsView->SetWordWrap(true); 914 fCreditsView->SetInsets(5, 5, 5, 5); 915 fCreditsView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); 916 917 BScrollView* creditsScroller = new BScrollView("creditsScroller", 918 fCreditsView, B_WILL_DRAW | B_FRAME_EVENTS, false, true, 919 B_PLAIN_BORDER); 920 921 // Haiku copyright 922 BFont font(be_bold_font); 923 font.SetSize(font.Size() + 4); 924 925 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 926 fCreditsView->Insert("Haiku\n"); 927 928 char string[1024]; 929 time_t time = ::time(NULL); 930 struct tm* tm = localtime(&time); 931 int32 year = tm->tm_year + 1900; 932 if (year < 2008) 933 year = 2008; 934 snprintf(string, sizeof(string), 935 COPYRIGHT_STRING "2001-%ld The Haiku project. ", year); 936 937 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 938 fCreditsView->Insert(string); 939 940 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 941 fCreditsView->Insert(B_TRANSLATE("The copyright to the Haiku code is " 942 "property of Haiku, Inc. or of the respective authors where expressly " 943 "noted in the source. Haiku" B_UTF8_REGISTERED 944 " and the HAIKU logo" B_UTF8_REGISTERED 945 " are registered trademarks of Haiku, Inc." 946 "\n\n")); 947 948 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kLinkBlue); 949 fCreditsView->InsertHyperText("http://www.haiku-os.org", 950 new URLAction("http://www.haiku-os.org")); 951 fCreditsView->Insert("\n\n"); 952 953 font.SetSize(be_bold_font->Size()); 954 font.SetFace(B_BOLD_FACE | B_ITALIC_FACE); 955 956 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 957 fCreditsView->Insert(B_TRANSLATE("Current maintainers:\n")); 958 959 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 960 fCreditsView->Insert( 961 "Ithamar R. Adema\n" 962 "Bruno G. Albuquerque\n" 963 "Stephan Aßmus\n" 964 "Salvatore Benedetto\n" 965 "Stefano Ceccherini\n" 966 "Rudolf Cornelissen\n" 967 "Alexandre Deckner\n" 968 "Adrien Destugues\n" 969 "Oliver Ruiz Dorantes\n" 970 "Axel Dörfler\n" 971 "Jérôme Duval\n" 972 "René Gollent\n" 973 "Bryce Groff\n" 974 "Colin Günther\n" 975 "Karsten Heimrich\n" 976 "Fredrik Holmqvist\n" 977 "Philippe Houdoin\n" 978 "Maurice Kalinowski\n" 979 "Euan Kirkhope\n" 980 "Ryan Leavengood\n" 981 "Michael Lotz\n" 982 "Brecht Machiels\n" 983 "Matt Madia\n" 984 "Scott McCreary\n" 985 "David McPaul\n" 986 "Wim van der Meer\n" 987 "Fredrik Modéen\n" 988 "Marcus Overhagen\n" 989 "Michael Pfeiffer\n" 990 "François Revol\n" 991 "Philippe Saint-Pierre\n" 992 "Andrej Spielmann\n" 993 "Jonas Sundström\n" 994 "Oliver Tappe\n" 995 "Gerasim Troeglazov\n" 996 "Alexander von Gluck IV\n" 997 "Ingo Weinhold\n" 998 "Alex Wilson\n" 999 "Artur Wyszyński\n" 1000 "Clemens Zeidler\n" 1001 "Siarzhuk Zharski\n" 1002 "\n"); 1003 1004 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1005 fCreditsView->Insert(B_TRANSLATE("Past maintainers:\n")); 1006 1007 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1008 fCreditsView->Insert( 1009 "Andrew Bachmann\n" 1010 "Tyler Dauwalder\n" 1011 "Daniel Furrer\n" 1012 "Andre Alves Garzia\n" 1013 "Erik Jaesler\n" 1014 "Marcin Konicki\n" 1015 "Waldemar Kornewald\n" 1016 "Thomas Kurschel\n" 1017 "Frans Van Nispen\n" 1018 "Adi Oanca\n" 1019 "Michael Phipps\n" 1020 "Niels Sascha Reedijk\n" 1021 "David Reid\n" 1022 "Hugo Santos\n" 1023 "Alexander G. M. Smith\n" 1024 "Bryan Varner\n" 1025 "Nathan Whitehorn\n" 1026 "Michael Wilber\n" 1027 "Jonathan Yoder\n" 1028 "Gabe Yoder\n" 1029 "\n"); 1030 1031 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1032 fCreditsView->Insert(B_TRANSLATE("Website, marketing & documentation:\n")); 1033 1034 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1035 fCreditsView->Insert( 1036 "Phil Greenway\n" 1037 "Gavin James\n" 1038 "Urias McCullough\n" 1039 "Niels Sascha Reedijk\n" 1040 "Joachim Seemer (Humdinger)\n" 1041 "Jonathan Yoder\n" 1042 "\n"); 1043 1044 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1045 fCreditsView->Insert(B_TRANSLATE("Contributors:\n")); 1046 1047 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1048 fCreditsView->Insert( 1049 "Andrea Anzani\n" 1050 "Sean Bartell\n" 1051 "Andre Braga\n" 1052 "Michael Bulash\n" 1053 "Bruce Cameron\n" 1054 "Jean-Loïc Charroud\n" 1055 "Greg Crain\n" 1056 "Michael Davidson\n" 1057 "David Dengg\n" 1058 "John Drinkwater\n" 1059 "Cian Duffy\n" 1060 "Vincent Duvert\n" 1061 "Mikael Eiman\n" 1062 "Fredrik Ekdahl\n" 1063 "Joshua R. Elsasser\n" 1064 "Atis Elsts\n" 1065 "Mark Erben\n" 1066 "Christian Fasshauer\n" 1067 "Andreas Färber\n" 1068 "Janito Ferreira Filho\n" 1069 "Pier Luigi Fiorini\n" 1070 "Marc Flerackers\n" 1071 "Michele Frau (zuMi)\n" 1072 "Deyan Genovski\n" 1073 "Pete Goodeve\n" 1074 "Lucian Adrian Grijincu\n" 1075 "Sean Healy\n" 1076 "Matthijs Hollemans\n" 1077 "Mathew Hounsell\n" 1078 "Morgan Howe\n" 1079 "Christophe Huriaux\n" 1080 "Jian Jiang\n" 1081 "Ma Jie\n" 1082 "Carwyn Jones\n" 1083 "Vasilis Kaoutsis\n" 1084 "James Kim\n" 1085 "Shintaro Kinugawa\n" 1086 "Jan Klötzke\n" 1087 "Kurtis Kopf\n" 1088 "Tomáš Kučera\n" 1089 "Luboš Kulič\n" 1090 "Elad Lahav\n" 1091 "Anthony Lee\n" 1092 "Santiago Lema\n" 1093 "Raynald Lesieur\n" 1094 "Oscar Lesta\n" 1095 "Jerome Leveque\n" 1096 "Brian Luft\n" 1097 "Christof Lutteroth\n" 1098 "Graham MacDonald\n" 1099 "Jorge G. Mare (Koki)\n" 1100 "Jan Matějek\n" 1101 "Brian Matzon\n" 1102 "Christopher ML Zumwalt May\n" 1103 "Andrew McCall\n" 1104 "Nathan Mentley\n" 1105 "Marius Middelthon\n" 1106 "Marco Minutoli\n" 1107 "Misza\n" 1108 "Hamish Morrison\n" 1109 "MrSiggler\n" 1110 "Takashi Murai\n" 1111 "Alan Murta\n" 1112 "Raghuram Nagireddy\n" 1113 "Kazuho Okui\n" 1114 "Jeroen Oortwijn (idefix)\n" 1115 "Pahtz\n" 1116 "Michael Paine\n" 1117 "Adrian Panasiuk\n" 1118 "Romain Picard\n" 1119 "Francesco Piccinno\n" 1120 "David Powell\n" 1121 "Jeremy Rand\n" 1122 "Hartmut Reh\n" 1123 "Daniel Reinhold\n" 1124 "Chris Roberts\n" 1125 "Samuel Rodríguez Pérez\n" 1126 "Thomas Roell\n" 1127 "Rafael Romo\n" 1128 "Ralf Schülke\n" 1129 "John Scipione\n" 1130 "Reznikov Sergei\n" 1131 "Zousar Shaker\n" 1132 "Caitlin Shaw\n" 1133 "Geoffry Song\n" 1134 "Daniel Switkin\n" 1135 "Atsushi Takamatsu\n" 1136 "James Urquhart\n" 1137 "Jason Vandermark\n" 1138 "Sandor Vroemisse\n" 1139 "Denis Washington\n" 1140 "Ulrich Wimboeck\n" 1141 "Johannes Wischert\n" 1142 "James Woodcock\n" 1143 "Hong Yul Yang\n" 1144 "Gerald Zajac\n" 1145 "Łukasz Zemczak\n" 1146 "JiSheng Zhang\n" 1147 "Zhao Shuai\n"); 1148 fCreditsView->Insert( 1149 B_TRANSLATE("\n" B_UTF8_ELLIPSIS 1150 " and probably some more we forgot to mention (sorry!)" 1151 "\n\n")); 1152 1153 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1154 fCreditsView->Insert(B_TRANSLATE("Translations:\n")); 1155 1156 BLanguage* lang; 1157 BString langName; 1158 1159 BList sortedTranslations; 1160 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1161 const Translation* translation = &gTranslations[i]; 1162 sortedTranslations.AddItem((void*)translation); 1163 } 1164 sortedTranslations.SortItems(TranslationComparator); 1165 1166 for (uint32 i = 0; i < kNumberOfTranslations; i ++) { 1167 const Translation& translation 1168 = *(const Translation*)sortedTranslations.ItemAt(i); 1169 1170 langName.Truncate(0); 1171 if (BLocaleRoster::Default()->GetLanguage(translation.languageCode, 1172 &lang) == B_OK) { 1173 lang->GetName(langName); 1174 delete lang; 1175 } else { 1176 // We failed to get the localized readable name, 1177 // go with what we have. 1178 langName.Append(translation.languageCode); 1179 } 1180 1181 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 1182 fCreditsView->Insert("\n"); 1183 fCreditsView->Insert(langName); 1184 fCreditsView->Insert("\n"); 1185 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1186 fCreditsView->Insert(translation.names); 1187 } 1188 1189 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1190 fCreditsView->Insert(B_TRANSLATE("\n\nSpecial thanks to:\n")); 1191 1192 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1193 BString beosCredits(B_TRANSLATE( 1194 "Be Inc. and its developer team, for having created BeOS!\n\n")); 1195 int32 beosOffset = beosCredits.FindFirst("BeOS"); 1196 fCreditsView->Insert(beosCredits.String(), 1197 (beosOffset < 0) ? beosCredits.Length() : beosOffset); 1198 if (beosOffset > -1) { 1199 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBeOSBlue); 1200 fCreditsView->Insert("B"); 1201 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBeOSRed); 1202 fCreditsView->Insert("e"); 1203 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1204 beosCredits.Remove(0, beosOffset + 2); 1205 fCreditsView->Insert(beosCredits.String(), beosCredits.Length()); 1206 } 1207 fCreditsView->Insert( 1208 B_TRANSLATE("Travis Geiselbrecht (and his NewOS kernel)\n")); 1209 fCreditsView->Insert( 1210 B_TRANSLATE("Michael Phipps (project founder)\n\n")); 1211 fCreditsView->Insert( 1212 B_TRANSLATE("The Haiku-Ports team\n")); 1213 fCreditsView->Insert( 1214 B_TRANSLATE("The Haikuware team and their bounty program\n")); 1215 fCreditsView->Insert( 1216 B_TRANSLATE("The BeGeistert team\n")); 1217 fCreditsView->Insert( 1218 B_TRANSLATE("Google & their Google Summer of Code program\n")); 1219 fCreditsView->Insert( 1220 B_TRANSLATE("The University of Auckland and Christof Lutteroth\n\n")); 1221 fCreditsView->Insert( 1222 B_TRANSLATE("... and the many people making donations!\n\n")); 1223 1224 // copyrights for various projects we use 1225 1226 BPath mitPath; 1227 _GetLicensePath("MIT", mitPath); 1228 BPath lgplPath; 1229 _GetLicensePath("GNU LGPL v2.1", lgplPath); 1230 1231 font.SetSize(be_bold_font->Size() + 4); 1232 font.SetFace(B_BOLD_FACE); 1233 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuGreen); 1234 fCreditsView->Insert(B_TRANSLATE("\nCopyrights\n\n")); 1235 1236 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1237 fCreditsView->Insert(B_TRANSLATE("[Click a license name to read the " 1238 "respective license.]\n\n")); 1239 1240 // Haiku license 1241 BString haikuLicense = B_TRANSLATE_COMMENT("The code that is unique to " 1242 "Haiku, especially the kernel and all code that applications may link " 1243 "against, is distributed under the terms of the <MIT license>. " 1244 "Some system libraries contain third party code distributed under the " 1245 "<LGPL license>. You can find the copyrights to third party code below." 1246 "\n\n", "<MIT license> and <LGPL license> aren't variables and can be " 1247 "translated. However, please, don't remove < and > as they're needed " 1248 "as placeholders for proper hypertext functionality."); 1249 int32 licensePart1 = haikuLicense.FindFirst("<"); 1250 int32 licensePart2 = haikuLicense.FindFirst(">"); 1251 int32 licensePart3 = haikuLicense.FindLast("<"); 1252 int32 licensePart4 = haikuLicense.FindLast(">"); 1253 BString part; 1254 haikuLicense.CopyInto(part, 0, licensePart1); 1255 fCreditsView->Insert(part); 1256 1257 part.Truncate(0); 1258 haikuLicense.CopyInto(part, licensePart1 + 1, licensePart2 - 1 1259 - licensePart1); 1260 fCreditsView->InsertHyperText(part, new OpenFileAction(mitPath.Path())); 1261 1262 part.Truncate(0); 1263 haikuLicense.CopyInto(part, licensePart2 + 1, licensePart3 - 1 1264 - licensePart2); 1265 fCreditsView->Insert(part); 1266 1267 part.Truncate(0); 1268 haikuLicense.CopyInto(part, licensePart3 + 1, licensePart4 - 1 1269 - licensePart3); 1270 fCreditsView->InsertHyperText(part, new OpenFileAction(lgplPath.Path())); 1271 1272 part.Truncate(0); 1273 haikuLicense.CopyInto(part, licensePart4 + 1, haikuLicense.Length() - 1 1274 - licensePart4); 1275 fCreditsView->Insert(part); 1276 1277 // GNU copyrights 1278 AddCopyrightEntry("The GNU Project", 1279 B_TRANSLATE("Contains software from the GNU Project, " 1280 "released under the GPL and LGPL licenses:\n" 1281 "GNU C Library, " 1282 "GNU coretools, diffutils, findutils, " 1283 "sharutils, gawk, bison, m4, make, " 1284 "gdb, wget, ncurses, termcap, " 1285 "Bourne Again Shell.\n" 1286 COPYRIGHT_STRING "The Free Software Foundation."), 1287 StringVector("GNU LGPL v2.1", "GNU GPL v2", "GNU GPL v3", NULL), 1288 StringVector(), 1289 "http://www.gnu.org"); 1290 1291 // FreeBSD copyrights 1292 AddCopyrightEntry("The FreeBSD Project", 1293 B_TRANSLATE("Contains software from the FreeBSD Project, " 1294 "released under the BSD license:\n" 1295 "cal, ftpd, ping, telnet, " 1296 "telnetd, traceroute\n" 1297 COPYRIGHT_STRING "1994-2008 The FreeBSD Project. " 1298 "All rights reserved."), 1299 "http://www.freebsd.org"); 1300 // TODO: License! 1301 1302 // NetBSD copyrights 1303 AddCopyrightEntry("The NetBSD Project", 1304 B_TRANSLATE("Contains software developed by the NetBSD " 1305 "Foundation, Inc. and its contributors:\n" 1306 "ftp, tput\n" 1307 COPYRIGHT_STRING "1996-2008 The NetBSD Foundation, Inc. " 1308 "All rights reserved."), 1309 "http://www.netbsd.org"); 1310 // TODO: License! 1311 1312 // FFMpeg copyrights 1313 _AddPackageCredit(PackageCredit("FFMpeg libavcodec") 1314 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2000-2007 Fabrice " 1315 "Bellard, et al.")) 1316 .SetLicenses("GNU LGPL v2.1", "GNU LGPL v2", NULL) 1317 .SetURL("http://www.ffmpeg.org")); 1318 1319 // AGG copyrights 1320 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 1321 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2006 Maxim " 1322 "Shemanarev (McSeem).")) 1323 .SetLicenses("Anti-Grain Geometry", B_TRANSLATE("BSD (3-clause)"), 1324 "GPC", NULL) 1325 .SetURL("http://www.antigrain.com")); 1326 1327 // PDFLib copyrights 1328 _AddPackageCredit(PackageCredit("PDFLib") 1329 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1997-2006 PDFlib GmbH and " 1330 "Thomas Merz. All rights reserved.\n" 1331 "PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.")) 1332 .SetLicense("PDFlib Lite") 1333 .SetURL("http://www.pdflib.com")); 1334 1335 // FreeType copyrights 1336 _AddPackageCredit(PackageCredit("FreeType2") 1337 .SetCopyright(B_TRANSLATE("Portions of this software are copyright. " 1338 COPYRIGHT_STRING "1996-2006 " 1339 "The FreeType Project. All rights reserved.")) 1340 .SetLicense("FTL") 1341 .SetURL("http://www.freetype.org")); 1342 1343 // Mesa3D (http://www.mesa3d.org) copyrights 1344 _AddPackageCredit(PackageCredit("Mesa") 1345 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2006 Brian Paul. " 1346 "Mesa3D Project. All rights reserved.")) 1347 .SetLicense("MIT") 1348 .SetURL("http://www.mesa3d.org")); 1349 1350 // SGI's GLU implementation copyrights 1351 _AddPackageCredit(PackageCredit("GLU") 1352 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1991-2000 " 1353 "Silicon Graphics, Inc. SGI's Software FreeB license. " 1354 "All rights reserved.")) 1355 .SetLicense("SGI Free B") 1356 .SetURL("http://www.sgi.com/products/software/opengl")); 1357 1358 // GLUT implementation copyrights 1359 _AddPackageCredit(PackageCredit("GLUT") 1360 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1361 "All rights reserved."), 1362 COPYRIGHT_STRING "1997 Be Inc.", 1363 COPYRIGHT_STRING "1999 Jake Hamby.", 1364 NULL) 1365 .SetLicense("GLUT (Mark Kilgard)") 1366 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1367 1368 // OpenGroup & DEC (BRegion backend) copyright 1369 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1370 .SetCopyrights(COPYRIGHT_STRING "1987-1988, 1998 The Open Group.", 1371 B_TRANSLATE(COPYRIGHT_STRING "1987-1988 Digital Equipment " 1372 "Corporation, Maynard, Massachusetts.\n" 1373 "All rights reserved."), 1374 NULL) 1375 .SetLicenses("OpenGroup", "DEC", NULL)); 1376 // TODO: URL 1377 1378 // VL-Gothic font 1379 _AddPackageCredit(PackageCredit("VL-Gothic font") 1380 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1990-2003 Wada Laboratory," 1381 " the University of Tokyo."), COPYRIGHT_STRING 1382 "2003-2004 Electronic Font Open Laboratory (/efont/).", 1383 COPYRIGHT_STRING "2003-2008 M+ FONTS PROJECT.", 1384 COPYRIGHT_STRING "2006-2009 Daisuke SUZUKI.", 1385 COPYRIGHT_STRING "2006-2009 Project Vine.", 1386 B_TRANSLATE("MIT license. All rights reserved."), 1387 NULL)); 1388 // TODO: License! 1389 1390 // expat copyrights 1391 _AddPackageCredit(PackageCredit("expat") 1392 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1998-2000 Thai " 1393 "Open Source Software Center Ltd and Clark Cooper."), 1394 B_TRANSLATE(COPYRIGHT_STRING "2001-2003 Expat maintainers."), 1395 NULL) 1396 .SetLicense("Expat") 1397 .SetURL("http://expat.sourceforge.net")); 1398 1399 // zlib copyrights 1400 _AddPackageCredit(PackageCredit("zlib") 1401 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2004 Jean-loup " 1402 "Gailly and Mark Adler.")) 1403 .SetLicense("Zlib") 1404 .SetURL("http://www.zlib.net")); 1405 1406 // zip copyrights 1407 _AddPackageCredit(PackageCredit("Info-ZIP") 1408 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1990-2002 Info-ZIP. " 1409 "All rights reserved.")) 1410 .SetLicense("Info-ZIP") 1411 .SetURL("http://www.info-zip.org")); 1412 1413 // bzip2 copyrights 1414 _AddPackageCredit(PackageCredit("bzip2") 1415 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-2005 Julian R " 1416 "Seward. All rights reserved.")) 1417 .SetLicense(B_TRANSLATE("BSD (4-clause)")) 1418 .SetURL("http://bzip.org")); 1419 1420 // lp_solve copyrights 1421 _AddPackageCredit(PackageCredit("lp_solve") 1422 .SetCopyright(COPYRIGHT_STRING 1423 "Michel Berkelaar, Kjell Eikland, Peter Notebaert") 1424 .SetLicense("GNU LGPL v2.1") 1425 .SetURL("http://lpsolve.sourceforge.net/")); 1426 1427 // OpenEXR copyrights 1428 _AddPackageCredit(PackageCredit("OpenEXR") 1429 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2005 Industrial " 1430 "Light & Magic, a division of Lucas Digital Ltd. LLC.")) 1431 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1432 .SetURL("http://www.openexr.com")); 1433 1434 // Bullet copyrights 1435 _AddPackageCredit(PackageCredit("Bullet") 1436 .SetCopyright(COPYRIGHT_STRING "2003-2008 Erwin Coumans") 1437 .SetLicense("Bullet") 1438 .SetURL("http://www.bulletphysics.com")); 1439 1440 // atftp copyrights 1441 _AddPackageCredit(PackageCredit("atftp") 1442 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2000 Jean-Pierre " 1443 "ervbefeL and Remi Lefebvre.")) 1444 .SetLicense("GNU GPL v2")); 1445 // TODO: URL! 1446 1447 // Netcat copyrights 1448 _AddPackageCredit(PackageCredit("Netcat") 1449 .SetCopyright(COPYRIGHT_STRING "1996 Hobbit.")); 1450 // TODO: License! 1451 1452 // acpica copyrights 1453 _AddPackageCredit(PackageCredit("acpica") 1454 .SetCopyright(COPYRIGHT_STRING "1999-2006 Intel Corp.") 1455 .SetLicense("Intel (ACPICA)") 1456 .SetURL("http://www.acpica.org")); 1457 1458 // unrar copyrights 1459 _AddPackageCredit(PackageCredit("unrar") 1460 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2008 Alexander " 1461 "L. Roshal. All rights reserved.")) 1462 .SetLicense("UnRAR") 1463 .SetURL("http://www.rarlab.com")); 1464 1465 // libpng copyrights 1466 _AddPackageCredit(PackageCredit("libpng") 1467 .SetCopyright(COPYRIGHT_STRING "2004, 2006-2008 Glenn " 1468 "Randers-Pehrson.") 1469 .SetLicense("LibPNG") 1470 .SetURL("http://www.libpng.org")); 1471 1472 // libjpeg copyrights 1473 _AddPackageCredit(PackageCredit("libjpeg") 1474 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1994-2009, Thomas G. " 1475 "Lane, Guido Vollbeding. This software is based in part on the " 1476 "work of the Independent JPEG Group.")) 1477 .SetLicense("LibJPEG") 1478 .SetURL("http://www.ijg.org")); 1479 1480 // libprint copyrights 1481 _AddPackageCredit(PackageCredit("libprint") 1482 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2000 Y.Takagi. " 1483 "All rights reserved."))); 1484 // TODO: License! 1485 1486 // cortex copyrights 1487 _AddPackageCredit(PackageCredit("Cortex") 1488 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1489 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1490 .SetURL("http://cortex.sourceforge.net/documentation")); 1491 1492 // FluidSynth copyrights 1493 _AddPackageCredit(PackageCredit("FluidSynth") 1494 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003 Peter Hanappe " 1495 "and others.")) 1496 .SetLicense("GNU LGPL v2") 1497 .SetURL("http://www.fluidsynth.org")); 1498 1499 // CannaIM copyrights 1500 _AddPackageCredit(PackageCredit("CannaIM") 1501 .SetCopyright(COPYRIGHT_STRING "1999 Masao Kawamura.")); 1502 // TODO: License! 1503 1504 // libxml2, libxslt, libexslt copyrights 1505 _AddPackageCredit(PackageCredit("libxml2, libxslt") 1506 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1998-2003 Daniel Veillard. " 1507 "All rights reserved.")) 1508 .SetLicense(B_TRANSLATE("MIT (no promotion)")) 1509 .SetURL("http://xmlsoft.org")); 1510 1511 _AddPackageCredit(PackageCredit("libexslt") 1512 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2001-2002 Thomas Broyer, " 1513 "Charlie Bozeman and Daniel Veillard. All rights reserved.")) 1514 .SetLicense(B_TRANSLATE("MIT (no promotion)")) 1515 .SetURL("http://xmlsoft.org")); 1516 1517 // Xiph.org Foundation copyrights 1518 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1519 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1520 B_TRANSLATE(COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1521 "All rights reserved."), NULL) 1522 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1523 .SetURL("http://www.xiph.org")); 1524 1525 // The Tcpdump Group 1526 _AddPackageCredit(PackageCredit("The Tcpdump Group") 1527 .SetCopyright("tcpdump, libpcap") 1528 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1529 .SetURL("http://www.tcpdump.org")); 1530 1531 // Matroska 1532 _AddPackageCredit(PackageCredit("libmatroska") 1533 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1534 "All rights reserved.")) 1535 .SetLicense("GNU LGPL v2.1") 1536 .SetURL("http://www.matroska.org")); 1537 1538 // BColorQuantizer (originally CQuantizer code) 1539 _AddPackageCredit(PackageCredit("CQuantizer") 1540 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1541 "All rights reserved.")) 1542 .SetLicense("CQuantizer") 1543 .SetURL("http://www.xdp.it")); 1544 1545 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1546 _AddPackageCredit(PackageCredit("MAPM") 1547 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2007 Michael C. " 1548 "Ring. All rights reserved.")) 1549 .SetLicense("MAPM") 1550 .SetURL("http://tc.umn.edu/~ringx004")); 1551 1552 // MkDepend 1.7 copyright (Makefile dependency generator) 1553 _AddPackageCredit(PackageCredit("MkDepend") 1554 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1555 "All rights reserved.")) 1556 .SetLicense("MkDepend") 1557 .SetURL("http://bearnip.com/lars/be")); 1558 1559 // libhttpd copyright (used as Poorman backend) 1560 _AddPackageCredit(PackageCredit("libhttpd") 1561 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995, 1998-2001 " 1562 "Jef Poskanzer. All rights reserved.")) 1563 .SetLicense("LibHTTPd") 1564 .SetURL("http://www.acme.com/software/thttpd/")); 1565 1566 #ifdef __INTEL__ 1567 // Udis86 copyrights 1568 _AddPackageCredit(PackageCredit("Udis86") 1569 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2004 " 1570 "Vivek Mohan. All rights reserved.")) 1571 .SetLicense(B_TRANSLATE("BSD (2-clause)")) 1572 .SetURL("http://udis86.sourceforge.net")); 1573 // TODO: License! - Project website refers to BSD License 1574 #endif 1575 1576 #ifdef __INTEL__ 1577 // Intel PRO/Wireless 2100 Firmware 1578 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 Firmware") 1579 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003-2006 " 1580 "Intel Corporation. All rights reserved.")) 1581 .SetLicense("Intel (2xxx firmware)") 1582 .SetURL("http://ipw2100.sourceforge.net/")); 1583 #endif 1584 1585 #ifdef __INTEL__ 1586 // Intel PRO/Wireless 2200BG Firmware 1587 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2200BG Firmware") 1588 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2004-2005 " 1589 "Intel Corporation. All rights reserved.")) 1590 .SetLicense("Intel (2xxx firmware)") 1591 .SetURL("http://ipw2200.sourceforge.net/")); 1592 #endif 1593 1594 #ifdef __INTEL__ 1595 // Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware 1596 _AddPackageCredit( 1597 PackageCredit( 1598 "Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware") 1599 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2007 " 1600 "Intel Corporation. All rights reserved.")) 1601 .SetLicense("Intel (firmware)") 1602 .SetURL("http://www.intellinuxwireless.org/")); 1603 #endif 1604 #ifdef __INTEL__ 1605 // Intel Wireless WiFi Link 4965AGN Adapter Firmware 1606 _AddPackageCredit( 1607 PackageCredit("Intel Wireless WiFi Link 4965AGN Adapter Firmware") 1608 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2007 " 1609 "Intel Corporation. All rights reserved.")) 1610 .SetLicense("Intel (firmware)") 1611 .SetURL("http://www.intellinuxwireless.org/")); 1612 #endif 1613 1614 #ifdef __INTEL__ 1615 // Marvell 88w8363 1616 _AddPackageCredit(PackageCredit("Marvell 88w8363") 1617 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007-2009 " 1618 "Marvell Semiconductor, Inc. All rights reserved.")) 1619 .SetLicense("Marvell (firmware)") 1620 .SetURL("http://www.marvell.com/")); 1621 #endif 1622 1623 #ifdef __INTEL__ 1624 // Ralink Firmware RT2501/RT2561/RT2661 1625 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 1626 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007 " 1627 "Ralink Technology Corporation. All rights reserved.")) 1628 .SetLicense("Ralink (firmware)") 1629 .SetURL("http://www.ralinktech.com/")); 1630 #endif 1631 1632 // Gutenprint 1633 _AddPackageCredit(PackageCredit("Gutenprint") 1634 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1635 "1999-2010 by the authors of Gutenprint. All rights reserved.")) 1636 .SetLicense("GNU GPL v2") 1637 .SetURL("http://gutenprint.sourceforge.net/")); 1638 1639 // libwebp 1640 _AddPackageCredit(PackageCredit("libwebp") 1641 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1642 "2010-2011 Google Inc. All rights reserved.")) 1643 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1644 .SetURL("http://www.webmproject.org/code/#libwebp_webp_image_library")); 1645 1646 // GTF 1647 _AddPackageCredit(PackageCredit("GTF") 1648 .SetCopyright(B_TRANSLATE("2001 by Andy Ritger based on the " 1649 "Generalized Timing Formula")) 1650 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1651 .SetURL("http://gtf.sourceforge.net/")); 1652 1653 _AddCopyrightsFromAttribute(); 1654 _AddPackageCreditEntries(); 1655 1656 return new CropView(creditsScroller, 0, 1, 1, 1); 1657 } 1658 1659 1660 status_t 1661 AboutView::_GetLicensePath(const char* license, BPath& path) 1662 { 1663 static const directory_which directoryConstants[] = { 1664 B_USER_DATA_DIRECTORY, 1665 B_COMMON_DATA_DIRECTORY, 1666 B_SYSTEM_DATA_DIRECTORY 1667 }; 1668 static const int dirCount = 3; 1669 1670 for (int i = 0; i < dirCount; i++) { 1671 struct stat st; 1672 status_t error = find_directory(directoryConstants[i], &path); 1673 if (error == B_OK && path.Append("licenses") == B_OK 1674 && path.Append(license) == B_OK 1675 && lstat(path.Path(), &st) == 0) { 1676 return B_OK; 1677 } 1678 } 1679 1680 path.Unset(); 1681 return B_ENTRY_NOT_FOUND; 1682 } 1683 1684 1685 void 1686 AboutView::_AddCopyrightsFromAttribute() 1687 { 1688 #ifdef __HAIKU__ 1689 // open the app executable file 1690 char appPath[B_PATH_NAME_LENGTH]; 1691 int appFD; 1692 if (BPrivate::get_app_path(appPath) != B_OK 1693 || (appFD = open(appPath, O_RDONLY)) < 0) { 1694 return; 1695 } 1696 1697 // open the attribute 1698 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 1699 close(appFD); 1700 if (attrFD < 0) 1701 return; 1702 1703 // attach it to a FILE 1704 FILE* attrFile = fdopen(attrFD, "r"); 1705 if (attrFile == NULL) { 1706 close(attrFD); 1707 return; 1708 } 1709 CObjectDeleter<FILE, int> _(attrFile, fclose); 1710 1711 // read and parse the copyrights 1712 BMessage package; 1713 BString fieldName; 1714 BString fieldValue; 1715 char lineBuffer[LINE_MAX]; 1716 while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) { 1717 // chop off line break 1718 size_t lineLen = strlen(line); 1719 if (lineLen > 0 && line[lineLen - 1] == '\n') 1720 line[--lineLen] = '\0'; 1721 1722 // flush previous field, if a new field begins, otherwise append 1723 if (lineLen == 0 || !isspace(line[0])) { 1724 // new field -- flush the previous one 1725 if (fieldName.Length() > 0) { 1726 fieldValue = trim_string(fieldValue.String(), 1727 fieldValue.Length()); 1728 package.AddString(fieldName.String(), fieldValue); 1729 fieldName = ""; 1730 } 1731 } else if (fieldName.Length() > 0) { 1732 // append to current field 1733 fieldValue += line; 1734 continue; 1735 } else { 1736 // bogus line -- ignore 1737 continue; 1738 } 1739 1740 if (lineLen == 0) 1741 continue; 1742 1743 // parse new field 1744 char* colon = strchr(line, ':'); 1745 if (colon == NULL) { 1746 // bogus line -- ignore 1747 continue; 1748 } 1749 1750 fieldName.SetTo(line, colon - line); 1751 fieldName = trim_string(line, colon - line); 1752 if (fieldName.Length() == 0) { 1753 // invalid field name 1754 continue; 1755 } 1756 1757 fieldValue = colon + 1; 1758 1759 if (fieldName == "Package") { 1760 // flush the current package 1761 _AddPackageCredit(PackageCredit(package)); 1762 package.MakeEmpty(); 1763 } 1764 } 1765 1766 // flush current package 1767 _AddPackageCredit(PackageCredit(package)); 1768 #endif 1769 } 1770 1771 1772 void 1773 AboutView::_AddPackageCreditEntries() 1774 { 1775 // sort the packages case-insensitively 1776 PackageCredit* packages[fPackageCredits.size()]; 1777 int32 count = 0; 1778 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1779 it != fPackageCredits.end(); ++it) { 1780 packages[count++] = it->second; 1781 } 1782 1783 if (count > 1) { 1784 std::sort(packages, packages + count, 1785 &PackageCredit::NameLessInsensitive); 1786 } 1787 1788 // add the credits 1789 for (int32 i = 0; i < count; i++) { 1790 PackageCredit* package = packages[i]; 1791 1792 BString text(package->CopyrightAt(0)); 1793 int32 count = package->CountCopyrights(); 1794 for (int32 i = 1; i < count; i++) 1795 text << "\n" << package->CopyrightAt(i); 1796 1797 AddCopyrightEntry(package->PackageName(), text.String(), 1798 package->Licenses(), package->Sources(), package->URL()); 1799 } 1800 } 1801 1802 1803 void 1804 AboutView::_AddPackageCredit(const PackageCredit& package) 1805 { 1806 if (!package.IsValid()) 1807 return; 1808 1809 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 1810 if (it != fPackageCredits.end()) { 1811 // If the new package credit isn't "better" than the old one, ignore it. 1812 PackageCredit* oldPackage = it->second; 1813 if (!package.IsBetterThan(*oldPackage)) 1814 return; 1815 1816 // replace the old credit 1817 fPackageCredits.erase(it); 1818 delete oldPackage; 1819 } 1820 1821 fPackageCredits[package.PackageName()] = new PackageCredit(package); 1822 } 1823 1824 1825 // #pragma mark - 1826 1827 1828 static const char* 1829 MemSizeToString(char string[], size_t size, system_info* info) 1830 { 1831 int inaccessibleMemory = int(info->ignored_pages 1832 * (B_PAGE_SIZE / 1048576.0f) + 0.5f); 1833 if (inaccessibleMemory > 0) { 1834 BString message(B_TRANSLATE("%total MiB total, %inaccessible MiB " 1835 "inaccessible")); 1836 1837 snprintf(string, size, "%d", int((info->max_pages 1838 + info->ignored_pages) * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1839 message.ReplaceFirst("%total", string); 1840 1841 snprintf(string, size, "%d", inaccessibleMemory); 1842 message.ReplaceFirst("%inaccessible", string); 1843 strncpy(string, message.String(), size); 1844 } else { 1845 snprintf(string, size, B_TRANSLATE("%d MiB total"), 1846 int(info->max_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1847 } 1848 1849 return string; 1850 } 1851 1852 1853 static const char* 1854 MemUsageToString(char string[], size_t size, system_info* info) 1855 { 1856 snprintf(string, size, B_TRANSLATE("%d MiB used (%d%%)"), 1857 int(info->used_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f), 1858 int(100 * info->used_pages / info->max_pages)); 1859 1860 return string; 1861 } 1862 1863 1864 static const char* 1865 UptimeToString(char string[], size_t size) 1866 { 1867 BDurationFormat formatter; 1868 BString str; 1869 1870 bigtime_t uptime = system_time(); 1871 bigtime_t now = (bigtime_t)time(NULL) * 1000000; 1872 formatter.Format(now - uptime, now, &str); 1873 str.CopyInto(string, 0, size); 1874 string[std::min((size_t)str.Length(), size)] = '\0'; 1875 1876 return string; 1877 } 1878 1879 1880 int 1881 main() 1882 { 1883 AboutApp app; 1884 app.Run(); 1885 return 0; 1886 } 1887 1888