232 lines
5.3 KiB
C++
232 lines
5.3 KiB
C++
/*
|
|
* Copyright 2012, Michael Lotz, mmlr@mlotz.ch. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
|
|
#include "KeyRequestWindow.h"
|
|
|
|
#include <Button.h>
|
|
#include <Catalog.h>
|
|
#include <CheckBox.h>
|
|
#include <GridLayout.h>
|
|
#include <GridView.h>
|
|
#include <GroupLayout.h>
|
|
#include <GroupView.h>
|
|
#include <Key.h>
|
|
#include <MenuField.h>
|
|
#include <MenuItem.h>
|
|
#include <NetworkDevice.h>
|
|
#include <PopUpMenu.h>
|
|
#include <SpaceLayoutItem.h>
|
|
#include <StringView.h>
|
|
#include <TextControl.h>
|
|
#include <TextView.h>
|
|
#include <View.h>
|
|
|
|
#include <new>
|
|
|
|
|
|
#undef B_TRANSLATION_CONTEXT
|
|
#define B_TRANSLATION_CONTEXT "KeyRequestWindow"
|
|
|
|
|
|
static const uint32 kMessageCancel = 'btcl';
|
|
static const uint32 kMessageUnlock = 'btul';
|
|
|
|
|
|
class KeyRequestView : public BView {
|
|
public:
|
|
KeyRequestView()
|
|
:
|
|
BView("KeyRequestView", B_WILL_DRAW),
|
|
fPassword(NULL)
|
|
{
|
|
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
|
|
|
BGroupLayout* rootLayout = new(std::nothrow) BGroupLayout(B_VERTICAL);
|
|
if (rootLayout == NULL)
|
|
return;
|
|
|
|
SetLayout(rootLayout);
|
|
|
|
BGridView* controls = new(std::nothrow) BGridView();
|
|
if (controls == NULL)
|
|
return;
|
|
|
|
BGridLayout* layout = controls->GridLayout();
|
|
|
|
float inset = ceilf(be_plain_font->Size() * 0.7);
|
|
rootLayout->SetInsets(inset, inset, inset, inset);
|
|
rootLayout->SetSpacing(inset);
|
|
layout->SetSpacing(inset, inset);
|
|
|
|
BStringView* label = new(std::nothrow) BStringView("keyringLabel",
|
|
B_TRANSLATE("Keyring:"));
|
|
if (label == NULL)
|
|
return;
|
|
|
|
int32 row = 0;
|
|
layout->AddView(label, 0, row);
|
|
|
|
fKeyringName = new(std::nothrow) BStringView("keyringName", "");
|
|
if (fKeyringName == NULL)
|
|
return;
|
|
|
|
layout->AddView(fKeyringName, 1, row++);
|
|
|
|
fPassword = new(std::nothrow) BTextControl(B_TRANSLATE("Password:"), "", NULL);
|
|
if (fPassword == NULL)
|
|
return;
|
|
|
|
BLayoutItem* layoutItem = fPassword->CreateTextViewLayoutItem();
|
|
layoutItem->SetExplicitMinSize(BSize(fPassword->StringWidth(
|
|
"0123456789012345678901234567890123456789") + inset,
|
|
B_SIZE_UNSET));
|
|
|
|
layout->AddItem(fPassword->CreateLabelLayoutItem(), 0, row);
|
|
layout->AddItem(layoutItem, 1, row++);
|
|
|
|
BGroupView* buttons = new(std::nothrow) BGroupView(B_HORIZONTAL);
|
|
if (buttons == NULL)
|
|
return;
|
|
|
|
fCancelButton = new(std::nothrow) BButton(B_TRANSLATE("Cancel"),
|
|
new BMessage(kMessageCancel));
|
|
buttons->GroupLayout()->AddView(fCancelButton);
|
|
|
|
buttons->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
|
|
|
|
fUnlockButton = new(std::nothrow) BButton(B_TRANSLATE("Unlock"),
|
|
new BMessage(kMessageUnlock));
|
|
buttons->GroupLayout()->AddView(fUnlockButton);
|
|
|
|
BTextView* message = new(std::nothrow) BTextView("message");
|
|
message->SetText(B_TRANSLATE("An application wants to access the "
|
|
"keyring below, but it is locked with a passphrase. Please enter "
|
|
"the passphrase to unlock the keyring.\n"
|
|
"If you unlock the keyring, it stays unlocked until the system is "
|
|
"shut down or the keyring is manually locked again.\n"
|
|
"If you cancel this dialog the keyring will remain locked."));
|
|
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);
|
|
|
|
rootLayout->AddView(message);
|
|
rootLayout->AddView(controls);
|
|
rootLayout->AddView(buttons);
|
|
}
|
|
|
|
virtual void
|
|
AttachedToWindow()
|
|
{
|
|
fCancelButton->SetTarget(Window());
|
|
fUnlockButton->SetTarget(Window());
|
|
fUnlockButton->MakeDefault(true);
|
|
fPassword->MakeFocus();
|
|
}
|
|
|
|
void
|
|
SetUp(const BString& keyringName)
|
|
{
|
|
fKeyringName->SetText(keyringName);
|
|
}
|
|
|
|
status_t
|
|
Complete(BMessage& keyMessage)
|
|
{
|
|
BPasswordKey password(fPassword->Text(), B_KEY_PURPOSE_KEYRING, "");
|
|
return password.Flatten(keyMessage);
|
|
}
|
|
|
|
private:
|
|
BStringView* fKeyringName;
|
|
BTextControl* fPassword;
|
|
BButton* fCancelButton;
|
|
BButton* fUnlockButton;
|
|
};
|
|
|
|
|
|
KeyRequestWindow::KeyRequestWindow()
|
|
:
|
|
BWindow(BRect(50, 50, 100, 100), B_TRANSLATE("Unlock keyring"),
|
|
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS
|
|
| B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | B_AUTO_UPDATE_SIZE_LIMITS
|
|
| B_CLOSE_ON_ESCAPE),
|
|
fRequestView(NULL),
|
|
fDoneSem(-1),
|
|
fResult(B_ERROR)
|
|
{
|
|
fDoneSem = create_sem(0, "keyring unlock dialog");
|
|
if (fDoneSem < 0)
|
|
return;
|
|
|
|
BLayout* layout = new(std::nothrow) BGroupLayout(B_HORIZONTAL);
|
|
if (layout == NULL)
|
|
return;
|
|
|
|
SetLayout(layout);
|
|
|
|
fRequestView = new(std::nothrow) KeyRequestView();
|
|
if (fRequestView == NULL)
|
|
return;
|
|
|
|
layout->AddView(fRequestView);
|
|
}
|
|
|
|
|
|
KeyRequestWindow::~KeyRequestWindow()
|
|
{
|
|
if (fDoneSem >= 0)
|
|
delete_sem(fDoneSem);
|
|
}
|
|
|
|
|
|
bool
|
|
KeyRequestWindow::QuitRequested()
|
|
{
|
|
fResult = B_CANCELED;
|
|
release_sem(fDoneSem);
|
|
return false;
|
|
}
|
|
|
|
|
|
void
|
|
KeyRequestWindow::MessageReceived(BMessage* message)
|
|
{
|
|
switch (message->what) {
|
|
case kMessageCancel:
|
|
case kMessageUnlock:
|
|
fResult = message->what == kMessageUnlock ? B_OK : B_CANCELED;
|
|
release_sem(fDoneSem);
|
|
return;
|
|
}
|
|
|
|
BWindow::MessageReceived(message);
|
|
}
|
|
|
|
|
|
status_t
|
|
KeyRequestWindow::RequestKey(const BString& keyringName, BMessage& keyMessage)
|
|
{
|
|
fRequestView->SetUp(keyringName);
|
|
|
|
ResizeToPreferred();
|
|
CenterOnScreen();
|
|
Show();
|
|
|
|
while (acquire_sem(fDoneSem) == B_INTERRUPTED)
|
|
;
|
|
|
|
status_t result = fResult;
|
|
if (result == B_OK)
|
|
result = fRequestView->Complete(keyMessage);
|
|
|
|
LockLooper();
|
|
Quit();
|
|
return result;
|
|
}
|