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 "John Scipione\n" 993 "Andrej Spielmann\n" 994 "Jonas Sundström\n" 995 "Oliver Tappe\n" 996 "Gerasim Troeglazov\n" 997 "Alexander von Gluck IV\n" 998 "Ingo Weinhold\n" 999 "Alex Wilson\n" 1000 "Artur Wyszyński\n" 1001 "Clemens Zeidler\n" 1002 "Siarzhuk Zharski\n" 1003 "\n"); 1004 1005 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1006 fCreditsView->Insert(B_TRANSLATE("Past maintainers:\n")); 1007 1008 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1009 fCreditsView->Insert( 1010 "Andrew Bachmann\n" 1011 "Tyler Dauwalder\n" 1012 "Daniel Furrer\n" 1013 "Andre Alves Garzia\n" 1014 "Erik Jaesler\n" 1015 "Marcin Konicki\n" 1016 "Waldemar Kornewald\n" 1017 "Thomas Kurschel\n" 1018 "Frans Van Nispen\n" 1019 "Adi Oanca\n" 1020 "Michael Phipps\n" 1021 "Niels Sascha Reedijk\n" 1022 "David Reid\n" 1023 "Hugo Santos\n" 1024 "Alexander G. M. Smith\n" 1025 "Bryan Varner\n" 1026 "Nathan Whitehorn\n" 1027 "Michael Wilber\n" 1028 "Jonathan Yoder\n" 1029 "Gabe Yoder\n" 1030 "\n"); 1031 1032 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1033 fCreditsView->Insert(B_TRANSLATE("Website, marketing & documentation:\n")); 1034 1035 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1036 fCreditsView->Insert( 1037 "Phil Greenway\n" 1038 "Gavin James\n" 1039 "Urias McCullough\n" 1040 "Niels Sascha Reedijk\n" 1041 "Joachim Seemer (Humdinger)\n" 1042 "Jonathan Yoder\n" 1043 "\n"); 1044 1045 fCreditsView->SetFontAndColor(&font, B_FONT_ALL, &kHaikuOrange); 1046 fCreditsView->Insert(B_TRANSLATE("Contributors:\n")); 1047 1048 fCreditsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kDarkGrey); 1049 fCreditsView->Insert( 1050 "Andrea Anzani\n" 1051 "Sean Bartell\n" 1052 "Andre Braga\n" 1053 "Michael Bulash\n" 1054 "Bruce Cameron\n" 1055 "Jean-Loïc Charroud\n" 1056 "Greg Crain\n" 1057 "Michael Davidson\n" 1058 "David Dengg\n" 1059 "John Drinkwater\n" 1060 "Cian Duffy\n" 1061 "Vincent Duvert\n" 1062 "Mikael Eiman\n" 1063 "Fredrik Ekdahl\n" 1064 "Joshua R. Elsasser\n" 1065 "Atis Elsts\n" 1066 "Mark Erben\n" 1067 "Christian Fasshauer\n" 1068 "Andreas Färber\n" 1069 "Janito Ferreira Filho\n" 1070 "Pier Luigi Fiorini\n" 1071 "Marc Flerackers\n" 1072 "Michele Frau (zuMi)\n" 1073 "Deyan Genovski\n" 1074 "Pete Goodeve\n" 1075 "Lucian Adrian Grijincu\n" 1076 "Sean Healy\n" 1077 "Matthijs Hollemans\n" 1078 "Mathew Hounsell\n" 1079 "Morgan Howe\n" 1080 "Christophe Huriaux\n" 1081 "Jian Jiang\n" 1082 "Ma Jie\n" 1083 "Carwyn Jones\n" 1084 "Vasilis Kaoutsis\n" 1085 "James Kim\n" 1086 "Shintaro Kinugawa\n" 1087 "Jan Klötzke\n" 1088 "Kurtis Kopf\n" 1089 "Tomáš Kučera\n" 1090 "Luboš Kulič\n" 1091 "Elad Lahav\n" 1092 "Anthony Lee\n" 1093 "Santiago Lema\n" 1094 "Raynald Lesieur\n" 1095 "Oscar Lesta\n" 1096 "Jerome Leveque\n" 1097 "Brian Luft\n" 1098 "Christof Lutteroth\n" 1099 "Graham MacDonald\n" 1100 "Jorge G. Mare (Koki)\n" 1101 "Jan Matějek\n" 1102 "Brian Matzon\n" 1103 "Christopher ML Zumwalt May\n" 1104 "Andrew McCall\n" 1105 "Nathan Mentley\n" 1106 "Marius Middelthon\n" 1107 "Marco Minutoli\n" 1108 "Misza\n" 1109 "Hamish Morrison\n" 1110 "MrSiggler\n" 1111 "Takashi Murai\n" 1112 "Alan Murta\n" 1113 "Raghuram Nagireddy\n" 1114 "Kazuho Okui\n" 1115 "Jeroen Oortwijn (idefix)\n" 1116 "Pahtz\n" 1117 "Michael Paine\n" 1118 "Adrian Panasiuk\n" 1119 "Romain Picard\n" 1120 "Francesco Piccinno\n" 1121 "David Powell\n" 1122 "Jeremy Rand\n" 1123 "Hartmut Reh\n" 1124 "Daniel Reinhold\n" 1125 "Chris Roberts\n" 1126 "Samuel Rodríguez Pérez\n" 1127 "Thomas Roell\n" 1128 "Rafael Romo\n" 1129 "Ralf Schülke\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 StringVector("BSD (2-clause)", "BSD (3-clause)", "BSD (4-clause)", 1300 NULL), 1301 StringVector(), 1302 "http://www.freebsd.org"); 1303 1304 // NetBSD copyrights 1305 AddCopyrightEntry("The NetBSD Project", 1306 B_TRANSLATE("Contains software developed by the NetBSD " 1307 "Foundation, Inc. and its contributors:\n" 1308 "ftp, tput\n" 1309 COPYRIGHT_STRING "1996-2008 The NetBSD Foundation, Inc. " 1310 "All rights reserved."), 1311 "http://www.netbsd.org"); 1312 // TODO: License! 1313 1314 // FFMpeg copyrights 1315 _AddPackageCredit(PackageCredit("FFMpeg libavcodec") 1316 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2000-2007 Fabrice " 1317 "Bellard, et al.")) 1318 .SetLicenses("GNU LGPL v2.1", "GNU LGPL v2", NULL) 1319 .SetURL("http://www.ffmpeg.org")); 1320 1321 // AGG copyrights 1322 _AddPackageCredit(PackageCredit("AntiGrain Geometry") 1323 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2006 Maxim " 1324 "Shemanarev (McSeem).")) 1325 .SetLicenses("Anti-Grain Geometry", B_TRANSLATE("BSD (3-clause)"), 1326 "GPC", NULL) 1327 .SetURL("http://www.antigrain.com")); 1328 1329 // PDFLib copyrights 1330 _AddPackageCredit(PackageCredit("PDFLib") 1331 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1997-2006 PDFlib GmbH and " 1332 "Thomas Merz. All rights reserved.\n" 1333 "PDFlib and PDFlib logo are registered trademarks of PDFlib GmbH.")) 1334 .SetLicense("PDFlib Lite") 1335 .SetURL("http://www.pdflib.com")); 1336 1337 // FreeType copyrights 1338 _AddPackageCredit(PackageCredit("FreeType2") 1339 .SetCopyright(B_TRANSLATE("Portions of this software are copyright. " 1340 COPYRIGHT_STRING "1996-2006 " 1341 "The FreeType Project. All rights reserved.")) 1342 .SetLicense("FTL") 1343 .SetURL("http://www.freetype.org")); 1344 1345 // Mesa3D (http://www.mesa3d.org) copyrights 1346 _AddPackageCredit(PackageCredit("Mesa") 1347 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2006 Brian Paul. " 1348 "Mesa3D Project. All rights reserved.")) 1349 .SetLicense("MIT") 1350 .SetURL("http://www.mesa3d.org")); 1351 1352 // SGI's GLU implementation copyrights 1353 _AddPackageCredit(PackageCredit("GLU") 1354 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1991-2000 " 1355 "Silicon Graphics, Inc. SGI's Software FreeB license. " 1356 "All rights reserved.")) 1357 .SetLicense("SGI Free B") 1358 .SetURL("http://www.sgi.com/products/software/opengl")); 1359 1360 // GLUT implementation copyrights 1361 _AddPackageCredit(PackageCredit("GLUT") 1362 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1994-1997 Mark Kilgard. " 1363 "All rights reserved."), 1364 COPYRIGHT_STRING "1997 Be Inc.", 1365 COPYRIGHT_STRING "1999 Jake Hamby.", 1366 NULL) 1367 .SetLicense("GLUT (Mark Kilgard)") 1368 .SetURL("http://www.opengl.org/resources/libraries/glut")); 1369 1370 // OpenGroup & DEC (BRegion backend) copyright 1371 _AddPackageCredit(PackageCredit("BRegion backend (XFree86)") 1372 .SetCopyrights(COPYRIGHT_STRING "1987-1988, 1998 The Open Group.", 1373 B_TRANSLATE(COPYRIGHT_STRING "1987-1988 Digital Equipment " 1374 "Corporation, Maynard, Massachusetts.\n" 1375 "All rights reserved."), 1376 NULL) 1377 .SetLicenses("OpenGroup", "DEC", NULL)); 1378 // TODO: URL 1379 1380 // VL-Gothic font 1381 _AddPackageCredit(PackageCredit("VL-Gothic font") 1382 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1990-2003 Wada Laboratory," 1383 " the University of Tokyo."), COPYRIGHT_STRING 1384 "2003-2004 Electronic Font Open Laboratory (/efont/).", 1385 COPYRIGHT_STRING "2003-2008 M+ FONTS PROJECT.", 1386 COPYRIGHT_STRING "2006-2009 Daisuke SUZUKI.", 1387 COPYRIGHT_STRING "2006-2009 Project Vine.", 1388 B_TRANSLATE("MIT license. All rights reserved."), 1389 NULL) 1390 .SetLicense("BSD (3-clause)") 1391 .SetURL("http://vlgothic.dicey.org/")); 1392 1393 // expat copyrights 1394 _AddPackageCredit(PackageCredit("expat") 1395 .SetCopyrights(B_TRANSLATE(COPYRIGHT_STRING "1998-2000 Thai " 1396 "Open Source Software Center Ltd and Clark Cooper."), 1397 B_TRANSLATE(COPYRIGHT_STRING "2001-2003 Expat maintainers."), 1398 NULL) 1399 .SetLicense("Expat") 1400 .SetURL("http://expat.sourceforge.net")); 1401 1402 // zlib copyrights 1403 _AddPackageCredit(PackageCredit("zlib") 1404 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2004 Jean-loup " 1405 "Gailly and Mark Adler.")) 1406 .SetLicense("Zlib") 1407 .SetURL("http://www.zlib.net")); 1408 1409 // zip copyrights 1410 _AddPackageCredit(PackageCredit("Info-ZIP") 1411 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1990-2002 Info-ZIP. " 1412 "All rights reserved.")) 1413 .SetLicense("Info-ZIP") 1414 .SetURL("http://www.info-zip.org")); 1415 1416 // bzip2 copyrights 1417 _AddPackageCredit(PackageCredit("bzip2") 1418 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-2005 Julian R " 1419 "Seward. All rights reserved.")) 1420 .SetLicense(B_TRANSLATE("BSD (4-clause)")) 1421 .SetURL("http://bzip.org")); 1422 1423 // lp_solve copyrights 1424 _AddPackageCredit(PackageCredit("lp_solve") 1425 .SetCopyright(COPYRIGHT_STRING 1426 "Michel Berkelaar, Kjell Eikland, Peter Notebaert") 1427 .SetLicense("GNU LGPL v2.1") 1428 .SetURL("http://lpsolve.sourceforge.net/")); 1429 1430 // OpenEXR copyrights 1431 _AddPackageCredit(PackageCredit("OpenEXR") 1432 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2005 Industrial " 1433 "Light & Magic, a division of Lucas Digital Ltd. LLC.")) 1434 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1435 .SetURL("http://www.openexr.com")); 1436 1437 // Bullet copyrights 1438 _AddPackageCredit(PackageCredit("Bullet") 1439 .SetCopyright(COPYRIGHT_STRING "2003-2008 Erwin Coumans") 1440 .SetLicense("Bullet") 1441 .SetURL("http://www.bulletphysics.com")); 1442 1443 // atftp copyrights 1444 _AddPackageCredit(PackageCredit("atftp") 1445 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2000 Jean-Pierre " 1446 "ervbefeL and Remi Lefebvre.")) 1447 .SetLicense("GNU GPL v2") 1448 .SetURL("http://freecode.com/projects/atftp")); 1449 1450 // Netcat copyrights 1451 _AddPackageCredit(PackageCredit("Netcat") 1452 .SetCopyright(COPYRIGHT_STRING "1996 Hobbit.") 1453 .SetLicense("Public Domain") 1454 .SetURL("http://nc110.sourceforge.net/")); 1455 1456 // acpica copyrights 1457 _AddPackageCredit(PackageCredit("acpica") 1458 .SetCopyright(COPYRIGHT_STRING "1999-2006 Intel Corp.") 1459 .SetLicense("Intel (ACPICA)") 1460 .SetURL("http://www.acpica.org")); 1461 1462 // unrar copyrights 1463 _AddPackageCredit(PackageCredit("unrar") 1464 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2008 Alexander " 1465 "L. Roshal. All rights reserved.")) 1466 .SetLicense("UnRAR") 1467 .SetURL("http://www.rarlab.com")); 1468 1469 // libpng copyrights 1470 _AddPackageCredit(PackageCredit("libpng") 1471 .SetCopyright(COPYRIGHT_STRING "2004, 2006-2008 Glenn " 1472 "Randers-Pehrson.") 1473 .SetLicense("LibPNG") 1474 .SetURL("http://www.libpng.org")); 1475 1476 // libjpeg copyrights 1477 _AddPackageCredit(PackageCredit("libjpeg") 1478 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1994-2009, Thomas G. " 1479 "Lane, Guido Vollbeding. This software is based in part on the " 1480 "work of the Independent JPEG Group.")) 1481 .SetLicense("LibJPEG") 1482 .SetURL("http://www.ijg.org")); 1483 1484 // libprint copyrights 1485 _AddPackageCredit(PackageCredit("libprint") 1486 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2000 Y.Takagi. " 1487 "All rights reserved."))); 1488 // TODO: License! 1489 1490 // cortex copyrights 1491 _AddPackageCredit(PackageCredit("Cortex") 1492 .SetCopyright(COPYRIGHT_STRING "1999-2000 Eric Moon.") 1493 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1494 .SetURL("http://cortex.sourceforge.net/documentation")); 1495 1496 // FluidSynth copyrights 1497 _AddPackageCredit(PackageCredit("FluidSynth") 1498 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003 Peter Hanappe " 1499 "and others.")) 1500 .SetLicense("GNU LGPL v2") 1501 .SetURL("http://www.fluidsynth.org")); 1502 1503 // CannaIM copyrights 1504 _AddPackageCredit(PackageCredit("CannaIM") 1505 .SetCopyright(COPYRIGHT_STRING "1999 Masao Kawamura.") 1506 .SetLicense("MIT")); 1507 1508 // libxml2, libxslt, libexslt copyrights 1509 _AddPackageCredit(PackageCredit("libxml2, libxslt") 1510 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1998-2003 Daniel Veillard. " 1511 "All rights reserved.")) 1512 .SetLicense(B_TRANSLATE("MIT (no promotion)")) 1513 .SetURL("http://xmlsoft.org")); 1514 1515 _AddPackageCredit(PackageCredit("libexslt") 1516 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2001-2002 Thomas Broyer, " 1517 "Charlie Bozeman and Daniel Veillard. All rights reserved.")) 1518 .SetLicense(B_TRANSLATE("MIT (no promotion)")) 1519 .SetURL("http://xmlsoft.org")); 1520 1521 // Xiph.org Foundation copyrights 1522 _AddPackageCredit(PackageCredit("Xiph.org Foundation") 1523 .SetCopyrights("libvorbis, libogg, libtheora, libspeex", 1524 B_TRANSLATE(COPYRIGHT_STRING "1994-2008 Xiph.Org. " 1525 "All rights reserved."), NULL) 1526 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1527 .SetURL("http://www.xiph.org")); 1528 1529 // The Tcpdump Group 1530 _AddPackageCredit(PackageCredit("The Tcpdump Group") 1531 .SetCopyright("tcpdump, libpcap") 1532 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1533 .SetURL("http://www.tcpdump.org")); 1534 1535 // Matroska 1536 _AddPackageCredit(PackageCredit("libmatroska") 1537 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2003 Steve Lhomme. " 1538 "All rights reserved.")) 1539 .SetLicense("GNU LGPL v2.1") 1540 .SetURL("http://www.matroska.org")); 1541 1542 // BColorQuantizer (originally CQuantizer code) 1543 _AddPackageCredit(PackageCredit("CQuantizer") 1544 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1996-1997 Jeff Prosise. " 1545 "All rights reserved.")) 1546 .SetLicense("CQuantizer") 1547 .SetURL("http://www.xdp.it")); 1548 1549 // MAPM (Mike's Arbitrary Precision Math Library) used by DeskCalc 1550 _AddPackageCredit(PackageCredit("MAPM") 1551 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1999-2007 Michael C. " 1552 "Ring. All rights reserved.")) 1553 .SetLicense("MAPM") 1554 .SetURL("http://tc.umn.edu/~ringx004")); 1555 1556 // MkDepend 1.7 copyright (Makefile dependency generator) 1557 _AddPackageCredit(PackageCredit("MkDepend") 1558 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995-2001 Lars Düning. " 1559 "All rights reserved.")) 1560 .SetLicense("MkDepend") 1561 .SetURL("http://bearnip.com/lars/be")); 1562 1563 // libhttpd copyright (used as Poorman backend) 1564 _AddPackageCredit(PackageCredit("libhttpd") 1565 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "1995, 1998-2001 " 1566 "Jef Poskanzer. All rights reserved.")) 1567 .SetLicense("LibHTTPd") 1568 .SetURL("http://www.acme.com/software/thttpd/")); 1569 1570 #ifdef __INTEL__ 1571 // Udis86 copyrights 1572 _AddPackageCredit(PackageCredit("Udis86") 1573 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2002-2004 " 1574 "Vivek Mohan. All rights reserved.")) 1575 .SetLicense(B_TRANSLATE("BSD (2-clause)")) 1576 .SetURL("http://udis86.sourceforge.net")); 1577 #endif 1578 1579 #ifdef __INTEL__ 1580 // Intel PRO/Wireless 2100 Firmware 1581 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2100 Firmware") 1582 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2003-2006 " 1583 "Intel Corporation. All rights reserved.")) 1584 .SetLicense("Intel (2xxx firmware)") 1585 .SetURL("http://ipw2100.sourceforge.net/")); 1586 #endif 1587 1588 #ifdef __INTEL__ 1589 // Intel PRO/Wireless 2200BG Firmware 1590 _AddPackageCredit(PackageCredit("Intel PRO/Wireless 2200BG Firmware") 1591 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2004-2005 " 1592 "Intel Corporation. All rights reserved.")) 1593 .SetLicense("Intel (2xxx firmware)") 1594 .SetURL("http://ipw2200.sourceforge.net/")); 1595 #endif 1596 1597 #ifdef __INTEL__ 1598 // Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware 1599 _AddPackageCredit( 1600 PackageCredit( 1601 "Intel PRO/Wireless 3945ABG/BG Network Connection Adapter Firmware") 1602 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2007 " 1603 "Intel Corporation. All rights reserved.")) 1604 .SetLicense("Intel (firmware)") 1605 .SetURL("http://www.intellinuxwireless.org/")); 1606 #endif 1607 #ifdef __INTEL__ 1608 // Intel Wireless WiFi Link 4965AGN Adapter Firmware 1609 _AddPackageCredit( 1610 PackageCredit("Intel Wireless WiFi Link 4965AGN Adapter Firmware") 1611 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2006-2007 " 1612 "Intel Corporation. All rights reserved.")) 1613 .SetLicense("Intel (firmware)") 1614 .SetURL("http://www.intellinuxwireless.org/")); 1615 #endif 1616 1617 #ifdef __INTEL__ 1618 // Marvell 88w8363 1619 _AddPackageCredit(PackageCredit("Marvell 88w8363") 1620 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007-2009 " 1621 "Marvell Semiconductor, Inc. All rights reserved.")) 1622 .SetLicense("Marvell (firmware)") 1623 .SetURL("http://www.marvell.com/")); 1624 #endif 1625 1626 #ifdef __INTEL__ 1627 // Ralink Firmware RT2501/RT2561/RT2661 1628 _AddPackageCredit(PackageCredit("Ralink Firmware RT2501/RT2561/RT2661") 1629 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING "2007 " 1630 "Ralink Technology Corporation. All rights reserved.")) 1631 .SetLicense("Ralink (firmware)") 1632 .SetURL("http://www.ralinktech.com/")); 1633 #endif 1634 1635 // Gutenprint 1636 _AddPackageCredit(PackageCredit("Gutenprint") 1637 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1638 "1999-2010 by the authors of Gutenprint. All rights reserved.")) 1639 .SetLicense("GNU GPL v2") 1640 .SetURL("http://gutenprint.sourceforge.net/")); 1641 1642 // libwebp 1643 _AddPackageCredit(PackageCredit("libwebp") 1644 .SetCopyright(B_TRANSLATE(COPYRIGHT_STRING 1645 "2010-2011 Google Inc. All rights reserved.")) 1646 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1647 .SetURL("http://www.webmproject.org/code/#libwebp_webp_image_library")); 1648 1649 // GTF 1650 _AddPackageCredit(PackageCredit("GTF") 1651 .SetCopyright(B_TRANSLATE("2001 by Andy Ritger based on the " 1652 "Generalized Timing Formula")) 1653 .SetLicense(B_TRANSLATE("BSD (3-clause)")) 1654 .SetURL("http://gtf.sourceforge.net/")); 1655 1656 _AddCopyrightsFromAttribute(); 1657 _AddPackageCreditEntries(); 1658 1659 return new CropView(creditsScroller, 0, 1, 1, 1); 1660 } 1661 1662 1663 status_t 1664 AboutView::_GetLicensePath(const char* license, BPath& path) 1665 { 1666 static const directory_which directoryConstants[] = { 1667 B_USER_DATA_DIRECTORY, 1668 B_COMMON_DATA_DIRECTORY, 1669 B_SYSTEM_DATA_DIRECTORY 1670 }; 1671 static const int dirCount = 3; 1672 1673 for (int i = 0; i < dirCount; i++) { 1674 struct stat st; 1675 status_t error = find_directory(directoryConstants[i], &path); 1676 if (error == B_OK && path.Append("licenses") == B_OK 1677 && path.Append(license) == B_OK 1678 && lstat(path.Path(), &st) == 0) { 1679 return B_OK; 1680 } 1681 } 1682 1683 path.Unset(); 1684 return B_ENTRY_NOT_FOUND; 1685 } 1686 1687 1688 void 1689 AboutView::_AddCopyrightsFromAttribute() 1690 { 1691 #ifdef __HAIKU__ 1692 // open the app executable file 1693 char appPath[B_PATH_NAME_LENGTH]; 1694 int appFD; 1695 if (BPrivate::get_app_path(appPath) != B_OK 1696 || (appFD = open(appPath, O_RDONLY)) < 0) { 1697 return; 1698 } 1699 1700 // open the attribute 1701 int attrFD = fs_fopen_attr(appFD, "COPYRIGHTS", B_STRING_TYPE, O_RDONLY); 1702 close(appFD); 1703 if (attrFD < 0) 1704 return; 1705 1706 // attach it to a FILE 1707 FILE* attrFile = fdopen(attrFD, "r"); 1708 if (attrFile == NULL) { 1709 close(attrFD); 1710 return; 1711 } 1712 CObjectDeleter<FILE, int> _(attrFile, fclose); 1713 1714 // read and parse the copyrights 1715 BMessage package; 1716 BString fieldName; 1717 BString fieldValue; 1718 char lineBuffer[LINE_MAX]; 1719 while (char* line = fgets(lineBuffer, sizeof(lineBuffer), attrFile)) { 1720 // chop off line break 1721 size_t lineLen = strlen(line); 1722 if (lineLen > 0 && line[lineLen - 1] == '\n') 1723 line[--lineLen] = '\0'; 1724 1725 // flush previous field, if a new field begins, otherwise append 1726 if (lineLen == 0 || !isspace(line[0])) { 1727 // new field -- flush the previous one 1728 if (fieldName.Length() > 0) { 1729 fieldValue = trim_string(fieldValue.String(), 1730 fieldValue.Length()); 1731 package.AddString(fieldName.String(), fieldValue); 1732 fieldName = ""; 1733 } 1734 } else if (fieldName.Length() > 0) { 1735 // append to current field 1736 fieldValue += line; 1737 continue; 1738 } else { 1739 // bogus line -- ignore 1740 continue; 1741 } 1742 1743 if (lineLen == 0) 1744 continue; 1745 1746 // parse new field 1747 char* colon = strchr(line, ':'); 1748 if (colon == NULL) { 1749 // bogus line -- ignore 1750 continue; 1751 } 1752 1753 fieldName.SetTo(line, colon - line); 1754 fieldName = trim_string(line, colon - line); 1755 if (fieldName.Length() == 0) { 1756 // invalid field name 1757 continue; 1758 } 1759 1760 fieldValue = colon + 1; 1761 1762 if (fieldName == "Package") { 1763 // flush the current package 1764 _AddPackageCredit(PackageCredit(package)); 1765 package.MakeEmpty(); 1766 } 1767 } 1768 1769 // flush current package 1770 _AddPackageCredit(PackageCredit(package)); 1771 #endif 1772 } 1773 1774 1775 void 1776 AboutView::_AddPackageCreditEntries() 1777 { 1778 // sort the packages case-insensitively 1779 PackageCredit* packages[fPackageCredits.size()]; 1780 int32 count = 0; 1781 for (PackageCreditMap::iterator it = fPackageCredits.begin(); 1782 it != fPackageCredits.end(); ++it) { 1783 packages[count++] = it->second; 1784 } 1785 1786 if (count > 1) { 1787 std::sort(packages, packages + count, 1788 &PackageCredit::NameLessInsensitive); 1789 } 1790 1791 // add the credits 1792 for (int32 i = 0; i < count; i++) { 1793 PackageCredit* package = packages[i]; 1794 1795 BString text(package->CopyrightAt(0)); 1796 int32 count = package->CountCopyrights(); 1797 for (int32 i = 1; i < count; i++) 1798 text << "\n" << package->CopyrightAt(i); 1799 1800 AddCopyrightEntry(package->PackageName(), text.String(), 1801 package->Licenses(), package->Sources(), package->URL()); 1802 } 1803 } 1804 1805 1806 void 1807 AboutView::_AddPackageCredit(const PackageCredit& package) 1808 { 1809 if (!package.IsValid()) 1810 return; 1811 1812 PackageCreditMap::iterator it = fPackageCredits.find(package.PackageName()); 1813 if (it != fPackageCredits.end()) { 1814 // If the new package credit isn't "better" than the old one, ignore it. 1815 PackageCredit* oldPackage = it->second; 1816 if (!package.IsBetterThan(*oldPackage)) 1817 return; 1818 1819 // replace the old credit 1820 fPackageCredits.erase(it); 1821 delete oldPackage; 1822 } 1823 1824 fPackageCredits[package.PackageName()] = new PackageCredit(package); 1825 } 1826 1827 1828 // #pragma mark - 1829 1830 1831 static const char* 1832 MemSizeToString(char string[], size_t size, system_info* info) 1833 { 1834 int inaccessibleMemory = int(info->ignored_pages 1835 * (B_PAGE_SIZE / 1048576.0f) + 0.5f); 1836 if (inaccessibleMemory > 0) { 1837 BString message(B_TRANSLATE("%total MiB total, %inaccessible MiB " 1838 "inaccessible")); 1839 1840 snprintf(string, size, "%d", int((info->max_pages 1841 + info->ignored_pages) * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1842 message.ReplaceFirst("%total", string); 1843 1844 snprintf(string, size, "%d", inaccessibleMemory); 1845 message.ReplaceFirst("%inaccessible", string); 1846 strncpy(string, message.String(), size); 1847 } else { 1848 snprintf(string, size, B_TRANSLATE("%d MiB total"), 1849 int(info->max_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f)); 1850 } 1851 1852 return string; 1853 } 1854 1855 1856 static const char* 1857 MemUsageToString(char string[], size_t size, system_info* info) 1858 { 1859 snprintf(string, size, B_TRANSLATE("%d MiB used (%d%%)"), 1860 int(info->used_pages * (B_PAGE_SIZE / 1048576.0f) + 0.5f), 1861 int(100 * info->used_pages / info->max_pages)); 1862 1863 return string; 1864 } 1865 1866 1867 static const char* 1868 UptimeToString(char string[], size_t size) 1869 { 1870 BDurationFormat formatter; 1871 BString str; 1872 1873 bigtime_t uptime = system_time(); 1874 bigtime_t now = (bigtime_t)time(NULL) * 1000000; 1875 formatter.Format(now - uptime, now, &str); 1876 str.CopyInto(string, 0, size); 1877 string[std::min((size_t)str.Length(), size)] = '\0'; 1878 1879 return string; 1880 } 1881 1882 1883 int 1884 main() 1885 { 1886 AboutApp app; 1887 app.Run(); 1888 return 0; 1889 } 1890 1891