SoftwareUpdater version 1.0.1

Changes:
-Bug fix in output when no network is detected on x64. Fixes #13345
-Do not display a final notification if SoftwareUpdater is front most
	window (redundant since the same message is displayed in window)
-Remove the "Continue anyway" prompt when no network detected
-Implement the --verbose command option:
	For update and full-sync modes, only displays Terminal output when
	--verbose is used
	For check mode show output on notifications
-Replace the "Show more details" popup menu with a check box
-Replace fprintf commands with other non-formatting commands if no
	formatting is needed (thanks Axel)
-Display a dialog and button to open the Repositories preflet if no
	repositories are enabled
-Do not display confirmation to quit until after downloads have started
This commit is contained in:
Brian Hill 2017-05-01 22:12:59 -04:00
parent 37422dff73
commit b35bccc0a4
16 changed files with 390 additions and 319 deletions

View File

@ -23,10 +23,10 @@ using namespace BPackageKit;
using namespace BPackageKit::BManager::BPrivate; using namespace BPackageKit::BManager::BPrivate;
CheckAction::CheckAction() CheckAction::CheckAction(bool verbose)
{ {
fCheckManager = new(std::nothrow) fCheckManager = new(std::nothrow)
CheckManager(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM); CheckManager(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, verbose);
} }
@ -61,7 +61,8 @@ CheckAction::Perform()
be_app->PostMessage(kMsgFinalQuit); be_app->PostMessage(kMsgFinalQuit);
return B_OK; return B_OK;
} catch (BNothingToDoException ex) { } catch (BNothingToDoException ex) {
fprintf(stdout, B_TRANSLATE("There were no updates found.")); puts(B_TRANSLATE("There were no updates found."));
fCheckManager->NoUpdatesNotification();
be_app->PostMessage(kMsgFinalQuit); be_app->PostMessage(kMsgFinalQuit);
return B_OK; return B_OK;
} catch (BException ex) { } catch (BException ex) {

View File

@ -14,7 +14,7 @@
class CheckAction { class CheckAction {
public: public:
CheckAction(); CheckAction(bool verbose);
~CheckAction(); ~CheckAction();
status_t Perform(); status_t Perform();

View File

@ -15,6 +15,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include <Application.h>
#include <Catalog.h> #include <Catalog.h>
#include <Message.h> #include <Message.h>
#include <Messenger.h> #include <Messenger.h>
@ -38,12 +39,25 @@ using namespace BPackageKit::BManager::BPrivate;
#define B_TRANSLATION_CONTEXT "CheckManager" #define B_TRANSLATION_CONTEXT "CheckManager"
CheckManager::CheckManager(BPackageInstallationLocation location) CheckManager::CheckManager(BPackageInstallationLocation location,
bool verbose)
: :
BPackageManager(location, &fClientInstallationInterface, this), BPackageManager(location, &fClientInstallationInterface, this),
BPackageManager::UserInteractionHandler(), BPackageManager::UserInteractionHandler(),
fClientInstallationInterface() fClientInstallationInterface(),
fVerbose(verbose),
fNotificationId("")
{ {
if (verbose) {
app_info info;
if (be_app->GetAppInfo(&info)!= B_OK)
fVerbose = false;
else
fNotificationId << info.team;
}
fHeaderChecking = B_TRANSLATE("Checking for updates");
fTextContacting = B_TRANSLATE("Contacting software repositories to check "
"for package updates.");
} }
@ -62,7 +76,7 @@ CheckManager::CheckNetworkConnection()
} }
// No network connection detected, cannot continue // No network connection detected, cannot continue
fprintf(stderr, B_TRANSLATE("No active network connection was found.\n")); fputs(B_TRANSLATE("No active network connection was found.\n"), stderr);
throw BAbortedByUserException(); throw BAbortedByUserException();
} }
@ -81,7 +95,7 @@ CheckManager::JobFailed(BSupportKit::BJob* job)
void void
CheckManager::JobAborted(BSupportKit::BJob* job) CheckManager::JobAborted(BSupportKit::BJob* job)
{ {
printf("Job aborted\n"); puts("Job aborted");
BString error = job->ErrorString(); BString error = job->ErrorString();
if (error.Length() > 0) { if (error.Length() > 0) {
error.ReplaceAll("\n", "\n*** "); error.ReplaceAll("\n", "\n*** ");
@ -90,10 +104,21 @@ CheckManager::JobAborted(BSupportKit::BJob* job)
} }
void
CheckManager::NoUpdatesNotification()
{
if (fVerbose) {
BString header = B_TRANSLATE("No updates available");
BString text = B_TRANSLATE("There were no updates found.");
_SendNotification(header.String(), text.String());
}
}
void void
CheckManager::HandleProblems() CheckManager::HandleProblems()
{ {
printf("Encountered problems:\n"); puts("Encountered problems:");
int32 problemCount = fSolver->CountProblems(); int32 problemCount = fSolver->CountProblems();
for (int32 i = 0; i < problemCount; i++) { for (int32 i = 0; i < problemCount; i++) {
@ -132,7 +157,7 @@ CheckManager::ConfirmChanges(bool fromMostSpecific)
count << updateCount; count << updateCount;
title.ReplaceFirst("%count%", count); title.ReplaceFirst("%count%", count);
BString text(B_TRANSLATE("Click here to install updates.")); BString text(B_TRANSLATE("Click here to install updates."));
_SendNotification(title, text); _SendNotification(title.String(), text.String());
} }
throw BAbortedByUserException(); throw BAbortedByUserException();
} }
@ -147,7 +172,7 @@ CheckManager::Warn(status_t error, const char* format, ...)
va_end(args); va_end(args);
if (error == B_OK) if (error == B_OK)
printf("\n"); puts("");
else else
printf(": %s\n", strerror(error)); printf(": %s\n", strerror(error));
} }
@ -156,6 +181,9 @@ CheckManager::Warn(status_t error, const char* format, ...)
void void
CheckManager::ProgressPackageDownloadStarted(const char* packageName) CheckManager::ProgressPackageDownloadStarted(const char* packageName)
{ {
if (fVerbose)
_SendNotification(fHeaderChecking.String(), fTextContacting.String());
printf("Downloading %s...\n", packageName); printf("Downloading %s...\n", packageName);
} }
@ -188,18 +216,18 @@ CheckManager::ProgressPackageDownloadActive(const char* packageName,
int ipart = (int)(completionPercentage * width); int ipart = (int)(completionPercentage * width);
int fpart = (int)(((completionPercentage * width) - ipart) * 8); int fpart = (int)(((completionPercentage * width) - ipart) * 8);
printf("\r"); // return to the beginning of the line fputs("\r", stdout); // return to the beginning of the line
for (position = 0; position < width; position++) { for (position = 0; position < width; position++) {
if (position < ipart) { if (position < ipart) {
// This part is fully downloaded, show a full block // This part is fully downloaded, show a full block
printf(progressChars[7]); fputs(progressChars[7], stdout);
} else if (position > ipart) { } else if (position > ipart) {
// This part is not downloaded, show a space // This part is not downloaded, show a space
printf(" "); fputs(" ", stdout);
} else { } else {
// This part is partially downloaded // This part is partially downloaded
printf(progressChars[fpart]); fputs(progressChars[fpart], stdout);
} }
} }
@ -215,12 +243,12 @@ void
CheckManager::ProgressPackageDownloadComplete(const char* packageName) CheckManager::ProgressPackageDownloadComplete(const char* packageName)
{ {
// Overwrite the progress bar with whitespace // Overwrite the progress bar with whitespace
printf("\r"); fputs("\r", stdout);
struct winsize w; struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
for (int i = 0; i < (w.ws_col); i++) for (int i = 0; i < (w.ws_col); i++)
printf(" "); fputs(" ", stdout);
printf("\r\x1b[1A"); // Go to previous line. fputs("\r\x1b[1A", stdout); // Go to previous line.
printf("Downloading %s...done.\n", packageName); printf("Downloading %s...done.\n", packageName);
} }
@ -229,6 +257,9 @@ CheckManager::ProgressPackageDownloadComplete(const char* packageName)
void void
CheckManager::ProgressPackageChecksumStarted(const char* title) CheckManager::ProgressPackageChecksumStarted(const char* title)
{ {
if (fVerbose)
_SendNotification(fHeaderChecking.String(), title);
printf("%s...", title); printf("%s...", title);
} }
@ -236,7 +267,7 @@ CheckManager::ProgressPackageChecksumStarted(const char* title)
void void
CheckManager::ProgressPackageChecksumComplete(const char* title) CheckManager::ProgressPackageChecksumComplete(const char* title)
{ {
printf("done.\n"); puts("done.");
} }
@ -275,11 +306,12 @@ CheckManager::_SendNotification(const char* title, const char* text)
notification.SetTitle(title); notification.SetTitle(title);
notification.SetContent(text); notification.SetContent(text);
notification.SetOnClickApp(kAppSignature); notification.SetOnClickApp(kAppSignature);
if(fVerbose)
notification.SetMessageID(fNotificationId);
BBitmap icon(_GetIcon()); BBitmap icon(_GetIcon());
if (icon.IsValid()) if (icon.IsValid())
notification.SetIcon(&icon); notification.SetIcon(&icon);
bigtime_t timeout = 30000000; notification.Send();
notification.Send(timeout);
} }

