packageinstaller:

* Reworded info_prepare() for clarity. 
* info_get_package_version() and info_get_package_name() were returning
  memory from a local variable. They return an error code now, possibly
  from info_prepare().

installedpackages:
* Simplifications and refactoring.
* Improve the layout of the interface (using layout management).
* Fix coding style issues.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28145 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-10-15 16:12:08 +00:00
parent 8cca2102aa
commit 714c386ac3
6 changed files with 219 additions and 163 deletions
+156 -79
View File
@@ -6,18 +6,26 @@
* Łukasz 'Sil2100' Zemczak <[email protected]> * Łukasz 'Sil2100' Zemczak <[email protected]>
*/ */
#include "UninstallView.h" #include "UninstallView.h"
#include <Alert.h>
#include <String.h>
#include <Directory.h>
#include <File.h>
#include <Entry.h>
#include <Button.h>
#include <Box.h>
#include <StringView.h>
#include <NodeMonitor.h>
#include <FindDirectory.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <Alert.h>
#include <Box.h>
#include <Button.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <FindDirectory.h>
#include <NodeMonitor.h>
#include <String.h>
#include <StringView.h>
#ifdef __HAIKU__
# include <GroupLayout.h>
# include <GroupLayoutBuilder.h>
# include <SpaceLayoutItem.h>
#endif
enum { enum {
@@ -37,20 +45,27 @@ enum {
// - Add a status window (reuse the one from PackageInstall) // - Add a status window (reuse the one from PackageInstall)
static const char* kNoPackageSelected = "No package selected.";
class UninstallView::InfoItem : public BStringItem { class UninstallView::InfoItem : public BStringItem {
public: public:
InfoItem(const char *name, const char *version, node_ref ref) InfoItem(const BString& name, const BString& version,
: BStringItem(name), const char* filename, const node_ref& ref)
fVersion(version), : BStringItem(name.String()),
fNodeRef(ref) fName(name),
fVersion(version),
fNodeRef(ref)
{ {
if (fName.Length() == 0)
SetText(filename);
} }
const char * GetName() { return BStringItem::Text(); } const char* GetName() { return fName.String(); }
const char * GetVersion() { return fVersion.String(); }; const char* GetVersion() { return fVersion.String(); };
node_ref GetNodeRef() { return fNodeRef; }; node_ref GetNodeRef() { return fNodeRef; };
private: private:
BString fName;
BString fVersion; BString fVersion;
node_ref fNodeRef; node_ref fNodeRef;
}; };
@@ -67,8 +82,6 @@ UninstallView::UninstallView(BRect frame)
UninstallView::~UninstallView() UninstallView::~UninstallView()
{ {
_ClearAppList();
// Stop all node watching // Stop all node watching
stop_watching(this); stop_watching(this);
} }
@@ -97,8 +110,7 @@ UninstallView::AttachedToWindow()
fToPackages.GetParent(&path); fToPackages.GetParent(&path);
if (dir.SetTo(path.Path()) != B_OK) if (dir.SetTo(path.Path()) != B_OK)
return; return;
} } else
else
fWatcherRunning = true; fWatcherRunning = true;
dir.GetNodeRef(&ref); dir.GetNodeRef(&ref);
@@ -111,7 +123,7 @@ UninstallView::AttachedToWindow()
void void
UninstallView::MessageReceived(BMessage *msg) UninstallView::MessageReceived(BMessage* msg)
{ {
switch (msg->what) { switch (msg->what) {
case B_NODE_MONITOR: case B_NODE_MONITOR:
@@ -138,11 +150,8 @@ UninstallView::MessageReceived(BMessage *msg)
usleep(10000); usleep(10000);
if (fWatcherRunning) { if (fWatcherRunning) {
name = info_get_package_name(filename.String()); _AddFile(filename.String(), ref);
version = info_get_package_version(filename.String()); } else {
fAppList->AddItem(new InfoItem(name.String(), version.String(), ref));
}
else {
// This most likely means we were waiting for the packages/ dir // This most likely means we were waiting for the packages/ dir
// to appear // to appear
if (filename == "packages") { if (filename == "packages") {
@@ -150,8 +159,7 @@ UninstallView::MessageReceived(BMessage *msg)
fWatcherRunning = true; fWatcherRunning = true;
} }
} }
} } else if (opcode == B_ENTRY_REMOVED) {
else if (opcode == B_ENTRY_REMOVED) {
node_ref ref; node_ref ref;
if (msg->FindInt32("device", &ref.device) != B_OK || if (msg->FindInt32("device", &ref.device) != B_OK ||
msg->FindInt64("node", &ref.node) != B_OK) msg->FindInt64("node", &ref.node) != B_OK)
@@ -163,13 +171,12 @@ UninstallView::MessageReceived(BMessage *msg)
iter = static_cast<InfoItem *>(fAppList->ItemAt(i)); iter = static_cast<InfoItem *>(fAppList->ItemAt(i));
if (iter->GetNodeRef() == ref) { if (iter->GetNodeRef() == ref) {
if (i == fAppList->CurrentSelection()) if (i == fAppList->CurrentSelection())
fDescription->SetText(T("No package selected")); fDescription->SetText(T(kNoPackageSelected));
fAppList->RemoveItem(i); fAppList->RemoveItem(i);
delete iter; delete iter;
} }
} }
} } else if (opcode == B_ENTRY_MOVED) {
else if (opcode == B_ENTRY_MOVED) {
ino_t from, to; ino_t from, to;
if (msg->FindInt64("from directory", &from) != B_OK || if (msg->FindInt64("from directory", &from) != B_OK ||
msg->FindInt64("to directory", &to) != B_OK) msg->FindInt64("to directory", &to) != B_OK)
@@ -182,8 +189,7 @@ UninstallView::MessageReceived(BMessage *msg)
if (ref.node == to) { if (ref.node == to) {
// Package added // Package added
// TODO // TODO
} } else if (ref.node == from) {
else if (ref.node == from) {
// Package removed // Package removed
// TODO // TODO
} }
@@ -192,23 +198,27 @@ UninstallView::MessageReceived(BMessage *msg)
} }
case P_MSG_SELECT: case P_MSG_SELECT:
{ {
fButton->SetEnabled(false);
fDescription->SetText(T(kNoPackageSelected));
int32 index = fAppList->CurrentSelection(); int32 index = fAppList->CurrentSelection();
if (index < 0) if (index < 0)
break; break;
fprintf(stderr, "Another debug message...\n"); fprintf(stderr, "Another debug message...\n");
InfoItem *item = dynamic_cast<InfoItem *>(fAppList->ItemAt(index)); InfoItem* item = dynamic_cast<InfoItem*>(fAppList->ItemAt(index));
if (!item) if (!item)
break; break;
fprintf(stderr, "Uh: %s and %s\n", item->GetName(), item->GetVersion()); fprintf(stderr, "Uh: %s and %s\n", item->GetName(),
item->GetVersion());
if (fCurrentSelection.SetTo(item->GetName(), item->GetVersion()) != B_OK) if (fCurrentSelection.SetTo(item->GetName(),
item->GetVersion()) != B_OK)
break; break;
fprintf(stderr, " ...how much longer?\n"); fButton->SetEnabled(true);
fDescription->SetText(fCurrentSelection.GetDescription()); fDescription->SetText(fCurrentSelection.GetDescription());
break; break;
} }
@@ -221,24 +231,23 @@ UninstallView::MessageReceived(BMessage *msg)
if (index < 0) if (index < 0)
break; break;
BAlert *notify; BAlert* notify;
if (fCurrentSelection.Uninstall() == B_OK) { if (fCurrentSelection.Uninstall() == B_OK) {
BListItem *item = static_cast<BListItem *>(fAppList->ItemAt(index)); BListItem* item = fAppList->RemoveItem(index);
fAppList->RemoveItem(index);
delete item; delete item;
fDescription->SetText(T("No package selected")); fDescription->SetText(T(kNoPackageSelected));
notify = new BAlert("removal_success", notify = new BAlert("removal_success",
T("The package you selected has been successfully removed " T("The package you selected has been successfully removed "
"from your system."), T("OK")); "from your system."), T("OK"));
} } else {
else
notify = new BAlert("removal_failed", notify = new BAlert("removal_failed",
T("The selected package was not removed from your system. The " T("The selected package was not removed from your system. "
"given installed package information file might have been " "The given installed package information file might have "
"corrupted."), T("OK"), NULL, "been corrupted."), T("OK"), NULL,
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
}
notify->Go(); notify->Go();
} }
@@ -253,24 +262,78 @@ void
UninstallView::_InitView() UninstallView::_InitView()
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
#ifdef __HAIKU__
BBox* descriptionBox = new BBox(B_PLAIN_BORDER, NULL);
BGroupLayout* descriptionLayout = new BGroupLayout(B_VERTICAL, 5);
descriptionBox->SetLayout(descriptionLayout);
BBox* buttonBox = new BBox(B_PLAIN_BORDER, NULL);
BGroupLayout* buttonLayout = new BGroupLayout(B_HORIZONTAL, 5);
buttonBox->SetLayout(buttonLayout);
fAppList = new BListView("pkg_list", B_SINGLE_SELECTION_LIST);
fAppList->SetSelectionMessage(new BMessage(P_MSG_SELECT));
BScrollView* scrollView = new BScrollView("list_scroll", fAppList,
B_FOLLOW_NONE, 0, false, true, B_NO_BORDER);
BGroupLayout* scrollLayout = new BGroupLayout(B_HORIZONTAL);
scrollView->SetLayout(scrollLayout);
BStringView* descriptionLabel = new BStringView("desc_label",
T("Package description"));
descriptionLabel->SetFont(be_bold_font);
fDescription = new BTextView("description", B_WILL_DRAW);
fDescription->MakeSelectable(false);
fDescription->MakeEditable(false);
fDescription->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fDescription->SetText(T(kNoPackageSelected));
fButton = new BButton("removal", T("Remove"), new BMessage(P_MSG_REMOVE));
fButton->SetEnabled(false);
SetLayout(new BGroupLayout(B_HORIZONTAL));
AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
.Add(scrollView)
.Add(BGroupLayoutBuilder(descriptionLayout)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 0)
.Add(descriptionLabel)
.AddGlue()
)
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 0)
.Add(BSpaceLayoutItem::CreateHorizontalStrut(10))
.Add(fDescription)
)
.SetInsets(5, 5, 5, 5)
)
.Add(BGroupLayoutBuilder(buttonLayout)
.AddGlue()
.Add(fButton)
.SetInsets(5, 5, 5, 5)
)
);
#else
BRect rect = Bounds().InsetBySelf(10.0f, 10.0f); BRect rect = Bounds().InsetBySelf(10.0f, 10.0f);
rect.bottom = 125.0f; rect.bottom = 125.0f;
rect.right -= B_V_SCROLL_BAR_WIDTH; rect.right -= B_V_SCROLL_BAR_WIDTH;
fAppList = new BListView(rect, "pkg_list", B_SINGLE_SELECTION_LIST, fAppList = new BListView(rect, "pkg_list", B_SINGLE_SELECTION_LIST,
B_FOLLOW_NONE); B_FOLLOW_NONE);
fAppList->SetSelectionMessage(new BMessage(P_MSG_SELECT)); fAppList->SetSelectionMessage(new BMessage(P_MSG_SELECT));
BScrollView *scroll = new BScrollView("list_scroll", fAppList, B_FOLLOW_NONE, BScrollView *scroll = new BScrollView("list_scroll", fAppList,
0, false, true); B_FOLLOW_NONE, 0, false, true);
AddChild(scroll); AddChild(scroll);
rect.top = rect.bottom + 8.0f; rect.top = rect.bottom + 8.0f;
rect.bottom += 120.0f; rect.bottom += 120.0f;
rect.right += B_V_SCROLL_BAR_WIDTH; rect.right += B_V_SCROLL_BAR_WIDTH;
BBox *box = new BBox(rect, "desc_box"); BBox* box = new BBox(rect, "desc_box");
BStringView *descLabel = new BStringView(BRect(3, 3, 10, 10), "desc_label", BStringView *descLabel = new BStringView(BRect(3, 3, 10, 10), "desc_label",
T("Package description:")); T("Package description:"));
descLabel->ResizeToPreferred(); descLabel->ResizeToPreferred();
box->AddChild(descLabel); box->AddChild(descLabel);
@@ -278,21 +341,23 @@ UninstallView::_InitView()
inside.top = descLabel->Frame().bottom + 10.0f; inside.top = descLabel->Frame().bottom + 10.0f;
inside.right -= B_V_SCROLL_BAR_WIDTH; inside.right -= B_V_SCROLL_BAR_WIDTH;
fDescription = new BTextView(inside, "description", fDescription = new BTextView(inside, "description",
BRect(0, 0, inside.Width(), inside.Height()), B_FOLLOW_NONE, B_WILL_DRAW); BRect(0, 0, inside.Width(), inside.Height()), B_FOLLOW_NONE,
B_WILL_DRAW);
fDescription->MakeSelectable(true); fDescription->MakeSelectable(true);
fDescription->MakeEditable(false); fDescription->MakeEditable(false);
fDescription->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); fDescription->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fDescription->SetText(T("No package selected.")); fDescription->SetText(T(kNoPackageSelected));
fDescScroll = new BScrollView("desc_scroll", fDescription, B_FOLLOW_NONE, fDescScroll = new BScrollView("desc_scroll", fDescription, B_FOLLOW_NONE,
0, false, true, B_NO_BORDER); 0, false, true, B_NO_BORDER);
box->AddChild(fDescScroll); box->AddChild(fDescScroll);
AddChild(box); AddChild(box);
fButton = new BButton(BRect(0, 0, 1, 1), "removal", T("Remove"), fButton = new BButton(BRect(0, 0, 1, 1), "removal", T("Remove"),
new BMessage(P_MSG_REMOVE)); new BMessage(P_MSG_REMOVE));
fButton->ResizeToPreferred(); fButton->ResizeToPreferred();
fButton->SetEnabled(false);
rect.top = rect.bottom + 5.0f; rect.top = rect.bottom + 5.0f;
rect.left = Bounds().Width() - 5.0f - fButton->Bounds().Width(); rect.left = Bounds().Width() - 5.0f - fButton->Bounds().Width();
@@ -301,6 +366,8 @@ UninstallView::_InitView()
AddChild(fButton); AddChild(fButton);
ResizeTo(Bounds().Width(), fButton->Frame().bottom + 10.0f); ResizeTo(Bounds().Width(), fButton->Frame().bottom + 10.0f);
#endif
} }
@@ -320,20 +387,17 @@ UninstallView::_ReloadAppList()
fprintf(stderr, "Ichi! %s\n", fToPackages.Path()); fprintf(stderr, "Ichi! %s\n", fToPackages.Path());
BEntry iter; BEntry iter;
node_ref ref; while (dir.GetNextEntry(&iter) == B_OK) {
char filename[B_FILE_NAME_LENGTH]; char filename[B_FILE_NAME_LENGTH];
BString name, version; if (iter.GetName(filename) != B_OK)
while (1) { continue;
ret = dir.GetNextEntry(&iter);
if (ret != B_OK) node_ref ref;
break; if (iter.GetNodeRef(&ref) != B_OK)
continue;
fprintf(stderr, "Found one!\n");
iter.GetName(filename); printf("Found package '%s'\n", filename);
iter.GetNodeRef(&ref); _AddFile(filename, ref);
name = info_get_package_name(filename);
version = info_get_package_version(filename);
fAppList->AddItem(new InfoItem(name.String(), version.String(), ref));
} }
if (ret != B_ENTRY_NOT_FOUND) if (ret != B_ENTRY_NOT_FOUND)
@@ -346,14 +410,27 @@ UninstallView::_ReloadAppList()
void void
UninstallView::_ClearAppList() UninstallView::_ClearAppList()
{ {
int32 i, count = fAppList->CountItems(); while (BListItem* item = fAppList->RemoveItem(0L))
BListItem *iter = 0; delete item;
}
for (i = 0;i < count;i++) {
iter = static_cast<BListItem *>(fAppList->ItemAt(0)); void
fAppList->RemoveItem((int32)0); UninstallView::_AddFile(const char* filename, const node_ref& ref)
delete iter; {
BString name;
status_t ret = info_get_package_name(filename, name);
if (ret != B_OK || name.Length() == 0) {
fprintf(stderr, "Error extracting package name: %s\n",
strerror(ret));
} }
BString version;
ret = info_get_package_version(filename, version);
if (ret != B_OK || version.Length() == 0) {
fprintf(stderr, "Error extracting package version: %s\n",
strerror(ret));
}
fAppList->AddItem(new InfoItem(name, version, filename, ref));
} }
+22 -21
View File
@@ -8,7 +8,6 @@
#ifndef UNINSTALLVIEW_H #ifndef UNINSTALLVIEW_H
#define UNINSTALLVIEW_H #define UNINSTALLVIEW_H
#include "InstalledPackageInfo.h"
#include <View.h> #include <View.h>
#include <Layout.h> #include <Layout.h>
#include <ListView.h> #include <ListView.h>
@@ -17,31 +16,33 @@
#include <TextView.h> #include <TextView.h>
#include <Path.h> #include <Path.h>
#include "InstalledPackageInfo.h"
class UninstallView : public BView { class UninstallView : public BView {
public: public:
UninstallView(BRect frame); UninstallView(BRect frame);
~UninstallView(); virtual ~UninstallView();
void AttachedToWindow(); virtual void AttachedToWindow();
void MessageReceived(BMessage *msg); virtual void MessageReceived(BMessage* message);
private: private:
class InfoItem; class InfoItem;
void _InitView(); void _InitView();
status_t _ReloadAppList(); status_t _ReloadAppList();
void _ClearAppList(); void _AddFile(const char* filename, const node_ref& ref);
void _CachePathToPackages(); void _ClearAppList();
void _CachePathToPackages();
BPath fToPackages; BPath fToPackages;
BListView *fAppList; BListView* fAppList;
BTextView *fDescription; BTextView* fDescription;
BButton *fButton; BButton* fButton;
BScrollView *fDescScroll; BScrollView* fDescScroll;
InstalledPackageInfo fCurrentSelection; InstalledPackageInfo fCurrentSelection;
bool fWatcherRunning; bool fWatcherRunning;
}; };
#endif // UNINSTALLVIEW_H
#endif
+10 -22
View File
@@ -6,7 +6,8 @@
* Łukasz 'Sil2100' Zemczak <[email protected]> * Łukasz 'Sil2100' Zemczak <[email protected]>
*/ */
#include "UninstallWindow.h" #include "UninstallWindow.h"
#include <Application.h>
#include <GroupLayout.h>
// Macro reserved for later localization // Macro reserved for later localization
@@ -14,28 +15,15 @@
UninstallWindow::UninstallWindow() UninstallWindow::UninstallWindow()
: BWindow(BRect(100, 100, 600, 300), T("Installed packages"), : BWindow(BRect(100, 100, 600, 300), T("Installed packages"),
B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE) B_TITLED_WINDOW, B_NOT_ZOOMABLE
| B_QUIT_ON_WINDOW_CLOSE | B_AUTO_UPDATE_SIZE_LIMITS)
{ {
fBackground = new UninstallView(Bounds()); SetLayout(new BGroupLayout(B_HORIZONTAL));
AddChild(fBackground);
ResizeTo(Bounds().Width(), fBackground->Bounds().Height()); BView* view = new UninstallView(Bounds());
} AddChild(view);
ResizeTo(Bounds().Width(), view->Bounds().Height());
UninstallWindow::~UninstallWindow()
{
RemoveChild(fBackground);
delete fBackground;
}
bool
UninstallWindow::QuitRequested()
{
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
} }
+3 -10
View File
@@ -14,15 +14,8 @@
class UninstallWindow : public BWindow { class UninstallWindow : public BWindow {
public: public:
UninstallWindow(); UninstallWindow();
~UninstallWindow();
bool QuitRequested();
private:
UninstallView *fBackground;
}; };
#endif // UNINSTALLWINDOW_H
#endif
@@ -23,50 +23,47 @@ const char * kPackagesDir = "packages";
static status_t static status_t
info_prepare(const char *filename, BFile *file, BMessage *info) info_prepare(const char *filename, BFile *file, BMessage *info)
{ {
if (!filename) if (filename == NULL || file == NULL || info == NULL)
return B_ERROR; return B_BAD_VALUE;
BPath path; BPath path;
if (find_directory(B_USER_CONFIG_DIRECTORY, &path) != B_OK status_t ret = find_directory(B_USER_CONFIG_DIRECTORY, &path);
|| path.Append(kPackagesDir) != B_OK if (ret == B_OK)
|| path.Append(filename) != B_OK) ret = path.Append(kPackagesDir);
return B_ERROR; if (ret == B_OK)
ret = path.Append(filename);
if (ret == B_OK)
ret = file->SetTo(path.Path(), B_READ_ONLY);
if (ret == B_OK)
ret = info->Unflatten(file);
if (ret == B_OK && info->what != P_PACKAGE_INFO)
ret = B_ERROR;
file->SetTo(path.Path(), B_READ_ONLY); return ret;
if (file->InitCheck() != B_OK)
return B_ERROR;
status_t ret = info->Unflatten(file);
if (ret != B_OK || info->what != P_PACKAGE_INFO)
return B_ERROR;
return B_OK;
} }
const char * status_t
info_get_package_name(const char *filename) info_get_package_name(const char *filename, BString &name)
{ {
BFile file; BFile file;
BMessage info; BMessage info;
if (info_prepare(filename, &file, &info) != B_OK) status_t ret = info_prepare(filename, &file, &info);
return NULL; if (ret == B_OK)
BString name; ret = info.FindString("package_name", &name);
info.FindString("package_name", &name); return ret;
return name.String();
} }
const char * status_t
info_get_package_version(const char *filename) info_get_package_version(const char *filename, BString &version)
{ {
BFile file; BFile file;
BMessage info; BMessage info;
if (info_prepare(filename, &file, &info) != B_OK) status_t ret = info_prepare(filename, &file, &info);
return NULL; if (ret == B_OK)
BString version; ret = info.FindString("package_version", &version);
info.FindString("package_version", &version); return ret;
return version.String();
} }
@@ -25,8 +25,8 @@ extern const char * kPackagesDir;
// Useful function for fetching the package name and version without parsing all // Useful function for fetching the package name and version without parsing all
// other data // other data
const char * info_get_package_name(const char *filename); status_t info_get_package_name(const char *filename, BString &name);
const char * info_get_package_version(const char *filename); status_t info_get_package_version(const char *filename, BString &name);
class InstalledPackageInfo { class InstalledPackageInfo {