Updates to SoftwareUpdater
Committing work done to make SoftwareUpdater functional. The application will find available updates, confirm with the user to apply updates, download packages and apply them. There are a few bugs and features remaining to be fixed and completed: *Bug with window resizing after packages start downloading- list view does not resize down *Tooltips to be implemented (showing repository and other details) *Proper handling of no network or failed repository connections *Testing of the problem solver *Mode to only check for availability of updates and post notification with results
This commit is contained in:
parent
74972d36d5
commit
ad7783e44d
|
@ -1,10 +1,20 @@
|
|||
SubDir HAIKU_TOP src apps softwareupdater ;
|
||||
|
||||
UsePrivateHeaders interface shared package ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src servers package ] ;
|
||||
|
||||
Application SoftwareUpdater :
|
||||
SoftwareUpdaterApp.cpp
|
||||
SoftwareUpdaterWindow.cpp
|
||||
StripeView.cpp
|
||||
UpdateAction.cpp
|
||||
UpdateManager.cpp
|
||||
WorkingLooper.cpp
|
||||
|
||||
# package_daemon
|
||||
ProblemWindow.cpp
|
||||
|
||||
: be localestub package translation [ TargetLibsupc++ ]
|
||||
: SoftwareUpdater.rdef
|
||||
;
|
||||
|
|
|
@ -9,7 +9,7 @@ resource app_version {
|
|||
variety = B_APPV_BETA,
|
||||
internal = 0,
|
||||
short_info = "SoftwareUpdater",
|
||||
long_info = "Software Updater ©2008-2016 Haiku"
|
||||
long_info = "Software Updater ©2008-2017 Haiku"
|
||||
};
|
||||
|
||||
resource vector_icon {
|
||||
|
|
|
@ -1,41 +1,75 @@
|
|||
/*
|
||||
* Copyright 2016 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2016-2017 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV <kallisti5@unixzen.com>
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
|
||||
#include "SoftwareUpdaterApp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <AppDefs.h>
|
||||
|
||||
#include "SoftwareUpdaterWindow.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "SoftwareUpdater"
|
||||
#include "constants.h"
|
||||
|
||||
|
||||
SoftwareUpdaterApp::SoftwareUpdaterApp()
|
||||
:
|
||||
BApplication("application/x-vnd.haiku-softwareupdater")
|
||||
BApplication("application/x-vnd.haiku-softwareupdater"),
|
||||
fWorker(NULL),
|
||||
fFinalQuitFlag(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SoftwareUpdaterApp::~SoftwareUpdaterApp()
|
||||
{
|
||||
if (fWorker) {
|
||||
fWorker->Lock();
|
||||
fWorker->Quit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SoftwareUpdaterApp::QuitRequested()
|
||||
{
|
||||
if (fFinalQuitFlag)
|
||||
return true;
|
||||
|
||||
// Simulate a cancel request from window- this gives the updater a chance
|
||||
// to quit cleanly
|
||||
if (fWindowMessenger.IsValid()) {
|
||||
fWindowMessenger.SendMessage(kMsgCancel);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareUpdaterApp::ReadyToRun()
|
||||
{
|
||||
SoftwareUpdaterWindow* window = new SoftwareUpdaterWindow();
|
||||
if (window)
|
||||
window->Show();
|
||||
fWorker = new WorkingLooper();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareUpdaterApp::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgRegister:
|
||||
message->FindMessenger(kKeyMessenger, &fWindowMessenger);
|
||||
break;
|
||||
|
||||
case kMsgFinalQuit:
|
||||
fFinalQuitFlag = true;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
|
||||
default:
|
||||
BApplication::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,22 +1,32 @@
|
|||
/*
|
||||
* Copyright 2016 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2016-2017 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV <kallisti5@unixzen.com>
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
#ifndef _SOFTWARE_UPDATER_APP_H
|
||||
#define _SOFTWARE_UPDATER_APP_H
|
||||
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
#include "WorkingLooper.h"
|
||||
|
||||
|
||||
class SoftwareUpdaterApp : public BApplication {
|
||||
public:
|
||||
SoftwareUpdaterApp();
|
||||
~SoftwareUpdaterApp();
|
||||
SoftwareUpdaterApp();
|
||||
~SoftwareUpdaterApp();
|
||||
virtual bool QuitRequested();
|
||||
void ReadyToRun();
|
||||
void MessageReceived(BMessage* message);
|
||||
|
||||
void ReadyToRun();
|
||||
private:
|
||||
WorkingLooper* fWorker;
|
||||
BMessenger fWindowMessenger;
|
||||
bool fFinalQuitFlag;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,121 +1,138 @@
|
|||
/*
|
||||
* Copyright 2016 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2016-2017 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV <kallisti5@unixzen.com>
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "SoftwareUpdaterWindow.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Alert.h>
|
||||
#include <AppDefs.h>
|
||||
#include <Application.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <Catalog.h>
|
||||
#include <ControlLook.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <LayoutUtils.h>
|
||||
#include <Message.h>
|
||||
#include <package/Context.h>
|
||||
#include <package/RefreshRepositoryRequest.h>
|
||||
#include <package/PackageRoster.h>
|
||||
#include <Resources.h>
|
||||
#include <SeparatorView.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <Roster.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "SoftwareUpdater"
|
||||
|
||||
|
||||
const uint32 kMsgUpdate = 'iUPD';
|
||||
const uint32 kMsgExit = 'iEXT';
|
||||
|
||||
|
||||
using namespace BPackageKit;
|
||||
#define B_TRANSLATION_CONTEXT "SoftwareUpdaterWindow"
|
||||
|
||||
|
||||
SoftwareUpdaterWindow::SoftwareUpdaterWindow()
|
||||
:
|
||||
BWindow(BRect(0, 0, 0, 300), "Software Update",
|
||||
B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE),
|
||||
// fUpdateManager(NULL),
|
||||
BWindow(BRect(0, 0, 300, 100),
|
||||
B_TRANSLATE_SYSTEM_NAME("SoftwareUpdater"), B_TITLED_WINDOW,
|
||||
B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE | B_NOT_CLOSABLE),
|
||||
fStripeView(NULL),
|
||||
fHeaderView(NULL),
|
||||
fDetailView(NULL),
|
||||
fUpdateButton(NULL),
|
||||
fCancelButton(NULL)
|
||||
fCancelButton(NULL),
|
||||
fStatusBar(NULL),
|
||||
fIcon(NULL),
|
||||
fCurrentState(STATE_HEAD),
|
||||
fWaitingSem(-1),
|
||||
fWaitingForButton(false),
|
||||
fUserCancelRequested(false)
|
||||
{
|
||||
fUpdateManager = new UpdateManager(
|
||||
BPackageKit::B_PACKAGE_INSTALLATION_LOCATION_HOME);
|
||||
fUpdateManager->SetDebugLevel(10);
|
||||
fUpdateManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES
|
||||
| BPackageManager::B_ADD_REMOTE_REPOSITORIES);
|
||||
|
||||
BBitmap* icon = new BBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32);
|
||||
fIcon = new BBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32);
|
||||
team_info teamInfo;
|
||||
get_team_info(B_CURRENT_TEAM, &teamInfo);
|
||||
app_info appInfo;
|
||||
be_roster->GetRunningAppInfo(teamInfo.team, &appInfo);
|
||||
BNodeInfo::GetTrackerIcon(&appInfo.ref, icon, B_LARGE_ICON);
|
||||
BNodeInfo::GetTrackerIcon(&appInfo.ref, fIcon, B_LARGE_ICON);
|
||||
|
||||
fStripeView = new StripeView(icon);
|
||||
fStripeView = new StripeView(fIcon);
|
||||
|
||||
BButton* fUpdateButton = new BButton("Update now",
|
||||
new BMessage(kMsgUpdate));
|
||||
fUpdateButton->Hide();
|
||||
|
||||
BButton* fCancelButton = new BButton("Cancel",
|
||||
new BMessage(kMsgExit));
|
||||
fUpdateButton = new BButton(B_TRANSLATE("Update now"),
|
||||
new BMessage(kMsgUpdateConfirmed));
|
||||
fUpdateButton->MakeDefault(true);
|
||||
// fUpdateButton->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_UNSET,
|
||||
// B_ALIGN_BOTTOM));
|
||||
fCancelButton = new BButton(B_TRANSLATE("Cancel"),
|
||||
new BMessage(kMsgCancel));
|
||||
// fCancelButton->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_UNSET,
|
||||
// B_ALIGN_BOTTOM));
|
||||
|
||||
fHeaderView = new BStringView("header",
|
||||
"Checking for updates...", B_WILL_DRAW);
|
||||
fDetailView = new BStringView("detail", "Contacting software repositories"
|
||||
" to check for package updates.", B_WILL_DRAW);
|
||||
B_TRANSLATE("Checking for updates"), B_WILL_DRAW);
|
||||
fHeaderView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
|
||||
fHeaderView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
|
||||
fDetailView = new BStringView("detail", B_TRANSLATE("Contacting software "
|
||||
"repositories to check for package updates."), B_WILL_DRAW);
|
||||
fDetailView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
|
||||
fDetailView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
|
||||
fStatusBar = new BStatusBar("progress");
|
||||
fStatusBar->SetMaxValue(1.0);
|
||||
|
||||
fListView = new PackageListView();
|
||||
fScrollView = new BScrollView("scrollview", fListView, B_WILL_DRAW,
|
||||
false, true);
|
||||
|
||||
BFont font;
|
||||
fHeaderView->GetFont(&font);
|
||||
font.SetFace(B_BOLD_FACE);
|
||||
font.SetSize(font.Size() * 1.5);
|
||||
fHeaderView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
|
||||
| B_FONT_FLAGS);
|
||||
|
||||
fHeaderView->SetFont(&font,
|
||||
B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE | B_FONT_FLAGS);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0)
|
||||
.Add(fStripeView)
|
||||
.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
|
||||
.SetInsets(0, B_USE_DEFAULT_SPACING,
|
||||
B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
|
||||
.Add(fHeaderView)
|
||||
.Add(fDetailView)
|
||||
.AddStrut(B_USE_DEFAULT_SPACING)
|
||||
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
|
||||
.AddGroup(B_VERTICAL, 0)
|
||||
.SetInsets(0, B_USE_WINDOW_SPACING,
|
||||
B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING)
|
||||
.AddGroup(new BGroupView(B_VERTICAL, B_USE_ITEM_SPACING))
|
||||
.Add(fHeaderView)
|
||||
.Add(fDetailView)
|
||||
.Add(fStatusBar)
|
||||
.Add(fScrollView)
|
||||
.End()
|
||||
.AddStrut(B_USE_SMALL_SPACING)
|
||||
.AddGroup(new BGroupView(B_HORIZONTAL))
|
||||
.AddGlue()
|
||||
.Add(fCancelButton)
|
||||
.Add(fUpdateButton)
|
||||
.End()
|
||||
.End()
|
||||
.AddGlue()
|
||||
//.Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
|
||||
;
|
||||
.End();
|
||||
|
||||
fDetailsLayoutItem = layout_item_for(fDetailView);
|
||||
fProgressLayoutItem = layout_item_for(fStatusBar);
|
||||
fPackagesLayoutItem = layout_item_for(fScrollView);
|
||||
fUpdateButtonLayoutItem = layout_item_for(fUpdateButton);
|
||||
|
||||
_SetState(STATE_DISPLAY_STATUS);
|
||||
CenterOnScreen();
|
||||
Show();
|
||||
|
||||
// Refresh our repos and update UI
|
||||
_Refresh();
|
||||
SetFlags(Flags() ^ B_AUTO_UPDATE_SIZE_LIMITS);
|
||||
|
||||
// Prevent resizing for now
|
||||
fDefaultRect = Bounds();
|
||||
SetSizeLimits(fDefaultRect.Width(), fDefaultRect.Width(),
|
||||
fDefaultRect.Height(), fDefaultRect.Height());
|
||||
|
||||
BMessage registerMessage(kMsgRegister);
|
||||
registerMessage.AddMessenger(kKeyMessenger, BMessenger(this));
|
||||
be_app->PostMessage(®isterMessage);
|
||||
|
||||
fCancelAlertResponse.SetMessage(new BMessage(kMsgCancelResponse));
|
||||
fCancelAlertResponse.SetTarget(this);
|
||||
}
|
||||
|
||||
|
||||
SoftwareUpdaterWindow::~SoftwareUpdaterWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SoftwareUpdaterWindow::QuitRequested()
|
||||
{
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
delete fIcon;
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,54 +140,628 @@ void
|
|||
SoftwareUpdaterWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgExit:
|
||||
QuitRequested();
|
||||
|
||||
case kMsgTextUpdate:
|
||||
{
|
||||
if (fCurrentState == STATE_DISPLAY_PROGRESS)
|
||||
_SetState(STATE_DISPLAY_STATUS);
|
||||
else if (fCurrentState != STATE_DISPLAY_STATUS)
|
||||
break;
|
||||
|
||||
BString header;
|
||||
BString detail;
|
||||
Lock();
|
||||
status_t result = message->FindString(kKeyHeader, &header);
|
||||
if (result == B_OK && header != fHeaderView->Text())
|
||||
fHeaderView->SetText(header.String());
|
||||
result = message->FindString(kKeyDetail, &detail);
|
||||
if (result == B_OK)
|
||||
fDetailView->SetText(detail.String());
|
||||
Unlock();
|
||||
break;
|
||||
case kMsgUpdate:
|
||||
}
|
||||
|
||||
case kMsgProgressUpdate:
|
||||
{
|
||||
if (fCurrentState == STATE_DISPLAY_STATUS)
|
||||
_SetState(STATE_DISPLAY_PROGRESS);
|
||||
else if (fCurrentState != STATE_DISPLAY_PROGRESS)
|
||||
break;
|
||||
|
||||
BString packageName;
|
||||
status_t result = message->FindString(kKeyPackageName, &packageName);
|
||||
if (result != B_OK)
|
||||
break;
|
||||
BString packageCount;
|
||||
result = message->FindString(kKeyPackageCount, &packageCount);
|
||||
if (result != B_OK)
|
||||
break;
|
||||
float percent;
|
||||
result = message->FindFloat(kKeyPercentage, &percent);
|
||||
if (result != B_OK)
|
||||
break;
|
||||
|
||||
BString header;
|
||||
Lock();
|
||||
result = message->FindString(kKeyHeader, &header);
|
||||
if (result == B_OK && header != fHeaderView->Text())
|
||||
fHeaderView->SetText(header.String());
|
||||
fStatusBar->SetTo(percent, packageName.String(),
|
||||
packageCount.String());
|
||||
Unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgCancel:
|
||||
{
|
||||
BAlert* alert = new BAlert("cancel request", B_TRANSLATE("Updates"
|
||||
" have not been completed, are you sure you want to quit?"),
|
||||
B_TRANSLATE("Quit"), B_TRANSLATE("Don't quit"), NULL,
|
||||
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
||||
alert->Go(&fCancelAlertResponse);
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgCancelResponse:
|
||||
{
|
||||
// Verify whether the cancel request was confirmed
|
||||
int32 selection = -1;
|
||||
message->FindInt32("which", &selection);
|
||||
if (selection != 0)
|
||||
break;
|
||||
|
||||
Lock();
|
||||
fHeaderView->SetText(B_TRANSLATE("Cancelling updates"));
|
||||
fDetailView->SetText(
|
||||
B_TRANSLATE("Attempting to cancel the updates..."));
|
||||
Unlock();
|
||||
fUserCancelRequested = true;
|
||||
|
||||
if (fWaitingForButton) {
|
||||
fButtonResult = message->what;
|
||||
delete_sem(fWaitingSem);
|
||||
fWaitingSem = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kMsgUpdateConfirmed:
|
||||
{
|
||||
if (fWaitingForButton) {
|
||||
fButtonResult = message->what;
|
||||
delete_sem(fWaitingSem);
|
||||
fWaitingSem = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareUpdaterWindow::_Error(const char* error)
|
||||
bool
|
||||
SoftwareUpdaterWindow::ConfirmUpdates(const char* text)
|
||||
{
|
||||
fHeaderView->SetText("Error encountered!");
|
||||
fDetailView->SetText(error);
|
||||
fUpdateButton->Hide();
|
||||
fCancelButton->Show();
|
||||
Lock();
|
||||
fHeaderView->SetText(B_TRANSLATE("Updates found"));
|
||||
fDetailView->SetText(text);
|
||||
fListView->SortItems();
|
||||
Unlock();
|
||||
|
||||
uint32 priorState = _GetState();
|
||||
_SetState(STATE_GET_CONFIRMATION);
|
||||
|
||||
_WaitForButtonClick();
|
||||
_SetState(priorState);
|
||||
return fButtonResult == kMsgUpdateConfirmed;
|
||||
}
|
||||
|
||||
void
|
||||
SoftwareUpdaterWindow::_Refresh()
|
||||
{
|
||||
BPackageRoster roster;
|
||||
BStringList repoNames(20);
|
||||
|
||||
status_t result = roster.GetRepositoryNames(repoNames);
|
||||
if (result != B_OK) {
|
||||
_Error("Unable to obtain repository names.");
|
||||
void
|
||||
SoftwareUpdaterWindow::UpdatesApplying(const char* header, const char* detail)
|
||||
{
|
||||
Lock();
|
||||
fHeaderView->SetText(header);
|
||||
fDetailView->SetText(detail);
|
||||
Unlock();
|
||||
_SetState(STATE_APPLY_UPDATES);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SoftwareUpdaterWindow::UserCancelRequested()
|
||||
{
|
||||
if (_GetState() > STATE_GET_CONFIRMATION)
|
||||
return false;
|
||||
|
||||
return fUserCancelRequested;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareUpdaterWindow::AddPackageInfo(uint32 install_type,
|
||||
const char* package_name, const char* cur_ver, const char* new_ver,
|
||||
const char* summary, const char* repository)
|
||||
{
|
||||
Lock();
|
||||
fListView->AddPackage(install_type, package_name, cur_ver, new_ver,
|
||||
summary, repository);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
|
||||
BLayoutItem*
|
||||
SoftwareUpdaterWindow::layout_item_for(BView* view)
|
||||
{
|
||||
BLayout* layout = view->Parent()->GetLayout();
|
||||
int32 index = layout->IndexOfView(view);
|
||||
return layout->ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
SoftwareUpdaterWindow::_WaitForButtonClick()
|
||||
{
|
||||
fButtonResult = 0;
|
||||
fWaitingForButton = true;
|
||||
fWaitingSem = create_sem(0, "WaitingSem");
|
||||
while (acquire_sem(fWaitingSem) == B_INTERRUPTED) {
|
||||
}
|
||||
fWaitingForButton = false;
|
||||
return fButtonResult;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareUpdaterWindow::_SetState(uint32 state)
|
||||
{
|
||||
if (state <= STATE_HEAD || state >= STATE_MAX)
|
||||
return;
|
||||
|
||||
Lock();
|
||||
|
||||
// Initial settings
|
||||
if (fCurrentState == STATE_HEAD) {
|
||||
fProgressLayoutItem->SetVisible(false);
|
||||
fPackagesLayoutItem->SetVisible(false);
|
||||
}
|
||||
fCurrentState = state;
|
||||
|
||||
// Update confirmation button
|
||||
// Show only when asking for confirmation to update
|
||||
if (fCurrentState == STATE_GET_CONFIRMATION)
|
||||
fUpdateButtonLayoutItem->SetVisible(true);
|
||||
else
|
||||
fUpdateButtonLayoutItem->SetVisible(false);
|
||||
|
||||
// View package info view
|
||||
// Show at confirmation prompt, hide at final update
|
||||
if (fCurrentState == STATE_GET_CONFIRMATION) {
|
||||
fPackagesLayoutItem->SetVisible(true);
|
||||
// Re-enable resizing
|
||||
SetSizeLimits(fDefaultRect.Width(), 9999,
|
||||
fDefaultRect.Height() + fListView->MinSize().Height() + 30, 9999);
|
||||
ResizeTo(Bounds().Width(), 400);
|
||||
}
|
||||
|
||||
// Progress bar and string view
|
||||
// Hide detail text while showing status bar
|
||||
if (fCurrentState == STATE_DISPLAY_PROGRESS) {
|
||||
fDetailsLayoutItem->SetVisible(false);
|
||||
fProgressLayoutItem->SetVisible(true);
|
||||
}
|
||||
else {
|
||||
fProgressLayoutItem->SetVisible(false);
|
||||
fDetailsLayoutItem->SetVisible(true);
|
||||
}
|
||||
|
||||
// Cancel button
|
||||
fCancelButton->SetEnabled(fCurrentState != STATE_APPLY_UPDATES);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
for (int i = 0; i < repoNames.CountStrings(); i++) {
|
||||
const BString& repoName = repoNames.StringAt(i);
|
||||
BRepositoryConfig repoConfig;
|
||||
result = roster.GetRepositoryConfig(repoName, &repoConfig);
|
||||
if (result != B_OK) {
|
||||
printf("Skipping '%s' repo due to unknown config\n",
|
||||
repoName.String());
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
BRefreshRepositoryRequest request(context, repoConfig);
|
||||
result = request.Process();
|
||||
if (result != B_OK) {
|
||||
printf("Skipping %s repo due to unreachable repo");
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
uint32
|
||||
SoftwareUpdaterWindow::_GetState()
|
||||
{
|
||||
return fCurrentState;
|
||||
}
|
||||
|
||||
|
||||
SuperItem::SuperItem(const char* label)
|
||||
:
|
||||
BListItem(),
|
||||
fLabel(label),
|
||||
fPackageIcon(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SuperItem::~SuperItem()
|
||||
{
|
||||
delete fPackageIcon;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SuperItem::DrawItem(BView* owner, BRect item_rect, bool complete)
|
||||
{
|
||||
float width;
|
||||
owner->GetPreferredSize(&width, NULL);
|
||||
BString label(fLabel);
|
||||
owner->TruncateString(&label, B_TRUNCATE_END, width);
|
||||
owner->SetFont(&fBoldFont);
|
||||
owner->DrawString(label.String(), BPoint(item_rect.left,
|
||||
item_rect.bottom - fFontHeight.descent - 1));
|
||||
owner->SetFont(&fRegularFont);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SuperItem::Update(BView *owner, const BFont *font)
|
||||
{
|
||||
fRegularFont = *font;
|
||||
fBoldFont = *font;
|
||||
fBoldFont.SetFace(B_BOLD_FACE);
|
||||
BListItem::Update(owner, &fBoldFont);
|
||||
|
||||
// Calculate height for PackageItem
|
||||
fRegularFont.GetHeight(&fFontHeight);
|
||||
fPackageItemHeight = 2 * (fFontHeight.ascent + fFontHeight.descent
|
||||
+ fFontHeight.leading);
|
||||
|
||||
// Calculate height for this item
|
||||
fBoldFont.GetHeight(&fFontHeight);
|
||||
SetHeight(fFontHeight.ascent + fFontHeight.descent
|
||||
+ fFontHeight.leading + 4);
|
||||
|
||||
_GetPackageIcon();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SuperItem::_GetPackageIcon()
|
||||
{
|
||||
delete fPackageIcon;
|
||||
fIconSize = int(fPackageItemHeight * .7);
|
||||
|
||||
status_t result = B_ERROR;
|
||||
BRect iconRect(0, 0, fIconSize - 1, fIconSize - 1);
|
||||
fPackageIcon = new BBitmap(iconRect, 0, B_RGBA32);
|
||||
BMimeType nodeType;
|
||||
nodeType.SetTo("application/x-vnd.haiku-package");
|
||||
result = nodeType.GetIcon(fPackageIcon, icon_size(fIconSize));
|
||||
// Get super type icon
|
||||
if (result != B_OK) {
|
||||
BMimeType superType;
|
||||
if (nodeType.GetSupertype(&superType) == B_OK)
|
||||
result = superType.GetIcon(fPackageIcon, icon_size(fIconSize));
|
||||
}
|
||||
if (result != B_OK) {
|
||||
delete fPackageIcon;
|
||||
fPackageIcon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PackageItem::PackageItem(const char* name, const char* version,
|
||||
const char* summary, const char* tooltip, SuperItem* super)
|
||||
:
|
||||
BListItem(),
|
||||
fName(name),
|
||||
fVersion(version),
|
||||
fSummary(summary),
|
||||
fTooltip(tooltip),
|
||||
fSuperItem(super)
|
||||
{
|
||||
fLabelOffset = be_control_look->DefaultLabelSpacing();
|
||||
// SetToolTip(fTooltip);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageItem::DrawItem(BView* owner, BRect item_rect, bool complete)
|
||||
{
|
||||
float width;
|
||||
owner->GetPreferredSize(&width, NULL);
|
||||
float nameWidth = width / 2.0;
|
||||
float offset_width = 0;
|
||||
|
||||
BBitmap* icon = fSuperItem->GetIcon();
|
||||
if (icon != NULL && icon->IsValid()) {
|
||||
int16 iconSize = fSuperItem->GetIconSize();
|
||||
float offsetMarginHeight = floor((Height() - iconSize) / 2);
|
||||
|
||||
//owner->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
|
||||
owner->SetDrawingMode(B_OP_ALPHA);
|
||||
owner->DrawBitmap(icon, BPoint(item_rect.left,
|
||||
item_rect.top + offsetMarginHeight));
|
||||
owner->SetDrawingMode(B_OP_COPY);
|
||||
offset_width += iconSize + fLabelOffset;
|
||||
}
|
||||
|
||||
// Package name
|
||||
font_height fontHeight = fSuperItem->GetFontHeight();
|
||||
BString name(fName);
|
||||
owner->TruncateString(&name, B_TRUNCATE_END, nameWidth);
|
||||
BPoint cursor(item_rect.left + offset_width,
|
||||
item_rect.bottom - fSmallTotalHeight - fontHeight.descent - 1);
|
||||
owner->DrawString(name.String(), cursor);
|
||||
cursor.x += owner->StringWidth(name.String()) + fLabelOffset;
|
||||
|
||||
// Change font and color
|
||||
owner->SetFont(&fSmallFont);
|
||||
owner->SetHighColor(tint_color(ui_color(B_LIST_ITEM_TEXT_COLOR), 0.7));
|
||||
|
||||
// Version
|
||||
BString version(fVersion);
|
||||
owner->TruncateString(&version, B_TRUNCATE_END, width - cursor.x);
|
||||
owner->DrawString(version.String(), cursor);
|
||||
|
||||
// Summary
|
||||
BString summary(fSummary);
|
||||
cursor.x = item_rect.left + offset_width;
|
||||
cursor.y = item_rect.bottom - fontHeight.descent;
|
||||
owner->TruncateString(&summary, B_TRUNCATE_END, width - cursor.x);
|
||||
owner->DrawString(summary.String(), cursor);
|
||||
|
||||
owner->SetFont(&fRegularFont);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageItem::Update(BView *owner, const BFont *font)
|
||||
{
|
||||
BListItem::Update(owner, font);
|
||||
SetItemHeight(font);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageItem::SetItemHeight(const BFont* font)
|
||||
{
|
||||
SetHeight(fSuperItem->GetPackageItemHeight());
|
||||
|
||||
fRegularFont = *font;
|
||||
fSmallFont = *font;
|
||||
fSmallFont.SetSize(font->Size() - 2);
|
||||
fSmallFont.GetHeight(&fSmallFontHeight);
|
||||
fSmallTotalHeight = fSmallFontHeight.ascent + fSmallFontHeight.descent
|
||||
+ fSmallFontHeight.leading;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PackageItem::ICompare(PackageItem* item)
|
||||
{
|
||||
// sort by package name
|
||||
return fName.ICompare(item->fName);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SortPackageItems(const BListItem* item1, const BListItem* item2)
|
||||
{
|
||||
PackageItem* first = (PackageItem*)item1;
|
||||
PackageItem* second = (PackageItem*)item2;
|
||||
return first->ICompare(second);
|
||||
}
|
||||
|
||||
|
||||
PackageListView::PackageListView()
|
||||
:
|
||||
BOutlineListView("Package list"),
|
||||
fSuperUpdateItem(NULL),
|
||||
fSuperInstallItem(NULL),
|
||||
fSuperUninstallItem(NULL)
|
||||
{
|
||||
SetExplicitMinSize(BSize(B_SIZE_UNSET, 40));
|
||||
SetExplicitPreferredSize(BSize(B_SIZE_UNSET, 400));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageListView::FrameResized(float newWidth, float newHeight)
|
||||
{
|
||||
BListView::FrameResized(newWidth, newHeight);
|
||||
|
||||
float count = CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BListItem *item = ItemAt(i);
|
||||
item->Update(this, be_plain_font);
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageListView::AddPackage(uint32 install_type, const char* name,
|
||||
const char* cur_ver, const char* new_ver, const char* summary,
|
||||
const char* repository)
|
||||
{
|
||||
SuperItem* super;
|
||||
BString version;
|
||||
BString tooltip;
|
||||
switch (install_type) {
|
||||
case PACKAGE_UPDATE:
|
||||
{
|
||||
if (fSuperUpdateItem == NULL) {
|
||||
fSuperUpdateItem = new SuperItem(
|
||||
B_TRANSLATE("Packages to be updated"));
|
||||
AddItem(fSuperUpdateItem);
|
||||
}
|
||||
super = fSuperUpdateItem;
|
||||
|
||||
version.SetTo(new_ver);
|
||||
tooltip.SetTo(B_TRANSLATE("Repository:"));
|
||||
tooltip.Append(" ").Append(repository)
|
||||
.Append("\n").Append(B_TRANSLATE("Update version"))
|
||||
.Append(" ").Append(cur_ver)
|
||||
.Append(" ").Append(B_TRANSLATE("to"))
|
||||
.Append(" ").Append(new_ver);
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKAGE_INSTALL:
|
||||
{
|
||||
if (fSuperInstallItem == NULL) {
|
||||
fSuperInstallItem = new SuperItem(
|
||||
B_TRANSLATE("New packages to be installed"));
|
||||
AddItem(fSuperInstallItem);
|
||||
}
|
||||
super = fSuperInstallItem;
|
||||
|
||||
version.SetTo(new_ver);
|
||||
tooltip.SetTo(B_TRANSLATE("Repository:"));
|
||||
tooltip.Append(" ").Append(repository)
|
||||
.Append("\n").Append(B_TRANSLATE("Install version"))
|
||||
.Append(" ").Append(new_ver);
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKAGE_UNINSTALL:
|
||||
{
|
||||
if (fSuperUninstallItem == NULL) {
|
||||
fSuperUninstallItem = new SuperItem(
|
||||
B_TRANSLATE("Packages to be uninstalled"));
|
||||
AddItem(fSuperUninstallItem);
|
||||
}
|
||||
super = fSuperUninstallItem;
|
||||
|
||||
version.SetTo("");
|
||||
tooltip.SetTo(B_TRANSLATE("Repository:"));
|
||||
tooltip.Append(" ").Append(repository)
|
||||
.Append("\n").Append(B_TRANSLATE("Uninstall version"))
|
||||
.Append(" ").Append(new_ver);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
PackageItem* item = new PackageItem(name, version.String(), summary,
|
||||
tooltip.String(), super);
|
||||
AddUnder(item, super);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageListView::SortItems()
|
||||
{
|
||||
if (fSuperUpdateItem != NULL)
|
||||
SortItemsUnder(fSuperUpdateItem, true, SortPackageItems);
|
||||
}
|
||||
|
||||
/*
|
||||
BSize
|
||||
PackageListView::PreferredSize()
|
||||
{
|
||||
return BSize(B_SIZE_UNSET, 200);
|
||||
}*/
|
||||
|
||||
/*
|
||||
void
|
||||
PackageListView::GetPreferredSize(float* _width, float* _height)
|
||||
{
|
||||
// TODO: Something more nice as default? I need to see how this looks
|
||||
// when there are actually any packages...
|
||||
if (_width != NULL)
|
||||
*_width = 400.0;
|
||||
|
||||
if (_height != NULL)
|
||||
*_height = 200.0;
|
||||
}*/
|
||||
|
||||
/*
|
||||
BSize
|
||||
PackageListView::MaxSize()
|
||||
{
|
||||
return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
|
||||
BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
FinalWindow::FinalWindow(BRect rect, BPoint location, const char* header,
|
||||
const char* detail)
|
||||
:
|
||||
BWindow(rect,
|
||||
B_TRANSLATE_SYSTEM_NAME("SoftwareUpdater"), B_TITLED_WINDOW,
|
||||
B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE
|
||||
| B_NOT_CLOSABLE | B_NOT_RESIZABLE),
|
||||
fHeaderView(NULL),
|
||||
fDetailView(NULL),
|
||||
fCancelButton(NULL)
|
||||
{
|
||||
fIcon = new BBitmap(BRect(0, 0, 31, 31), 0, B_RGBA32);
|
||||
team_info teamInfo;
|
||||
get_team_info(B_CURRENT_TEAM, &teamInfo);
|
||||
app_info appInfo;
|
||||
be_roster->GetRunningAppInfo(teamInfo.team, &appInfo);
|
||||
BNodeInfo::GetTrackerIcon(&appInfo.ref, fIcon, B_LARGE_ICON);
|
||||
|
||||
SetSizeLimits(rect.Width(), B_SIZE_UNLIMITED, 0, B_SIZE_UNLIMITED);
|
||||
fStripeView = new StripeView(fIcon);
|
||||
fHeaderView = new BStringView("header", header, B_WILL_DRAW);
|
||||
fHeaderView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
|
||||
fHeaderView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
|
||||
fDetailView = new BStringView("detail", detail, B_WILL_DRAW);
|
||||
fDetailView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
|
||||
fDetailView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP));
|
||||
fCancelButton = new BButton(B_TRANSLATE("Quit"),
|
||||
new BMessage(kMsgCancel));
|
||||
fCancelButton->MakeDefault(true);
|
||||
|
||||
BFont font;
|
||||
fHeaderView->GetFont(&font);
|
||||
font.SetFace(B_BOLD_FACE);
|
||||
font.SetSize(font.Size() * 1.5);
|
||||
fHeaderView->SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE
|
||||
| B_FONT_FLAGS);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_HORIZONTAL, 0)
|
||||
.Add(fStripeView)
|
||||
.AddGroup(B_VERTICAL, 0)
|
||||
.SetInsets(0, B_USE_WINDOW_SPACING,
|
||||
B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING)
|
||||
.AddGroup(B_VERTICAL, B_USE_ITEM_SPACING)
|
||||
.Add(fHeaderView)
|
||||
.Add(fDetailView)
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.AddGlue()
|
||||
.Add(fCancelButton)
|
||||
.End()
|
||||
.End()
|
||||
.End()
|
||||
.End();
|
||||
|
||||
MoveTo(location);
|
||||
Show();
|
||||
}
|
||||
|
||||
|
||||
FinalWindow::~FinalWindow()
|
||||
{
|
||||
delete fIcon;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FinalWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
|
||||
case kMsgCancel:
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
be_app->PostMessage(kMsgFinalQuit);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,181 @@
|
|||
/*
|
||||
* Copyright 2016 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2016-2017 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV <kallisti5@unixzen.com>
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
#ifndef _SOFTWARE_UPDATER_WINDOW_H
|
||||
#define _SOFTWARE_UPDATER_WINDOW_H
|
||||
|
||||
|
||||
#include <Button.h>
|
||||
#include <Roster.h>
|
||||
#include <GroupView.h>
|
||||
#include <OutlineListView.h>
|
||||
#include <Point.h>
|
||||
#include <ScrollView.h>
|
||||
#include <StatusBar.h>
|
||||
#include <StringView.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "StripeView.h"
|
||||
#include "UpdateManager.h"
|
||||
|
||||
using namespace BPrivate;
|
||||
|
||||
enum {
|
||||
PACKAGE_UPDATE,
|
||||
PACKAGE_INSTALL,
|
||||
PACKAGE_UNINSTALL
|
||||
};
|
||||
|
||||
|
||||
class SuperItem : public BListItem {
|
||||
public:
|
||||
SuperItem(const char* label);
|
||||
~SuperItem();
|
||||
virtual void DrawItem(BView*, BRect, bool);
|
||||
virtual void Update(BView *owner, const BFont *font);
|
||||
font_height GetFontHeight() { return fFontHeight; };
|
||||
float GetPackageItemHeight()
|
||||
{ return fPackageItemHeight; };
|
||||
BBitmap* GetIcon() { return fPackageIcon; };
|
||||
int16 GetIconSize() { return fIconSize; };
|
||||
|
||||
private:
|
||||
void _GetPackageIcon();
|
||||
|
||||
BString fLabel;
|
||||
BFont fRegularFont;
|
||||
BFont fBoldFont;
|
||||
font_height fFontHeight;
|
||||
float fPackageItemHeight;
|
||||
BBitmap* fPackageIcon;
|
||||
int16 fIconSize;
|
||||
};
|
||||
|
||||
|
||||
class PackageItem : public BListItem {
|
||||
public:
|
||||
PackageItem(const char* name,
|
||||
const char* version,
|
||||
const char* summary,
|
||||
const char* tooltip,
|
||||
SuperItem* super);
|
||||
virtual void DrawItem(BView*, BRect, bool);
|
||||
virtual void Update(BView *owner, const BFont *font);
|
||||
void SetItemHeight(const BFont* font);
|
||||
int ICompare(PackageItem* item);
|
||||
|
||||
private:
|
||||
BString fName;
|
||||
BString fVersion;
|
||||
BString fSummary;
|
||||
BString fTooltip;
|
||||
BFont fRegularFont;
|
||||
BFont fSmallFont;
|
||||
font_height fSmallFontHeight;
|
||||
float fSmallTotalHeight;
|
||||
float fLabelOffset;
|
||||
SuperItem* fSuperItem;
|
||||
};
|
||||
|
||||
|
||||
class PackageListView : public BOutlineListView {
|
||||
public:
|
||||
PackageListView();
|
||||
virtual void FrameResized(float newWidth, float newHeight);
|
||||
// virtual BSize PreferredSize();
|
||||
// virtual void GetPreferredSize(float* _width, float* _height);
|
||||
// virtual BSize MaxSize();
|
||||
void AddPackage(uint32 install_type,
|
||||
const char* name,
|
||||
const char* cur_ver,
|
||||
const char* new_ver,
|
||||
const char* summary,
|
||||
const char* repository);
|
||||
void SortItems();
|
||||
|
||||
private:
|
||||
SuperItem* fSuperUpdateItem;
|
||||
SuperItem* fSuperInstallItem;
|
||||
SuperItem* fSuperUninstallItem;
|
||||
};
|
||||
|
||||
|
||||
class SoftwareUpdaterWindow : public BWindow {
|
||||
public:
|
||||
SoftwareUpdaterWindow();
|
||||
~SoftwareUpdaterWindow();
|
||||
bool QuitRequested();
|
||||
|
||||
void MessageReceived(BMessage* message);
|
||||
bool ConfirmUpdates(const char* text);
|
||||
void UpdatesApplying(const char* header,
|
||||
const char* detail);
|
||||
bool UserCancelRequested();
|
||||
void AddPackageInfo(uint32 install_type,
|
||||
const char* package_name,
|
||||
const char* cur_ver,
|
||||
const char* new_ver,
|
||||
const char* summary,
|
||||
const char* repository);
|
||||
const BBitmap* GetIcon() { return fIcon; };
|
||||
BRect GetDefaultRect() { return fDefaultRect; };
|
||||
BPoint GetLocation() { return Frame().LeftTop(); };
|
||||
BLayoutItem* layout_item_for(BView* view);
|
||||
|
||||
private:
|
||||
void _Error(const char* error);
|
||||
void _Refresh();
|
||||
|
||||
UpdateManager* fUpdateManager;
|
||||
uint32 _WaitForButtonClick();
|
||||
void _SetState(uint32 state);
|
||||
uint32 _GetState();
|
||||
|
||||
BRect fDefaultRect;
|
||||
StripeView* fStripeView;
|
||||
app_info* fAppInfo;
|
||||
|
||||
BStringView* fHeaderView;
|
||||
BStringView* fDetailView;
|
||||
BButton* fUpdateButton;
|
||||
BButton* fCancelButton;
|
||||
BStatusBar* fStatusBar;
|
||||
#if USE_PANE_SWITCH
|
||||
PaneSwitch* fPackagesSwitch;
|
||||
BLayoutItem* fPkgSwitchLayoutItem;
|
||||
#endif
|
||||
PackageListView* fListView;
|
||||
BScrollView* fScrollView;
|
||||
BLayoutItem* fDetailsLayoutItem;
|
||||
BLayoutItem* fPackagesLayoutItem;
|
||||
BLayoutItem* fProgressLayoutItem;
|
||||
BLayoutItem* fUpdateButtonLayoutItem;
|
||||
BBitmap* fIcon;
|
||||
|
||||
uint32 fCurrentState;
|
||||
sem_id fWaitingSem;
|
||||
bool fWaitingForButton;
|
||||
uint32 fButtonResult;
|
||||
bool fUserCancelRequested;
|
||||
BInvoker fCancelAlertResponse;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
int SortPackageItems(const BListItem* item1, const BListItem* item2);
|
||||
|
||||
|
||||
class FinalWindow : public BWindow {
|
||||
public:
|
||||
FinalWindow(BRect rect, BPoint location,
|
||||
const char* header, const char* detail);
|
||||
~FinalWindow();
|
||||
|
||||
void MessageReceived(BMessage* message);
|
||||
private:
|
||||
|
||||
StripeView* fStripeView;
|
||||
BStringView* fHeaderView;
|
||||
BStringView* fDetailView;
|
||||
BButton* fCancelButton;
|
||||
BBitmap* fIcon;
|
||||
};
|
||||
|
||||
|
||||
#endif // _SOFTWARE_UPDATER_WINDOW_H
|
||||
|
|
|
@ -26,7 +26,7 @@ StripeView::StripeView(BBitmap* icon)
|
|||
if (icon != NULL)
|
||||
width += icon->Bounds().Width() + 32.0f;
|
||||
|
||||
SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
|
||||
SetExplicitSize(BSize(width, B_SIZE_UNSET));
|
||||
SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,6 @@ StripeView::SetIcon(BBitmap* icon)
|
|||
if (icon != NULL)
|
||||
width += icon->Bounds().Width() + 32.0f;
|
||||
|
||||
SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
|
||||
SetExplicitSize(BSize(width, B_SIZE_UNSET));
|
||||
SetExplicitPreferredSize(BSize(width, B_SIZE_UNLIMITED));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright 2017, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "UpdateAction.h"
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <Catalog.h>
|
||||
#include <package/manager/Exceptions.h>
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "UpdateAction"
|
||||
|
||||
|
||||
using namespace BPackageKit;
|
||||
//using namespace BPackageKit::BPrivate;
|
||||
using namespace BPackageKit::BManager::BPrivate;
|
||||
|
||||
|
||||
UpdateAction::UpdateAction()
|
||||
{
|
||||
fUpdateManager = new(std::nothrow)
|
||||
UpdateManager(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
|
||||
}
|
||||
|
||||
|
||||
UpdateAction::~UpdateAction()
|
||||
{
|
||||
delete fUpdateManager;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
UpdateAction::Perform()
|
||||
{
|
||||
fUpdateManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES
|
||||
| BPackageManager::B_ADD_REMOTE_REPOSITORIES
|
||||
| BPackageManager::B_REFRESH_REPOSITORIES);
|
||||
|
||||
try {
|
||||
// These values indicate that all updates should be installed
|
||||
int packageCount = 0;
|
||||
const char* const packages = "";
|
||||
|
||||
// perform the update
|
||||
// fUpdateManager->SetDebugLevel(1);
|
||||
fUpdateManager->Update(&packages, packageCount);
|
||||
} catch (BFatalErrorException ex) {
|
||||
BString errorString;
|
||||
errorString.SetToFormat(
|
||||
"Fatal error occurred while updating packages: "
|
||||
"%s (%s)\n", ex.Message().String(),
|
||||
ex.Details().String());
|
||||
BAlert* alert(new(std::nothrow) BAlert(B_TRANSLATE("Fatal error"),
|
||||
errorString, B_TRANSLATE("Close"), NULL, NULL,
|
||||
B_WIDTH_AS_USUAL, B_STOP_ALERT));
|
||||
if (alert != NULL)
|
||||
alert->Go();
|
||||
fUpdateManager->FinalUpdate(B_TRANSLATE("Updates did not complete"),
|
||||
ex.Message());
|
||||
return ex.Error();
|
||||
} catch (BAbortedByUserException ex) {
|
||||
fprintf(stderr, "Updates aborted by user: %s\n",
|
||||
ex.Message().String());
|
||||
// No need for a final message since user initiated cancel request
|
||||
// Note: activate FinalUpdate() call for testing final message window
|
||||
//fUpdateManager->FinalUpdate(B_TRANSLATE("Updates cancelled"),
|
||||
// B_TRANSLATE("No packages have been updated."));
|
||||
// Note: comment out when testing final message window
|
||||
be_app->PostMessage(kMsgFinalQuit);
|
||||
return B_OK;
|
||||
} catch (BNothingToDoException ex) {
|
||||
fprintf(stderr, "Nothing to do while updating packages : %s\n",
|
||||
ex.Message().String());
|
||||
fUpdateManager->FinalUpdate(B_TRANSLATE("No updates available"),
|
||||
B_TRANSLATE("There were no updates found."));
|
||||
return B_OK;
|
||||
} catch (BException ex) {
|
||||
fprintf(stderr, "Exception occurred while updating packages : %s\n",
|
||||
ex.Message().String());
|
||||
fUpdateManager->FinalUpdate(B_TRANSLATE("Updates did not complete"),
|
||||
ex.Message());
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2017, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
#ifndef UPDATE_ACTION_H
|
||||
#define UPDATE_ACTION_H
|
||||
|
||||
|
||||
#include "UpdateManager.h"
|
||||
|
||||
|
||||
class UpdateAction {
|
||||
public:
|
||||
UpdateAction();
|
||||
~UpdateAction();
|
||||
status_t Perform();
|
||||
|
||||
private:
|
||||
|
||||
UpdateManager* fUpdateManager;
|
||||
};
|
||||
|
||||
|
||||
#endif // UPDATE_ACTION_H
|
|
@ -1,11 +1,12 @@
|
|||
/*
|
||||
* Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2013-2017, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler <axeld@pinc-software.de>
|
||||
* Rene Gollent <rene@gollent.com>
|
||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
|
||||
|
||||
|
@ -14,28 +15,53 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Catalog.h>
|
||||
#include <Notification.h>
|
||||
|
||||
#include <package/CommitTransactionResult.h>
|
||||
#include <package/DownloadFileRequest.h>
|
||||
#include <package/RefreshRepositoryRequest.h>
|
||||
#include <package/manager/Exceptions.h>
|
||||
#include <package/solver/SolverPackage.h>
|
||||
#include <package/solver/SolverProblem.h>
|
||||
#include <package/solver/SolverProblemSolution.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "AutoDeleter.h"
|
||||
#include "ProblemWindow.h"
|
||||
#include "ResultWindow.h"
|
||||
|
||||
using namespace BPackageKit;
|
||||
using namespace BPackageKit::BManager::BPrivate;
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "UpdateManager"
|
||||
|
||||
|
||||
UpdateManager::UpdateManager(BPackageInstallationLocation location)
|
||||
:
|
||||
BPackageManager(location, &fClientInstallationInterface, this),
|
||||
BPackageManager::UserInteractionHandler(),
|
||||
fClientInstallationInterface()
|
||||
fClientInstallationInterface(),
|
||||
fStatusWindow(NULL),
|
||||
fFinalWindow(NULL),
|
||||
fCurrentStep(ACTION_STEP_INIT),
|
||||
fChangesConfirmed(false)
|
||||
{
|
||||
fStatusWindow = new SoftwareUpdaterWindow();
|
||||
_SetCurrentStep(ACTION_STEP_START);
|
||||
}
|
||||
|
||||
|
||||
UpdateManager::~UpdateManager()
|
||||
{
|
||||
if (fStatusWindow != NULL)
|
||||
fStatusWindow->PostMessage(B_QUIT_REQUESTED);
|
||||
if (fFinalWindow != NULL)
|
||||
fFinalWindow->PostMessage(B_QUIT_REQUESTED);
|
||||
if (fProblemWindow != NULL)
|
||||
fProblemWindow->PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,13 +80,29 @@ void
|
|||
UpdateManager::JobAborted(BSupportKit::BJob* job)
|
||||
{
|
||||
//DIE(job->Result(), "aborted");
|
||||
printf("Job aborted\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UpdateManager::FinalUpdate(const char* header, const char* text)
|
||||
{
|
||||
_FinalUpdate(header, text);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UpdateManager::HandleProblems()
|
||||
{
|
||||
int32 problemCount = fSolver->CountProblems();
|
||||
if (fProblemWindow == NULL)
|
||||
fProblemWindow = new ProblemWindow;
|
||||
|
||||
ProblemWindow::SolverPackageSet installPackages;
|
||||
ProblemWindow::SolverPackageSet uninstallPackages;
|
||||
if (!fProblemWindow->Go(fSolver,installPackages, uninstallPackages))
|
||||
throw BAbortedByUserException();
|
||||
|
||||
/* int32 problemCount = fSolver->CountProblems();
|
||||
for (int32 i = 0; i < problemCount; i++) {
|
||||
// print problem and possible solutions
|
||||
BSolverProblem* problem = fSolver->ProblemAt(i);
|
||||
|
@ -96,7 +138,7 @@ UpdateManager::HandleProblems()
|
|||
if (strcmp(buffer, "s\n") == 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
|
||||
char* end;
|
||||
long selected = strtol(buffer, &end, 0);
|
||||
if (end == buffer || *end != '\n' || selected < 1
|
||||
|
@ -109,10 +151,10 @@ UpdateManager::HandleProblems()
|
|||
problem->SolutionAt(selected - 1));
|
||||
if (error != B_OK)
|
||||
DIE(error, "failed to set solution");
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,20 +164,55 @@ UpdateManager::ConfirmChanges(bool fromMostSpecific)
|
|||
printf("The following changes will be made:\n");
|
||||
|
||||
int32 count = fInstalledRepositories.CountItems();
|
||||
int32 upgradeCount = 0;
|
||||
int32 installCount = 0;
|
||||
int32 uninstallCount = 0;
|
||||
|
||||
if (fromMostSpecific) {
|
||||
for (int32 i = count - 1; i >= 0; i--)
|
||||
_PrintResult(*fInstalledRepositories.ItemAt(i));
|
||||
_PrintResult(*fInstalledRepositories.ItemAt(i), upgradeCount,
|
||||
installCount, uninstallCount);
|
||||
} else {
|
||||
for (int32 i = 0; i < count; i++)
|
||||
_PrintResult(*fInstalledRepositories.ItemAt(i));
|
||||
_PrintResult(*fInstalledRepositories.ItemAt(i), upgradeCount,
|
||||
installCount, uninstallCount);
|
||||
}
|
||||
|
||||
/*
|
||||
if (!fDecisionProvider.YesNoDecisionNeeded(BString(), "Continue?", "yes",
|
||||
"no", "yes")) {
|
||||
//exit(1);
|
||||
|
||||
printf("Upgrade count=%" B_PRId32 ", Install count=%" B_PRId32
|
||||
", Uninstall count=%" B_PRId32 "\n",
|
||||
upgradeCount, installCount, uninstallCount);
|
||||
BString text;
|
||||
if (upgradeCount == 1)
|
||||
text.SetTo(B_TRANSLATE_COMMENT("There is 1 update "
|
||||
"%dependancies%available.",
|
||||
"Do not translate %dependancies%"));
|
||||
else
|
||||
text.SetTo(B_TRANSLATE_COMMENT("There are %count% updates "
|
||||
"%dependancies%available.",
|
||||
"Do not translate %count% or %dependancies%"));
|
||||
BString countString;
|
||||
countString << upgradeCount;
|
||||
text.ReplaceFirst("%count%", countString);
|
||||
BString dependancies("");
|
||||
if (installCount) {
|
||||
dependancies.SetTo("(");
|
||||
dependancies.Append(B_TRANSLATE("with")).Append(" ");
|
||||
if (installCount == 1)
|
||||
dependancies.Append(B_TRANSLATE("1 new dependancy"));
|
||||
else {
|
||||
dependancies << installCount;
|
||||
dependancies.Append(" ").Append(B_TRANSLATE("new dependancies"));
|
||||
}
|
||||
dependancies.Append(") ");
|
||||
}
|
||||
*/
|
||||
text.ReplaceFirst("%dependancies%", dependancies);
|
||||
fChangesConfirmed = fStatusWindow->ConfirmUpdates(text.String());
|
||||
if (!fChangesConfirmed)
|
||||
throw BAbortedByUserException();
|
||||
|
||||
_SetCurrentStep(ACTION_STEP_DOWNLOAD);
|
||||
fPackageDownloadsTotal = upgradeCount + installCount;
|
||||
fPackageDownloadsCount = 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,6 +234,18 @@ UpdateManager::Warn(status_t error, const char* format, ...)
|
|||
void
|
||||
UpdateManager::ProgressPackageDownloadStarted(const char* packageName)
|
||||
{
|
||||
if (fCurrentStep == ACTION_STEP_DOWNLOAD) {
|
||||
BString header(B_TRANSLATE("Downloading packages"));
|
||||
BString packageCount;
|
||||
packageCount.SetToFormat(
|
||||
B_TRANSLATE_COMMENT("%i of %i", "Do not translate %i"),
|
||||
fPackageDownloadsCount,
|
||||
fPackageDownloadsTotal);
|
||||
_UpdateDownloadProgress(header.String(), packageName, packageCount,
|
||||
0.0);
|
||||
fNewDownloadStarted = false;
|
||||
}
|
||||
|
||||
printf("Downloading %s...\n", packageName);
|
||||
}
|
||||
|
||||
|
@ -165,10 +254,23 @@ void
|
|||
UpdateManager::ProgressPackageDownloadActive(const char* packageName,
|
||||
float completionPercentage, off_t bytes, off_t totalBytes)
|
||||
{
|
||||
return;
|
||||
/*
|
||||
if (!fInteractive)
|
||||
return;
|
||||
if (fCurrentStep == ACTION_STEP_DOWNLOAD) {
|
||||
// Fix a bug where a 100% completion percentage gets sent at the start
|
||||
// of a package download
|
||||
if (!fNewDownloadStarted) {
|
||||
if (completionPercentage > 0 && completionPercentage < 1)
|
||||
fNewDownloadStarted = true;
|
||||
else
|
||||
completionPercentage = 0.0;
|
||||
}
|
||||
BString packageCount;
|
||||
packageCount.SetToFormat(
|
||||
B_TRANSLATE_COMMENT("%i of %i", "Do not translate %i"),
|
||||
fPackageDownloadsCount,
|
||||
fPackageDownloadsTotal);
|
||||
_UpdateDownloadProgress(NULL, packageName, packageCount,
|
||||
completionPercentage);
|
||||
}
|
||||
|
||||
static const char* progressChars[] = {
|
||||
"\xE2\x96\x8F",
|
||||
|
@ -213,13 +315,16 @@ UpdateManager::ProgressPackageDownloadActive(const char* packageName,
|
|||
printf(" %3d%%", (int)(completionPercentage * 100));
|
||||
|
||||
fflush(stdout);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UpdateManager::ProgressPackageDownloadComplete(const char* packageName)
|
||||
{
|
||||
if (fCurrentStep == ACTION_STEP_DOWNLOAD)
|
||||
fPackageDownloadsCount++;
|
||||
|
||||
// Overwrite the progress bar with whitespace
|
||||
printf("\r");
|
||||
struct winsize w;
|
||||
|
@ -235,6 +340,10 @@ UpdateManager::ProgressPackageDownloadComplete(const char* packageName)
|
|||
void
|
||||
UpdateManager::ProgressPackageChecksumStarted(const char* title)
|
||||
{
|
||||
// Repository checksums
|
||||
if (fCurrentStep == ACTION_STEP_START)
|
||||
_UpdateStatusWindow(NULL, title);
|
||||
|
||||
printf("%s...", title);
|
||||
}
|
||||
|
||||
|
@ -249,6 +358,11 @@ UpdateManager::ProgressPackageChecksumComplete(const char* title)
|
|||
void
|
||||
UpdateManager::ProgressStartApplyingChanges(InstalledRepository& repository)
|
||||
{
|
||||
_SetCurrentStep(ACTION_STEP_APPLY);
|
||||
BString header(B_TRANSLATE("Applying changes"));
|
||||
BString detail(B_TRANSLATE("Packages are being updated"));
|
||||
fStatusWindow->UpdatesApplying(header.String(), detail.String());
|
||||
|
||||
printf("[%s] Applying changes ...\n", repository.Name().String());
|
||||
}
|
||||
|
||||
|
@ -257,6 +371,12 @@ void
|
|||
UpdateManager::ProgressTransactionCommitted(InstalledRepository& repository,
|
||||
const BCommitTransactionResult& result)
|
||||
{
|
||||
_SetCurrentStep(ACTION_STEP_COMPLETE);
|
||||
BString header(B_TRANSLATE("Updates completed"));
|
||||
BString detail(B_TRANSLATE("A reboot may be necessary to complete some "
|
||||
"updates."));
|
||||
_FinalUpdate(header.String(), detail.String());
|
||||
|
||||
const char* repositoryName = repository.Name().String();
|
||||
|
||||
int32 issueCount = result.CountIssues();
|
||||
|
@ -285,7 +405,8 @@ UpdateManager::ProgressApplyingChangesDone(InstalledRepository& repository)
|
|||
|
||||
|
||||
void
|
||||
UpdateManager::_PrintResult(InstalledRepository& installationRepository)
|
||||
UpdateManager::_PrintResult(InstalledRepository& installationRepository,
|
||||
int32& upgradeCount, int32& installCount, int32& uninstallCount)
|
||||
{
|
||||
if (!installationRepository.HasChanges())
|
||||
return;
|
||||
|
@ -319,7 +440,8 @@ UpdateManager::_PrintResult(InstalledRepository& installationRepository)
|
|||
if (dynamic_cast<MiscLocalRepository*>(package->Repository()) != NULL)
|
||||
repository = "local file";
|
||||
else
|
||||
repository.SetToFormat("repository %s", package->Repository()->Name().String());
|
||||
repository.SetToFormat("repository %s",
|
||||
package->Repository()->Name().String());
|
||||
|
||||
int position = upgradedPackages.IndexOf(package->Info().Name());
|
||||
if (position >= 0) {
|
||||
|
@ -328,18 +450,106 @@ UpdateManager::_PrintResult(InstalledRepository& installationRepository)
|
|||
upgradedPackageVersions.StringAt(position).String(),
|
||||
package->Info().Version().ToString().String(),
|
||||
repository.String());
|
||||
fStatusWindow->AddPackageInfo(PACKAGE_UPDATE,
|
||||
package->Info().Name().String(),
|
||||
upgradedPackageVersions.StringAt(position).String(),
|
||||
package->Info().Version().ToString().String(),
|
||||
package->Info().Summary().String(),
|
||||
package->Repository()->Name().String());
|
||||
upgradeCount++;
|
||||
} else {
|
||||
printf(" install package %s-%s from %s\n",
|
||||
package->Info().Name().String(),
|
||||
package->Info().Version().ToString().String(),
|
||||
repository.String());
|
||||
fStatusWindow->AddPackageInfo(PACKAGE_INSTALL,
|
||||
package->Info().Name().String(),
|
||||
NULL,
|
||||
package->Info().Version().ToString().String(),
|
||||
package->Info().Summary().String(),
|
||||
package->Repository()->Name().String());
|
||||
installCount++;
|
||||
}
|
||||
}
|
||||
|
||||
BStringList uninstallList;
|
||||
for (int32 i = 0; BSolverPackage* package = packagesToDeactivate.ItemAt(i);
|
||||
i++) {
|
||||
if (upgradedPackages.HasString(package->Info().Name()))
|
||||
continue;
|
||||
printf(" uninstall package %s\n", package->VersionedName().String());
|
||||
fStatusWindow->AddPackageInfo(PACKAGE_UNINSTALL,
|
||||
package->Info().Name().String(),
|
||||
package->Info().Version().ToString(),
|
||||
NULL,
|
||||
package->Info().Summary().String(),
|
||||
package->Repository()->Name().String());
|
||||
uninstallCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UpdateManager::_UpdateStatusWindow(const char* header, const char* detail)
|
||||
{
|
||||
if (header == NULL && detail == NULL)
|
||||
return;
|
||||
|
||||
if (fStatusWindow->UserCancelRequested())
|
||||
throw BAbortedByUserException();
|
||||
|
||||
BMessage message(kMsgTextUpdate);
|
||||
if (header != NULL)
|
||||
message.AddString(kKeyHeader, header);
|
||||
if (detail != NULL)
|
||||
message.AddString(kKeyDetail, detail);
|
||||
fStatusWindow->PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UpdateManager::_UpdateDownloadProgress(const char* header,
|
||||
const char* packageName, const char* packageCount,
|
||||
float completionPercentage)
|
||||
{
|
||||
if (packageName == NULL || packageCount == NULL)
|
||||
return;
|
||||
|
||||
if (fStatusWindow->UserCancelRequested())
|
||||
throw BAbortedByUserException();
|
||||
|
||||
BMessage message(kMsgProgressUpdate);
|
||||
if (header != NULL)
|
||||
message.AddString(kKeyHeader, header);
|
||||
message.AddString(kKeyPackageName, packageName);
|
||||
message.AddString(kKeyPackageCount, packageCount);
|
||||
message.AddFloat(kKeyPercentage, completionPercentage);
|
||||
fStatusWindow->PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UpdateManager::_FinalUpdate(const char* header, const char* text)
|
||||
{
|
||||
BNotification notification(B_INFORMATION_NOTIFICATION);
|
||||
notification.SetGroup("SoftwareUpdater");
|
||||
notification.SetTitle(header);
|
||||
notification.SetContent(text);
|
||||
const BBitmap* icon = fStatusWindow->GetIcon();
|
||||
if (icon != NULL)
|
||||
notification.SetIcon(icon);
|
||||
notification.Send();
|
||||
|
||||
BPoint location(fStatusWindow->GetLocation());
|
||||
BRect rect(fStatusWindow->GetDefaultRect());
|
||||
fStatusWindow->PostMessage(B_QUIT_REQUESTED);
|
||||
fStatusWindow = NULL;
|
||||
|
||||
fFinalWindow = new FinalWindow(rect, location, header, text);
|
||||
}
|
||||
|
||||
void
|
||||
UpdateManager::_SetCurrentStep(int32 step)
|
||||
{
|
||||
fCurrentStep = step;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* Copyright 2013-2015, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2013-2017, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||
* Rene Gollent <rene@gollent.com>
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
#ifndef UPDATE_MANAGER_H
|
||||
#define UPDATE_MANAGER_H
|
||||
|
@ -13,6 +14,9 @@
|
|||
#include <package/DaemonClient.h>
|
||||
#include <package/manager/PackageManager.h>
|
||||
|
||||
#include "SoftwareUpdaterWindow.h"
|
||||
|
||||
class ProblemWindow;
|
||||
|
||||
//using namespace BPackageKit;
|
||||
using BPackageKit::BPrivate::BDaemonClient;
|
||||
|
@ -28,7 +32,9 @@ public:
|
|||
|
||||
virtual void JobFailed(BSupportKit::BJob* job);
|
||||
virtual void JobAborted(BSupportKit::BJob* job);
|
||||
|
||||
|
||||
void FinalUpdate(const char* header,
|
||||
const char* text);
|
||||
private:
|
||||
// UserInteractionHandler
|
||||
virtual void HandleProblems();
|
||||
|
@ -60,11 +66,32 @@ private:
|
|||
|
||||
private:
|
||||
void _PrintResult(InstalledRepository&
|
||||
installationRepository);
|
||||
installationRepository,
|
||||
int32& upgradeCount,
|
||||
int32& installCount,
|
||||
int32& uninstallCount);
|
||||
void _UpdateStatusWindow(const char* header,
|
||||
const char* detail);
|
||||
void _UpdateDownloadProgress(const char* header,
|
||||
const char* packageName,
|
||||
const char* packageCount,
|
||||
float completionPercentage);
|
||||
void _FinalUpdate(const char* header,
|
||||
const char* text);
|
||||
void _SetCurrentStep(int32 step);
|
||||
|
||||
private:
|
||||
BPackageManager::ClientInstallationInterface
|
||||
fClientInstallationInterface;
|
||||
|
||||
SoftwareUpdaterWindow* fStatusWindow;
|
||||
FinalWindow* fFinalWindow;
|
||||
ProblemWindow* fProblemWindow;
|
||||
uint32 fCurrentStep;
|
||||
bool fChangesConfirmed;
|
||||
bool fNewDownloadStarted;
|
||||
int32 fPackageDownloadsTotal;
|
||||
int32 fPackageDownloadsCount;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2017, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "WorkingLooper.h"
|
||||
|
||||
|
||||
WorkingLooper::WorkingLooper()
|
||||
:
|
||||
BLooper("WorkingLooper")
|
||||
{
|
||||
Run();
|
||||
PostMessage(kMsgStart);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WorkingLooper::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case kMsgStart:
|
||||
{
|
||||
fAction.Perform();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BLooper::MessageReceived(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2017, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
#ifndef _WORKING_LOOPER_H
|
||||
#define _WORKING_LOOPER_H
|
||||
|
||||
|
||||
#include <Looper.h>
|
||||
#include <Message.h>
|
||||
|
||||
#include "UpdateAction.h"
|
||||
|
||||
|
||||
const uint32 kMsgStart = 'iSTA';
|
||||
|
||||
|
||||
class WorkingLooper : public BLooper {
|
||||
public:
|
||||
WorkingLooper();
|
||||
void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
UpdateAction fAction;
|
||||
};
|
||||
|
||||
|
||||
#endif // _WORKING_LOOPER_H
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2017, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Brian Hill <supernova@warpmail.net>
|
||||
*/
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
|
||||
enum {
|
||||
ACTION_STEP_INIT = 0,
|
||||
ACTION_STEP_START,
|
||||
ACTION_STEP_DOWNLOAD,
|
||||
ACTION_STEP_APPLY,
|
||||
ACTION_STEP_COMPLETE,
|
||||
ACTION_STEP_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
STATE_HEAD = 0,
|
||||
STATE_DISPLAY_STATUS,
|
||||
STATE_DISPLAY_PROGRESS,
|
||||
STATE_GET_CONFIRMATION,
|
||||
STATE_APPLY_UPDATES,
|
||||
STATE_MAX
|
||||
};
|
||||
|
||||
// Message what values
|
||||
static const uint32 kMsgTextUpdate = 'iUPD';
|
||||
static const uint32 kMsgProgressUpdate = 'iPRO';
|
||||
static const uint32 kMsgCancel = 'iCAN';
|
||||
static const uint32 kMsgCancelResponse = 'iCRE';
|
||||
static const uint32 kMsgUpdateConfirmed = 'iCON';
|
||||
static const uint32 kMsgClose = 'iCLO';
|
||||
static const uint32 kMsgShow = 'iSHO';
|
||||
static const uint32 kMsgShowInfo = 'iSHI';
|
||||
static const uint32 kMsgRegister = 'iREG';
|
||||
static const uint32 kMsgFinalQuit = 'iFIN';
|
||||
|
||||
// Message data keys
|
||||
#define kKeyHeader "key_header"
|
||||
#define kKeyDetail "key_detail"
|
||||
#define kKeyPackageName "key_packagename"
|
||||
#define kKeyPackageCount "key_packagecount"
|
||||
#define kKeyPercentage "key_percentage"
|
||||
#define kKeyFrame "key_frame"
|
||||
#define kKeyMessenger "key_messenger"
|
||||
|
||||
|
||||
#endif // CONSTANTS_H
|
Loading…
Reference in New Issue