View File

@ -31,11 +31,13 @@ class CheckManager : public BPackageManager,
private BPackageManager::UserInteractionHandler { private BPackageManager::UserInteractionHandler {
public: public:
CheckManager( CheckManager(
BPackageInstallationLocation location); BPackageInstallationLocation location,
bool verbose);
void CheckNetworkConnection(); void CheckNetworkConnection();
virtual void JobFailed(BSupportKit::BJob* job); virtual void JobFailed(BSupportKit::BJob* job);
virtual void JobAborted(BSupportKit::BJob* job); virtual void JobAborted(BSupportKit::BJob* job);
void NoUpdatesNotification();
private: private:
// UserInteractionHandler // UserInteractionHandler
@ -69,6 +71,10 @@ private:
fClientInstallationInterface; fClientInstallationInterface;
ProblemWindow* fProblemWindow; ProblemWindow* fProblemWindow;
bool fVerbose;
BString fNotificationId;
BString fHeaderChecking;
BString fTextContacting;
}; };

View File

@ -5,7 +5,7 @@ resource app_flags B_SINGLE_LAUNCH;
resource app_version { resource app_version {
major = 1, major = 1,
middle = 0, middle = 0,
minor = 0, minor = 1,
variety = B_APPV_BETA, variety = B_APPV_BETA,
internal = 0, internal = 0,
short_info = "SoftwareUpdater", short_info = "SoftwareUpdater",

View File

@ -9,6 +9,9 @@
#include "SoftwareUpdaterApp.h" #include "SoftwareUpdaterApp.h"
#include <getopt.h>
#include <stdlib.h>
#include <Catalog.h> #include <Catalog.h>
#undef B_TRANSLATION_CONTEXT #undef B_TRANSLATION_CONTEXT
@ -16,7 +19,7 @@
static const char* const kUsage = B_TRANSLATE_COMMENT( static const char* const kUsage = B_TRANSLATE_COMMENT(
"Usage: SoftwareUpdater <command>\n" "Usage: SoftwareUpdater <command> [ <option> ]\n"
"Updates installed packages.\n" "Updates installed packages.\n"
"\n" "\n"
"Commands:\n" "Commands:\n"
@ -24,16 +27,29 @@ static const char* const kUsage = B_TRANSLATE_COMMENT(
" check - Check for available updates but only display a " " check - Check for available updates but only display a "
"notification with results.\n" "notification with results.\n"
" full-sync - Synchronize the installed packages with the " " full-sync - Synchronize the installed packages with the "
"repositories.\n", "Command line usage help") "repositories.\n"
"\n"
"Options:\n"
" -h or --help Print this usage help\n"
" -v or --verbose Output verbose information\n",
"Command line usage help")
; ;
static struct option const kLongOptions[] = {
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{NULL}
};
SoftwareUpdaterApp::SoftwareUpdaterApp() SoftwareUpdaterApp::SoftwareUpdaterApp()
: :
BApplication(kAppSignature), BApplication(kAppSignature),
fWorker(NULL), fWorker(NULL),
fFinalQuitFlag(false), fFinalQuitFlag(false),
fActionRequested(UPDATE) fActionRequested(UPDATE),
fVerbose(false),
fArgvsAccepted(true)
{ {
} }
@ -67,29 +83,63 @@ SoftwareUpdaterApp::QuitRequested()
void void
SoftwareUpdaterApp::ReadyToRun() SoftwareUpdaterApp::ReadyToRun()
{ {
fWorker = new WorkingLooper(fActionRequested); // Argvs no longer accepted once the process starts
fArgvsAccepted = false;
fWorker = new WorkingLooper(fActionRequested, fVerbose);
} }
void void
SoftwareUpdaterApp::ArgvReceived(int32 argc, char **argv) SoftwareUpdaterApp::ArgvReceived(int32 argc, char **argv)
{ {
// Only one command allowed if (!fArgvsAccepted) {
if (argc > 2) { fputs(B_TRANSLATE("Argument variables are no longer accepted\n"),
fprintf(stderr, kUsage); stderr);
PostMessage(B_QUIT_REQUESTED);
return; return;
} else if (argc == 2) { }
fActionRequested = USER_SELECTION_NEEDED;
const char* command = argv[1]; int c;
if (strcmp("update", command) == 0) while ((c = getopt_long(argc, argv, "hv", kLongOptions, NULL)) != -1) {
fActionRequested = UPDATE; switch (c) {
else if (strcmp("check", command) == 0) case 0:
fActionRequested = UPDATE_CHECK_ONLY; break;
else if (strcmp("full-sync", command) == 0) case 'h':
fActionRequested = FULLSYNC; fputs(kUsage, stdout);
else exit(0);
fprintf(stderr, kUsage); break;
case 'v':
fVerbose = true;
break;
default:
fputs(kUsage, stderr);
exit(1);
break;
}
}
const char* command = "";
int32 argCount = argc - optind;
if (argCount == 0)
return;
else if (argCount > 1) {
fputs(kUsage, stderr);
exit(1);
} else
command = argv[optind];
fActionRequested = USER_SELECTION_NEEDED;
if (strcmp("update", command) == 0)
fActionRequested = UPDATE;
else if (strcmp("check", command) == 0)
fActionRequested = UPDATE_CHECK_ONLY;
else if (strcmp("full-sync", command) == 0)
fActionRequested = FULLSYNC;
else {
fputs(B_TRANSLATE_COMMENT("Unrecognized argument", "Error message"),
stderr);
fprintf(stderr, " \"%s\"\n", command);
fputs(kUsage, stderr);
} }
} }
@ -116,11 +166,6 @@ SoftwareUpdaterApp::MessageReceived(BMessage* message)
int int
main(int argc, const char* const* argv) main(int argc, const char* const* argv)
{ {
if (argc > 2) {
fprintf(stderr, kUsage);
return 1;
}
SoftwareUpdaterApp app; SoftwareUpdaterApp app;
return app.Run(); return app.Run();
} }

View File

@ -29,6 +29,8 @@ private:
BMessenger fWindowMessenger; BMessenger fWindowMessenger;
bool fFinalQuitFlag; bool fFinalQuitFlag;
update_type fActionRequested; update_type fActionRequested;
bool fVerbose;
bool fArgvsAccepted;
}; };

