diff --git a/src/apps/haiku-depot/MainWindow.cpp b/src/apps/haiku-depot/MainWindow.cpp index 1c2a18a6cf..efd6fcb85b 100644 --- a/src/apps/haiku-depot/MainWindow.cpp +++ b/src/apps/haiku-depot/MainWindow.cpp @@ -1,10 +1,13 @@ /* * Copyright 2013, Stephan Aßmus . + * Copyright 2013, Rene Gollent, rene@gollent.com. * All rights reserved. Distributed under the terms of the MIT License. */ #include "MainWindow.h" +#include + #include #include @@ -17,24 +20,42 @@ #include #include #include +#include #include +#include +#include +#include +#include + +#include "DecisionProvider.h" #include "FilterView.h" +#include "JobStateListener.h" #include "PackageInfoView.h" #include "PackageListView.h" + #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "MainWindow" +using namespace BPackageKit; + + +typedef std::map PackageInfoMap; +typedef std::map > PackageLocationMap; +typedef std::map DepotInfoMap; + + MainWindow::MainWindow(BRect frame) : BWindow(frame, B_TRANSLATE_SYSTEM_NAME("HaikuDepot"), B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, - B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS) + B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), + fPackageManager(B_PACKAGE_INSTALLATION_LOCATION_HOME) { - _InitDummyModel(); + _InitModel(); BMenuBar* menuBar = new BMenuBar(B_TRANSLATE("Main Menu")); _BuildMenu(menuBar); @@ -185,130 +206,118 @@ MainWindow::_ClearPackage() void -MainWindow::_InitDummyModel() +MainWindow::_InitModel() { - // TODO: The Model needs to be filled initially by the Package Kit APIs. - // It already caches information locally. Error handlers need to be - // installed to display problems to the user. When a package is selected - // for display, extra information is retrieved like screen-shots, user- - // ratings and so on. This triggers notifications which in turn updates - // the UI. + BPackageRoster roster; - DepotInfo depot(B_TRANSLATE("Default")); + BStringList repositoryNames; + status_t result = roster.GetRepositoryNames(repositoryNames); - // WonderBrush - PackageInfoRef wonderbrush(new(std::nothrow) PackageInfo( - BitmapRef(new SharedBitmap(601), true), - "WonderBrush", - "2.1.2", - PublisherInfo( - BitmapRef(), - "YellowBites", - "superstippi@gmx.de", - "http://www.yellowbites.com"), - "A vector based graphics editor.", - "WonderBrush is YellowBites' software for doing graphics design " - "on Haiku. It combines many great under-the-hood features with " - "powerful tools and an efficient and intuitive interface.", - "2.1.2 - Initial Haiku release."), true); - wonderbrush->AddCategory(fModel.CategoryGraphics()); - wonderbrush->AddCategory(fModel.CategoryProductivity()); + // TODO: notify user + if (result != B_OK) + return; - depot.AddPackage(wonderbrush); + DepotInfoMap depots; - // Paladin - PackageInfoRef paladin(new(std::nothrow) PackageInfo( - BitmapRef(new SharedBitmap(602), true), - "Paladin", - "1.2.0", - PublisherInfo( - BitmapRef(), - "DarkWyrm", - "bpmagic@columbus.rr.com", - "http://darkwyrm-haiku.blogspot.com"), - "A C/C++ IDE based on Pe.", - "If you like BeIDE, you'll like Paladin even better. " - "The interface is streamlined, it has some features sorely " - "missing from BeIDE, like running a project in the Terminal, " - "and has a bundled text editor based upon Pe.", - ""), true); - paladin->AddCategory(fModel.CategoryDevelopment()); + DecisionProvider decisionProvider; + JobStateListener listener; + BContext context(decisionProvider, listener); - depot.AddPackage(paladin); + for (int32 i = 0; i < repositoryNames.CountStrings(); ++i) { + const BString& repoName = repositoryNames.StringAt(i); + BRepositoryConfig repoConfig; + result = roster.GetRepositoryConfig(repoName, &repoConfig); + if (result != B_OK) { + // TODO: notify user + continue; + } - // Sequitur - PackageInfoRef sequitur(new(std::nothrow) PackageInfo( - BitmapRef(new SharedBitmap(604), true), - "Sequitur", - "2.1.0", - PublisherInfo( - BitmapRef(), - "Angry Red Planet", - "hackborn@angryredplanet.com", - "http://www.angryredplanet.com"), - "BeOS-native MIDI sequencer.", - "Sequitur is a BeOS-native MIDI sequencer with a MIDI processing " - "add-on architecture. It allows you to record, compose, store, " - "and play back music from your computer. Sequitur is designed for " - "people who like to tinker with their music. It facilitates rapid, " - "dynamic, and radical processing of your performance.", + BRefreshRepositoryRequest refreshRequest(context, repoConfig); + result = refreshRequest.Process(); + if (result != B_OK) { + // TODO: notify user + continue; + } - "== Sequitur 2.1 Release Notes ==\n" - "04 August 2002\n\n" - "Features\n\n" - " * Important fix to file IO that prevents data corruption.\n\n" - " * Dissolve filter could cause crash when operating on notes " - "with extremely short durations. (thanks to David Shipman)\n\n" - " * New tool bar ARP Curves (select Tool Bars->Show->ARP Curves " - "in a track window) contains new tools for shaping events. Each " - "tool is documented in the Tool Guide, but in general they are " - "used to shape control change, pitch bend, tempo and velocity " - "events (and notes if you're feeling creative), and the curve " - "can be altered by pressing the 'z' and 'x' keys.\n\n" - "All curve tools make use of a new tool seed for drawing " - "bezier curves; see section 6.3.2. of the user's guide for an " - "explanation of the Curve seed.\n\n" - " * New menu items in the Song window: '''Edit->Expand Marked Range''' " - "and '''Edit->Contract Marked Range'''. These items are only active if " - "the loop markers are on. The Expand command shifts everything " - "from the left marker to the end of the song over by the total " - "loop range. The Contract command deletes the area within the " - "loop markers, then shifts everything after the right marker " - "left by the total loop range. If no tracks are selected, the " - "entire song is shifted. Otherwise, only the selected tracks are " - "affected.\n\n" - " * System exclusive commands can now be added to devices. There " - "is no user interface for doing so, although developer tools are " - "provided here. Currently, the E-mu Proteus 2000 and E-mu EOS " - "devices include sysex commands for controlling the FX.\n\n" - " * A new page has been added to the Preferences window, Views. " - "This page lets you set the height for the various views in " - "Sequitur, such as pitch bend, control change, etc.\n\n" - " * Multiple instances of the same MIDI device are given unique " - "names. For example, two instances of SynC Modular will be " - "named \"SynC Modular 1\" and \"SynC Modular 2\" so they can be " - "accessed independently. (thanks to David Shipman)\n\n" - " * In the track window, holding down the CTRL key now accesses " - "an alternate set of active tools. (Assign these tools by " - "holding down the CTRL key and clicking on the desired tool)\n\n" - " * Right mouse button can now be mapped to any tool. (thanks " - "to David Shipman)\n\n" - " * The Vaccine.P and Vaccine.V filters have been deprecated " - "(although they are still available here). They are replaced by " - "the Vaccine filter. In addition to injecting a motion into the " - "pitch and velocity of notes, this new filter can inject it " - "into control change, pitch bend, tempo change and channel " - "pressure events. The new tool Broken Down Line uses this " - "filter.\n\n" - " * ''Note to filter developers:'' The filter API has changed. You " - "will need to recompile your filters."), true); - sequitur->AddCategory(fModel.CategoryAudio()); + depots[repoName] = DepotInfo(repoName); + } - depot.AddPackage(sequitur); + fPackageManager.Init(PackageManager::B_ADD_INSTALLED_REPOSITORIES + | PackageManager::B_ADD_REMOTE_REPOSITORIES); - // Finish off - fModel.AddDepot(depot); + BObjectList packages; + result = fPackageManager.Solver()->FindPackages("", + BSolver::B_FIND_CASE_INSENSITIVE | BSolver::B_FIND_IN_NAME + | BSolver::B_FIND_IN_SUMMARY | BSolver::B_FIND_IN_DESCRIPTION + | BSolver::B_FIND_IN_PROVIDES, + packages); + if (result != B_OK) { + // TODO: notify user + return; + } + + if (packages.IsEmpty()) + return; + + PackageLocationMap packageLocations; + PackageInfoMap foundPackages; + // if a given package is installed locally, we will potentially + // get back multiple entries, one for each local installation + // location, and one for each remote repository the package + // is available in. The above map is used to ensure that in such + // cases we consolidate the information, rather than displaying + // duplicates + for (int32 i = 0; i < packages.CountItems(); i++) { + BSolverPackage* package = packages.ItemAt(i); + const BPackageInfo& repoPackageInfo = package->Info(); + PackageInfoRef modelInfo; + PackageInfoMap::iterator it = foundPackages.find( + repoPackageInfo.Name()); + if (it != foundPackages.end()) + modelInfo = it->second; + else { + modelInfo.SetTo(new(std::nothrow) PackageInfo(NULL, + repoPackageInfo.Name(), repoPackageInfo.Version().ToString(), + PublisherInfo(BitmapRef(), repoPackageInfo.Vendor(), "", ""), + repoPackageInfo.Summary(), repoPackageInfo.Description(), ""), + true); + if (modelInfo.Get() == NULL) + return; + } + + BSolverRepository* repository = package->Repository(); + if (dynamic_cast(repository) + != NULL) { + depots[repository->Name()].AddPackage(modelInfo); + } else { + const char* installationLocation = NULL; + if (repository == static_cast( + fPackageManager.SystemRepository())) { + installationLocation = "system"; + } else if (repository == static_cast( + fPackageManager.CommonRepository())) { + installationLocation = "common"; + } else if (repository == static_cast( + fPackageManager.HomeRepository())) { + installationLocation = "home"; + } + + if (installationLocation != NULL) + packageLocations[installationLocation].AddItem(modelInfo.Get()); + } + } + + for (DepotInfoMap::iterator it = depots.begin(); it != depots.end(); ++it) + fModel.AddDepot(it->second); + + for (PackageLocationMap::iterator it = packageLocations.begin(); + it != packageLocations.end(); ++it) { + for (int32 i = 0; i < it->second.CountItems(); i++) { + fModel.SetPackageState(it->second.ItemAt(i), ACTIVATED); + // TODO: indicate the specific installation location + // and verify that the package is in fact activated + // by querying the package roster + } + } - fModel.SetPackageState(wonderbrush, UNINSTALLED); - fModel.SetPackageState(paladin, ACTIVATED); } diff --git a/src/apps/haiku-depot/MainWindow.h b/src/apps/haiku-depot/MainWindow.h index 7b59771b3d..7342f7b02a 100644 --- a/src/apps/haiku-depot/MainWindow.h +++ b/src/apps/haiku-depot/MainWindow.h @@ -38,7 +38,7 @@ private: void _AdoptPackage(const PackageInfoRef& package); void _ClearPackage(); - void _InitDummyModel(); + void _InitModel(); private: FilterView* fFilterView; @@ -49,7 +49,8 @@ private: Model fModel; PackageList fVisiblePackages; - PackageManager fPackageManager; + PackageManager + fPackageManager; }; #endif // MAIN_WINDOW_H