SoftwareUpdater fixes and network status check

Bug fix- use a proper sized 32 pixel application icon for notifications
Bug fix- sorting list of packages to install and uninstall added
Removed use of FinalWindow class now that resizing issues are resolved
Diaplsy alert if no network connections are found at application start
This commit is contained in:
Brian Hill
2017-03-19 18:05:02 -04:00
parent acdfec1189
commit 9458fd57e2
10 changed files with 244 additions and 258 deletions
+1 -1
View File
@@ -15,6 +15,6 @@ Application SoftwareUpdater :
# package_daemon
ProblemWindow.cpp
: be localestub package translation [ TargetLibsupc++ ]
: be localestub package translation libbnetapi.so [ TargetLibsupc++ ]
: SoftwareUpdater.rdef
;
@@ -39,7 +39,6 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fUpdateButton(NULL),
fCancelButton(NULL),
fStatusBar(NULL),
fIcon(NULL),
fCurrentState(STATE_HEAD),
fWaitingSem(-1),
fWaitingForButton(false),
@@ -47,24 +46,15 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fWarningAlertCount(0)
{
int32 iconSize = int(be_plain_font->Size() * 32.0 / 12.0);
fIcon = new BBitmap(BRect(0, 0, iconSize - 1, iconSize - 1), 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, icon_size(iconSize));
fStripeView = new StripeView(fIcon);
// At 12 point font, icon size is 32, at 24 point it is 64
BBitmap icon = GetIcon(iconSize);
fStripeView = new StripeView(icon);
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",
B_TRANSLATE("Checking for updates"), B_WILL_DRAW);
@@ -134,12 +124,6 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
}
SoftwareUpdaterWindow::~SoftwareUpdaterWindow()
{
delete fIcon;
}
void
SoftwareUpdaterWindow::MessageReceived(BMessage* message)
{
@@ -198,6 +182,12 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
case kMsgCancel:
{
if (_GetState() == STATE_FINAL_MESSAGE) {
PostMessage(B_QUIT_REQUESTED);
be_app->PostMessage(kMsgFinalQuit);
break;
}
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,
@@ -219,6 +209,7 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
fHeaderView->SetText(B_TRANSLATE("Cancelling updates"));
fDetailView->SetText(
B_TRANSLATE("Attempting to cancel the updates..."));
fCancelButton->SetEnabled(false);
Unlock();
fUserCancelRequested = true;
@@ -244,6 +235,21 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
fWarningAlertCount--;
break;
case kMsgNetworkAlert:
{
BAlert* alert = new BAlert("network_connection",
B_TRANSLATE_COMMENT("No active network connection was found",
"Alert message"),
B_TRANSLATE_COMMENT("Continue anyway", "Alert button label"),
B_TRANSLATE_COMMENT("Quit","Alert button label"),
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
int32 result = alert->Go();
BMessage reply;
reply.AddInt32(kKeyAlertResult, result);
message->SendReply(&reply);
break;
}
default:
BWindow::MessageReceived(message);
}
@@ -314,6 +320,40 @@ SoftwareUpdaterWindow::ShowWarningAlert(const char* text)
}
BBitmap
SoftwareUpdaterWindow::GetIcon(int32 iconSize)
{
BBitmap icon(BRect(0, 0, iconSize - 1, iconSize - 1), 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, icon_size(iconSize));
return icon;
}
BBitmap
SoftwareUpdaterWindow::GetNotificationIcon()
{
return GetIcon(B_LARGE_ICON);
}
void
SoftwareUpdaterWindow::FinalUpdate(const char* header, const char* detail)
{
if (_GetState() == STATE_FINAL_MESSAGE)
return;
_SetState(STATE_FINAL_MESSAGE);
Lock();
fHeaderView->SetText(header);
fDetailView->SetText(detail);
Unlock();
}
BLayoutItem*
SoftwareUpdaterWindow::layout_item_for(BView* view)
{
@@ -368,6 +408,14 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
fDefaultRect.Height() + 4 * fListView->ItemHeight(), 9999);
ResizeTo(defaultWidth, .75 * defaultWidth);
}
else if (fCurrentState == STATE_FINAL_MESSAGE) {
fPackagesLayoutItem->SetVisible(false);
float defaultWidth = fDefaultRect.Width();
float defaultHeight = fDefaultRect.Height();
SetSizeLimits(defaultWidth, defaultWidth, defaultHeight,
defaultHeight);
ResizeTo(defaultWidth, defaultHeight);
}
// Progress bar and string view
// Hide detail text while showing status bar
@@ -381,6 +429,8 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
}
// Cancel button
if (fCurrentState == STATE_FINAL_MESSAGE)
fCancelButton->SetLabel(B_TRANSLATE("Quit"));
fCancelButton->SetEnabled(fCurrentState != STATE_APPLY_UPDATES);
Unlock();
@@ -566,7 +616,7 @@ PackageItem::SetItemHeight(const BFont* font)
int
PackageItem::ICompare(PackageItem* item)
PackageItem::NameCompare(PackageItem* item)
{
// sort by package name
return fName.ICompare(item->fName);
@@ -578,7 +628,7 @@ SortPackageItems(const BListItem* item1, const BListItem* item2)
{
PackageItem* first = (PackageItem*)item1;
PackageItem* second = (PackageItem*)item2;
return first->ICompare(second);
return first->NameCompare(second);
}
@@ -648,7 +698,7 @@ PackageListView::AddPackage(uint32 install_type, const char* name,
tooltip.Append(B_TRANSLATE_COMMENT("Updating version",
"Tooltip text"))
.Append(" ").Append(cur_ver)
.Append(" ").Append(B_TRANSLATE("to"))
.Append(" ").Append(B_TRANSLATE_COMMENT("to", "Tooltip text"))
.Append(" ").Append(new_ver);
break;
}
@@ -700,6 +750,10 @@ PackageListView::SortItems()
{
if (fSuperUpdateItem != NULL)
SortItemsUnder(fSuperUpdateItem, true, SortPackageItems);
if (fSuperInstallItem != NULL)
SortItemsUnder(fSuperInstallItem, true, SortPackageItems);
if (fSuperUninstallItem != NULL)
SortItemsUnder(fSuperUninstallItem, true, SortPackageItems);
}
@@ -714,84 +768,3 @@ PackageListView::ItemHeight()
return fSuperUninstallItem->GetPackageItemHeight();
return 0;
}
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)
{
int32 iconSize = int(be_plain_font->Size() * 32.0 / 12.0);
fIcon = new BBitmap(BRect(0, 0, iconSize - 1, iconSize - 1), 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, icon_size(iconSize));
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);
}
}
@@ -67,7 +67,7 @@ public:
virtual void DrawItem(BView*, BRect, bool);
virtual void Update(BView *owner, const BFont *font);
void SetItemHeight(const BFont* font);
int ICompare(PackageItem* item);
int NameCompare(PackageItem* item);
BTextToolTip* ToolTip() { return fToolTip; };
private:
@@ -110,8 +110,6 @@ private:
class SoftwareUpdaterWindow : public BWindow {
public:
SoftwareUpdaterWindow();
~SoftwareUpdaterWindow();
void MessageReceived(BMessage* message);
bool ConfirmUpdates(const char* text);
void UpdatesApplying(const char* header,
@@ -124,10 +122,13 @@ public:
const char* summary,
const char* repository);
void ShowWarningAlert(const char* text);
const BBitmap* GetIcon() { return fIcon; };
BBitmap GetIcon(int32 iconSize);
BBitmap GetNotificationIcon();
BRect GetDefaultRect() { return fDefaultRect; };
BPoint GetLocation() { return Frame().LeftTop(); };
BLayoutItem* layout_item_for(BView* view);
void FinalUpdate(const char* header,
const char* detail);
private:
uint32 _WaitForButtonClick();
@@ -141,17 +142,12 @@ private:
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;
@@ -168,21 +164,4 @@ private:
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
+13 -10
View File
@@ -15,18 +15,21 @@
#include <LayoutUtils.h>
StripeView::StripeView(BBitmap* icon)
static const float kTopOffset = 10.0f;
StripeView::StripeView(BBitmap& icon)
:
BView("StripeView", B_WILL_DRAW),
fIcon(icon),
fWidth(0.0),
fStripeWidth(0.0)
fIconSize(0.0),
fWidth(0.0)
{
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
if (icon != NULL) {
fStripeWidth = icon->Bounds().Width();
fWidth = 2 * fStripeWidth + 2.0f;
if (fIcon.IsValid()) {
fIconSize = fIcon.Bounds().Width();
fWidth = 2 * fIconSize + 2.0f;
}
}
@@ -34,20 +37,20 @@ StripeView::StripeView(BBitmap* icon)
void
StripeView::Draw(BRect updateRect)
{
if (fIcon == NULL)
if (fIconSize == 0)
return;
SetHighColor(ViewColor());
FillRect(updateRect);
BRect stripeRect = Bounds();
stripeRect.right = fStripeWidth;
stripeRect.right = fIconSize;
SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
FillRect(stripeRect);
SetDrawingMode(B_OP_ALPHA);
SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
DrawBitmapAsync(fIcon, BPoint(fStripeWidth / 2.0f, 10.0f));
DrawBitmapAsync(&fIcon, BPoint(fIconSize / 2.0f, kTopOffset));
}
@@ -65,7 +68,7 @@ StripeView::GetPreferredSize(float* _width, float* _height)
*_width = fWidth;
if (_height != NULL)
*_height = fStripeWidth + 20.0f;
*_height = fIconSize + 2 * kTopOffset;
}
+3 -3
View File
@@ -18,7 +18,7 @@
class StripeView : public BView {
public:
StripeView(BBitmap* icon);
StripeView(BBitmap& icon);
virtual void Draw(BRect updateRect);
virtual BSize PreferredSize();
@@ -26,9 +26,9 @@ public:
virtual BSize MaxSize();
private:
BBitmap* fIcon;
BBitmap fIcon;
float fIconSize;
float fWidth;
float fStripeWidth;
};
+2 -4
View File
@@ -42,6 +42,8 @@ status_t
UpdateAction::Perform()
{
try {
fUpdateManager->CheckNetworkConnection();
fUpdateManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES
| BPackageManager::B_ADD_REMOTE_REPOSITORIES
| BPackageManager::B_REFRESH_REPOSITORIES);
@@ -61,10 +63,6 @@ UpdateAction::Perform()
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) {
-1
View File
@@ -19,7 +19,6 @@ public:
status_t Perform();
private:
UpdateManager* fUpdateManager;
};
+50 -16
View File
@@ -17,6 +17,10 @@
#include <Alert.h>
#include <Catalog.h>
#include <Message.h>
#include <Messenger.h>
#include <NetworkInterface.h>
#include <NetworkRoster.h>
#include <Notification.h>
#include <package/CommitTransactionResult.h>
@@ -45,7 +49,6 @@ UpdateManager::UpdateManager(BPackageInstallationLocation location)
BPackageManager::UserInteractionHandler(),
fClientInstallationInterface(),
fStatusWindow(NULL),
fFinalWindow(NULL),
fCurrentStep(ACTION_STEP_INIT),
fChangesConfirmed(false)
{
@@ -58,13 +61,48 @@ 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);
}
void
UpdateManager::CheckNetworkConnection()
{
BNetworkRoster& roster = BNetworkRoster::Default();
BNetworkInterface interface;
uint32 cookie = 0;
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
uint32 flags = interface.Flags();
if ((flags & IFF_LOOPBACK) == 0
&& (flags & (IFF_UP | IFF_LINK)) == (IFF_UP | IFF_LINK)) {
return;
}
}
// No network connection detected, display warning
int32 result = 0;
BMessenger messenger(fStatusWindow);
if (messenger.IsValid()) {
BMessage message(kMsgNetworkAlert);
BMessage reply;
messenger.SendMessage(&message, &reply);
reply.FindInt32(kKeyAlertResult, &result);
}
else {
BAlert* alert = new BAlert("network_connection",
B_TRANSLATE_COMMENT("No active network connection was found",
"Alert message"),
B_TRANSLATE_COMMENT("Continue anyway", "Alert button label"),
B_TRANSLATE_COMMENT("Quit","Alert button label"),
NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
result = alert->Go();
}
if (result)
throw BAbortedByUserException();
}
void
UpdateManager::JobFailed(BSupportKit::BJob* job)
{
@@ -230,8 +268,11 @@ UpdateManager::Warn(status_t error, const char* format, ...)
else
printf(": %s\n", strerror(error));
if (fStatusWindow != NULL)
if (fStatusWindow != NULL) {
if (fStatusWindow->UserCancelRequested())
throw BAbortedByUserException();
fStatusWindow->ShowWarningAlert(buffer);
}
else {
BString text("SoftwareUpdater:\n");
text.Append(buffer);
@@ -542,26 +583,19 @@ UpdateManager::_UpdateDownloadProgress(const char* header,
void
UpdateManager::_FinalUpdate(const char* header, const char* text)
{
if (fFinalWindow != NULL)
return;
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);
BBitmap icon(fStatusWindow->GetNotificationIcon());
if (icon.IsValid())
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);
fStatusWindow->FinalUpdate(header, text);
}
void
UpdateManager::_SetCurrentStep(int32 step)
{
+1 -4
View File
@@ -30,19 +30,17 @@ public:
BPackageKit::BPackageInstallationLocation location);
~UpdateManager();
void CheckNetworkConnection();
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();
virtual void ConfirmChanges(bool fromMostSpecific);
virtual void Warn(status_t error, const char* format, ...);
virtual void ProgressPackageDownloadStarted(
const char* packageName);
virtual void ProgressPackageDownloadActive(
@@ -85,7 +83,6 @@ private:
fClientInstallationInterface;
SoftwareUpdaterWindow* fStatusWindow;
FinalWindow* fFinalWindow;
ProblemWindow* fProblemWindow;
uint32 fCurrentStep;
bool fChangesConfirmed;
+3
View File
@@ -23,6 +23,7 @@ enum {
STATE_DISPLAY_PROGRESS,
STATE_GET_CONFIRMATION,
STATE_APPLY_UPDATES,
STATE_FINAL_MESSAGE,
STATE_MAX
};
@@ -33,6 +34,7 @@ static const uint32 kMsgCancel = 'iCAN';
static const uint32 kMsgCancelResponse = 'iCRE';
static const uint32 kMsgUpdateConfirmed = 'iCON';
static const uint32 kMsgWarningDismissed = 'iWDI';
static const uint32 kMsgNetworkAlert = 'iNAL';
static const uint32 kMsgRegister = 'iREG';
static const uint32 kMsgFinalQuit = 'iFIN';
@@ -43,6 +45,7 @@ static const uint32 kMsgFinalQuit = 'iFIN';
#define kKeyPackageCount "key_packagecount"
#define kKeyPercentage "key_percentage"
#define kKeyMessenger "key_messenger"
#define kKeyAlertResult "key_alertresult"
#endif // CONSTANTS_H