HaikuDepot: WIP to open .hpkg files.

* When opening .hpkg files, shows just the PackageInfoView in a smaller
   window.
 * PackageInfo constructor with BPackageInfo argument
 * Default pkg icon has a single instance only. Before, there would be another
   instance for each repository refresh.

TODO:
 * Install button on single package view is non functional
 * Probably needs to do someting different when opening .hpkg from an
   installed packages folder (show the regular list and focus that package?).
 * The filter view and list view are still constructed for the single package
   mode.
 * ...
This commit is contained in:
Stephan Aßmus
2014-10-10 22:42:07 +02:00
parent bb9112df02
commit 6d519fd175
7 changed files with 270 additions and 51 deletions
+5 -1
View File
@@ -14,7 +14,11 @@ resource app_version {
internal = 1,
short_info = "HaikuDepot",
long_info = "HaikuDepot ©2013 Haiku"
long_info = "HaikuDepot ©2013-2014 Haiku"
};
resource file_types message {
"types" = "application/x-vnd.haiku-package"
};
resource vector_icon {
+48 -2
View File
@@ -444,9 +444,14 @@ ScreenshotInfo::operator!=(const ScreenshotInfo& other) const
// #pragma mark - PackageInfo
BitmapRef
PackageInfo::sDefaultIcon(new(std::nothrow) SharedBitmap(
"application/x-vnd.haiku-package"), true);
PackageInfo::PackageInfo()
:
fIcon(),
fIcon(sDefaultIcon),
fTitle(),
fVersion(),
fPublisher(),
@@ -466,12 +471,46 @@ PackageInfo::PackageInfo()
}
PackageInfo::PackageInfo(const BPackageInfo& info)
:
fIcon(sDefaultIcon),
fTitle(info.Name()),
fVersion(info.Version()),
fPublisher(),
fShortDescription(info.Summary()),
fFullDescription(info.Description()),
fChangelog(),
fUserRatings(),
fCachedRatingSummary(),
fScreenshotInfos(),
fScreenshots(),
fState(NONE),
fDownloadProgress(0.0),
fFlags(info.Flags()),
fSystemDependency(false),
fArchitecture(info.ArchitectureName())
{
BString publisherURL;
if (info.URLList().CountStrings() > 0)
publisherURL = info.URLList().StringAt(0);
BString publisherName = info.Vendor();
if (publisherName.IsEmpty()) {
const BStringList& rightsList = info.CopyrightList();
if (rightsList.CountStrings() > 0)
publisherName = rightsList.StringAt(0);
}
fPublisher = PublisherInfo(BitmapRef(), publisherName, "", publisherURL);
}
PackageInfo::PackageInfo(const BString& title,
const BPackageVersion& version, const PublisherInfo& publisher,
const BString& shortDescription, const BString& fullDescription,
int32 flags, const char* architecture)
:
fIcon(),
fIcon(sDefaultIcon),
fTitle(title),
fVersion(version),
fPublisher(publisher),
@@ -814,6 +853,13 @@ PackageInfo::RemoveListener(const PackageInfoListenerRef& listener)
}
void
PackageInfo::CleanupDefaultIcon()
{
sDefaultIcon.Unset();
}
void
PackageInfo::_NotifyListeners(uint32 changes)
{
+7 -1
View File
@@ -9,7 +9,7 @@
#include <set>
#include <Referenceable.h>
#include <package/PackageVersion.h>
#include <package/PackageInfo.h>
#include "List.h"
#include "PackageInfoListener.h"
@@ -229,12 +229,14 @@ enum PackageState {
};
using BPackageKit::BPackageInfo;
using BPackageKit::BPackageVersion;
class PackageInfo : public BReferenceable {
public:
PackageInfo();
PackageInfo(const BPackageInfo& info);
PackageInfo(
const BString& title,
const BPackageVersion& version,
@@ -320,6 +322,8 @@ public:
void RemoveListener(
const PackageInfoListenerRef& listener);
static void CleanupDefaultIcon();
private:
void _NotifyListeners(uint32 changes);
@@ -344,6 +348,8 @@ private:
int32 fFlags;
bool fSystemDependency;
BString fArchitecture;
static BitmapRef sDefaultIcon;
};
+142 -16
View File
@@ -10,6 +10,8 @@
#include <Catalog.h>
#include <Entry.h>
#include <Message.h>
#include <package/PackageInfo.h>
#include <Path.h>
#include <String.h>
#include "support.h"
@@ -24,20 +26,24 @@
App::App()
:
BApplication("application/x-vnd.Haiku-HaikuDepot"),
fMainWindow(NULL)
fMainWindow(NULL),
fWindowCount(0),
fSettingsRead(false)
{
}
App::~App()
{
PackageInfo::CleanupDefaultIcon();
}
bool
App::QuitRequested()
{
if (fMainWindow->LockLooperWithTimeout(1500000) == B_OK) {
if (fMainWindow != NULL
&& fMainWindow->LockLooperWithTimeout(1500000) == B_OK) {
BMessage windowSettings;
fMainWindow->StoreSettings(windowSettings);
@@ -53,18 +59,14 @@ App::QuitRequested()
void
App::ReadyToRun()
{
BRect frame(50.0, 50.0, 749.0, 549.0);
if (fWindowCount > 0)
return;
BMessage settings;
status_t status = load_settings(&settings, "main_settings", "HaikuDepot");
if (status == B_OK) {
settings.FindRect("window frame", &frame);
}
make_sure_frame_is_on_screen(frame);
fMainWindow = new MainWindow(frame, settings);
fMainWindow->Show();
_LoadSettings(settings);
fMainWindow = new MainWindow(_GetNextWindowFrame(false), settings);
_ShowWindow(fMainWindow);
}
@@ -80,7 +82,9 @@ App::MessageReceived(BMessage* message)
_StoreSettings(windowSettings);
}
Quit();
fWindowCount--;
if (fWindowCount == 0)
Quit();
break;
}
@@ -92,8 +96,130 @@ App::MessageReceived(BMessage* message)
void
App::_StoreSettings(const BMessage& windowSettings)
App::RefsReceived(BMessage* message)
{
save_settings(&windowSettings, "main_settings", "HaikuDepot");
entry_ref ref;
int32 index = 0;
while (message->FindRef("refs", index++, &ref) == B_OK) {
BEntry entry(&ref, true);
_Open(entry);
}
}
void
App::ArgvReceived(int32 argc, char* argv[])
{
for (int i = 1; i < argc; i++) {
BEntry entry(argv[i], true);
_Open(entry);
}
}
// #pragma mark - private
void
App::_Open(const BEntry& entry)
{
BPath path;
if (!entry.Exists() || !entry.GetPath(&path) == B_OK) {
fprintf(stderr, "Package file not found: %s\n", path.Path());
return;
}
// Try to parse package file via Package Kit
BPackageKit::BPackageInfo info;
status_t status = info.ReadFromPackageFile(path.Path());
if (status != B_OK) {
fprintf(stderr, "Failed to parse package file: %s\n",
strerror(status));
return;
}
// Transfer information into PackageInfo
PackageInfoRef package(new(std::nothrow) PackageInfo(info), true);
if (package.Get() == NULL) {
fprintf(stderr, "Could not allocate PackageInfo\n");
return;
}
BMessage settings;
_LoadSettings(settings);
MainWindow* window = new MainWindow(_GetNextWindowFrame(true), settings,
package);
_ShowWindow(window);
}
void
App::_ShowWindow(MainWindow* window)
{
window->Show();
fWindowCount++;
}
bool
App::_LoadSettings(BMessage& settings)
{
if (!fSettingsRead) {
fSettings = true;
if (load_settings(&fSettings, "main_settings", "HaikuDepot") != B_OK)
fSettings.MakeEmpty();
}
settings = fSettings;
return !fSettings.IsEmpty();
}
void
App::_StoreSettings(const BMessage& settings)
{
// Take what is in settings and replace data under the same name in
// fSettings, leaving anything in fSettings that is not contained in
// settings.
int32 i = 0;
char* name;
type_code type;
int32 count;
while (settings.GetInfo(B_ANY_TYPE, i++, &name, &type, &count) == B_OK) {
fSettings.RemoveName(name);
for (int32 j = 0; j < count; j++) {
const void* data;
ssize_t size;
if (settings.FindData(name, type, j, &data, &size) != B_OK)
break;
fSettings.AddData(name, type, data, size);
}
}
save_settings(&fSettings, "main_settings", "HaikuDepot");
}
BRect
App::_GetNextWindowFrame(bool singlePackageMode)
{
BRect frame;
if (singlePackageMode)
frame = BRect(50.0, 50.0, 649.0, 349.0);
else
frame = BRect(50.0, 50.0, 749.0, 549.0);
BMessage settings;
if (_LoadSettings(settings)) {
if (singlePackageMode)
settings.FindRect("small window frame", &frame);
else
settings.FindRect("window frame", &frame);
}
make_sure_frame_is_on_screen(frame);
return frame;
}
+14 -1
View File
@@ -9,6 +9,7 @@
#include <Application.h>
class BEntry;
class MainWindow;
@@ -20,11 +21,23 @@ public:
virtual bool QuitRequested();
virtual void ReadyToRun();
virtual void MessageReceived(BMessage* message);
virtual void RefsReceived(BMessage* message);
virtual void ArgvReceived(int32 argc, char* argv[]);
private:
void _StoreSettings(const BMessage& windowSettings);
void _Open(const BEntry& entry);
void _ShowWindow(MainWindow* window);
bool _LoadSettings(BMessage& settings);
void _StoreSettings(const BMessage& windowSettings);
BRect _GetNextWindowFrame(bool singlePackageMode);
private:
MainWindow* fMainWindow;
int32 fWindowCount;
BMessage fSettings;
bool fSettingsRead;
};
+50 -30
View File
@@ -111,6 +111,7 @@ MainWindow::MainWindow(BRect frame, const BMessage& settings)
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
fModelListener(new MessageModelListener(BMessenger(this)), true),
fTerminating(false),
fSinglePackageMode(false),
fModelWorker(B_BAD_THREAD_ID)
{
BMenuBar* menuBar = new BMenuBar(B_TRANSLATE("Main Menu"));
@@ -182,6 +183,40 @@ MainWindow::MainWindow(BRect frame, const BMessage& settings)
}
MainWindow::MainWindow(BRect frame, const BMessage& settings,
const PackageInfoRef& package)
:
BWindow(frame, B_TRANSLATE_SYSTEM_NAME("HaikuDepot"),
B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
fLogOutItem(NULL),
fModelListener(new MessageModelListener(BMessenger(this)), true),
fTerminating(false),
fSinglePackageMode(true),
fModelWorker(B_BAD_THREAD_ID)
{
fFilterView = new FilterView();
fPackageListView = new PackageListView(fModel.Lock());
fPackageInfoView = new PackageInfoView(fModel.Lock(), this);
BLayoutBuilder::Group<>(this, B_VERTICAL)
.Add(fPackageInfoView)
.SetInsets(0, B_USE_WINDOW_INSETS, 0, 0)
;
fModel.AddListener(fModelListener);
// Restore settings
BString username;
if (settings.FindString("username", &username) == B_OK
&& username.Length() > 0) {
fModel.SetUsername(username);
}
fPackageInfoView->SetPackage(package);
}
MainWindow::~MainWindow()
{
BPackageRoster().StopWatching(this);
@@ -381,15 +416,19 @@ MainWindow::MessageReceived(BMessage* message)
void
MainWindow::StoreSettings(BMessage& settings) const
{
settings.AddRect("window frame", Frame());
if (fSinglePackageMode)
settings.AddRect("small window frame", Frame());
else {
settings.AddRect("window frame", Frame());
BMessage columnSettings;
fPackageListView->SaveState(&columnSettings);
settings.AddMessage("column settings", &columnSettings);
settings.AddBool("show develop packages", fModel.ShowDevelopPackages());
settings.AddBool("show source packages", fModel.ShowSourcePackages());
BMessage columnSettings;
fPackageListView->SaveState(&columnSettings);
settings.AddMessage("column settings", &columnSettings);
settings.AddBool("show develop packages", fModel.ShowDevelopPackages());
settings.AddBool("show source packages", fModel.ShowSourcePackages());
}
settings.AddString("username", fModel.Username());
}
@@ -610,9 +649,6 @@ MainWindow::_RefreshPackageList()
// system packages in order to compute the list of protected
// dependencies indicated above.
BitmapRef defaultIcon(new(std::nothrow) SharedBitmap(
"application/x-vnd.haiku-package"), true);
for (int32 i = 0; i < packages.CountItems(); i++) {
BSolverPackage* package = packages.ItemAt(i);
const BPackageInfo& repoPackageInfo = package->Info();
@@ -623,23 +659,7 @@ MainWindow::_RefreshPackageList()
modelInfo.SetTo(it->second);
else {
// Add new package info
BString publisherURL;
if (repoPackageInfo.URLList().CountStrings() > 0)
publisherURL = repoPackageInfo.URLList().StringAt(0);
BString publisherName = repoPackageInfo.Vendor();
const BStringList& rightsList = repoPackageInfo.CopyrightList();
if (rightsList.CountStrings() > 0)
publisherName = rightsList.StringAt(0);
modelInfo.SetTo(new(std::nothrow) PackageInfo(
repoPackageInfo.Name(),
repoPackageInfo.Version(),
PublisherInfo(BitmapRef(), publisherName,
"", publisherURL), repoPackageInfo.Summary(),
repoPackageInfo.Description(),
repoPackageInfo.Flags(),
repoPackageInfo.ArchitectureName()),
modelInfo.SetTo(new(std::nothrow) PackageInfo(repoPackageInfo),
true);
if (modelInfo.Get() == NULL)
@@ -648,7 +668,6 @@ MainWindow::_RefreshPackageList()
foundPackages[repoPackageInfo.Name()] = modelInfo;
}
modelInfo->SetIcon(defaultIcon);
modelInfo->AddListener(this);
BSolverRepository* repository = package->Repository();
@@ -905,7 +924,8 @@ void
MainWindow::_UpdateAuthorization()
{
BString username(fModel.Username());
fLogOutItem->SetEnabled(username.Length() > 0);
if (fLogOutItem != NULL)
fLogOutItem->SetEnabled(username.Length() > 0);
fFilterView->SetUsername(username);
}
+4
View File
@@ -31,6 +31,9 @@ class MainWindow : public BWindow, private PackageInfoListener,
public:
MainWindow(BRect frame,
const BMessage& settings);
MainWindow(BRect frame,
const BMessage& settings,
const PackageInfoRef& package);
virtual ~MainWindow();
// BWindow interface
@@ -90,6 +93,7 @@ private:
PackageList fVisiblePackages;
bool fTerminating;
bool fSinglePackageMode;
thread_id fModelWorker;
thread_id fPendingActionsWorker;