btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / installer / PackageViews.cpp
blob3987afd4f4d00f6cc8426cebf340bd6569518e78
1 /*
2 * Copyright 2009, Stephan Aßmus <superstippi@gmx.de>
3 * Copyright 2005, Jérôme DUVAL.
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
7 #include "PackageViews.h"
9 #include <stdio.h>
11 #include <Catalog.h>
12 #include <ControlLook.h>
13 #include <Directory.h>
14 #include <Entry.h>
15 #include <fs_attr.h>
16 #include <LayoutUtils.h>
17 #include <Locale.h>
18 #include <Messenger.h>
19 #include <ScrollBar.h>
20 #include <String.h>
21 #include <View.h>
22 #include <Window.h>
24 #include "InstallerDefs.h"
25 #include "StringForSize.h"
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "PackagesView"
31 #define ICON_ATTRIBUTE "INSTALLER PACKAGE: ICON"
34 Package::Package(const char *folder)
36 Group(),
37 fSize(0),
38 fIcon(NULL)
40 SetFolder(folder);
44 Package::~Package()
46 delete fIcon;
50 Package *
51 Package::PackageFromEntry(BEntry &entry)
53 char folder[B_FILE_NAME_LENGTH];
54 entry.GetName(folder);
55 BDirectory directory(&entry);
56 if (directory.InitCheck() != B_OK)
57 return NULL;
58 Package *package = new Package(folder);
59 bool alwaysOn;
60 bool onByDefault;
61 int32 size;
62 char group[64];
63 memset(group, 0, 64);
64 if (directory.ReadAttr("INSTALLER PACKAGE: NAME", B_STRING_TYPE, 0,
65 package->fName, 64) < 0) {
66 goto err;
68 if (directory.ReadAttr("INSTALLER PACKAGE: GROUP", B_STRING_TYPE, 0,
69 group, 64) < 0) {
70 goto err;
72 if (directory.ReadAttr("INSTALLER PACKAGE: DESCRIPTION", B_STRING_TYPE, 0,
73 package->fDescription, 64) < 0) {
74 goto err;
76 if (directory.ReadAttr("INSTALLER PACKAGE: ON_BY_DEFAULT", B_BOOL_TYPE, 0,
77 &onByDefault, sizeof(onByDefault)) < 0) {
78 goto err;
80 if (directory.ReadAttr("INSTALLER PACKAGE: ALWAYS_ON", B_BOOL_TYPE, 0,
81 &alwaysOn, sizeof(alwaysOn)) < 0) {
82 goto err;
84 if (directory.ReadAttr("INSTALLER PACKAGE: SIZE", B_INT32_TYPE, 0,
85 &size, sizeof(size)) < 0) {
86 goto err;
88 package->SetGroupName(group);
89 package->SetSize(size);
90 package->SetAlwaysOn(alwaysOn);
91 package->SetOnByDefault(onByDefault);
93 attr_info info;
94 if (directory.GetAttrInfo(ICON_ATTRIBUTE, &info) == B_OK) {
95 char buffer[info.size];
96 BMessage msg;
97 if ((directory.ReadAttr(ICON_ATTRIBUTE, info.type, 0, buffer,
98 info.size) == info.size)
99 && (msg.Unflatten(buffer) == B_OK)) {
100 package->SetIcon(new BBitmap(&msg));
103 return package;
104 err:
105 delete package;
106 return NULL;
110 void
111 Package::GetSizeAsString(char* string, size_t stringSize)
113 string_for_size(fSize, string, stringSize);
117 Group::Group()
122 Group::~Group()
127 PackageCheckBox::PackageCheckBox(BRect rect, Package *item)
129 BCheckBox(rect.OffsetBySelf(7, 0), "pack_cb", item->Name(), NULL),
130 fPackage(item)
135 PackageCheckBox::~PackageCheckBox()
137 delete fPackage;
141 void
142 PackageCheckBox::Draw(BRect update)
144 BCheckBox::Draw(update);
145 char string[15];
146 fPackage->GetSizeAsString(string, sizeof(string));
147 float width = StringWidth(string);
148 DrawString(string, BPoint(Bounds().right - width - 8, 11));
150 const BBitmap *icon = fPackage->Icon();
151 if (icon)
152 DrawBitmap(icon, BPoint(Bounds().right - 92, 0));
156 void
157 PackageCheckBox::MouseMoved(BPoint point, uint32 transit,
158 const BMessage* dragMessage)
160 printf("%s called\n", __PRETTY_FUNCTION__);
161 if (transit == B_ENTERED_VIEW) {
162 BMessage msg(MSG_STATUS_MESSAGE);
163 msg.AddString("status", fPackage->Description());
164 BMessenger(NULL, Window()).SendMessage(&msg);
165 } else if (transit == B_EXITED_VIEW) {
166 BMessage msg(MSG_STATUS_MESSAGE);
167 BMessenger(NULL, Window()).SendMessage(&msg);
172 GroupView::GroupView(BRect rect, Group *group)
174 BStringView(rect, "group", group->GroupName()),
175 fGroup(group)
177 SetFont(be_bold_font);
181 GroupView::~GroupView()
183 delete fGroup;
187 // #pragma mark -
190 PackagesView::PackagesView(BRect rect, const char* name)
192 BView(rect, name, B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS)
197 PackagesView::PackagesView(const char* name)
199 BView(name, B_WILL_DRAW | B_FRAME_EVENTS)
204 PackagesView::~PackagesView()
210 void
211 PackagesView::Clean()
213 BView* view;
214 while ((view = ChildAt(0))) {
215 if (dynamic_cast<GroupView*>(view)
216 || dynamic_cast<PackageCheckBox*>(view)) {
217 RemoveChild(view);
218 delete view;
221 ScrollTo(0, 0);
225 void
226 PackagesView::AddPackages(BList& packages, BMessage* msg)
228 int32 count = packages.CountItems();
229 BRect rect = Bounds();
230 BRect bounds = rect;
231 rect.left = 1;
232 rect.bottom = 15;
233 rect.top = 0;
234 BString lastGroup = "";
235 for (int32 i = 0; i < count; i++) {
236 void* item = packages.ItemAt(i);
237 Package* package = static_cast<Package*>(item);
238 if (lastGroup != BString(package->GroupName())) {
239 rect.OffsetBy(0, 1);
240 lastGroup = package->GroupName();
241 Group* group = new Group();
242 group->SetGroupName(package->GroupName());
243 GroupView *view = new GroupView(rect, group);
244 AddChild(view);
245 rect.OffsetBy(0, 17);
247 PackageCheckBox* checkBox = new PackageCheckBox(rect, package);
248 checkBox->SetValue(package->OnByDefault()
249 ? B_CONTROL_ON : B_CONTROL_OFF);
250 checkBox->SetEnabled(!package->AlwaysOn());
251 checkBox->SetMessage(new BMessage(*msg));
252 AddChild(checkBox);
253 rect.OffsetBy(0, 20);
255 ResizeTo(bounds.Width(), rect.top);
256 Invalidate();
260 void
261 PackagesView::GetTotalSizeAsString(char* string, size_t stringSize)
263 int32 count = CountChildren();
264 int32 size = 0;
265 for (int32 i = 0; i < count; i++) {
266 PackageCheckBox* cb = dynamic_cast<PackageCheckBox*>(ChildAt(i));
267 if (cb && cb->Value())
268 size += cb->GetPackage()->Size();
270 string_for_size(size, string, stringSize);
274 void
275 PackagesView::GetPackagesToInstall(BList* list, int32* size)
277 int32 count = CountChildren();
278 *size = 0;
279 for (int32 i = 0; i < count; i++) {
280 PackageCheckBox* cb = dynamic_cast<PackageCheckBox*>(ChildAt(i));
281 if (cb && cb->Value()) {
282 list->AddItem(cb->GetPackage());
283 *size += cb->GetPackage()->Size();
289 void
290 PackagesView::FrameResized(float width, float height)
292 if (CountChildren() == 0)
293 Invalidate();
295 BScrollBar* scrollBar = ScrollBar(B_VERTICAL);
296 if (scrollBar == NULL)
297 return;
299 float virtualHeight = 0.0;
301 int32 count = CountChildren();
302 if (count > 0) {
303 BView* child = ChildAt(count - 1);
304 virtualHeight = child->Frame().bottom;
307 if (height > virtualHeight) {
308 scrollBar->SetRange(0.0f, 0.0f);
309 scrollBar->SetValue(0.0f);
310 } else {
311 scrollBar->SetRange(0.0f, virtualHeight - height);
312 scrollBar->SetProportion(height / virtualHeight);
315 scrollBar->SetSteps(15, height);
319 void
320 PackagesView::Draw(BRect updateRect)
322 if (CountChildren() > 0)
323 return;
325 be_control_look->DrawLabel(this,
326 B_TRANSLATE("No optional packages available."),
327 Bounds(), updateRect, ViewColor(), BControlLook::B_DISABLED,
328 BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE));
332 void
333 PackagesView::GetPreferredSize(float* _width, float* _height)
335 // TODO: Something more nice as default? I need to see how this looks
336 // when there are actually any packages...
337 if (_width != NULL)
338 *_width = 400.0;
340 if (_height != NULL)
341 *_height = 80.0;
345 BSize
346 PackagesView::MaxSize()
348 return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
349 BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));