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