SoftwareUpdater improvements and fixes

Improvements:
* Close box on window tab replaces cancel button
* Final window quit button made default
* Window frame and details checkbox option saved to settings file and
  restored upon start of application
Bug fixes:
* Fixed strings not truncating properly in scroll view
* Application was unnecessarily aborting the Haiku shutdown process
* Window corner grabber now not shown when window is not resizable
This commit is contained in:
Brian Hill
2017-07-09 22:49:52 +00:00
parent 8412d1d17a
commit acfd5c8676
18 changed files with 216 additions and 63 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
+1 -1
View File
@@ -3,7 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef CHECK_ACTION_H
#define CHECK_ACTION_H
+1 -1
View File
@@ -6,7 +6,7 @@
* Axel Dörfler <[email protected]>
* Rene Gollent <[email protected]>
* Ingo Weinhold <[email protected]>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
+1 -1
View File
@@ -5,7 +5,7 @@
* Authors:
* Ingo Weinhold <[email protected]>
* Rene Gollent <[email protected]>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef CHECK_MANAGER_H
#define CHECK_MANAGER_H
@@ -5,7 +5,7 @@ resource app_flags B_SINGLE_LAUNCH;
resource app_version {
major = 1,
middle = 0,
minor = 1,
minor = 2,
variety = B_APPV_BETA,
internal = 0,
short_info = "SoftwareUpdater",
@@ -4,7 +4,7 @@
*
* Authors:
* Alexander von Gluck IV <[email protected]>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#include "SoftwareUpdaterApp.h"
@@ -71,11 +71,8 @@ SoftwareUpdaterApp::QuitRequested()
// Simulate a cancel request from window- this gives the updater a chance
// to quit cleanly
if (fWindowMessenger.IsValid()) {
if (fWindowMessenger.IsValid())
fWindowMessenger.SendMessage(kMsgCancel);
return false;
}
return true;
}
@@ -4,7 +4,7 @@
*
* Authors:
* Alexander von Gluck IV <[email protected]>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef _SOFTWARE_UPDATER_APP_H
#define _SOFTWARE_UPDATER_APP_H
@@ -4,7 +4,7 @@
*
* Authors:
* Alexander von Gluck IV <kallisti5@unixzen.com>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
@@ -15,10 +15,12 @@
#include <Application.h>
#include <Catalog.h>
#include <ControlLook.h>
#include <FindDirectory.h>
#include <LayoutBuilder.h>
#include <LayoutUtils.h>
#include <Message.h>
#include <Roster.h>
#include <Screen.h>
#include <String.h>
#include "constants.h"
@@ -29,9 +31,9 @@
SoftwareUpdaterWindow::SoftwareUpdaterWindow()
:
BWindow(BRect(0, 0, 300, 100),
BWindow(BRect(0, 0, 300, 10),
B_TRANSLATE_SYSTEM_NAME("SoftwareUpdater"), B_TITLED_WINDOW,
B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE | B_NOT_CLOSABLE),
B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
fStripeView(NULL),
fHeaderView(NULL),
fDetailView(NULL),
@@ -43,8 +45,13 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fWaitingForButton(false),
fUpdateConfirmed(false),
fUserCancelRequested(false),
fWarningAlertCount(0)
fWarningAlertCount(0),
fSettingsReadStatus(B_ERROR),
fSaveFrameChanges(false),
fMessageRunner(NULL),
fFrameChangeMessage(kMsgWindowFrameChanged)
{
// Layout
BBitmap icon = GetIcon(32 * icon_layout_scale());
fStripeView = new StripeView(icon);
@@ -95,9 +102,6 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
.AddGroup(new BGroupView(B_HORIZONTAL))
.Add(fDetailsCheckbox)
.AddGlue()
.End()
.AddGroup(new BGroupView(B_HORIZONTAL))
.AddGlue()
.Add(fCancelButton)
.Add(fUpdateButton)
.End()
@@ -107,12 +111,12 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fDetailsLayoutItem = layout_item_for(fDetailView);
fProgressLayoutItem = layout_item_for(fStatusBar);
fPackagesLayoutItem = layout_item_for(fScrollView);
fCancelButtonLayoutItem = layout_item_for(fCancelButton);
fUpdateButtonLayoutItem = layout_item_for(fUpdateButton);
fDetailsCheckboxLayoutItem = layout_item_for(fDetailsCheckbox);
_SetState(STATE_DISPLAY_STATUS);
CenterOnScreen();
Show();
SetFlags(Flags() ^ B_AUTO_UPDATE_SIZE_LIMITS);
// Prevent resizing for now
@@ -120,6 +124,24 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
SetSizeLimits(fDefaultRect.Width(), fDefaultRect.Width(),
fDefaultRect.Height(), fDefaultRect.Height());
// Read settings file
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath);
if (status == B_OK) {
fSettingsPath.Append(kSettingsFilename);
fSettingsReadStatus = _ReadSettings(fInitialSettings);
}
// Move to saved setting position
if (fSettingsReadStatus == B_OK) {
BRect windowFrame;
status = fInitialSettings.FindRect(kKeyWindowFrame, &windowFrame);
if (status == B_OK) {
BScreen screen(this);
if (screen.Frame().Contains(windowFrame.LeftTop()))
MoveTo(windowFrame.LeftTop());
}
}
Show();
BMessage registerMessage(kMsgRegister);
registerMessage.AddMessenger(kKeyMessenger, BMessenger(this));
be_app->PostMessage(&registerMessage);
@@ -131,6 +153,48 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
}
bool
SoftwareUpdaterWindow::QuitRequested()
{
PostMessage(kMsgCancel);
return false;
}
void
SoftwareUpdaterWindow::FrameMoved(BPoint newPosition)
{
BWindow::FrameMoved(newPosition);
// Create a message runner to consolidate all function calls from a
// move into one message post after moving has ceased for .5 seconds
if (fSaveFrameChanges) {
if (fMessageRunner == NULL) {
fMessageRunner = new BMessageRunner(this, &fFrameChangeMessage,
500000, 1);
} else
fMessageRunner->SetInterval(500000);
}
}
void
SoftwareUpdaterWindow::FrameResized(float newWidth, float newHeight)
{
BWindow::FrameResized(newWidth, newHeight);
// Create a message runner to consolidate all function calls from a
// resize into one message post after resizing has ceased for .5 seconds
if (fSaveFrameChanges) {
if (fMessageRunner == NULL) {
fMessageRunner = new BMessageRunner(this, &fFrameChangeMessage,
500000, 1);
} else
fMessageRunner->SetInterval(500000);
}
}
void
SoftwareUpdaterWindow::MessageReceived(BMessage* message)
{
@@ -164,7 +228,8 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
break;
BString packageName;
status_t result = message->FindString(kKeyPackageName, &packageName);
status_t result = message->FindString(kKeyPackageName,
&packageName);
if (result != B_OK)
break;
BString packageCount;
@@ -192,7 +257,6 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
case kMsgCancel:
{
if (_GetState() == STATE_FINAL_MESSAGE) {
PostMessage(B_QUIT_REQUESTED);
be_app->PostMessage(kMsgFinalQuit);
break;
}
@@ -203,7 +267,6 @@ 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;
@@ -237,7 +300,6 @@ 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;
@@ -262,12 +324,19 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
case kMsgMoreDetailsToggle:
fListView->SetMoreDetails(fDetailsCheckbox->Value() != 0);
_WriteSettings();
break;
case kMsgWarningDismissed:
fWarningAlertCount--;
break;
case kMsgWindowFrameChanged:
delete fMessageRunner;
fMessageRunner = NULL;
_WriteSettings();
break;
case kMsgGetUpdateType:
{
BString text(
@@ -461,6 +530,7 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
fProgressLayoutItem->SetVisible(false);
fPackagesLayoutItem->SetVisible(false);
fDetailsCheckboxLayoutItem->SetVisible(false);
fCancelButtonLayoutItem->SetVisible(false);
}
fCurrentState = state;
@@ -471,24 +541,23 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
else
fUpdateButtonLayoutItem->SetVisible(false);
// View package info view
// View package info view and checkbox
// Show at confirmation prompt, hide at final update
if (fCurrentState == STATE_GET_CONFIRMATION) {
fPackagesLayoutItem->SetVisible(true);
fDetailsCheckboxLayoutItem->SetVisible(true);
// Re-enable resizing
float defaultWidth = fDefaultRect.Width();
SetSizeLimits(defaultWidth, 9999,
fDefaultRect.Height() + 4 * fListView->ItemHeight(), 9999);
ResizeTo(defaultWidth, .75 * defaultWidth);
if (fSettingsReadStatus == B_OK) {
bool showMoreDetails;
status_t result = fInitialSettings.FindBool(kKeyShowDetails,
&showMoreDetails);
if (result == B_OK) {
fDetailsCheckbox->SetValue(showMoreDetails ? 1 : 0);
fListView->SetMoreDetails(showMoreDetails);
}
}
} else if (fCurrentState == STATE_FINAL_MESSAGE) {
fPackagesLayoutItem->SetVisible(false);
fDetailsCheckboxLayoutItem->SetVisible(false);
float defaultWidth = fDefaultRect.Width();
float defaultHeight = fDefaultRect.Height();
SetSizeLimits(defaultWidth, defaultWidth, defaultHeight,
defaultHeight);
ResizeTo(defaultWidth, defaultHeight);
}
// Progress bar and string view
@@ -501,10 +570,52 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
fDetailsLayoutItem->SetVisible(true);
}
// Cancel button
if (fCurrentState == STATE_FINAL_MESSAGE)
fCancelButton->SetLabel(B_TRANSLATE("Quit"));
fCancelButton->SetEnabled(fCurrentState != STATE_APPLY_UPDATES);
// Resizing
if (fCurrentState == STATE_GET_CONFIRMATION) {
// Enable resizing
float defaultWidth = fDefaultRect.Width();
SetSizeLimits(defaultWidth, B_SIZE_UNLIMITED,
fDefaultRect.Height() + 4 * fListView->ItemHeight(),
B_SIZE_UNLIMITED);
SetFlags(Flags() ^ B_NOT_RESIZABLE);
// Recall saved settings
BScreen screen(this);
BRect screenFrame = screen.Frame();
bool windowResized = false;
if (fSettingsReadStatus == B_OK) {
BRect windowFrame;
status_t result = fInitialSettings.FindRect(kKeyWindowFrame,
&windowFrame);
if (result == B_OK) {
if (screenFrame.Contains(windowFrame)) {
ResizeTo(windowFrame.Width(), windowFrame.Height());
windowResized = true;
}
}
}
if (!windowResized)
ResizeTo(defaultWidth, .75 * defaultWidth);
// Check that the bottom of window is on screen
float screenBottom = screenFrame.bottom;
float windowBottom = DecoratorFrame().bottom;
if (windowBottom > screenBottom)
MoveBy(0, screenBottom - windowBottom);
fSaveFrameChanges = true;
} else if (fCurrentState == STATE_APPLY_UPDATES)
fSaveFrameChanges = false;
else if (fCurrentState == STATE_FINAL_MESSAGE) {
// Disable resizing
fSaveFrameChanges = false;
ResizeTo(fDefaultRect.Width(), fDefaultRect.Height());
SetFlags(Flags() | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_RESIZABLE);
}
// Quit button
if (fCurrentState == STATE_FINAL_MESSAGE) {
fCancelButtonLayoutItem->SetVisible(true);
fCancelButton->SetLabel(B_TRANSLATE_COMMENT("Quit", "Button label"));
fCancelButton->MakeDefault(true);
}
Unlock();
}
@@ -517,6 +628,35 @@ SoftwareUpdaterWindow::_GetState()
}
status_t
SoftwareUpdaterWindow::_WriteSettings()
{
BFile file;
status_t status = file.SetTo(fSettingsPath.Path(),
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (status == B_OK) {
BMessage settings;
settings.AddBool(kKeyShowDetails, fDetailsCheckbox->Value() != 0);
settings.AddRect(kKeyWindowFrame, Frame());
status = settings.Flatten(&file);
}
file.Unset();
return status;
}
status_t
SoftwareUpdaterWindow::_ReadSettings(BMessage& settings)
{
BFile file;
status_t status = file.SetTo(fSettingsPath.Path(), B_READ_ONLY);
if (status == B_OK)
status = settings.Unflatten(&file);
file.Unset();
return status;
}
SuperItem::SuperItem(const char* label)
:
BListItem(),
@@ -641,28 +781,24 @@ PackageItem::DrawItem(BView* owner, BRect item_rect, bool complete)
{
owner->PushState();
float width;
owner->GetPreferredSize(&width, NULL);
float width = owner->Frame().Width();
float nameWidth = width / 2.0;
float offset_width = 0;
float offsetWidth = 0;
bool showMoreDetails = fSuperItem->GetDetailLevel();
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);
BPoint location = BPoint(item_rect.left,
item_rect.top + offsetMarginHeight);
owner->DrawBitmap(icon, location);
owner->SetDrawingMode(B_OP_COPY);
offsetWidth = iconSize + fLabelOffset;
if (fDrawBarFlag)
_DrawBar(location, owner, icon_size(iconSize));
offset_width += iconSize + fLabelOffset;
}
owner->SetFont(&fRegularFont);
@@ -672,7 +808,7 @@ PackageItem::DrawItem(BView* owner, BRect item_rect, bool complete)
font_height fontHeight = fSuperItem->GetFontHeight();
BString name(fName);
owner->TruncateString(&name, B_TRUNCATE_END, nameWidth);
BPoint cursor(item_rect.left + offset_width,
BPoint cursor(item_rect.left + offsetWidth,
item_rect.bottom - fSmallTotalHeight - fontHeight.descent - 1);
if (showMoreDetails)
cursor.y -= fSmallTotalHeight + 1;
@@ -694,7 +830,7 @@ PackageItem::DrawItem(BView* owner, BRect item_rect, bool complete)
// Summary
BString summary(fSummary);
cursor.x = item_rect.left + offset_width;
cursor.x = item_rect.left + offsetWidth;
cursor.y += fSmallTotalHeight;
owner->TruncateString(&summary, B_TRUNCATE_END, width - cursor.x);
owner->DrawString(summary.String(), cursor);
@@ -974,6 +1110,8 @@ PackageListView::ItemHeight()
void
PackageListView::SetMoreDetails(bool showMore)
{
if (showMore == fShowMoreDetails)
return;
fShowMoreDetails = showMore;
_SetItemHeights();
InvalidateLayout();
@@ -4,7 +4,7 @@
*
* Authors:
* Alexander von Gluck IV <kallisti5@unixzen.com>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef _SOFTWARE_UPDATER_WINDOW_H
#define _SOFTWARE_UPDATER_WINDOW_H
@@ -13,8 +13,10 @@
#include <Button.h>
#include <CheckBox.h>
#include <GroupView.h>
#include <OutlineListView.h>
#include <MessageRunner.h>
#include <NodeInfo.h>
#include <OutlineListView.h>
#include <Path.h>
#include <Point.h>
#include <ScrollView.h>
#include <StatusBar.h>
@@ -134,6 +136,9 @@ private:
class SoftwareUpdaterWindow : public BWindow {
public:
SoftwareUpdaterWindow();
bool QuitRequested();
void FrameMoved(BPoint newPosition);
void FrameResized(float newWidth, float newHeight);
void MessageReceived(BMessage* message);
bool ConfirmUpdates();
void UpdatesApplying(const char* header,
@@ -159,6 +164,8 @@ private:
uint32 _WaitForButtonClick();
void _SetState(uint32 state);
uint32 _GetState();
status_t _WriteSettings();
status_t _ReadSettings(BMessage& settings);
BRect fDefaultRect;
StripeView* fStripeView;
@@ -173,6 +180,7 @@ private:
BLayoutItem* fDetailsLayoutItem;
BLayoutItem* fPackagesLayoutItem;
BLayoutItem* fProgressLayoutItem;
BLayoutItem* fCancelButtonLayoutItem;
BLayoutItem* fUpdateButtonLayoutItem;
BLayoutItem* fDetailsCheckboxLayoutItem;
@@ -185,7 +193,12 @@ private:
BInvoker fCancelAlertResponse;
int32 fWarningAlertCount;
BInvoker fWarningAlertDismissed;
BPath fSettingsPath;
status_t fSettingsReadStatus;
BMessage fInitialSettings;
bool fSaveFrameChanges;
BMessageRunner* fMessageRunner;
BMessage fFrameChangeMessage;
};
+1 -1
View File
@@ -6,7 +6,7 @@
* Ryan Leavengood <leavengood@gmail.com>
* John Scipione <jscipione@gmail.com>
* Joseph Groover <looncraz@looncraz.net>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
+1 -1
View File
@@ -6,7 +6,7 @@
* Ryan Leavengood <leavengood@gmail.com>
* John Scipione <jscipione@gmail.com>
* Joseph Groover <looncraz@looncraz.net>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef _STRIPE_VIEW_H
#define _STRIPE_VIEW_H
+1 -1
View File
@@ -3,7 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
+1 -1
View File
@@ -3,7 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef UPDATE_ACTION_H
#define UPDATE_ACTION_H
+3 -3
View File
@@ -6,7 +6,7 @@
* Axel Dörfler <axeld@pinc-software.de>
* Rene Gollent <rene@gollent.com>
* Ingo Weinhold <ingo_weinhold@gmx.de>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
@@ -57,9 +57,9 @@ UpdateManager::UpdateManager(BPackageInstallationLocation location,
UpdateManager::~UpdateManager()
{
if (fStatusWindow != NULL)
fStatusWindow->PostMessage(B_QUIT_REQUESTED);
fStatusWindow->Quit();
if (fProblemWindow != NULL)
fProblemWindow->PostMessage(B_QUIT_REQUESTED);
fProblemWindow->Quit();
}
+1 -1
View File
@@ -5,7 +5,7 @@
* Authors:
* Ingo Weinhold <ingo_weinhold@gmx.de>
* Rene Gollent <rene@gollent.com>
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef UPDATE_MANAGER_H
#define UPDATE_MANAGER_H
+1 -1
View File
@@ -3,7 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
+1 -1
View File
@@ -3,7 +3,7 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef _WORKING_LOOPER_H
#define _WORKING_LOOPER_H
+6 -1
View File
@@ -3,12 +3,13 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* Brian Hill <supernova@warpmail.net>
* Brian Hill <supernova@tycho.email>
*/
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define kAppSignature "application/x-vnd.haiku-softwareupdater"
#define kSettingsFilename "SoftwareUpdater_settings"
enum {
ACTION_STEP_INIT = 0,
@@ -51,6 +52,7 @@ static const uint32 kMsgNoRepositories = 'iNRE';
static const uint32 kMsgRegister = 'iREG';
static const uint32 kMsgFinalQuit = 'iFIN';
static const uint32 kMsgMoreDetailsToggle = 'iDTO';
static const uint32 kMsgWindowFrameChanged = 'iWFC';
// Message data keys
#define kKeyHeader "key_header"
@@ -61,5 +63,8 @@ static const uint32 kMsgMoreDetailsToggle = 'iDTO';
#define kKeyMessenger "key_messenger"
#define kKeyAlertResult "key_alertresult"
// Settings keys
#define kKeyShowDetails "ShowDetails"
#define kKeyWindowFrame "WindowFrame"
#endif // CONSTANTS_H