Threading fixes for Mac, spinner fix for iOS.
[UPDATED] TestFlight. [FIXED] Mac: References to MPAppDelegate that should be OS-independant now use MPAppDelegate_Shared. [FIXED] Mac: Threading and content UI updates. [FIXED] iOS: Spinner was showing when going back to unlock VC.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
../../../../../../MasterPassword/Resources/Data/ciphers.plist
|
||||
@@ -1 +0,0 @@
|
||||
../../../../../../Resources/ciphers.plist
|
||||
@@ -6,7 +6,7 @@
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPAppDelegate.h"
|
||||
#import "MPAppDelegate_Shared.h"
|
||||
|
||||
@implementation MPConfig
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
NSStringFromSelector( @selector(iCloudDecided) ) : @NO
|
||||
}];
|
||||
|
||||
self.delegate = [MPAppDelegate get];
|
||||
self.delegate = [MPAppDelegate_Shared get];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
#import "MPEntities.h"
|
||||
#import "MPAppDelegate.h"
|
||||
#import "MPAppDelegate_Shared.h"
|
||||
|
||||
@implementation NSManagedObjectContext(MP)
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
|
||||
- (id)content {
|
||||
|
||||
MPKey *key = [MPAppDelegate get].key;
|
||||
MPKey *key = [MPAppDelegate_Shared get].key;
|
||||
if (!key)
|
||||
return nil;
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
|
||||
- (void)setContent:(id)content {
|
||||
|
||||
MPKey *key = [MPAppDelegate get].key;
|
||||
MPKey *key = [MPAppDelegate_Shared get].key;
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
|
||||
@@ -8,12 +8,7 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MPPasswordWindowController : NSWindowController<NSTextFieldDelegate> {
|
||||
|
||||
NSString *_content;
|
||||
}
|
||||
|
||||
@property(nonatomic, strong) NSString *content;
|
||||
@interface MPPasswordWindowController : NSWindowController<NSTextFieldDelegate>
|
||||
|
||||
@property(nonatomic, weak) IBOutlet NSTextField *siteField;
|
||||
@property(nonatomic, weak) IBOutlet NSTextField *contentField;
|
||||
|
||||
@@ -16,13 +16,14 @@
|
||||
|
||||
@interface MPPasswordWindowController()
|
||||
|
||||
@property(nonatomic, strong) NSArray /* MPElementEntity */ *siteResults;
|
||||
@property(nonatomic) BOOL inProgress;
|
||||
@property(nonatomic) BOOL siteFieldPreventCompletion;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPPasswordWindowController
|
||||
@implementation MPPasswordWindowController {
|
||||
NSManagedObjectID *_activeElementOID;
|
||||
}
|
||||
|
||||
- (void)windowDidLoad {
|
||||
|
||||
@@ -30,7 +31,7 @@
|
||||
self.window.styleMask = NSHUDWindowMask | NSTitledWindowMask | NSUtilityWindowMask | NSClosableWindowMask;
|
||||
else
|
||||
self.window.styleMask = NSTexturedBackgroundWindowMask | NSResizableWindowMask | NSTitledWindowMask | NSClosableWindowMask;
|
||||
|
||||
|
||||
[self setContent:@""];
|
||||
[self.tipField setStringValue:@""];
|
||||
|
||||
@@ -110,19 +111,23 @@
|
||||
switch (returnCode) {
|
||||
case NSAlertAlternateReturn:
|
||||
// "Change" button.
|
||||
if ([[NSAlert alertWithMessageText:@"Changing Master Password"
|
||||
defaultButton:nil alternateButton:[PearlStrings get].commonButtonCancel otherButton:nil
|
||||
informativeTextWithFormat:
|
||||
@"This will allow you to log in with a different master password.\n\n"
|
||||
@"Note that you will only see the sites and passwords for the master password you log in with.\n"
|
||||
@"If you log in with a different master password, your current sites will be unavailable.\n\n"
|
||||
@"You can always change back to your current master password later.\n"
|
||||
@"Your current sites and passwords will then become available again."] runModal]
|
||||
== 1) {
|
||||
{
|
||||
NSInteger returnCode_ = [[NSAlert
|
||||
alertWithMessageText:@"Changing Master Password" defaultButton:nil
|
||||
alternateButton:[PearlStrings get].commonButtonCancel otherButton:nil informativeTextWithFormat:
|
||||
@"This will allow you to log in with a different master password.\n\n"
|
||||
@"Note that you will only see the sites and passwords for the master password you log in with.\n"
|
||||
@"If you log in with a different master password, your current sites will be unavailable.\n\n"
|
||||
@"You can always change back to your current master password later.\n"
|
||||
@"Your current sites and passwords will then become available again."]
|
||||
runModal];
|
||||
|
||||
if (returnCode_ == NSAlertDefaultReturn) {
|
||||
activeUser.keyID = nil;
|
||||
[[MPMacAppDelegate get] forgetSavedKeyFor:activeUser];
|
||||
[[MPMacAppDelegate get] signOutAnimated:YES];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NSAlertOtherReturn:
|
||||
@@ -137,7 +142,7 @@
|
||||
self.inProgress = YES;
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0 ), ^{
|
||||
BOOL success = [[MPMacAppDelegate get] signInAsUser:activeUser
|
||||
usingMasterPassword:[(NSSecureTextField *)alert.accessoryView stringValue]];
|
||||
usingMasterPassword:[(NSSecureTextField *)alert.accessoryView stringValue]];
|
||||
self.inProgress = NO;
|
||||
|
||||
dispatch_async( dispatch_get_main_queue(), ^{
|
||||
@@ -171,29 +176,31 @@
|
||||
if (![query length] || ![MPMacAppDelegate get].key)
|
||||
return nil;
|
||||
|
||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )];
|
||||
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"uses_" ascending:NO]];
|
||||
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(name BEGINSWITH[cd] %@) AND user == %@",
|
||||
query, [[MPMacAppDelegate get] activeUserForThread]];
|
||||
__block NSMutableArray *mutableResults = [NSMutableArray array];
|
||||
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
|
||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )];
|
||||
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO]];
|
||||
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(name BEGINSWITH[cd] %@) AND user == %@",
|
||||
query, [[MPMacAppDelegate get] activeUserInContext:context]];
|
||||
|
||||
NSError *error = nil;
|
||||
self.siteResults = [[MPMacAppDelegate managedObjectContextForThreadIfReady] executeFetchRequest:fetchRequest error:&error];
|
||||
if (error)
|
||||
err(@"While fetching elements for completion: %@", error);
|
||||
NSError *error = nil;
|
||||
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
|
||||
if (error)
|
||||
err(@"While fetching elements for completion: %@", error);
|
||||
|
||||
if ([self.siteResults count] == 1) {
|
||||
[textView setString:[(MPElementEntity *)[self.siteResults objectAtIndex:0] name]];
|
||||
[textView setSelectedRange:NSMakeRange( [query length], [[textView string] length] - [query length] )];
|
||||
if ([self trySite])
|
||||
return nil;
|
||||
if (siteResults) {
|
||||
for (MPElementEntity *element in siteResults)
|
||||
[mutableResults addObject:element.name];
|
||||
//[mutableResults addObject:query]; // For when the app should be able to create new sites.
|
||||
}
|
||||
}];
|
||||
|
||||
if ([mutableResults count] == 1) {
|
||||
//[textView setString:[(MPElementEntity *)[siteResults objectAtIndex:0] name]];
|
||||
//[textView setSelectedRange:NSMakeRange( [query length], [[textView string] length] - [query length] )];
|
||||
[self trySiteAndCopyContent:NO];
|
||||
}
|
||||
|
||||
NSMutableArray *mutableResults = [NSMutableArray arrayWithCapacity:[self.siteResults count] + 1];
|
||||
if (self.siteResults)
|
||||
for (MPElementEntity *element in self.siteResults)
|
||||
[mutableResults addObject:element.name];
|
||||
// [mutableResults addObject:query]; // For when the app should be able to create new sites.
|
||||
|
||||
return mutableResults;
|
||||
}
|
||||
|
||||
@@ -205,9 +212,8 @@
|
||||
}
|
||||
if ((self.siteFieldPreventCompletion = [NSStringFromSelector( commandSelector ) hasPrefix:@"delete"]))
|
||||
return NO;
|
||||
if (commandSelector == @selector(insertNewline:) && [self.content length]) {
|
||||
if ([self trySite])
|
||||
[self copyContents];
|
||||
if (commandSelector == @selector(insertNewline:)) {
|
||||
[self trySiteAndCopyContent:YES];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@@ -215,26 +221,6 @@
|
||||
}
|
||||
|
||||
- (void)copyContents {
|
||||
|
||||
[[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
if (![[NSPasteboard generalPasteboard] setString:self.content forType:NSPasteboardTypeString]) {
|
||||
wrn(@"Couldn't copy password to pasteboard.");
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch_async( dispatch_get_main_queue(), ^{
|
||||
self.tipField.alphaValue = 1;
|
||||
[self.tipField setStringValue:@"Copied! Hit ⎋ (ESC) to close window."];
|
||||
dispatch_time_t popTime = dispatch_time( DISPATCH_TIME_NOW, (int64_t)(5.0f * NSEC_PER_SEC) );
|
||||
dispatch_after( popTime, dispatch_get_main_queue(), ^{
|
||||
[NSAnimationContext beginGrouping];
|
||||
[[NSAnimationContext currentContext] setDuration:0.2f];
|
||||
[self.tipField.animator setAlphaValue:0];
|
||||
[NSAnimationContext endGrouping];
|
||||
} );
|
||||
} );
|
||||
|
||||
[[self findElement] use];
|
||||
}
|
||||
|
||||
- (void)controlTextDidEndEditing:(NSNotification *)note {
|
||||
@@ -242,7 +228,7 @@
|
||||
if (note.object != self.siteField)
|
||||
return;
|
||||
|
||||
[self trySite];
|
||||
[self trySiteAndCopyContent:NO];
|
||||
}
|
||||
|
||||
- (void)controlTextDidChange:(NSNotification *)note {
|
||||
@@ -251,13 +237,12 @@
|
||||
return;
|
||||
|
||||
// Update the site content as the site name changes.
|
||||
BOOL hasValidSite = [self trySite];
|
||||
BOOL enterPressed = [[NSApp currentEvent] type] == NSKeyDown &&
|
||||
[[[NSApp currentEvent] charactersIgnoringModifiers] isEqualToString:@"\r"];
|
||||
[self trySiteAndCopyContent:enterPressed];
|
||||
|
||||
if ([[NSApp currentEvent] type] == NSKeyDown && [[[NSApp currentEvent] charactersIgnoringModifiers] isEqualToString:@"\r"]) {
|
||||
if (hasValidSite)
|
||||
[self copyContents];
|
||||
if (enterPressed)
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.siteFieldPreventCompletion) {
|
||||
self.siteFieldPreventCompletion = NO;
|
||||
@@ -269,43 +254,70 @@
|
||||
self.siteFieldPreventCompletion = NO;
|
||||
}
|
||||
|
||||
- (NSString *)content {
|
||||
- (MPElementEntity *)activeElementForThread {
|
||||
|
||||
return _content;
|
||||
if (!_activeElementOID)
|
||||
return nil;
|
||||
|
||||
NSManagedObjectContext *moc = [MPMacAppDelegate managedObjectContextForThreadIfReady];
|
||||
if (!moc)
|
||||
return nil;
|
||||
|
||||
NSError *error;
|
||||
MPElementEntity *activeElement = (MPElementEntity *)[moc existingObjectWithID:_activeElementOID error:&error];
|
||||
if (!activeElement)
|
||||
err(@"Couldn't retrieve active element: %@", error);
|
||||
|
||||
return activeElement;
|
||||
}
|
||||
|
||||
- (void)setContent:(NSString *)content {
|
||||
|
||||
_content = content;
|
||||
|
||||
NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];
|
||||
paragraph.alignment = NSCenterTextAlignment;
|
||||
|
||||
[self.contentField setAttributedStringValue:
|
||||
[[NSAttributedString alloc] initWithString:_content
|
||||
attributes:[[NSMutableDictionary alloc] initWithObjectsAndKeys:
|
||||
paragraph, NSParagraphStyleAttributeName,
|
||||
nil]]];
|
||||
[self.contentField setAttributedStringValue:[[NSAttributedString alloc] initWithString:content attributes:@{
|
||||
NSParagraphStyleAttributeName : paragraph
|
||||
}]];
|
||||
}
|
||||
|
||||
- (BOOL)trySite {
|
||||
- (void)trySiteAndCopyContent:(BOOL)copyContent {
|
||||
|
||||
MPElementEntity *result = [self findElement];
|
||||
if (!result) {
|
||||
[self setContent:@""];
|
||||
[self.tipField setStringValue:@""];
|
||||
return NO;
|
||||
}
|
||||
[self setContent:@""];
|
||||
[self.tipField setStringValue:@"Generating..."];
|
||||
|
||||
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0 ), ^{
|
||||
NSString *description = [result.content description];
|
||||
if (!description)
|
||||
description = @"";
|
||||
NSString *content = [[self activeElementForThread].content description];
|
||||
if (!content)
|
||||
content = @"";
|
||||
if (copyContent) {
|
||||
[[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
if (![[NSPasteboard generalPasteboard] setString:content forType:NSPasteboardTypeString]) {
|
||||
wrn(@"Couldn't copy password to pasteboard.");
|
||||
return;
|
||||
}
|
||||
|
||||
MPElementEntity *activeElement = [self activeElementForThread];
|
||||
[activeElement use];
|
||||
[activeElement.managedObjectContext saveToStore];
|
||||
}
|
||||
|
||||
dispatch_async( dispatch_get_main_queue(), ^{
|
||||
[self setContent:description];
|
||||
[self.tipField setStringValue:@"Hit ⌤ (ENTER) to copy the password."];
|
||||
[self setContent:content];
|
||||
|
||||
self.tipField.alphaValue = 1;
|
||||
if (!copyContent)
|
||||
[self.tipField setStringValue:@"Hit ⌤ (ENTER) to copy the password."];
|
||||
else {
|
||||
[self.tipField setStringValue:@"Copied! Hit ⎋ (ESC) to close window."];
|
||||
dispatch_time_t popTime = dispatch_time( DISPATCH_TIME_NOW, (int64_t)(5.0f * NSEC_PER_SEC) );
|
||||
dispatch_after( popTime, dispatch_get_main_queue(), ^{
|
||||
[NSAnimationContext beginGrouping];
|
||||
[[NSAnimationContext currentContext] setDuration:0.2f];
|
||||
[self.tipField.animator setAlphaValue:0];
|
||||
[NSAnimationContext endGrouping];
|
||||
} );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
@@ -329,17 +341,6 @@
|
||||
});
|
||||
}];
|
||||
*/
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (MPElementEntity *)findElement {
|
||||
|
||||
for (MPElementEntity *element in self.siteResults)
|
||||
if ([element.name isEqualToString:[self.siteField stringValue]])
|
||||
return element;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -126,7 +126,6 @@
|
||||
self.tip.text = @"";
|
||||
self.nameLabel.layer.cornerRadius = 5;
|
||||
self.avatarTemplate.hidden = YES;
|
||||
self.spinner.alpha = 0;
|
||||
self.passwordTipView.hidden = NO;
|
||||
self.createPasswordTipView.hidden = NO;
|
||||
[self.emergencyPassword setTitle:@"" forState:UIControlStateNormal];
|
||||
@@ -200,13 +199,14 @@
|
||||
[self updateUsers];
|
||||
|
||||
self.uiContainer.alpha = 0;
|
||||
self.spinner.alpha = 0;
|
||||
|
||||
[super viewWillAppear:animated];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
|
||||
if (!animated)
|
||||
if (!animated && !self.navigationController.presentedViewController)
|
||||
[[self findTargetedAvatar] setSelected:YES];
|
||||
else
|
||||
[self updateLayoutAnimated:YES allowScroll:YES completion:nil];
|
||||
|
||||
@@ -611,47 +611,6 @@
|
||||
postNotificationName:MPCheckConfigNotification object:NSStringFromSelector( configKey ) userInfo:nil];
|
||||
}
|
||||
|
||||
#pragma mark - UbiquityStoreManagerDelegate
|
||||
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager willLoadStoreIsCloud:(BOOL)isCloudStore {
|
||||
|
||||
[super ubiquityStoreManager:manager willLoadStoreIsCloud:isCloudStore];
|
||||
|
||||
if (!isCloudStore && ![[MPConfig get].iCloudDecided boolValue])
|
||||
[self alertCloudDisabledForManager:manager];
|
||||
}
|
||||
|
||||
- (void)alertCloudDisabledForManager:(UbiquityStoreManager *)manager {
|
||||
|
||||
[PearlAlert showAlertWithTitle:@"iCloud" message:
|
||||
@"iCloud is now disabled.\n\n"
|
||||
@"It is highly recommended you enable iCloud."
|
||||
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
|
||||
if (buttonIndex == [alert firstOtherButtonIndex] + 0) {
|
||||
[PearlAlert showAlertWithTitle:@"About iCloud" message:
|
||||
@"iCloud is Apple's solution for saving your data in \"the cloud\" "
|
||||
@"and making sure your other iPhones, iPads and Macs are in sync.\n\n"
|
||||
@"For Master Password, that means your sites are available on all your "
|
||||
@"Apple devices, and you always have a backup of them in case "
|
||||
@"you lose one or need to restore.\n\n"
|
||||
@"Thanks to the way Master Password works, it doesn't need to send your "
|
||||
@"site's passwords to Apple for the backup to work: Only their names are "
|
||||
@"saved. If you set a custom password it will be sent to iCloud after "
|
||||
@"being encrypted with your master password.\n\n"
|
||||
@"Apple can never see any of your passwords."
|
||||
viewStyle:UIAlertViewStyleDefault
|
||||
initAlert:nil tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
|
||||
[self alertCloudDisabledForManager:manager];
|
||||
}
|
||||
cancelTitle:[PearlStrings get].commonButtonThanks otherTitles:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
[MPConfig get].iCloudDecided = @YES;
|
||||
if (buttonIndex == [alert firstOtherButtonIndex] + 1)
|
||||
manager.cloudEnabled = YES;
|
||||
} cancelTitle:@"Leave Off" otherTitles:@"Explain?", @"Enable iCloud", nil];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Google+
|
||||
|
||||
|
||||
@@ -2810,6 +2810,190 @@ However, it means that anyone who finds your device unlocked can do the same.</s
|
||||
<image name="ui_textfield.png" width="158" height="34"/>
|
||||
<image name="unlocked.png" width="84" height="80"/>
|
||||
</resources>
|
||||
<classes>
|
||||
<class className="MPAppViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPAppViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="deblock:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="gorillas:" candidateClass="UIButton"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPAppsViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPAppsViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="exit"/>
|
||||
<relationship kind="outlet" name="pagePositionView" candidateClass="UIImageView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPElementListAllViewController" superclassName="MPElementListController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListAllViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="add:"/>
|
||||
<relationship kind="action" name="close:"/>
|
||||
<relationship kind="outlet" name="navigationBar" candidateClass="UINavigationBar"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPElementListController" superclassName="UITableViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="outlet" name="delegate"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPElementListSearchController" superclassName="MPElementListController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPElementListSearchController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="outlet" name="searchDisplayController" candidateClass="UISearchDisplayController"/>
|
||||
<relationship kind="outlet" name="searchTipContainer" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPGuideViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPGuideViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="close"/>
|
||||
<relationship kind="action" name="play"/>
|
||||
<relationship kind="action" name="toggleVolume"/>
|
||||
<relationship kind="outlet" name="content" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="contentButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="contentText" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="contentTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="contentTipText" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="largePlayButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="progress" candidateClass="UIProgressView"/>
|
||||
<relationship kind="outlet" name="siteNameTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="smallPlayButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="toolButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="toolTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="typeButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="typeTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="usernameButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="usernameTip" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="volumeButton" candidateClass="UIButton"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPMainViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPMainViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="action:" candidateClass="UIBarButtonItem"/>
|
||||
<relationship kind="action" name="closeAlert"/>
|
||||
<relationship kind="action" name="closeOutdatedAlert"/>
|
||||
<relationship kind="action" name="copyContent"/>
|
||||
<relationship kind="action" name="editLoginName:" candidateClass="UILongPressGestureRecognizer"/>
|
||||
<relationship kind="action" name="editPassword"/>
|
||||
<relationship kind="action" name="incrementPasswordCounter"/>
|
||||
<relationship kind="action" name="infoOutdatedAlert"/>
|
||||
<relationship kind="action" name="panHelpDown:" candidateClass="UIPanGestureRecognizer"/>
|
||||
<relationship kind="action" name="panHelpUp:" candidateClass="UIPanGestureRecognizer"/>
|
||||
<relationship kind="action" name="resetPasswordCounter:" candidateClass="UILongPressGestureRecognizer"/>
|
||||
<relationship kind="action" name="searchOutdatedElements"/>
|
||||
<relationship kind="action" name="toggleUser"/>
|
||||
<relationship kind="action" name="upgradePassword"/>
|
||||
<relationship kind="outlet" name="actionsTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="alertBody" candidateClass="UITextView"/>
|
||||
<relationship kind="outlet" name="alertContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="alertTitle" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="contentContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="contentField" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="contentTipBody" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="contentTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="displayContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="helpContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="helpView" candidateClass="UIWebView"/>
|
||||
<relationship kind="outlet" name="loginNameContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="loginNameField" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="loginNameTipBody" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="loginNameTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="outdatedAlertBack" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="outdatedAlertCloseButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="outdatedAlertContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="passwordCounter" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordEdit" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="passwordIncrementer" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="passwordUpgrade" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="passwordUser" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="pullDownGesture" candidateClass="UIPanGestureRecognizer"/>
|
||||
<relationship kind="outlet" name="pullDownView" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="pullUpGesture" candidateClass="UIPanGestureRecognizer"/>
|
||||
<relationship kind="outlet" name="pullUpView" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="searchDelegate" candidateClass="MPElementListSearchController"/>
|
||||
<relationship kind="outlet" name="searchTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="siteName" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="toolTipBody" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="toolTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="toolTipEditIcon" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="typeButton" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="typeTipContainer" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPPreferencesViewController" superclassName="UITableViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPPreferencesViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="didToggleSwitch:" candidateClass="UISwitch"/>
|
||||
<relationship kind="action" name="settings:"/>
|
||||
<relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
|
||||
<relationship kind="outlet" name="changeMPCell" candidateClass="UITableViewCell"/>
|
||||
<relationship kind="outlet" name="defaultTypeLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="exportCell" candidateClass="UITableViewCell"/>
|
||||
<relationship kind="outlet" name="savePasswordSwitch" candidateClass="UISwitch"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPSetupViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPSetupViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="close:" candidateClass="UIBarButtonItem"/>
|
||||
<relationship kind="outlet" name="cloudSwitch" candidateClass="UISwitch"/>
|
||||
<relationship kind="outlet" name="rememberLoginSwitch" candidateClass="UISwitch"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPTypeViewController" superclassName="UITableViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPTypeViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="outlet" name="recommendedTipContainer" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="MPUnlockViewController" superclassName="UIViewController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPUnlockViewController.h"/>
|
||||
<relationships>
|
||||
<relationship kind="action" name="add:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="emergencyClose:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="emergencyCopy:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="facebook:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="google:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="mail:" candidateClass="UIButton"/>
|
||||
<relationship kind="action" name="targetedUserAction:" candidateClass="UILongPressGestureRecognizer"/>
|
||||
<relationship kind="action" name="twitter:" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="avatarTemplate" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="avatarsView" candidateClass="UIScrollView"/>
|
||||
<relationship kind="outlet" name="createPasswordTipView" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="emergencyActivity" candidateClass="UIActivityIndicatorView"/>
|
||||
<relationship kind="outlet" name="emergencyContentTipContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="emergencyCounter" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="emergencyCounterStepper" candidateClass="UIStepper"/>
|
||||
<relationship kind="outlet" name="emergencyGeneratorContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="emergencyMasterPassword" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="emergencyName" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="emergencyPassword" candidateClass="UIButton"/>
|
||||
<relationship kind="outlet" name="emergencySite" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="emergencyTypeControl" candidateClass="UISegmentedControl"/>
|
||||
<relationship kind="outlet" name="nameLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="newsView" candidateClass="UIWebView"/>
|
||||
<relationship kind="outlet" name="oldNameLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordField" candidateClass="UITextField"/>
|
||||
<relationship kind="outlet" name="passwordFieldLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordTipLabel" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="passwordTipView" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="passwordView" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="spinner" candidateClass="UIImageView"/>
|
||||
<relationship kind="outlet" name="targetedUserActionGesture" candidateClass="UILongPressGestureRecognizer"/>
|
||||
<relationship kind="outlet" name="tip" candidateClass="UILabel"/>
|
||||
<relationship kind="outlet" name="uiContainer" candidateClass="UIView"/>
|
||||
<relationship kind="outlet" name="wordWall" candidateClass="UIView"/>
|
||||
</relationships>
|
||||
</class>
|
||||
<class className="PearlNavigationController" superclassName="UINavigationController">
|
||||
<source key="sourceIdentifier" type="project" relativePath="./Classes/PearlNavigationController.h"/>
|
||||
</class>
|
||||
</classes>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<nil key="statusBar"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
|
||||
Reference in New Issue
Block a user