haiku/src/servers/keystore/AppAccessRequestWindow.cpp

197 lines
4.7 KiB
C++

/*
* Copyright 2012, Michael Lotz, mmlr@mlotz.ch. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#include "AppAccessRequestWindow.h"
#include <Catalog.h>
#include <LayoutBuilder.h>
#include <LayoutUtils.h>
#include <NodeInfo.h>
#include <Roster.h>
#include <SpaceLayoutItem.h>
#include <TextView.h>
#include <new>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "AppAccessRequestWindow"
static const uint32 kMessageDisallow = 'btda';
static const uint32 kMessageOnce = 'btao';
static const uint32 kMessageAlways = 'btaa';
AppAccessRequestWindow::AppAccessRequestWindow(const char* keyringName,
const char* signature, const char* path, const char* accessString,
bool appIsNew, bool appWasUpdated)
:
BWindow(BRect(50, 50, 100, 100), B_TRANSLATE("Application keyring access"),
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS
| B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_AUTO_UPDATE_SIZE_LIMITS
| B_CLOSE_ON_ESCAPE),
fDoneSem(-1),
fResult(kMessageDisallow)
{
fDoneSem = create_sem(0, "application keyring access dialog");
if (fDoneSem < 0)
return;
BBitmap icon = GetIcon(32 * icon_layout_scale());
fStripeView = new BStripeView(icon);
float inset = ceilf(be_plain_font->Size() * 0.7);
BTextView* message = new(std::nothrow) BTextView("Message");
if (message == NULL)
return;
BString details;
details << B_TRANSLATE("The application:\n"
"%signature% (%path%)\n\n");
details.ReplaceFirst("%signature%", signature);
details.ReplaceFirst("%path%", path);
if (keyringName != NULL) {
details << B_TRANSLATE("requests access to keyring:\n"
"%keyringName%\n\n");
details.ReplaceFirst("%keyringName%", keyringName);
}
if (accessString != NULL) {
details << B_TRANSLATE("to perform the following action:\n"
"%accessString%\n\n");
details.ReplaceFirst("%accessString%", accessString);
}
if (appIsNew)
details << B_TRANSLATE("This application hasn't been granted "
"access before.");
else if (appWasUpdated) {
details << B_TRANSLATE("This application has been updated since "
"it was last granted access.");
} else {
details << B_TRANSLATE("This application doesn't yet have the "
"required privileges.");
}
message->SetText(details);
message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
message->MakeEditable(false);
message->MakeSelectable(false);
message->SetWordWrap(true);
message->SetExplicitMinSize(BSize(message->StringWidth(
"01234567890123456789012345678901234567890123456789") + inset,
B_SIZE_UNSET));
fDisallowButton = new(std::nothrow) BButton(B_TRANSLATE("Disallow"),
new BMessage(kMessageDisallow));
fOnceButton = new(std::nothrow) BButton(B_TRANSLATE("Allow once"),
new BMessage(kMessageOnce));
fAlwaysButton = new(std::nothrow) BButton(B_TRANSLATE("Allow always"),
new BMessage(kMessageAlways));
BLayoutBuilder::Group<>(this, B_HORIZONTAL, B_USE_ITEM_SPACING)
.Add(fStripeView)
.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(message)
.End()
.AddStrut(B_USE_SMALL_SPACING)
.AddGroup(new BGroupView(B_HORIZONTAL))
.Add(fDisallowButton)
.AddGlue()
.Add(fOnceButton)
.Add(fAlwaysButton)
.End()
.End()
.End();
}
AppAccessRequestWindow::~AppAccessRequestWindow()
{
if (fDoneSem >= 0)
delete_sem(fDoneSem);
}
bool
AppAccessRequestWindow::QuitRequested()
{
fResult = kMessageDisallow;
release_sem(fDoneSem);
return false;
}
void
AppAccessRequestWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMessageDisallow:
case kMessageOnce:
case kMessageAlways:
fResult = message->what;
release_sem(fDoneSem);
return;
}
BWindow::MessageReceived(message);
}
status_t
AppAccessRequestWindow::RequestAppAccess(bool& allowAlways)
{
ResizeToPreferred();
CenterOnScreen();
Show();
while (acquire_sem(fDoneSem) == B_INTERRUPTED)
;
status_t result;
switch (fResult) {
default:
case kMessageDisallow:
result = B_NOT_ALLOWED;
allowAlways = false;
break;
case kMessageOnce:
result = B_OK;
allowAlways = false;
break;
case kMessageAlways:
result = B_OK;
allowAlways = true;
break;
}
LockLooper();
Quit();
return result;
}
BBitmap
AppAccessRequestWindow::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;
}