hrev47995 adds 1 changeset to branch 'master' old head: bb9112df023feb0398638dad9074db49a5c1a10f new head: 6d519fd17558a53659c82f7a5ac101b7b6be1213 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=6d519fd+%5Ebb9112d ---------------------------------------------------------------------------- 6d519fd: 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. * ... [ Stephan Aßmus <superstippi@xxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev47995 Commit: 6d519fd17558a53659c82f7a5ac101b7b6be1213 URL: http://cgit.haiku-os.org/haiku/commit/?id=6d519fd Author: Stephan Aßmus <superstippi@xxxxxx> Date: Fri Oct 10 20:36:37 2014 UTC ---------------------------------------------------------------------------- 7 files changed, 269 insertions(+), 50 deletions(-) src/apps/haikudepot/HaikuDepot.rdef | 6 +- src/apps/haikudepot/model/PackageInfo.cpp | 50 +++++++- src/apps/haikudepot/model/PackageInfo.h | 8 +- src/apps/haikudepot/ui/App.cpp | 158 +++++++++++++++++++++++--- src/apps/haikudepot/ui/App.h | 13 +++ src/apps/haikudepot/ui/MainWindow.cpp | 80 ++++++++----- src/apps/haikudepot/ui/MainWindow.h | 4 + ---------------------------------------------------------------------------- diff --git a/src/apps/haikudepot/HaikuDepot.rdef b/src/apps/haikudepot/HaikuDepot.rdef index 6246b96..d8eb7dd 100644 --- a/src/apps/haikudepot/HaikuDepot.rdef +++ b/src/apps/haikudepot/HaikuDepot.rdef @@ -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 { diff --git a/src/apps/haikudepot/model/PackageInfo.cpp b/src/apps/haikudepot/model/PackageInfo.cpp index 8167f85..c0ff4d0 100644 --- a/src/apps/haikudepot/model/PackageInfo.cpp +++ b/src/apps/haikudepot/model/PackageInfo.cpp @@ -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), @@ -815,6 +854,13 @@ PackageInfo::RemoveListener(const PackageInfoListenerRef& listener) void +PackageInfo::CleanupDefaultIcon() +{ + sDefaultIcon.Unset(); +} + + +void PackageInfo::_NotifyListeners(uint32 changes) { int count = fListeners.CountItems(); diff --git a/src/apps/haikudepot/model/PackageInfo.h b/src/apps/haikudepot/model/PackageInfo.h index b9e6f47..741b2c2 100644 --- a/src/apps/haikudepot/model/PackageInfo.h +++ b/src/apps/haikudepot/model/PackageInfo.h @@ -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; }; diff --git a/src/apps/haikudepot/ui/App.cpp b/src/apps/haikudepot/ui/App.cpp index efa2823..7b320fe 100644 --- a/src/apps/haikudepot/ui/App.cpp +++ b/src/apps/haikudepot/ui/App.cpp @@ -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) +{ + 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) { - save_settings(&windowSettings, "main_settings", "HaikuDepot"); + 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; } diff --git a/src/apps/haikudepot/ui/App.h b/src/apps/haikudepot/ui/App.h index b4ba3f0..83dbee1 100644 --- a/src/apps/haikudepot/ui/App.h +++ b/src/apps/haikudepot/ui/App.h @@ -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 _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; }; diff --git a/src/apps/haikudepot/ui/MainWindow.cpp b/src/apps/haikudepot/ui/MainWindow.cpp index 12c2990..cd935e5 100644 --- a/src/apps/haikudepot/ui/MainWindow.cpp +++ b/src/apps/haikudepot/ui/MainWindow.cpp @@ -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()); - - BMessage columnSettings; - fPackageListView->SaveState(&columnSettings); - - settings.AddMessage("column settings", &columnSettings); + if (fSinglePackageMode) + settings.AddRect("small window frame", Frame()); + else { + settings.AddRect("window frame", Frame()); - 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); } diff --git a/src/apps/haikudepot/ui/MainWindow.h b/src/apps/haikudepot/ui/MainWindow.h index 0c13328..fd8273b 100644 --- a/src/apps/haikudepot/ui/MainWindow.h +++ b/src/apps/haikudepot/ui/MainWindow.h @@ -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;