/* * Copyright 2009, Stephan Aßmus * Copyright 2005, Jérôme DUVAL. * All rights reserved. Distributed under the terms of the MIT License. */ #include "PackageViews.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "InstallerDefs.h" #include "StringForSize.h" #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "PackagesView" #define ICON_ATTRIBUTE "INSTALLER PACKAGE: ICON" Package::Package(const BPath &path) : Group(), fSize(0), fIcon(NULL) { SetPath(path); } Package::~Package() { delete fIcon; } Package * Package::PackageFromEntry(BEntry &entry) { BPath path; entry.GetPath(&path); BPackageKit::BPackageInfo info; info.ReadFromPackageFile(path.Path()); if (info.InitCheck() != B_OK) return NULL; Package *package = new Package(path); package->fName = info.Name(); package->fDescription = info.Summary(); bool alwaysOn = false; bool onByDefault = true; off_t size = 0; entry.GetSize(&size); char group[64]; memset(group, 0, 64); BNode node(&entry); // FIXME enable these when the attributes on the packages are actually // populated by the buildsystem. For now, assume everything is // on-by-default and optional, and have no groups. #if 0 if (node.ReadAttr("INSTALLER PACKAGE: GROUP", B_STRING_TYPE, 0, group, 64) < 0) { goto err; } if (node.ReadAttr("INSTALLER PACKAGE: ON_BY_DEFAULT", B_BOOL_TYPE, 0, &onByDefault, sizeof(onByDefault)) < 0) { goto err; } if (node.ReadAttr("INSTALLER PACKAGE: ALWAYS_ON", B_BOOL_TYPE, 0, &alwaysOn, sizeof(alwaysOn)) < 0) { goto err; } #endif package->SetGroupName(group); package->SetSize(size); package->SetAlwaysOn(alwaysOn); package->SetOnByDefault(onByDefault); attr_info attributes; if (node.GetAttrInfo(ICON_ATTRIBUTE, &attributes) == B_OK) { char buffer[attributes.size]; BMessage msg; if ((node.ReadAttr(ICON_ATTRIBUTE, attributes.type, 0, buffer, attributes.size) == attributes.size) && (msg.Unflatten(buffer) == B_OK)) { package->SetIcon(new BBitmap(&msg)); } } return package; #if 0 err: #endif delete package; return NULL; } void Package::GetSizeAsString(char* string, size_t stringSize) { string_for_size(fSize, string, stringSize); } Group::Group() { } Group::~Group() { } PackageCheckBox::PackageCheckBox(Package *item) : BCheckBox("pack_cb", item->Name(), NULL), fPackage(item) { SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE); SetIcon(fPackage->Icon()); } PackageCheckBox::~PackageCheckBox() { delete fPackage; } void PackageCheckBox::Draw(BRect update) { BCheckBox::Draw(update); // Draw the label char string[15]; fPackage->GetSizeAsString(string, sizeof(string)); float width = StringWidth(string); BRect sizeRect = Bounds(); sizeRect.left = sizeRect.right - width; be_control_look->DrawLabel(this, string, NULL, sizeRect, update, ui_color(B_DOCUMENT_BACKGROUND_COLOR), be_control_look->Flags(this)); } void PackageCheckBox::MouseMoved(BPoint point, uint32 transit, const BMessage* dragMessage) { if (transit == B_ENTERED_VIEW) { BMessage msg(MSG_STATUS_MESSAGE); msg.AddString("status", fPackage->Description()); BMessenger(NULL, Window()).SendMessage(&msg); } else if (transit == B_EXITED_VIEW) { BMessage msg(MSG_STATUS_MESSAGE); BMessenger(NULL, Window()).SendMessage(&msg); } } GroupView::GroupView(Group *group) : BStringView("group", group->GroupName()), fGroup(group) { SetFont(be_bold_font); } GroupView::~GroupView() { delete fGroup; } // #pragma mark - PackagesView::PackagesView(const char* name) : BView(name, B_WILL_DRAW) { BGroupLayout* layout = new BGroupLayout(B_VERTICAL); layout->SetSpacing(0); layout->SetInsets(B_USE_SMALL_SPACING, 0); SetLayout(layout); SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR); SetExplicitMinSize(BSize(B_SIZE_UNSET, 80)); } PackagesView::~PackagesView() { } void PackagesView::Clean() { BView* view; while ((view = ChildAt(0))) { if (dynamic_cast(view) || dynamic_cast(view)) { RemoveChild(view); delete view; } } ScrollTo(0, 0); BView* parent = Parent(); BRect r = parent->Bounds(); parent->FrameResized(r.Width(), r.Height()); } void PackagesView::AddPackages(BList& packages, BMessage* msg) { int32 count = packages.CountItems(); BString lastGroup = ""; for (int32 i = 0; i < count; i++) { void* item = packages.ItemAt(i); Package* package = static_cast(item); if (lastGroup != BString(package->GroupName())) { lastGroup = package->GroupName(); Group* group = new Group(); group->SetGroupName(package->GroupName()); GroupView *view = new GroupView(group); AddChild(view); } PackageCheckBox* checkBox = new PackageCheckBox(package); checkBox->SetValue(package->OnByDefault() ? B_CONTROL_ON : B_CONTROL_OFF); checkBox->SetEnabled(!package->AlwaysOn()); checkBox->SetMessage(new BMessage(*msg)); AddChild(checkBox); } Invalidate(); // Force scrollbars to update BView* parent = Parent(); BRect r = parent->Bounds(); parent->FrameResized(r.Width(), r.Height()); } void PackagesView::GetTotalSizeAsString(char* string, size_t stringSize) { int32 count = CountChildren(); int32 size = 0; for (int32 i = 0; i < count; i++) { PackageCheckBox* cb = dynamic_cast(ChildAt(i)); if (cb && cb->Value()) size += cb->GetPackage()->Size(); } string_for_size(size, string, stringSize); } void PackagesView::GetPackagesToInstall(BList* list, int32* size) { int32 count = CountChildren(); *size = 0; for (int32 i = 0; i < count; i++) { PackageCheckBox* cb = dynamic_cast(ChildAt(i)); if (cb && cb->Value()) { list->AddItem(cb->GetPackage()); *size += cb->GetPackage()->Size(); } } } void PackagesView::Draw(BRect updateRect) { if (CountChildren() > 0) return; be_control_look->DrawLabel(this, B_TRANSLATE("No optional packages available."), Bounds(), updateRect, ViewColor(), BControlLook::B_DISABLED, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE)); }