2
0

Initial window improvements, reveal and reset master password.

[FIXED]     Initial intro window didn't always show up reliably.
[ADDED]     Ability to temporarily reveal master password while typing it.
[IMPROVED]  When you go down the sites list, fade out the fade-out gradient to prevent the selection from becoming invisible.
[ADDED]     Ability to reset your master password.
[UPDATED]   Initial screenshot of Master Password for Mac and iPhone.
This commit is contained in:
Maarten Billemont 2014-06-29 23:18:25 -04:00
parent 6d4d57441b
commit f1a72d8160
11 changed files with 525 additions and 151 deletions

View File

@ -1,6 +1,6 @@
language: objective-c
xcode_workspace: MasterPassword.xcworkspace
xcode_scheme: MasterPassword iOS (Development)
xcode_scheme: 'MasterPassword iOS (Development)'
xcode_sdk: iphonesimulator
git:
submodules: false

View File

@ -1,20 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4514" systemVersion="13B3116" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13D65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4514"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPMacAppDelegate">
<customObject id="-2" userLabel="File's Owner" customClass="MPInitialWindowController">
<connections>
<outlet property="enableCloudButton" destination="409" id="572"/>
<outlet property="openAtLoginButton" destination="508" id="571"/>
<outlet property="window" destination="1" id="ngh-EA-JYN"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" wantsToBeColor="NO" animationBehavior="default" id="1">
<window title="Welcome to Master Password" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" animationBehavior="default" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowCollectionBehavior key="collectionBehavior" moveToActiveSpace="YES"/>
<rect key="contentRect" x="196" y="240" width="833" height="540"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
<view key="contentView" id="2" userLabel="Container">
@ -125,7 +127,7 @@ from anywhere.</string>
<constraints>
<constraint firstAttribute="width" constant="530" id="566"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="To begin, press: command, control and P or access the ●●●| menu icon." id="563">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="To begin, hold: command, control and P (⌘⌃P) or access the ●●●| menu icon." id="563">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>

View File

@ -0,0 +1,29 @@
/**
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
*
* See the enclosed file LICENSE for license information (LGPLv3). If you did
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
*
* @author Maarten Billemont <lhunath@lyndir.com>
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
*/
//
// MPInitialWindowController.h
// MPInitialWindowController
//
// Created by lhunath on 2014-06-29.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
//
#import <AppKit/AppKit.h>
@interface MPInitialWindowController : NSWindowController
@property(nonatomic, weak) IBOutlet NSButton *openAtLoginButton;
@property(nonatomic, weak) IBOutlet NSButton *enableCloudButton;
- (IBAction)iphoneAppStore:(id)sender;
- (IBAction)togglePreference:(id)sender;
@end

View File

@ -0,0 +1,60 @@
/**
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
*
* See the enclosed file LICENSE for license information (LGPLv3). If you did
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
*
* @author Maarten Billemont <lhunath@lyndir.com>
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
*/
//
// MPInitialWindowController.h
// MPInitialWindowController
//
// Created by lhunath on 2014-06-29.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
//
#import "MPInitialWindowController.h"
#import "MPMacAppDelegate.h"
#import "MPAppDelegate_Store.h"
@implementation MPInitialWindowController
#pragma mark - Life
- (void)windowDidLoad {
[super windowDidLoad];
[[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:self.window
queue:nil usingBlock:^(NSNotification *note) {
[MPMacAppDelegate get].initialWindowController = nil;
}];
}
#pragma mark - Actions
- (IBAction)iphoneAppStore:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/id510296984"]];
[self close];
}
- (IBAction)togglePreference:(id)sender {
if (sender == self.enableCloudButton) {
if (([MPMacAppDelegate get].storeManager.cloudEnabled = self.enableCloudButton.state == NSOnState)) {
NSAlert *alert = [NSAlert new];
alert.messageText = @"iCloud Enabled";
alert.informativeText = @"If you already have a user on another iCloud-enabled device, "
@"it may take a moment for that user to sync down to this device.";
[alert runModal];
}
}
if (sender == self.openAtLoginButton)
[[MPMacAppDelegate get] setLoginItemEnabled:self.openAtLoginButton.state == NSOnState];
}
@end

View File

@ -10,11 +10,13 @@
#import "MPAppDelegate_Shared.h"
#import "RHStatusItemView.h"
#import "MPPasswordWindowController.h"
#import "MPInitialWindowController.h"
@interface MPMacAppDelegate : MPAppDelegate_Shared<NSApplicationDelegate>
@property(nonatomic, strong) RHStatusItemView *statusView;
@property(nonatomic, strong) MPPasswordWindowController *passwordWindow;
@property(nonatomic, strong) MPPasswordWindowController *passwordWindowController;
@property(nonatomic, strong) MPInitialWindowController *initialWindowController;
@property(nonatomic, weak) IBOutlet NSMenuItem *lockItem;
@property(nonatomic, weak) IBOutlet NSMenuItem *showItem;
@property(nonatomic, strong) IBOutlet NSMenu *statusMenu;
@ -26,17 +28,15 @@
@property(nonatomic, weak) IBOutlet NSMenuItem *createUserItem;
@property(nonatomic, weak) IBOutlet NSMenuItem *deleteUserItem;
@property(nonatomic, weak) IBOutlet NSMenuItem *usersItem;
@property(nonatomic, weak) IBOutlet NSButton *openAtLoginButton;
@property(nonatomic, weak) IBOutlet NSButton *enableCloudButton;
- (IBAction)showPasswordWindow:(id)sender;
- (void)setLoginItemEnabled:(BOOL)enabled;
- (IBAction)togglePreference:(id)sender;
- (IBAction)newUser:(NSMenuItem *)sender;
- (IBAction)lock:(id)sender;
- (IBAction)rebuildCloud:(id)sender;
- (IBAction)corruptCloud:(id)sender;
- (IBAction)terminate:(id)sender;
- (IBAction)iphoneAppStore:(id)sender;
- (IBAction)showPopup:(id)sender;
@end

View File