View File

@ -41,6 +41,7 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fCurrentState(STATE_HEAD), fCurrentState(STATE_HEAD),
fWaitingSem(-1), fWaitingSem(-1),
fWaitingForButton(false), fWaitingForButton(false),
fUpdateConfirmed(false),
fUserCancelRequested(false), fUserCancelRequested(false),
fWarningAlertCount(0) fWarningAlertCount(0)
{ {
@ -68,6 +69,10 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fScrollView = new BScrollView("scrollview", fListView, B_WILL_DRAW, fScrollView = new BScrollView("scrollview", fListView, B_WILL_DRAW,
false, true); false, true);
fDetailsCheckbox = new BCheckBox("detailscheckbox",
B_TRANSLATE("Show more details"),
new BMessage(kMsgMoreDetailsToggle));
BFont font; BFont font;
fHeaderView->GetFont(&font); fHeaderView->GetFont(&font);
font.SetFace(B_BOLD_FACE); font.SetFace(B_BOLD_FACE);
@ -87,6 +92,10 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
.Add(fScrollView) .Add(fScrollView)
.End() .End()
.AddStrut(B_USE_SMALL_SPACING) .AddStrut(B_USE_SMALL_SPACING)
.AddGroup(new BGroupView(B_HORIZONTAL))
.Add(fDetailsCheckbox)
.AddGlue()
.End()
.AddGroup(new BGroupView(B_HORIZONTAL)) .AddGroup(new BGroupView(B_HORIZONTAL))
.AddGlue() .AddGlue()
.Add(fCancelButton) .Add(fCancelButton)
@ -99,6 +108,7 @@ SoftwareUpdaterWindow::SoftwareUpdaterWindow()
fProgressLayoutItem = layout_item_for(fStatusBar); fProgressLayoutItem = layout_item_for(fStatusBar);
fPackagesLayoutItem = layout_item_for(fScrollView); fPackagesLayoutItem = layout_item_for(fScrollView);
fUpdateButtonLayoutItem = layout_item_for(fUpdateButton); fUpdateButtonLayoutItem = layout_item_for(fUpdateButton);
fDetailsCheckboxLayoutItem = layout_item_for(fDetailsCheckbox);
_SetState(STATE_DISPLAY_STATUS); _SetState(STATE_DISPLAY_STATUS);
CenterOnScreen(); CenterOnScreen();
@ -186,7 +196,26 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
be_app->PostMessage(kMsgFinalQuit); be_app->PostMessage(kMsgFinalQuit);
break; break;
} }
if (!fUpdateConfirmed) {
// Downloads have not started yet, we will request to cancel
// without confirming
Lock();
fHeaderView->SetText(B_TRANSLATE("Cancelling updates"));
fDetailView->SetText(
B_TRANSLATE("Attempting to cancel the updates..."));
fCancelButton->SetEnabled(false);
Unlock();
fUserCancelRequested = true;
if (fWaitingForButton) {
fButtonResult = message->what;
delete_sem(fWaitingSem);
fWaitingSem = -1;
}
break;
}
// Confirm with the user to cancel
BAlert* alert = new BAlert("cancel request", B_TRANSLATE("Updates" BAlert* alert = new BAlert("cancel request", B_TRANSLATE("Updates"
" have not been completed, are you sure you want to quit?"), " have not been completed, are you sure you want to quit?"),
B_TRANSLATE("Quit"), B_TRANSLATE("Don't quit"), NULL, B_TRANSLATE("Quit"), B_TRANSLATE("Don't quit"), NULL,
@ -198,7 +227,7 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
case kMsgCancelResponse: case kMsgCancelResponse:
{ {
// Verify whether the cancel request was confirmed // Verify whether the cancel alert was confirmed
int32 selection = -1; int32 selection = -1;
message->FindInt32("which", &selection); message->FindInt32("which", &selection);
if (selection != 0) if (selection != 0)
@ -226,29 +255,19 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
fButtonResult = message->what; fButtonResult = message->what;
delete_sem(fWaitingSem); delete_sem(fWaitingSem);
fWaitingSem = -1; fWaitingSem = -1;
fUpdateConfirmed = true;
} }
break; break;
} }
case kMsgMoreDetailsToggle:
fListView->SetMoreDetails(fDetailsCheckbox->Value() != 0);
break;
case kMsgWarningDismissed: case kMsgWarningDismissed:
fWarningAlertCount--; fWarningAlertCount--;
break; 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;
}
case kMsgGetUpdateType: case kMsgGetUpdateType:
{ {
BString text( BString text(
@ -285,6 +304,24 @@ SoftwareUpdaterWindow::MessageReceived(BMessage* message)
break; break;
} }
case kMsgNoRepositories:
{
BString text(
B_TRANSLATE_COMMENT(
"No remote repositories are available. Please verify that some"
" repositories are enabled using the Repositories preflet or"
" the \'pkgman\' command.", "Error message"));
BAlert* alert = new BAlert("repositories", text,
B_TRANSLATE_COMMENT("Quit", "Alert button label"),
B_TRANSLATE_COMMENT("Open Repositories","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: default:
BWindow::MessageReceived(message); BWindow::MessageReceived(message);
} }
@ -423,6 +460,7 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
if (fCurrentState == STATE_HEAD) { if (fCurrentState == STATE_HEAD) {
fProgressLayoutItem->SetVisible(false); fProgressLayoutItem->SetVisible(false);
fPackagesLayoutItem->SetVisible(false); fPackagesLayoutItem->SetVisible(false);
fDetailsCheckboxLayoutItem->SetVisible(false);
} }
fCurrentState = state; fCurrentState = state;
@ -437,6 +475,7 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
// Show at confirmation prompt, hide at final update // Show at confirmation prompt, hide at final update
if (fCurrentState == STATE_GET_CONFIRMATION) { if (fCurrentState == STATE_GET_CONFIRMATION) {
fPackagesLayoutItem->SetVisible(true); fPackagesLayoutItem->SetVisible(true);
fDetailsCheckboxLayoutItem->SetVisible(true);
// Re-enable resizing // Re-enable resizing
float defaultWidth = fDefaultRect.Width(); float defaultWidth = fDefaultRect.Width();
SetSizeLimits(defaultWidth, 9999, SetSizeLimits(defaultWidth, 9999,
@ -444,6 +483,7 @@ SoftwareUpdaterWindow::_SetState(uint32 state)
ResizeTo(defaultWidth, .75 * defaultWidth); ResizeTo(defaultWidth, .75 * defaultWidth);
} else if (fCurrentState == STATE_FINAL_MESSAGE) { } else if (fCurrentState == STATE_FINAL_MESSAGE) {
fPackagesLayoutItem->SetVisible(false); fPackagesLayoutItem->SetVisible(false);
fDetailsCheckboxLayoutItem->SetVisible(false);
float defaultWidth = fDefaultRect.Width(); float defaultWidth = fDefaultRect.Width();
float defaultHeight = fDefaultRect.Height(); float defaultHeight = fDefaultRect.Height();
SetSizeLimits(defaultWidth, defaultWidth, defaultHeight, SetSizeLimits(defaultWidth, defaultWidth, defaultHeight,
@ -781,44 +821,11 @@ PackageListView::PackageListView()
fLastProgressItem(NULL), fLastProgressItem(NULL),
fLastProgressValue(-1) fLastProgressValue(-1)
{ {
fMenu = new BPopUpMenu(B_EMPTY_STRING, false, false);
fDetailMenuItem = new BMenuItem("Show more details", new BMessage());
fMenu->AddItem(fDetailMenuItem);
SetExplicitMinSize(BSize(B_SIZE_UNSET, 40)); SetExplicitMinSize(BSize(B_SIZE_UNSET, 40));
SetExplicitPreferredSize(BSize(B_SIZE_UNSET, 400)); SetExplicitPreferredSize(BSize(B_SIZE_UNSET, 400));
} }
void
PackageListView::AttachedToWindow()
{
BOutlineListView::AttachedToWindow();
fDetailMenuItem->SetTarget(this);
}
void
PackageListView::MessageReceived(BMessage* message)
{
switch(message->what)
{
case kMsgMoreDetailsOff:
case kMsgMoreDetailsOn:
{
fShowMoreDetails = message->what == kMsgMoreDetailsOn;
_SetItemHeights();
InvalidateLayout();
ResizeToPreferred();
break;
}
default:
BOutlineListView::MessageReceived(message);
}
}
void void
PackageListView::FrameResized(float newWidth, float newHeight) PackageListView::FrameResized(float newWidth, float newHeight)
{ {
@ -833,31 +840,6 @@ PackageListView::FrameResized(float newWidth, float newHeight)
} }
void
PackageListView::MouseDown(BPoint where)
{
BOutlineListView::MouseDown(where);
int32 button;
Looper()->CurrentMessage()->FindInt32("buttons", &button);
if (button & B_SECONDARY_MOUSE_BUTTON) {
if (fShowMoreDetails) {
fDetailMenuItem->SetMarked(true);
fDetailMenuItem->Message()->what = kMsgMoreDetailsOff;
} else {
fDetailMenuItem->SetMarked(false);
fDetailMenuItem->Message()->what = kMsgMoreDetailsOn;
}
// Offset point so cursor isn't over checkmark
ConvertToScreen(&where);
where.x -= 10;
where.y -= 10;
fMenu->Go(where, true, true, BRect(where.x - 2, where.y - 2,
where.x + 2, where.y + 2), true);
}
}
void void
PackageListView::AddPackage(uint32 install_type, const char* name, PackageListView::AddPackage(uint32 install_type, const char* name,
const char* cur_ver, const char* new_ver, const char* summary, const char* cur_ver, const char* new_ver, const char* summary,
@ -989,6 +971,16 @@ PackageListView::ItemHeight()
} }
void
PackageListView::SetMoreDetails(bool showMore)
{
fShowMoreDetails = showMore;
_SetItemHeights();
InvalidateLayout();
ResizeToPreferred();
}
void void
PackageListView::_SetItemHeights() PackageListView::_SetItemHeights()
{ {

View File

@ -11,12 +11,11 @@
#include <Button.h> #include <Button.h>
#include <CheckBox.h>
#include <GroupView.h> #include <GroupView.h>
#include <OutlineListView.h> #include <OutlineListView.h>
#include <MenuItem.h>
#include <NodeInfo.h> #include <NodeInfo.h>
#include <Point.h> #include <Point.h>
#include <PopUpMenu.h>
#include <ScrollView.h> #include <ScrollView.h>
#include <StatusBar.h> #include <StatusBar.h>
#include <StringView.h> #include <StringView.h>
@ -106,10 +105,7 @@ private:
class PackageListView : public BOutlineListView { class PackageListView : public BOutlineListView {
public: public:
PackageListView(); PackageListView();
void AttachedToWindow();
virtual void MessageReceived(BMessage*);
virtual void FrameResized(float newWidth, float newHeight); virtual void FrameResized(float newWidth, float newHeight);
virtual void MouseDown(BPoint where);
void AddPackage(uint32 install_type, void AddPackage(uint32 install_type,
const char* name, const char* name,
const char* cur_ver, const char* cur_ver,
@ -121,6 +117,7 @@ public:
float percent); float percent);
void SortItems(); void SortItems();
float ItemHeight(); float ItemHeight();
void SetMoreDetails(bool showMore);
private: private:
void _SetItemHeights(); void _SetItemHeights();
@ -129,8 +126,6 @@ private:
SuperItem* fSuperInstallItem; SuperItem* fSuperInstallItem;
SuperItem* fSuperUninstallItem; SuperItem* fSuperUninstallItem;
bool fShowMoreDetails; bool fShowMoreDetails;
BPopUpMenu *fMenu;
BMenuItem *fDetailMenuItem;
PackageItem* fLastProgressItem; PackageItem* fLastProgressItem;
int16 fLastProgressValue; int16 fLastProgressValue;
}; };
@ -174,15 +169,18 @@ private:
BStatusBar* fStatusBar; BStatusBar* fStatusBar;
PackageListView* fListView; PackageListView* fListView;
BScrollView* fScrollView; BScrollView* fScrollView;
BCheckBox* fDetailsCheckbox;
BLayoutItem* fDetailsLayoutItem; BLayoutItem* fDetailsLayoutItem;
BLayoutItem* fPackagesLayoutItem; BLayoutItem* fPackagesLayoutItem;
BLayoutItem* fProgressLayoutItem; BLayoutItem* fProgressLayoutItem;
BLayoutItem* fUpdateButtonLayoutItem; BLayoutItem* fUpdateButtonLayoutItem;
BLayoutItem* fDetailsCheckboxLayoutItem;
uint32 fCurrentState; uint32 fCurrentState;
sem_id fWaitingSem; sem_id fWaitingSem;
bool fWaitingForButton; bool fWaitingForButton;
uint32 fButtonResult; uint32 fButtonResult;
bool fUpdateConfirmed;
bool fUserCancelRequested; bool fUserCancelRequested;
BInvoker fCancelAlertResponse; BInvoker fCancelAlertResponse;
int32 fWarningAlertCount; int32 fWarningAlertCount;

View File

@ -23,10 +23,12 @@ using namespace BPackageKit;
using namespace BPackageKit::BManager::BPrivate; using namespace BPackageKit::BManager::BPrivate;
UpdateAction::UpdateAction() UpdateAction::UpdateAction(bool verbose)
:
fVerbose(verbose)
{ {
fUpdateManager = new(std::nothrow) fUpdateManager = new(std::nothrow)
UpdateManager(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM); UpdateManager(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, verbose);
} }
@ -56,6 +58,7 @@ UpdateAction::Perform(update_type action_request)
fUpdateManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES fUpdateManager->Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES
| BPackageManager::B_ADD_REMOTE_REPOSITORIES | BPackageManager::B_ADD_REMOTE_REPOSITORIES
| BPackageManager::B_REFRESH_REPOSITORIES); | BPackageManager::B_REFRESH_REPOSITORIES);
fUpdateManager->CheckRepositories();
// fUpdateManager->SetDebugLevel(1); // fUpdateManager->SetDebugLevel(1);
if(action == UPDATE) { if(action == UPDATE) {
@ -75,21 +78,24 @@ UpdateAction::Perform(update_type action_request)
ex.Message()); ex.Message());
return ex.Error(); return ex.Error();
} catch (BAbortedByUserException ex) { } catch (BAbortedByUserException ex) {
fprintf(stderr, "Updates aborted by user: %s\n", if (fVerbose)
ex.Message().String()); fprintf(stderr, "Updates aborted by user: %s\n",
ex.Message().String());
// No need for a final message since user initiated cancel request // No need for a final message since user initiated cancel request
be_app->PostMessage(kMsgFinalQuit); be_app->PostMessage(kMsgFinalQuit);
return B_OK; return B_OK;
} catch (BNothingToDoException ex) { } catch (BNothingToDoException ex) {
fprintf(stderr, "Nothing to do while updating packages : %s\n", if (fVerbose)
ex.Message().String()); fprintf(stderr, "Nothing to do while updating packages : %s\n",
ex.Message().String());
fUpdateManager->FinalUpdate(B_TRANSLATE("No updates available"), fUpdateManager->FinalUpdate(B_TRANSLATE("No updates available"),
B_TRANSLATE("There were no updates found.")); B_TRANSLATE("There were no updates found."));
return B_OK; return B_OK;
} catch (BException ex) { } catch (BException ex) {
fprintf(stderr, B_TRANSLATE( if (fVerbose)
fprintf(stderr, B_TRANSLATE(
"Exception occurred while updating packages : %s\n"), "Exception occurred while updating packages : %s\n"),
ex.Message().String()); ex.Message().String());
fUpdateManager->FinalUpdate(B_TRANSLATE("Updates did not complete"), fUpdateManager->FinalUpdate(B_TRANSLATE("Updates did not complete"),
ex.Message()); ex.Message());
return B_ERROR; return B_ERROR;

View File

@ -14,12 +14,13 @@
class UpdateAction { class UpdateAction {
public: public:
UpdateAction(); UpdateAction(bool verbose);
~UpdateAction(); ~UpdateAction();
status_t Perform(update_type action_request); status_t Perform(update_type action_request);
private: private:
UpdateManager* fUpdateManager; UpdateManager* fUpdateManager;
bool fVerbose;
}; };

View File

@ -16,12 +16,14 @@
#include <unistd.h> #include <unistd.h>
#include <Alert.h> #include <Alert.h>
#include <Application.h>
#include <Catalog.h> #include <Catalog.h>
#include <Message.h> #include <Message.h>
#include <Messenger.h> #include <Messenger.h>
#include <NetworkInterface.h> #include <NetworkInterface.h>
#include <NetworkRoster.h> #include <NetworkRoster.h>
#include <Notification.h> #include <Notification.h>
#include <Roster.h>
#include <package/manager/Exceptions.h> #include <package/manager/Exceptions.h>
#include <package/solver/SolverPackage.h> #include <package/solver/SolverPackage.h>
@ -36,14 +38,16 @@ using namespace BPackageKit::BManager::BPrivate;
#define B_TRANSLATION_CONTEXT "UpdateManager" #define B_TRANSLATION_CONTEXT "UpdateManager"
UpdateManager::UpdateManager(BPackageInstallationLocation location) UpdateManager::UpdateManager(BPackageInstallationLocation location,
bool verbose)
: :
BPackageManager(location, &fClientInstallationInterface, this), BPackageManager(location, &fClientInstallationInterface, this),
BPackageManager::UserInteractionHandler(), BPackageManager::UserInteractionHandler(),
fClientInstallationInterface(), fClientInstallationInterface(),
fStatusWindow(NULL), fStatusWindow(NULL),
fCurrentStep(ACTION_STEP_INIT), fCurrentStep(ACTION_STEP_INIT),
fChangesConfirmed(false) fChangesConfirmed(false),
fVerbose(verbose)
{ {
fStatusWindow = new SoftwareUpdaterWindow(); fStatusWindow = new SoftwareUpdaterWindow();
_SetCurrentStep(ACTION_STEP_START); _SetCurrentStep(ACTION_STEP_START);
@ -73,25 +77,9 @@ UpdateManager::CheckNetworkConnection()
} }
} }
// No network connection detected, display warning // No network connection detected, cannot continue
int32 result = 0; throw BException(B_TRANSLATE_COMMENT(
BMessenger messenger(fStatusWindow); "No active network connection was found", "Error message"));
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();
} }
@ -110,9 +98,36 @@ UpdateManager::GetUpdateType()
} }
void
UpdateManager::CheckRepositories()
{
int32 count = fOtherRepositories.CountItems();
if (fVerbose)
printf("Remote repositories available: %" B_PRId32 "\n", count);
if (count == 0) {
BMessenger messenger(fStatusWindow);
if (messenger.IsValid()) {
BMessage message(kMsgNoRepositories);
BMessage reply;
messenger.SendMessage(&message, &reply);
int32 result;
reply.FindInt32(kKeyAlertResult, &result);
if (result == 1)
be_roster->Launch("application/x-vnd.Haiku-Repositories");
}
be_app->PostMessage(kMsgFinalQuit);
throw BException(B_TRANSLATE_COMMENT(
"No remote repositories are available", "Error message"));
}
}
void void
UpdateManager::JobFailed(BSupportKit::BJob* job) UpdateManager::JobFailed(BSupportKit::BJob* job)
{ {
if (!fVerbose)
return;
BString error = job->ErrorString(); BString error = job->ErrorString();
if (error.Length() > 0) { if (error.Length() > 0) {
error.ReplaceAll("\n", "\n*** "); error.ReplaceAll("\n", "\n*** ");
@ -124,7 +139,8 @@ UpdateManager::JobFailed(BSupportKit::BJob* job)
void void
UpdateManager::JobAborted(BSupportKit::BJob* job) UpdateManager::JobAborted(BSupportKit::BJob* job)
{ {
printf("Job aborted\n"); if (fVerbose)
puts("Job aborted");
} }
@ -146,67 +162,14 @@ UpdateManager::HandleProblems()
if (!fProblemWindow->Go(fSolver,installPackages, uninstallPackages)) if (!fProblemWindow->Go(fSolver,installPackages, uninstallPackages))
throw BAbortedByUserException(); throw BAbortedByUserException();
fProblemWindow->Hide(); fProblemWindow->Hide();
/* int32 problemCount = fSolver->CountProblems();
for (int32 i = 0; i < problemCount; i++) {
// print problem and possible solutions
BSolverProblem* problem = fSolver->ProblemAt(i);
printf("problem %" B_PRId32 ": %s\n", i + 1,
problem->ToString().String());
int32 solutionCount = problem->CountSolutions();
for (int32 k = 0; k < solutionCount; k++) {
const BSolverProblemSolution* solution = problem->SolutionAt(k);
printf(" solution %" B_PRId32 ":\n", k + 1);
int32 elementCount = solution->CountElements();
for (int32 l = 0; l < elementCount; l++) {
const BSolverProblemSolutionElement* element
= solution->ElementAt(l);
printf(" - %s\n", element->ToString().String());
}
}
// let the user choose a solution
printf("Please select a solution, skip the problem for now or quit.\n");
for (;;) {
if (solutionCount > 1)
printf("select [1...%" B_PRId32 "/s/q]: ", solutionCount);
else
printf("select [1/s/q]: ");
char buffer[32];
if (fgets(buffer, sizeof(buffer), stdin) == NULL
|| strcmp(buffer, "q\n") == 0) {
//exit(1);
}
if (strcmp(buffer, "s\n") == 0)
break;
char* end;
long selected = strtol(buffer, &end, 0);
if (end == buffer || *end != '\n' || selected < 1
|| selected > solutionCount) {
printf("*** invalid input\n");
continue;
}
status_t error = fSolver->SelectProblemSolution(problem,
problem->SolutionAt(selected - 1));
if (error != B_OK)
DIE(error, "failed to set solution");
break;
}
}*/
} }
void void
UpdateManager::ConfirmChanges(bool fromMostSpecific) UpdateManager::ConfirmChanges(bool fromMostSpecific)
{ {
printf("The following changes will be made:\n"); if (fVerbose)
puts("The following changes will be made:");
int32 count = fInstalledRepositories.CountItems(); int32 count = fInstalledRepositories.CountItems();
int32 upgradeCount = 0; int32 upgradeCount = 0;
@ -223,9 +186,10 @@ UpdateManager::ConfirmChanges(bool fromMostSpecific)
installCount, uninstallCount); installCount, uninstallCount);
} }
printf("Upgrade count=%" B_PRId32 ", Install count=%" B_PRId32 if (fVerbose)
", Uninstall count=%" B_PRId32 "\n", printf("Upgrade count=%" B_PRId32 ", Install count=%" B_PRId32
upgradeCount, installCount, uninstallCount); ", Uninstall count=%" B_PRId32 "\n",
upgradeCount, installCount, uninstallCount);
fChangesConfirmed = fStatusWindow->ConfirmUpdates(); fChangesConfirmed = fStatusWindow->ConfirmUpdates();
if (!fChangesConfirmed) if (!fChangesConfirmed)
@ -243,14 +207,16 @@ UpdateManager::Warn(status_t error, const char* format, ...)
char buffer[256]; char buffer[256];
va_list args; va_list args;
va_start(args, format); va_start(args, format);
vfprintf(stderr, format, args);
vsnprintf(buffer, sizeof(buffer), format, args); vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args); va_end(args);
if (error == B_OK) if (fVerbose) {
printf("\n"); fputs(buffer, stderr);
else if (error == B_OK)
printf(": %s\n", strerror(error)); puts("");
else
printf(": %s\n", strerror(error));
}
if (fStatusWindow != NULL) { if (fStatusWindow != NULL) {
if (fStatusWindow->UserCancelRequested()) if (fStatusWindow->UserCancelRequested())
@ -275,7 +241,8 @@ UpdateManager::ProgressPackageDownloadStarted(const char* packageName)
fNewDownloadStarted = false; fNewDownloadStarted = false;
} }
printf("Downloading %s...\n", packageName); if (fVerbose)
printf("Downloading %s...\n", packageName);
} }
@ -295,49 +262,51 @@ UpdateManager::ProgressPackageDownloadActive(const char* packageName,
_UpdateDownloadProgress(NULL, packageName, completionValue * 100.0); _UpdateDownloadProgress(NULL, packageName, completionValue * 100.0);
} }
static const char* progressChars[] = { if (fVerbose) {
"\xE2\x96\x8F", static const char* progressChars[] = {
"\xE2\x96\x8E", "\xE2\x96\x8F",
"\xE2\x96\x8D", "\xE2\x96\x8E",
"\xE2\x96\x8C", "\xE2\x96\x8D",
"\xE2\x96\x8B", "\xE2\x96\x8C",
"\xE2\x96\x8A", "\xE2\x96\x8B",
"\xE2\x96\x89", "\xE2\x96\x8A",
"\xE2\x96\x88", "\xE2\x96\x89",
}; "\xE2\x96\x88",
};
int width = 70;
int width = 70;
struct winsize winSize;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winSize) == 0 struct winsize winSize;
&& winSize.ws_col < 77) { if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winSize) == 0
// We need 7 characters for the percent display && winSize.ws_col < 77) {
width = winSize.ws_col - 7; // We need 7 characters for the percent display
} width = winSize.ws_col - 7;
int position;
int ipart = (int)(completionValue * width);
int fpart = (int)(((completionValue * width) - ipart) * 8);
printf("\r"); // return to the beginning of the line
for (position = 0; position < width; position++) {
if (position < ipart) {
// This part is fully downloaded, show a full block
printf(progressChars[7]);
} else if (position > ipart) {
// This part is not downloaded, show a space
printf(" ");
} else {
// This part is partially downloaded
printf(progressChars[fpart]);
} }
int position;
int ipart = (int)(completionValue * width);
int fpart = (int)(((completionValue * width) - ipart) * 8);
fputs("\r", stdout); // return to the beginning of the line
for (position = 0; position < width; position++) {
if (position < ipart) {
// This part is fully downloaded, show a full block
fputs(progressChars[7], stdout);
} else if (position > ipart) {
// This part is not downloaded, show a space
fputs(" ", stdout);
} else {
// This part is partially downloaded
fputs(progressChars[fpart], stdout);
}
}
// Also print the progress percentage
printf(" %3d%%", (int)(completionValue * 100));
fflush(stdout);
} }
// Also print the progress percentage
printf(" %3d%%", (int)(completionValue * 100));
fflush(stdout);
} }
@ -350,15 +319,17 @@ UpdateManager::ProgressPackageDownloadComplete(const char* packageName)
fPackageDownloadsCount++; fPackageDownloadsCount++;
} }
// Overwrite the progress bar with whitespace if (fVerbose) {
printf("\r"); // Overwrite the progress bar with whitespace
struct winsize w; fputs("\r", stdout);
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); struct winsize w;
for (int i = 0; i < (w.ws_col); i++) ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
printf(" "); for (int i = 0; i < (w.ws_col); i++)
printf("\r\x1b[1A"); // Go to previous line. fputs(" ", stdout);
fputs("\r\x1b[1A", stdout); // Go to previous line.
printf("Downloading %s...done.\n", packageName);
printf("Downloading %s...done.\n", packageName);
}
} }
@ -369,14 +340,16 @@ UpdateManager::ProgressPackageChecksumStarted(const char* title)
if (fCurrentStep == ACTION_STEP_START) if (fCurrentStep == ACTION_STEP_START)
_UpdateStatusWindow(NULL, title); _UpdateStatusWindow(NULL, title);
printf("%s...", title); if (fVerbose)
printf("%s...", title);
} }
void void
UpdateManager::ProgressPackageChecksumComplete(const char* title) UpdateManager::ProgressPackageChecksumComplete(const char* title)
{ {
printf("done.\n"); if (fVerbose)
puts("done.");
} }
@ -388,7 +361,8 @@ UpdateManager::ProgressStartApplyingChanges(InstalledRepository& repository)
BString detail(B_TRANSLATE("Packages are being updated")); BString detail(B_TRANSLATE("Packages are being updated"));
fStatusWindow->UpdatesApplying(header.String(), detail.String()); fStatusWindow->UpdatesApplying(header.String(), detail.String());
printf("[%s] Applying changes ...\n", repository.Name().String()); if (fVerbose)
printf("[%s] Applying changes ...\n", repository.Name().String());
} }
@ -402,30 +376,33 @@ UpdateManager::ProgressTransactionCommitted(InstalledRepository& repository,
"updates.")); "updates."));
_FinalUpdate(header.String(), detail.String()); _FinalUpdate(header.String(), detail.String());
const char* repositoryName = repository.Name().String(); if (fVerbose) {
const char* repositoryName = repository.Name().String();
int32 issueCount = result.CountIssues(); int32 issueCount = result.CountIssues();
for (int32 i = 0; i < issueCount; i++) { for (int32 i = 0; i < issueCount; i++) {
const BTransactionIssue* issue = result.IssueAt(i); const BTransactionIssue* issue = result.IssueAt(i);
if (issue->PackageName().IsEmpty()) { if (issue->PackageName().IsEmpty()) {
printf("[%s] warning: %s\n", repositoryName, printf("[%s] warning: %s\n", repositoryName,
issue->ToString().String()); issue->ToString().String());
} else { } else {
printf("[%s] warning: package %s: %s\n", repositoryName, printf("[%s] warning: package %s: %s\n", repositoryName,
issue->PackageName().String(), issue->ToString().String()); issue->PackageName().String(), issue->ToString().String());
}
} }
printf("[%s] Changes applied. Old activation state backed up in \"%s\"\n",
repositoryName, result.OldStateDirectory().String());
printf("[%s] Cleaning up ...\n", repositoryName);
} }
printf("[%s] Changes applied. Old activation state backed up in \"%s\"\n",
repositoryName, result.OldStateDirectory().String());
printf("[%s] Cleaning up ...\n", repositoryName);
} }
void void
UpdateManager::ProgressApplyingChangesDone(InstalledRepository& repository) UpdateManager::ProgressApplyingChangesDone(InstalledRepository& repository)
{ {
printf("[%s] Done.\n", repository.Name().String()); if (fVerbose)
printf("[%s] Done.\n", repository.Name().String());
} }
@ -436,7 +413,8 @@ UpdateManager::_PrintResult(InstalledRepository& installationRepository,
if (!installationRepository.HasChanges()) if (!installationRepository.HasChanges())
return; return;
printf(" in %s:\n", installationRepository.Name().String()); if (fVerbose)
printf(" in %s:\n", installationRepository.Name().String());
PackageList& packagesToActivate PackageList& packagesToActivate
= installationRepository.PackagesToActivate(); = installationRepository.PackagesToActivate();
@ -470,11 +448,12 @@ UpdateManager::_PrintResult(InstalledRepository& installationRepository,
int position = upgradedPackages.IndexOf(package->Info().Name()); int position = upgradedPackages.IndexOf(package->Info().Name());
if (position >= 0) { if (position >= 0) {
printf(" upgrade package %s-%s to %s from %s\n", if (fVerbose)
package->Info().Name().String(), printf(" upgrade package %s-%s to %s from %s\n",
upgradedPackageVersions.StringAt(position).String(), package->Info().Name().String(),
package->Info().Version().ToString().String(), upgradedPackageVersions.StringAt(position).String(),
repository.String()); package->Info().Version().ToString().String(),
repository.String());
fStatusWindow->AddPackageInfo(PACKAGE_UPDATE, fStatusWindow->AddPackageInfo(PACKAGE_UPDATE,
package->Info().Name().String(), package->Info().Name().String(),
upgradedPackageVersions.StringAt(position).String(), upgradedPackageVersions.StringAt(position).String(),
@ -484,10 +463,11 @@ UpdateManager::_PrintResult(InstalledRepository& installationRepository,
package->Info().FileName().String()); package->Info().FileName().String());
upgradeCount++; upgradeCount++;
} else { } else {
printf(" install package %s-%s from %s\n", if (fVerbose)
package->Info().Name().String(), printf(" install package %s-%s from %s\n",
package->Info().Version().ToString().String(), package->Info().Name().String(),
repository.String()); package->Info().Version().ToString().String(),
repository.String());
fStatusWindow->AddPackageInfo(PACKAGE_INSTALL, fStatusWindow->AddPackageInfo(PACKAGE_INSTALL,
package->Info().Name().String(), package->Info().Name().String(),
NULL, NULL,
@ -504,7 +484,9 @@ UpdateManager::_PrintResult(InstalledRepository& installationRepository,
i++) { i++) {
if (upgradedPackages.HasString(package->Info().Name())) if (upgradedPackages.HasString(package->Info().Name()))
continue; continue;
printf(" uninstall package %s\n", package->VersionedName().String()); if (fVerbose)
printf(" uninstall package %s\n",
package->VersionedName().String());
fStatusWindow->AddPackageInfo(PACKAGE_UNINSTALL, fStatusWindow->AddPackageInfo(PACKAGE_UNINSTALL,
package->Info().Name().String(), package->Info().Name().String(),
package->Info().Version().ToString(), package->Info().Version().ToString(),
@ -563,14 +545,16 @@ UpdateManager::_UpdateDownloadProgress(const char* header,
void void
UpdateManager::_FinalUpdate(const char* header, const char* text) UpdateManager::_FinalUpdate(const char* header, const char* text)
{ {
BNotification notification(B_INFORMATION_NOTIFICATION); if (!fStatusWindow->IsFront()) {
notification.SetGroup("SoftwareUpdater"); BNotification notification(B_INFORMATION_NOTIFICATION);
notification.SetTitle(header); notification.SetGroup("SoftwareUpdater");
notification.SetContent(text); notification.SetTitle(header);
BBitmap icon(fStatusWindow->GetNotificationIcon()); notification.SetContent(text);
if (icon.IsValid()) BBitmap icon(fStatusWindow->GetNotificationIcon());
notification.SetIcon(&icon); if (icon.IsValid())
notification.Send(); notification.SetIcon(&icon);
notification.Send();
}
fStatusWindow->FinalUpdate(header, text); fStatusWindow->FinalUpdate(header, text);
} }

View File

@ -29,11 +29,13 @@ class UpdateManager : public BPackageManager,
private BPackageManager::UserInteractionHandler { private BPackageManager::UserInteractionHandler {
public: public:
UpdateManager( UpdateManager(
BPackageInstallationLocation location); BPackageInstallationLocation location,
bool verbose);
~UpdateManager(); ~UpdateManager();
void CheckNetworkConnection(); void CheckNetworkConnection();
update_type GetUpdateType(); update_type GetUpdateType();
void CheckRepositories();
virtual void JobFailed(BSupportKit::BJob* job); virtual void JobFailed(BSupportKit::BJob* job);
virtual void JobAborted(BSupportKit::BJob* job); virtual void JobAborted(BSupportKit::BJob* job);
void FinalUpdate(const char* header, void FinalUpdate(const char* header,
@ -91,6 +93,7 @@ private:
bool fNewDownloadStarted; bool fNewDownloadStarted;
int32 fPackageDownloadsTotal; int32 fPackageDownloadsTotal;
int32 fPackageDownloadsCount; int32 fPackageDownloadsCount;
bool fVerbose;
}; };

View File

@ -10,12 +10,13 @@
#include "WorkingLooper.h" #include "WorkingLooper.h"
WorkingLooper::WorkingLooper(update_type action) WorkingLooper::WorkingLooper(update_type action, bool verbose)
: :
BLooper("WorkingLooper"), BLooper("WorkingLooper"),
fUpdateAction(NULL), fUpdateAction(NULL),
fCheckAction(NULL), fCheckAction(NULL),
fActionRequested(action) fActionRequested(action),
fVerbose(verbose)
{ {
Run(); Run();
PostMessage(kMsgStart); PostMessage(kMsgStart);
@ -36,10 +37,10 @@ WorkingLooper::MessageReceived(BMessage* message)
case kMsgStart: case kMsgStart:
{ {
if (fActionRequested == UPDATE_CHECK_ONLY) { if (fActionRequested == UPDATE_CHECK_ONLY) {
fCheckAction = new CheckAction; fCheckAction = new CheckAction(fVerbose);
fCheckAction->Perform(); fCheckAction->Perform();
} else { } else {
fUpdateAction = new UpdateAction(); fUpdateAction = new UpdateAction(fVerbose);
fUpdateAction->Perform(fActionRequested); fUpdateAction->Perform(fActionRequested);
} }
break; break;

View File

@ -21,7 +21,7 @@ const uint32 kMsgStart = 'iSTA';
class WorkingLooper : public BLooper { class WorkingLooper : public BLooper {
public: public:
WorkingLooper(update_type action); WorkingLooper(update_type action, bool verbose);
~WorkingLooper(); ~WorkingLooper();
void MessageReceived(BMessage* message); void MessageReceived(BMessage* message);
@ -29,6 +29,7 @@ private:
UpdateAction* fUpdateAction; UpdateAction* fUpdateAction;
CheckAction* fCheckAction; CheckAction* fCheckAction;
update_type fActionRequested; update_type fActionRequested;
bool fVerbose;
}; };

View File

@ -46,12 +46,11 @@ static const uint32 kMsgCancel = 'iCAN';
static const uint32 kMsgCancelResponse = 'iCRE'; static const uint32 kMsgCancelResponse = 'iCRE';
static const uint32 kMsgUpdateConfirmed = 'iCON'; static const uint32 kMsgUpdateConfirmed = 'iCON';
static const uint32 kMsgWarningDismissed = 'iWDI'; static const uint32 kMsgWarningDismissed = 'iWDI';
static const uint32 kMsgNetworkAlert = 'iNAL';
static const uint32 kMsgGetUpdateType = 'iGUP'; static const uint32 kMsgGetUpdateType = 'iGUP';
static const uint32 kMsgNoRepositories = 'iNRE';
static const uint32 kMsgRegister = 'iREG'; static const uint32 kMsgRegister = 'iREG';
static const uint32 kMsgFinalQuit = 'iFIN'; static const uint32 kMsgFinalQuit = 'iFIN';
static const uint32 kMsgMoreDetailsOn = 'iDON'; static const uint32 kMsgMoreDetailsToggle = 'iDTO';
static const uint32 kMsgMoreDetailsOff = 'iDOF';
// Message data keys // Message data keys
#define kKeyHeader "key_header" #define kKeyHeader "key_header"