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.
7 #include "PackageViews.h"
12 #include <ControlLook.h>
13 #include <Directory.h>
16 #include <LayoutUtils.h>
18 #include <Messenger.h>
19 #include <ScrollBar.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
)
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
)
58 Package
*package
= new Package(folder
);
64 if (directory
.ReadAttr("INSTALLER PACKAGE: NAME", B_STRING_TYPE
, 0,
65 package
->fName
, 64) < 0) {
68 if (directory
.ReadAttr("INSTALLER PACKAGE: GROUP", B_STRING_TYPE
, 0,
72 if (directory
.ReadAttr("INSTALLER PACKAGE: DESCRIPTION", B_STRING_TYPE
, 0,
73 package
->fDescription
, 64) < 0) {
76 if (directory
.ReadAttr("INSTALLER PACKAGE: ON_BY_DEFAULT", B_BOOL_TYPE
, 0,
77 &onByDefault
, sizeof(onByDefault
)) < 0) {
80 if (directory
.ReadAttr("INSTALLER PACKAGE: ALWAYS_ON", B_BOOL_TYPE
, 0,
81 &alwaysOn
, sizeof(alwaysOn
)) < 0) {
84 if (directory
.ReadAttr("INSTALLER PACKAGE: SIZE", B_INT32_TYPE
, 0,
85 &size
, sizeof(size
)) < 0) {
88 package
->SetGroupName(group
);
89 package
->SetSize(size
);
90 package
->SetAlwaysOn(alwaysOn
);
91 package
->SetOnByDefault(onByDefault
);
94 if (directory
.GetAttrInfo(ICON_ATTRIBUTE
, &info
) == B_OK
) {
95 char buffer
[info
.size
];
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
));
111 Package::GetSizeAsString(char* string
, size_t stringSize
)
113 string_for_size(fSize
, string
, stringSize
);
127 PackageCheckBox::PackageCheckBox(BRect rect
, Package
*item
)
129 BCheckBox(rect
.OffsetBySelf(7, 0), "pack_cb", item
->Name(), NULL
),
135 PackageCheckBox::~PackageCheckBox()
142 PackageCheckBox::Draw(BRect update
)
144 BCheckBox::Draw(update
);
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();
152 DrawBitmap(icon
, BPoint(Bounds().right
- 92, 0));
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()),
177 SetFont(be_bold_font
);
181 GroupView::~GroupView()
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()
211 PackagesView::Clean()
214 while ((view
= ChildAt(0))) {
215 if (dynamic_cast<GroupView
*>(view
)
216 || dynamic_cast<PackageCheckBox
*>(view
)) {
226 PackagesView::AddPackages(BList
& packages
, BMessage
* msg
)
228 int32 count
= packages
.CountItems();
229 BRect rect
= Bounds();
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())) {
240 lastGroup
= package
->GroupName();
241 Group
* group
= new Group();
242 group
->SetGroupName(package
->GroupName());
243 GroupView
*view
= new GroupView(rect
, group
);
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
));
253 rect
.OffsetBy(0, 20);
255 ResizeTo(bounds
.Width(), rect
.top
);
261 PackagesView::GetTotalSizeAsString(char* string
, size_t stringSize
)
263 int32 count
= CountChildren();
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
);
275 PackagesView::GetPackagesToInstall(BList
* list
, int32
* size
)
277 int32 count
= CountChildren();
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();
290 PackagesView::FrameResized(float width
, float height
)
292 if (CountChildren() == 0)
295 BScrollBar
* scrollBar
= ScrollBar(B_VERTICAL
);
296 if (scrollBar
== NULL
)
299 float virtualHeight
= 0.0;
301 int32 count
= CountChildren();
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
);
311 scrollBar
->SetRange(0.0f
, virtualHeight
- height
);
312 scrollBar
->SetProportion(height
/ virtualHeight
);
315 scrollBar
->SetSteps(15, height
);
320 PackagesView::Draw(BRect updateRect
)
322 if (CountChildren() > 0)
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
));
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...
346 PackagesView::MaxSize()
348 return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
349 BSize(B_SIZE_UNLIMITED
, B_SIZE_UNLIMITED
));