Files
haiku-beta6/src/apps/installer/PackageViews.cpp
T
Jérôme Duval 9f3d8cb64f code style update
now mount the target partition before copying


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21113 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-05-12 13:37:02 +00:00

285 lines
6.0 KiB
C++

/*
* Copyright 2005, Jérôme DUVAL. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <fs_attr.h>
#include <Directory.h>
#include <Entry.h>
#include <Messenger.h>
#include <ScrollBar.h>
#include <String.h>
#include <stdio.h>
#include <View.h>
#include "PackageViews.h"
#include "InstallerWindow.h"
#define ICON_ATTRIBUTE "INSTALLER PACKAGE: ICON"
void SizeAsString(off_t size, char *string);
void
SizeAsString(off_t size, char *string)
{
double kb = size / 1024.0;
if (kb < 1.0) {
sprintf(string, "%Ld B", size);
return;
}
float mb = kb / 1024.0;
if (mb < 1.0) {
sprintf(string, "%3.1f KB", kb);
return;
}
float gb = mb / 1024.0;
if (gb < 1.0) {
sprintf(string, "%3.1f MB", mb);
return;
}
float tb = gb / 1024.0;
if (tb < 1.0) {
sprintf(string, "%3.1f GB", gb);
return;
}
sprintf(string, "%.1f TB", tb);
}
Package::Package(const char *folder)
: Group(),
fSize(0),
fIcon(NULL)
{
SetFolder(folder);
}
Package::~Package()
{
delete fIcon;
}
Package *
Package::PackageFromEntry(BEntry &entry)
{
char folder[B_FILE_NAME_LENGTH];
entry.GetName(folder);
BDirectory directory(&entry);
if (directory.InitCheck() != B_OK)
return NULL;
Package *package = new Package(folder);
bool alwaysOn;
bool onByDefault;
int32 size;
char group[64];
memset(group, 0, 64);
if (directory.ReadAttr("INSTALLER PACKAGE: NAME", B_STRING_TYPE, 0, package->fName, 64) < 0)
goto err;
if (directory.ReadAttr("INSTALLER PACKAGE: GROUP", B_STRING_TYPE, 0, group, 64) < 0)
goto err;
if (directory.ReadAttr("INSTALLER PACKAGE: DESCRIPTION", B_STRING_TYPE, 0, package->fDescription, 64) < 0)
goto err;
if (directory.ReadAttr("INSTALLER PACKAGE: ON_BY_DEFAULT", B_BOOL_TYPE, 0, &onByDefault, sizeof(onByDefault)) < 0)
goto err;
if (directory.ReadAttr("INSTALLER PACKAGE: ALWAYS_ON", B_BOOL_TYPE, 0, &alwaysOn, sizeof(alwaysOn)) < 0)
goto err;
if (directory.ReadAttr("INSTALLER PACKAGE: SIZE", B_INT32_TYPE, 0, &size, sizeof(size)) < 0)
goto err;
package->SetGroupName(group);
package->SetSize(size);
package->SetAlwaysOn(alwaysOn);
package->SetOnByDefault(onByDefault);
attr_info info;
if (directory.GetAttrInfo(ICON_ATTRIBUTE, &info) == B_OK) {
char buffer[info.size];
BMessage msg;
if ((directory.ReadAttr(ICON_ATTRIBUTE, info.type, 0, buffer, info.size) == info.size)
&& (msg.Unflatten(buffer) == B_OK)) {
package->SetIcon(new BBitmap(&msg));
}
}
return package;
err:
delete package;
return NULL;
}
void
Package::GetSizeAsString(char *string)
{
SizeAsString(fSize, string);
}
Group::Group()
{
}
Group::~Group()
{
}
PackageCheckBox::PackageCheckBox(BRect rect, Package *item)
: BCheckBox(rect.OffsetBySelf(7, 0), "pack_cb", item->Name(), NULL),
fPackage(item)
{
}
PackageCheckBox::~PackageCheckBox()
{
delete fPackage;
}
void
PackageCheckBox::Draw(BRect update)
{
BCheckBox::Draw(update);
char string[15];
fPackage->GetSizeAsString(string);
float width = StringWidth(string);
DrawString(string, BPoint(Bounds().right - width - 8, 11));
const BBitmap *icon = fPackage->Icon();
if (icon)
DrawBitmap(icon, BPoint(Bounds().right - 92, 0));
}
void
PackageCheckBox::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
{
printf("%s called\n", __PRETTY_FUNCTION__);
if (transit == B_ENTERED_VIEW) {
BMessage msg(STATUS_MESSAGE);
msg.AddString("status", fPackage->Description());
BMessenger(NULL, Window()).SendMessage(&msg);
} else if (transit == B_EXITED_VIEW) {
BMessage msg(STATUS_MESSAGE);
BMessenger(NULL, Window()).SendMessage(&msg);
}
}
GroupView::GroupView(BRect rect, Group *group)
: BStringView(rect, "group", group->GroupName()),
fGroup(group)
{
SetFont(be_bold_font);
}
GroupView::~GroupView()
{
delete fGroup;
}
PackagesView::PackagesView(BRect rect, const char* name)
: BView(rect, name, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS)
{
}
PackagesView::~PackagesView()
{
}
void
PackagesView::Clean()
{
BView *view;
while ((view = ChildAt(0))) {
if (dynamic_cast<GroupView*>(view) || dynamic_cast<PackageCheckBox*>(view)) {
RemoveChild(view);
delete view;
}
}
ScrollTo(0, 0);
}
void
PackagesView::AddPackages(BList &packages, BMessage *msg)
{
int32 count = packages.CountItems();
BRect rect = Bounds();
BRect bounds = rect;
rect.left = 1;
rect.bottom = 15;
rect.top = 0;
BString lastGroup = "";
for (int32 i = 0; i < count; i++) {
void *item = packages.ItemAt(i);
Package *package = static_cast<Package *>(item);
if (lastGroup != BString(package->GroupName())) {
rect.OffsetBy(0, 1);
lastGroup = package->GroupName();
Group *group = new Group();
group->SetGroupName(package->GroupName());
GroupView *view = new GroupView(rect, group);
AddChild(view);
rect.OffsetBy(0, 17);
}
PackageCheckBox *checkBox = new PackageCheckBox(rect, package);
checkBox->SetValue(package->OnByDefault() ? B_CONTROL_ON : B_CONTROL_OFF);
checkBox->SetEnabled(!package->AlwaysOn());
checkBox->SetMessage(new BMessage(*msg));
AddChild(checkBox);
rect.OffsetBy(0, 20);
}
ResizeTo(bounds.Width(), rect.top);
BScrollBar *vertScroller = ScrollBar(B_VERTICAL);
if (vertScroller->Bounds().Height() > rect.top) {
vertScroller->SetRange(0.0f, 0.0f);
vertScroller->SetValue(0.0f);
} else {
vertScroller->SetRange(0.0f, rect.top - vertScroller->Bounds().Height());
vertScroller->SetProportion(vertScroller->Bounds().Height() / rect.top);
}
vertScroller->SetSteps(15, vertScroller->Bounds().Height());
Invalidate();
}
void
PackagesView::GetTotalSizeAsString(char *string)
{
int32 count = CountChildren();
int32 size = 0;
for (int32 i = 0; i < count; i++) {
PackageCheckBox *cb = dynamic_cast<PackageCheckBox*>(ChildAt(i));
if (cb && cb->Value())
size += cb->GetPackage()->Size();
}
SizeAsString(size, string);
}
void
PackagesView::GetPackagesToInstall(BList *list, int32 *size)
{
int32 count = CountChildren();
*size = 0;
for (int32 i = 0; i < count; i++) {
PackageCheckBox *cb = dynamic_cast<PackageCheckBox*>(ChildAt(i));
if (cb && cb->Value()) {
list->AddItem(cb->GetPackage());
*size += cb->GetPackage()->Size();
}
}
}