@ -22,11 +22,6 @@
@end
@interface MPMacAppDelegate()
@property(nonatomic, strong) NSWindowController *initialWindow;
@end
@implementation MPMacAppDelegate
#pragma clang diagnostic push
@ -131,10 +126,9 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
err( @"Error registering 'lock' hotkey: %i", (int)status );
// Initial display.
if ([[MPMacConfig get].firstRun boolValue]) {
self.initialWindow = [[NSWindowController alloc] initWithWindowNibName:@"MPInitialWindow" owner:self];
[self.initialWindow.window setLevel:NSFloatingWindowLevel];
[self.initialWindow showWindow:self];
if ([[MPMacConfig get].firstRun boolValue]){
[(self.initialWindowController = [[MPInitialWindowController alloc] initWithWindowNibName:@"MPInitialWindow"]).window makeKeyAndOrderFront:self];
[NSApp activateIgnoringOtherApps:YES];
}
}
@ -185,7 +179,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
}
self.openAtLoginItem.state = loginItemEnabled? NSOnState: NSOffState;
self.openAtLoginButton.state = loginItemEnabled? NSOnState: NSOffState;
self.initialWindowController.openAtLoginButton.state = loginItemEnabled? NSOnState: NSOffState;
}
- (BOOL)loginItemEnabled {
@ -320,23 +314,12 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)togglePreference:(id)sender {
if (sender == self.enableCloudButton) {
if (([self storeManager].cloudEnabled = self.enableCloudButton.state == NSOnState)) {
NSAlert *alert = [NSAlert new];
alert.messageText = @"iCloud Enabled";
alert.informativeText = @"If you already have a user on another iCloud-enabled device, "
@"it may take a moment for that user to sync down to this device.";
[alert runModal];
}
}
if (sender == self.useCloudItem)
[self storeManager].cloudEnabled = self.useCloudItem.state != NSOnState;
if (sender == self.hidePasswordsItem)
[MPConfig get].hidePasswords = [NSNumber numberWithBool:![[MPConfig get].hidePasswords boolValue]];
if (sender == self.rememberPasswordItem)
[MPConfig get].rememberLogin = [NSNumber numberWithBool:![[MPConfig get].rememberLogin boolValue]];
if (sender == self.openAtLoginButton)
[self setLoginItemEnabled:self.openAtLoginButton.state == NSOnState];
if (sender == self.openAtLoginItem)
[self setLoginItemEnabled:self.openAtLoginItem.state != NSOnState];
if (sender == self.savePasswordItem) {
@ -432,20 +415,12 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)terminate:(id)sender {
[self.passwordWindow close];
self.passwordWindow = nil;
[self.passwordWindowController close];
self.passwordWindowController = nil;
[NSApp terminate:nil];
}
- (IBAction)iphoneAppStore:(id)sender {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/id510296984"]];
[self.initialWindow close];
self.initialWindow = nil;
}
- (IBAction)showPopup:(id)sender {
[self.statusView popUpMenu];
@ -466,12 +441,12 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
}
// Don't show window if we weren't already running (ie. if we haven't been activated before).
PearlProfiler *profiler = [PearlProfiler profilerForTask:@"passwordWindow"];
if (!self.passwordWindow)
self.passwordWindow = [[MPPasswordWindowController alloc] initWithWindowNibName:@"MPPasswordWindowController"];
PearlProfiler *profiler = [PearlProfiler profilerForTask:@"passwordWindowController"];
if (!self.passwordWindowController)
self.passwordWindowController = [[MPPasswordWindowController alloc] initWithWindowNibName:@"MPPasswordWindowController"];
[profiler finishJob:@"init"];
[self.passwordWindow showWindow:self];
[self.passwordWindowController showWindow:self];
[profiler finishJob:@"show"];
}
@ -607,7 +582,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (void)updateMenuItems {
MPUserEntity *activeUser = [self activeUserForMainThread];
// if (!(self.showItem.enabled = ![self.passwordWindow.window isVisible])) {
// if (!(self.showItem.enabled = ![self.passwordWindowController.window isVisible])) {
// self.showItem.title = @"Show (Showing)";
// self.showItem.toolTip = @"Master Password is already showing.";
// }
@ -633,7 +608,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
BOOL loginItemEnabled = [self loginItemEnabled];
self.openAtLoginItem.state = loginItemEnabled? NSOnState: NSOffState;
self.openAtLoginButton.state = loginItemEnabled? NSOnState: NSOffState;
self.initialWindowController.openAtLoginButton.state = loginItemEnabled? NSOnState: NSOffState;
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
self.savePasswordItem.state = activeUser.saveKey? NSOnState: NSOffState;
@ -654,7 +629,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
}
self.useCloudItem.state = self.storeManager.cloudEnabled? NSOnState: NSOffState;
self.enableCloudButton.state = self.storeManager.cloudEnabled? NSOnState: NSOffState;
self.initialWindowController.enableCloudButton.state = self.storeManager.cloudEnabled? NSOnState: NSOffState;
self.useCloudItem.enabled = self.storeManager.cloudAvailable;
if (self.storeManager.cloudAvailable) {
self.useCloudItem.title = @"Use iCloud";

View File

@ -19,16 +19,21 @@
#import <Cocoa/Cocoa.h>
#import "MPElementModel.h"
@class MPMacAppDelegate;
@interface MPPasswordWindowController : NSWindowController<NSTextViewDelegate, NSTextFieldDelegate, NSTableViewDataSource, NSTableViewDelegate>
@property(nonatomic, strong) NSMutableArray *elements;
@property(nonatomic) NSMutableArray *elements;
@property(nonatomic) NSString *masterPassword;
@property(nonatomic) BOOL alternatePressed;
@property(nonatomic) BOOL locked;
@property(nonatomic, weak) IBOutlet NSArrayController *elementsController;
@property(nonatomic, weak) IBOutlet NSImageView *blurView;
@property(nonatomic, weak) IBOutlet NSTextField *inputLabel;
@property(nonatomic, weak) IBOutlet NSTextField *securePasswordField;
@property(nonatomic, weak) IBOutlet NSTextField *revealPasswordField;
@property(nonatomic, weak) IBOutlet NSSearchField *siteField;
@property(nonatomic, weak) IBOutlet NSSecureTextField *passwordField;
@property(nonatomic, weak) IBOutlet NSTableView *siteTable;
@property(nonatomic, weak) IBOutlet NSProgressIndicator *progressView;

View File

@ -25,6 +25,7 @@
#import "PearlProfiler.h"
#define MPAlertIncorrectMP @"MPAlertIncorrectMP"
#define MPAlertChangeMP @"MPAlertChangeMP"
#define MPAlertCreateSite @"MPAlertCreateSite"
#define MPAlertChangeType @"MPAlertChangeType"
#define MPAlertChangeLogin @"MPAlertChangeLogin"
@ -34,6 +35,7 @@
@interface MPPasswordWindowController()
@property(nonatomic, copy) NSString *currentSiteText;
@property(nonatomic, strong) CAGradientLayer *siteGradient;
@end
@implementation MPPasswordWindowController { BOOL _skipTextChange; }
@ -57,6 +59,12 @@
[self fadeIn];
[self updateUser];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:self.window
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSWindow *sheet = [self.window attachedSheet];
if (sheet)
[NSApp endSheet:sheet];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillResignActiveNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self fadeOut];
@ -69,20 +77,20 @@
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self updateUser];
}];
[self.elementsController observeKeyPath:@"selection"
withBlock:^(id from, id to, NSKeyValueChange cause, id _self) {
[self updateSelection];
[self observeKeyPath:@"elementsController.selection"
withBlock:^(id from, id to, NSKeyValueChange cause, id _self) {
[_self updateSelection];
}];
NSSearchFieldCell *siteFieldCell = self.siteField.cell;
siteFieldCell.searchButtonCell = nil;
siteFieldCell.cancelButtonCell = nil;
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.colors = @[ (__bridge id)[NSColor whiteColor].CGColor, (__bridge id)[NSColor clearColor].CGColor ];
gradient.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
gradient.frame = self.siteTable.bounds;
self.siteTable.superview.superview.layer.mask = gradient;
self.siteGradient = [CAGradientLayer layer];
self.siteGradient.colors = @[ (__bridge id)[NSColor whiteColor].CGColor, (__bridge id)[NSColor clearColor].CGColor ];
self.siteGradient.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
self.siteGradient.frame = self.siteTable.bounds;
self.siteTable.superview.superview.layer.mask = self.siteGradient;
}
- (void)flagsChanged:(NSEvent *)theEvent {
@ -91,6 +99,14 @@
if (alternatePressed != self.alternatePressed) {
self.alternatePressed = alternatePressed;
[self.selectedElement updateContent];
if (self.locked) {
NSTextField *passwordField = self.securePasswordField;
if (self.securePasswordField.isHidden)
passwordField = self.revealPasswordField;
[passwordField becomeFirstResponder];
[[passwordField currentEditor] moveToEndOfLine:nil];
}
}
[super flagsChanged:theEvent];
@ -107,29 +123,11 @@
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector {
if (control == self.passwordField) {
if (control == self.siteField) {
if (commandSelector == @selector( insertNewline: )) {
NSString *password = self.passwordField.stringValue;
[self.progressView startAnimation:self];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
MPUserEntity *activeUser = [[MPMacAppDelegate get] activeUserInContext:moc];
NSString *userName = activeUser.name;
BOOL success = [[MPMacAppDelegate get] signInAsUser:activeUser saveInContext:moc usingMasterPassword:password];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.progressView stopAnimation:self];
if (!success)
[[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
NSLocalizedDescriptionKey : PearlString( @"Incorrect master password for user %@", userName )
}]] beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector( alertDidEnd:returnCode:contextInfo: ) contextInfo:MPAlertIncorrectMP];
}];
}];
[self useSite];
return YES;
}
}
if (control == self.siteField) {
if (commandSelector == @selector( moveUp: )) {
[self.elementsController selectPrevious:self];
return YES;
@ -155,6 +153,26 @@
return YES;
}
- (IBAction)doUnlockUser:(id)sender {
[self.progressView startAnimation:self];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
MPUserEntity *activeUser = [[MPMacAppDelegate get] activeUserInContext:moc];
NSString *userName = activeUser.name;
BOOL success = [[MPMacAppDelegate get] signInAsUser:activeUser saveInContext:moc usingMasterPassword:self.masterPassword];
PearlMainQueue( ^{
self.masterPassword = nil;
[self.progressView stopAnimation:self];
if (!success)
[[NSAlert alertWithError:[NSError errorWithDomain:MPErrorDomain code:0 userInfo:@{
NSLocalizedDescriptionKey : PearlString( @"Incorrect master password for user %@", userName )
}]] beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector( alertDidEnd:returnCode:contextInfo: ) contextInfo:MPAlertIncorrectMP];
} );
}];
}
- (IBAction)doSearchElements:(id)sender {
[self updateElements];
@ -180,6 +198,34 @@
if (contextInfo == MPAlertIncorrectMP)
return;
if (contextInfo == MPAlertChangeMP) {
switch (returnCode) {
case NSAlertFirstButtonReturn: {
// "Reset" button.
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPUserEntity *activeUser = [[MPMacAppDelegate get] activeUserInContext:context];
NSString *activeUserName = activeUser.name;
activeUser.keyID = nil;
[[MPMacAppDelegate get] forgetSavedKeyFor:activeUser];
[context saveToStore];
PearlMainQueue( ^{
NSAlert *alert_ = [NSAlert new];
alert_.messageText = @"Master Password Reset";
alert_.informativeText = strf( @"%@'s master password has been reset.\n\nYou can now set a new one by logging in.",
activeUserName );
[alert_ beginSheetModalForWindow:self.window modalDelegate:nil didEndSelector:NULL contextInfo:nil];
if ([MPMacAppDelegate get].key)
[[MPMacAppDelegate get] signOutAnimated:YES];
} );
}];
}
default:
break;
}
return;
}
if (contextInfo == MPAlertCreateSite) {
switch (returnCode) {
case NSAlertFirstButtonReturn: {
@ -265,7 +311,7 @@
- (NSString *)query {
return [self.siteField.stringValue stringByReplacingCharactersInRange:self.siteField.currentEditor.selectedRange withString:@""];
return [self.siteField.stringValue stringByReplacingCharactersInRange:self.siteField.currentEditor.selectedRange withString:@""]?: @"";
}
- (void)insertObject:(MPElementModel *)model inElementsAtIndex:(NSUInteger)index {
@ -318,6 +364,21 @@
didEndSelector:@selector( alertDidEnd:returnCode:contextInfo: ) contextInfo:MPAlertChangeLogin];
}
- (IBAction)resetMasterPassword:(id)sender {
MPUserEntity *activeUser = [MPMacAppDelegate get].activeUserForMainThread;
NSAlert *alert = [NSAlert new];
[alert addButtonWithTitle:@"Reset"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Reset My Master Password"];
[alert setInformativeText:strf( @"This will allow you to change %@'s master password.\n\n"
@"WARNING: All your site passwords will change. Do this only if you've forgotten your "
@"master password and are fully prepared to change all your sites' passwords to the new ones.", activeUser.name )];
[alert beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector( alertDidEnd:returnCode:contextInfo: ) contextInfo:MPAlertChangeMP];
}
- (IBAction)changePassword:(id)sender {
if (!self.selectedElement.stored)
@ -367,10 +428,6 @@
- (BOOL)handleCommand:(SEL)commandSelector {
if (commandSelector == @selector( insertNewline: )) {
[self useSite];
return YES;
}
if (commandSelector == @selector( cancel: ) || commandSelector == @selector( cancelOperation: )) {
[self fadeOut];
return YES;
@ -379,29 +436,52 @@
return NO;
}
- (void)useSite {
MPElementModel *selectedElement = [self selectedElement];
if (selectedElement) {
// Performing action while content is available. Copy it.
[self copyContent:selectedElement.content];
[self fadeOut];
NSUserNotification *notification = [NSUserNotification new];
notification.title = @"Password Copied";
if (selectedElement.loginName.length)
notification.subtitle = PearlString( @"%@ at %@", selectedElement.loginName, selectedElement.siteName );
else
notification.subtitle = selectedElement.siteName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
else {
NSString *siteName = [self.siteField stringValue];
if ([siteName length])
// Performing action without content but a site name is written.
[self createNewSite:siteName];
}
}
- (void)updateUser {
[MPMacAppDelegate managedObjectContextForMainThreadPerformBlock:^(NSManagedObjectContext *mainContext) {
self.passwordField.hidden = YES;
self.siteField.hidden = YES;
self.siteTable.hidden = YES;
self.locked = YES;
self.inputLabel.stringValue = @"";
self.passwordField.stringValue = @"";
self.siteField.stringValue = @"";
MPUserEntity *mainActiveUser = [[MPMacAppDelegate get] activeUserInContext:mainContext];
if (mainActiveUser) {
if ([MPMacAppDelegate get].key) {
self.inputLabel.stringValue = strf( @"%@'s password for:", mainActiveUser.name );
self.siteField.hidden = NO;
self.siteTable.hidden = NO;
self.locked = NO;
[self.siteField becomeFirstResponder];
}
else {
self.inputLabel.stringValue = strf( @"Enter %@'s master password:", mainActiveUser.name );
self.passwordField.hidden = NO;
[self.passwordField becomeFirstResponder];
NSTextField *passwordField = self.securePasswordField;
if (self.securePasswordField.isHidden)
passwordField = self.revealPasswordField;
[passwordField becomeFirstResponder];
}
}
@ -464,33 +544,20 @@
NSMakeRange( siteNameQueryRange.length, siteName.length - siteNameQueryRange.length );
}
NSRect selectedCellFrame = [self.siteTable frameOfCellAtColumn:0 row:((NSInteger)self.elementsController.selectionIndex)];
[[(NSClipView *)self.siteTable.superview animator] setBoundsOrigin:selectedCellFrame.origin];
[self.siteTable scrollRowToVisible:(NSInteger)self.elementsController.selectionIndex];
[self updateGradient];
}
- (void)useSite {
- (void)updateGradient {
MPElementModel *selectedElement = [self selectedElement];
if (selectedElement) {
// Performing action while content is available. Copy it.
[self copyContent:selectedElement.content];
[self fadeOut];
NSUserNotification *notification = [NSUserNotification new];
notification.title = @"Password Copied";
if (selectedElement.loginName.length)
notification.subtitle = PearlString( @"%@ at %@", selectedElement.loginName, selectedElement.siteName );
else
notification.subtitle = selectedElement.siteName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
else {
NSString *siteName = [self.siteField stringValue];
if ([siteName length])
// Performing action without content but a site name is written.
[self createNewSite:siteName];
}
NSView *siteScrollView = self.siteTable.superview.superview;
NSRect selectedCellFrame = [self.siteTable frameOfCellAtColumn:0 row:((NSInteger)self.elementsController.selectionIndex)];
CGFloat selectedOffset = [siteScrollView convertPoint:selectedCellFrame.origin fromView:self.siteTable].y;
CGFloat gradientOpacity = selectedOffset / siteScrollView.bounds.size.height;
self.siteGradient.colors = @[
(__bridge id)[NSColor whiteColor].CGColor,
(__bridge id)[NSColor colorWithDeviceWhite:1 alpha:gradientOpacity].CGColor
];
}
- (void)createNewSite:(NSString *)siteName {

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6154.17" systemVersion="13D65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13D65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6154.17"/>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPPasswordWindowController">
@ -9,11 +10,12 @@
<outlet property="blurView" destination="Bwc-sd-6gm" id="wNV-0x-LJn"/>
<outlet property="elementsController" destination="mcS-ik-b0n" id="cdF-BL-lfg"/>
<outlet property="inputLabel" destination="OnR-s6-d4P" id="p6G-Ut-cdu"/>
<outlet property="passwordField" destination="iGR-wo-ual" id="sJN-aE-j7G"/>
<outlet property="passwordTypesBox" destination="bZe-7q-i6q" id="Ai3-pt-i6K"/>
<outlet property="passwordTypesMatrix" destination="3fr-Fd-pxx" id="T8g-mS-lxP"/>
<outlet property="progressView" destination="oSh-Ec-8Nf" id="rob-p0-gr7"/>
<outlet property="siteField" destination="CnS-iI-dhr" id="nPo-Kb-YM2"/>
<outlet property="revealPasswordField" destination="v80-wd-hUR" id="N1U-6B-r1R"/>
<outlet property="securePasswordField" destination="iGR-wo-ual" id="DGh-5i-3u4"/>
<outlet property="siteField" destination="CnS-iI-dhr" id="Ogo-lS-dcT"/>
<outlet property="siteTable" destination="xvJ-5c-vDp" id="ClP-j8-DyI"/>
<outlet property="window" destination="QvC-M9-y7g" id="dPy-F3-9rn"/>
</connections>
@ -23,14 +25,14 @@
<window title="Master Password" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hasShadow="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MPPasswordWindow">
<windowCollectionBehavior key="collectionBehavior" transient="YES" ignoresCycle="YES" fullScreenAuxiliary="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="640" height="530"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
<rect key="contentRect" x="0.0" y="0.0" width="640" height="560"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="640" height="530"/>
<rect key="frame" x="0.0" y="0.0" width="640" height="560"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Bwc-sd-6gm" userLabel="Screen Capture">
<rect key="frame" x="0.0" y="0.0" width="640" height="530"/>
<rect key="frame" x="0.0" y="0.0" width="640" height="560"/>
<contentFilters>
<ciFilter name="CIGaussianBlur">
<configuration>
@ -41,19 +43,19 @@
<ciFilter name="CISepiaTone">
<configuration>
<null key="inputImage"/>
<real key="inputIntensity" value="0.29999999999999999"/>
<real key="inputIntensity" value="0.40000000000000002"/>
</configuration>
</ciFilter>
</contentFilters>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="small-screen" id="ArA-2w-I56"/>
</imageView>
<secureTextField hidden="YES" focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iGR-wo-ual" userLabel="Password Field">
<rect key="frame" x="18" y="243" width="604" height="44"/>
<secureTextField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iGR-wo-ual" userLabel="Secure Master Password">
<rect key="frame" x="18" y="258" width="604" height="44"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" alignment="center" usesSingleLineMode="YES" id="NcX-1Z-2OC">
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" focusRingType="none" alignment="center" usesSingleLineMode="YES" id="NcX-1Z-2OC">
<font key="font" metaFont="system" size="36"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
@ -62,16 +64,89 @@
</allowedInputSourceLocales>
</secureTextFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="egd-Ny-IEz"/>
<action selector="doUnlockUser:" target="-2" id="uLy-ug-wfr"/>
<binding destination="-2" name="hidden" keyPath="alternatePressed" id="lNd-Rl-r2P"/>
<binding destination="-2" name="hidden2" keyPath="locked" previousBinding="lNd-Rl-r2P" id="X7v-Rm-f7l">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="-1"/>
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="value" keyPath="masterPassword" id="5CH-Bd-Z1e">
<dictionary key="options">
<bool key="NSConditionallySetsEditable" value="NO"/>
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
</binding>
<outlet property="delegate" destination="-2" id="3es-rz-2Mx"/>
</connections>
</secureTextField>
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="v80-wd-hUR" userLabel="Reveal Master Password">
<rect key="frame" x="18" y="258" width="604" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" focusRingType="none" alignment="center" placeholderString="" usesSingleLineMode="YES" id="gRw-5C-YUN">
<font key="font" metaFont="system" size="36"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</textFieldCell>
<connections>
<action selector="doUnlockUser:" target="-2" id="fMq-6m-sTD"/>
<binding destination="-2" name="hidden" keyPath="alternatePressed" id="NQY-cm-9h9">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="hidden2" keyPath="locked" previousBinding="NQY-cm-9h9" id="Dg8-Gx-Mgx">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="-1"/>
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="value" keyPath="masterPassword" id="ug7-gM-pBW">
<dictionary key="options">
<bool key="NSConditionallySetsEditable" value="NO"/>
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
</binding>
<outlet property="delegate" destination="-2" id="2nK-Rc-uyR"/>
</connections>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R46-fx-n14" userLabel="Reset Master Password">
<rect key="frame" x="242" y="19" width="156" height="20"/>
<buttonCell key="cell" type="inline" title="Reset My Master Password" bezelStyle="inline" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="B7Z-72-fVP">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="11" name="HelveticaNeue-Bold"/>
</buttonCell>
<connections>
<action selector="resetMasterPassword:" target="-2" id="kCy-X0-teH"/>
<binding destination="-2" name="hidden" keyPath="locked" id="LFo-aw-CMB">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</button>
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="35" horizontalPageScroll="10" verticalLineScroll="35" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Bme-XK-MMc" userLabel="Sites Table">
<rect key="frame" x="64" y="80" width="512" height="132"/>
<rect key="frame" x="64" y="80" width="512" height="147"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="e11-59-xSS">
<rect key="frame" x="0.0" y="0.0" width="512" height="132"/>
<rect key="frame" x="0.0" y="0.0" width="512" height="147"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" id="xvJ-5c-vDp">
<rect key="frame" x="0.0" y="0.0" width="515" height="147"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
@ -158,9 +233,12 @@
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="mcf-ST-XXI">
<autoresizingMask key="autoresizingMask"/>
</scroller>
<connections>
<binding destination="-2" name="hidden" keyPath="locked" id="FF1-c9-zmm"/>
</connections>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OnR-s6-d4P" userLabel="Input Label">
<rect key="frame" x="209" y="295" width="223" height="20"/>
<rect key="frame" x="209" y="310" width="223" height="20"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
@ -172,7 +250,7 @@
</textFieldCell>
</textField>
<searchField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CnS-iI-dhr" userLabel="Site Field">
<rect key="frame" x="62" y="243" width="516" height="44"/>
<rect key="frame" x="62" y="258" width="516" height="44"/>
<constraints>
<constraint firstAttribute="width" constant="512" id="rW7-Vq-4Xy"/>
</constraints>
@ -180,13 +258,14 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
</shadow>
<searchFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" alignment="center" placeholderString="Site Name" sendsSearchStringImmediately="YES" id="ppl-2c-1E9">
<searchFieldCell key="cell" selectable="YES" editable="YES" focusRingType="none" alignment="center" placeholderString="Site Name" sendsSearchStringImmediately="YES" id="ppl-2c-1E9">
<font key="font" size="36" name="HelveticaNeue-Thin"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="calibratedRGB"/>
</searchFieldCell>
<connections>
<action selector="doSearchElements:" target="-2" id="31H-Rt-R87"/>
<action selector="doSearchElements:" target="-2" id="NJO-iR-OXt"/>
<binding destination="-2" name="hidden" keyPath="locked" id="fAX-uK-cgn"/>
<outlet property="delegate" destination="-2" id="2WA-uI-asx"/>
</connections>
</searchField>
@ -284,7 +363,7 @@
</connections>
</button>
<progressIndicator hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="oSh-Ec-8Nf">
<rect key="frame" x="312" y="494" width="16" height="16"/>
<rect key="frame" x="312" y="524" width="16" height="16"/>
</progressIndicator>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XuF-Sp-6JD" userLabel="Delete Button">
<rect key="frame" x="375" y="19" width="70" height="20"/>
@ -330,10 +409,10 @@
</connections>
</button>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="NGk-Io-Buc">
<rect key="frame" x="20" y="323" width="600" height="163"/>
<rect key="frame" x="20" y="338" width="600" height="178"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XUV-zU-Y9c">
<rect key="frame" x="96" y="45" width="408" height="73"/>
<rect key="frame" x="298" y="41" width="4" height="97"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
@ -347,8 +426,8 @@
</configuration>
</ciFilter>
</contentFilters>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="QuxmDapiJiln3," id="WVV-EE-tkB">
<font key="font" size="48" name="SourceCodePro-Regular"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" placeholderString="" id="WVV-EE-tkB">
<font key="font" size="64" name="SourceCodePro-Regular"/>
<color key="textColor" name="keyboardFocusIndicatorColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -361,25 +440,110 @@
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.contentDisplay" id="djg-i5-pwt"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ia6-7b-dFr">
<rect key="frame" x="114" y="82" width="372" height="14"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No password set. Click &quot;Change Password&quot; on the bottom to set one." id="eDQ-iz-97a">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="selection.stored" previousBinding="hIV-Oj-0k4" id="ejq-kZ-id9">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="-1"/>
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden3" keyPath="selection.content.length" previousBinding="ejq-kZ-id9" id="gWc-Yz-7sI">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="0"/>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="hIV-Oj-0k4">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="6Qf-5O-Cvk"/>
<constraint firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="7sl-qi-HY9"/>
<constraint firstItem="Ia6-7b-dFr" firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="KqM-uR-Obm"/>
<constraint firstItem="Ia6-7b-dFr" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="NFQ-aw-8tm"/>
</constraints>
</customView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rhm-sC-xFS">
<rect key="frame" x="80" y="220" width="481" height="15"/>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="npC-Kk-gUM">
<rect key="frame" x="140" y="235" width="359" height="15"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.70000000000000007" colorSpace="calibratedWhite"/>
<color key="color" white="0.0" alpha="0.69999999999999996" colorSpace="calibratedWhite"/>
</shadow>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Hit enter ⏎ to copy the password, then paste it using ⌘V. Use the arrows ⇅ to navigate the list." id="n3W-XU-dya">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Type the name of your site, then hit enter ⏎ to create a password for it." id="QTI-cz-Onx">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="Apq-gz-Fye">
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="canRemove" previousBinding="rpi-M2-6ad" id="vW0-PV-bYs">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="-1"/>
</dictionary>
</binding>
<binding destination="-2" name="hidden" keyPath="locked" id="rpi-M2-6ad"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rhm-sC-xFS">
<rect key="frame" x="37" y="235" width="566" height="15"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.70000000000000007" colorSpace="calibratedWhite"/>
</shadow>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Hit enter ⏎ to copy the password, then paste it using ⌘V. Use the arrows ⇅ to navigate the list or esc ⎋ to exit." id="n3W-XU-dya">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="canRemove" previousBinding="bcg-eq-V5Z" id="F9K-Cg-G6h">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="-1"/>
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="hidden" keyPath="locked" id="bcg-eq-V5Z"/>
</connections>
</textField>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lW3-2z-cEa">
<rect key="frame" x="190" y="235" width="260" height="15"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.69999999999999996" colorSpace="calibratedWhite"/>
</shadow>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Hold alt ⌥ to temporarily reveal what you've typed." id="4Ep-xX-Ky8">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="hidden" keyPath="locked" id="sdC-5X-XtI">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
@ -387,7 +551,7 @@
</connections>
</textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="Aue-Zx-6Mf">
<rect key="frame" x="588" y="478" width="32" height="32"/>
<rect key="frame" x="588" y="508" width="32" height="32"/>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_gear" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="i8r-9N-vcQ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -519,8 +683,49 @@
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="UpZ-rb-NXd">
<rect key="frame" x="242" y="70" width="157" height="14"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Click here to set a password:" id="gjc-Fw-xa1">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="canRemove" previousBinding="WYo-IW-qdh" id="C3l-ng-Hqh">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="-1"/>
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden3" keyPath="selection.stored" previousBinding="C3l-ng-Hqh" id="83Q-cv-B55">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="-1"/>
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden4" keyPath="selection.content.length" previousBinding="83Q-cv-B55" id="ywp-JP-ogX">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
<integer key="NSNoSelectionPlaceholder" value="-1"/>
<integer key="NSNotApplicablePlaceholder" value="-1"/>
<integer key="NSNullPlaceholder" value="0"/>
</dictionary>
</binding>
<binding destination="-2" name="hidden" keyPath="alternatePressed" id="WYo-IW-qdh"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gAU-xs-aae">
<rect key="frame" x="595" y="460" width="19" height="14"/>
<rect key="frame" x="595" y="490" width="19" height="14"/>
<shadow key="shadow" blurRadius="1">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
@ -540,6 +745,7 @@
</textField>
</subviews>
<constraints>
<constraint firstItem="v80-wd-hUR" firstAttribute="top" secondItem="iGR-wo-ual" secondAttribute="top" id="1iV-OU-5Ay"/>
<constraint firstItem="brI-fg-Kav" firstAttribute="centerX" secondItem="vES-W5-m4x" secondAttribute="centerX" id="1tN-p4-2m4"/>
<constraint firstItem="Ido-NQ-3MY" firstAttribute="top" secondItem="1Qo-iG-CQt" secondAttribute="bottom" constant="4" id="3MM-M7-OKF"/>
<constraint firstAttribute="bottom" secondItem="Bwc-sd-6gm" secondAttribute="bottom" id="3fF-7g-c6C"/>
@ -558,18 +764,22 @@
<constraint firstAttribute="trailing" secondItem="iGR-wo-ual" secondAttribute="trailing" constant="20" symbolic="YES" id="LW8-vu-scs"/>
<constraint firstItem="Aue-Zx-6Mf" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="Lts-go-pIX"/>
<constraint firstAttribute="bottom" secondItem="Bme-XK-MMc" secondAttribute="bottom" constant="80" id="MbE-Oa-J9k"/>
<constraint firstItem="CnS-iI-dhr" firstAttribute="centerX" secondItem="npC-Kk-gUM" secondAttribute="centerX" id="O7q-Xc-mx3"/>
<constraint firstAttribute="centerX" secondItem="OnR-s6-d4P" secondAttribute="centerX" id="Pun-kD-jgl"/>
<constraint firstItem="gAU-xs-aae" firstAttribute="top" secondItem="Aue-Zx-6Mf" secondAttribute="bottom" constant="4" id="QkM-BN-dOT"/>
<constraint firstAttribute="centerX" secondItem="CnS-iI-dhr" secondAttribute="centerX" id="Qqi-bu-q65"/>
<constraint firstItem="brI-fg-Kav" firstAttribute="top" secondItem="UpZ-rb-NXd" secondAttribute="bottom" constant="4" id="Xc0-lG-4St"/>
<constraint firstItem="vES-W5-m4x" firstAttribute="centerX" secondItem="d3u-Ze-9uf" secondAttribute="centerX" id="YnC-cX-p8p"/>
<constraint firstItem="qal-PP-YtO" firstAttribute="top" secondItem="XuF-Sp-6JD" secondAttribute="bottom" constant="4" id="YuB-MK-njZ"/>
<constraint firstItem="NGk-Io-Buc" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="ZVb-SX-b24"/>
<constraint firstItem="1Qo-iG-CQt" firstAttribute="centerY" secondItem="vES-W5-m4x" secondAttribute="centerY" id="ZeK-3S-ZWW"/>
<constraint firstItem="brI-fg-Kav" firstAttribute="centerX" secondItem="UpZ-rb-NXd" secondAttribute="centerX" id="b9H-8D-b8a"/>
<constraint firstAttribute="centerX" secondItem="oSh-Ec-8Nf" secondAttribute="centerX" id="c28-5a-C45"/>
<constraint firstItem="oSh-Ec-8Nf" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="cUB-xF-1Wr"/>
<constraint firstItem="brI-fg-Kav" firstAttribute="top" secondItem="uol-dE-I8H" secondAttribute="bottom" constant="4" id="czZ-ad-0sw"/>
<constraint firstItem="vES-W5-m4x" firstAttribute="top" secondItem="d3u-Ze-9uf" secondAttribute="bottom" constant="8" symbolic="YES" id="d3h-VT-ilM"/>
<constraint firstItem="XuF-Sp-6JD" firstAttribute="leading" secondItem="vES-W5-m4x" secondAttribute="trailing" constant="8" symbolic="YES" id="d43-2g-dap"/>
<constraint firstAttribute="bottom" secondItem="R46-fx-n14" secondAttribute="bottom" constant="20" symbolic="YES" id="djJ-T6-7Rr"/>
<constraint firstItem="OnR-s6-d4P" firstAttribute="top" secondItem="NGk-Io-Buc" secondAttribute="bottom" constant="8" symbolic="YES" id="dr2-eR-Yup"/>
<constraint firstAttribute="bottom" secondItem="vES-W5-m4x" secondAttribute="bottom" constant="20" symbolic="YES" id="eHI-Tn-bYD"/>
<constraint firstItem="rhm-sC-xFS" firstAttribute="top" secondItem="CnS-iI-dhr" secondAttribute="bottom" constant="8" symbolic="YES" id="f1g-ug-BVL"/>
@ -577,14 +787,21 @@
<constraint firstItem="CnS-iI-dhr" firstAttribute="centerX" secondItem="rhm-sC-xFS" secondAttribute="centerX" id="gmg-aZ-1Si"/>
<constraint firstItem="Bme-XK-MMc" firstAttribute="top" secondItem="rhm-sC-xFS" secondAttribute="bottom" constant="8" symbolic="YES" id="gsL-Ww-yLa"/>
<constraint firstItem="9b3-wy-KBb" firstAttribute="top" secondItem="vES-W5-m4x" secondAttribute="bottom" constant="4" id="hKa-2u-uL3"/>
<constraint firstAttribute="centerX" secondItem="R46-fx-n14" secondAttribute="centerX" id="hvb-7h-xDS"/>
<constraint firstItem="Bme-XK-MMc" firstAttribute="centerX" secondItem="CnS-iI-dhr" secondAttribute="centerX" id="i7B-jz-xgm"/>
<constraint firstItem="lW3-2z-cEa" firstAttribute="top" secondItem="iGR-wo-ual" secondAttribute="bottom" constant="8" symbolic="YES" id="jg5-h1-0Gn"/>
<constraint firstItem="vES-W5-m4x" firstAttribute="leading" secondItem="1Qo-iG-CQt" secondAttribute="trailing" constant="8" symbolic="YES" id="kTZ-lP-vnR"/>
<constraint firstAttribute="centerX" secondItem="iGR-wo-ual" secondAttribute="centerX" id="kXB-yZ-sur"/>
<constraint firstItem="9b3-wy-KBb" firstAttribute="centerX" secondItem="vES-W5-m4x" secondAttribute="centerX" id="leH-oh-7OJ"/>
<constraint firstItem="vES-W5-m4x" firstAttribute="top" secondItem="brI-fg-Kav" secondAttribute="bottom" constant="8" symbolic="YES" id="rCP-oh-rWr"/>
<constraint firstItem="v80-wd-hUR" firstAttribute="trailing" secondItem="iGR-wo-ual" secondAttribute="trailing" id="rIx-cQ-PNt"/>
<constraint firstItem="brI-fg-Kav" firstAttribute="centerX" secondItem="uol-dE-I8H" secondAttribute="centerX" id="s5w-Nc-YJY"/>
<constraint firstItem="Bwc-sd-6gm" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="tea-fv-b1S"/>
<constraint firstItem="lW3-2z-cEa" firstAttribute="centerX" secondItem="iGR-wo-ual" secondAttribute="centerX" id="vML-2u-shw"/>
<constraint firstItem="v80-wd-hUR" firstAttribute="bottom" secondItem="iGR-wo-ual" secondAttribute="bottom" id="xiX-8e-pNR"/>
<constraint firstItem="v80-wd-hUR" firstAttribute="leading" secondItem="iGR-wo-ual" secondAttribute="leading" id="yVZ-Ar-5ov"/>
<constraint firstItem="gAU-xs-aae" firstAttribute="centerX" secondItem="Aue-Zx-6Mf" secondAttribute="centerX" id="yxU-bl-dmQ"/>
<constraint firstItem="npC-Kk-gUM" firstAttribute="top" secondItem="CnS-iI-dhr" secondAttribute="bottom" constant="8" symbolic="YES" id="zs0-eA-5MW"/>
</constraints>
<animations/>
</view>
@ -596,14 +813,14 @@
</connections>
</arrayController>
<box autoresizesSubviews="NO" title="Password Types" borderType="line" titlePosition="noTitle" id="bZe-7q-i6q">
<rect key="frame" x="0.0" y="0.0" width="386" height="186"/>
<rect key="frame" x="0.0" y="0.0" width="416" height="250"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView">
<rect key="frame" x="1" y="1" width="384" height="184"/>
<rect key="frame" x="1" y="1" width="414" height="248"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<matrix verticalHuggingPriority="750" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3fr-Fd-pxx">
<rect key="frame" x="18" y="14" width="348" height="158"/>
<rect key="frame" x="18" y="78" width="378" height="158"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="179" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
@ -648,13 +865,26 @@
</column>
</cells>
</matrix>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kCO-1M-Wz1">
<rect key="frame" x="16" y="14" width="382" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="kl0-P1-6ZY">
<font key="font" metaFont="toolTip"/>
<string key="title">"Personal password" allows you to store your own password. It cannot be regenerated in the event of loss. "Device private password" is similar but will never leave your device: it cannot be synced, backed up or exported.</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
<constraints>
<constraint firstAttribute="trailing" secondItem="3fr-Fd-pxx" secondAttribute="trailing" constant="16" id="Nnp-8v-Zcf"/>
<constraint firstItem="3fr-Fd-pxx" firstAttribute="top" secondItem="bZe-7q-i6q" secondAttribute="top" constant="11" id="VDj-5W-sPg"/>
<constraint firstItem="kCO-1M-Wz1" firstAttribute="top" secondItem="3fr-Fd-pxx" secondAttribute="bottom" constant="8" symbolic="YES" id="hYU-dI-L16"/>
<constraint firstAttribute="bottom" secondItem="kCO-1M-Wz1" secondAttribute="bottom" constant="11" id="nKV-GE-YZC"/>
<constraint firstItem="3fr-Fd-pxx" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="phM-M0-PZT"/>
<constraint firstAttribute="bottom" secondItem="3fr-Fd-pxx" secondAttribute="bottom" constant="11" id="z2T-aP-O0g"/>
<constraint firstItem="kCO-1M-Wz1" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="tBx-V3-p6R"/>
<constraint firstAttribute="trailing" secondItem="kCO-1M-Wz1" secondAttribute="trailing" constant="16" id="vtf-Od-7d8"/>
</constraints>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>

View File

@ -11,6 +11,7 @@
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */; };
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */; };
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
93D39C5789EFA607CF788082 /* MPElementModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E73BF5CBF8E5B005CD3 /* MPElementModel.m */; };
93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D394EEFF5BF555A55AF361 /* PearlProfiler.h */; };
@ -307,12 +308,14 @@
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
93D39240B5143E01F0B75E96 /* MPElementModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementModel.h; sourceTree = "<group>"; };
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindowController.h; sourceTree = "<group>"; };
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInitialWindowController.h; sourceTree = "<group>"; };
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
93D394EEFF5BF555A55AF361 /* PearlProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PearlProfiler.h; path = ../../../External/Pearl/Pearl/PearlProfiler.h; sourceTree = "<group>"; };
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
93D3977484534E99F9BA579D /* MPPasswordWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindow.h; sourceTree = "<group>"; };
93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindowController.m; sourceTree = "<group>"; };
93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Indexing.m"; sourceTree = "<group>"; };
93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPInitialWindowController.m; sourceTree = "<group>"; };
93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindow.m; sourceTree = "<group>"; };
93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PearlProfiler.m; path = ../../../External/Pearl/Pearl/PearlProfiler.m; sourceTree = "<group>"; };
93D39E73BF5CBF8E5B005CD3 /* MPElementModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementModel.m; sourceTree = "<group>"; };
@ -1210,6 +1213,8 @@
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */,
93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */,
93D3977484534E99F9BA579D /* MPPasswordWindow.h */,
93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */,
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */,
);
path = Mac;
sourceTree = "<group>";
@ -2466,6 +2471,7 @@
93D39C5789EFA607CF788082 /* MPElementModel.m in Sources */,
93D39F833DEC1C89B2F795AC /* MPPasswordWindowController.m in Sources */,
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */,
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 KiB

After

Width:  |  Height:  |  Size: 381 KiB