Listing all sites now with bookmark button and modal VC.
[ADDED] Modal VC to show all sites. [UPDATED] All sites button on search bar now uses bookmark button. [REMOVED] Query string hack for search results button.
This commit is contained in:
parent
2bb0e2e3ef
commit
9a68cbf533
@ -17,6 +17,7 @@
|
|||||||
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D394077F8FAB8167647187 /* Twitter.framework */; };
|
93D399433EA75E50656040CB /* Twitter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D394077F8FAB8167647187 /* Twitter.framework */; };
|
||||||
93D399B873AF89808151D2F5 /* MPAppsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390DABAE4368E90E37340 /* MPAppsViewController.m */; };
|
93D399B873AF89808151D2F5 /* MPAppsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390DABAE4368E90E37340 /* MPAppsViewController.m */; };
|
||||||
93D39BCE5F69D8EBE7E9F6EC /* MPAppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E070BD3F45B3045A1DA /* MPAppViewController.m */; };
|
93D39BCE5F69D8EBE7E9F6EC /* MPAppViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E070BD3F45B3045A1DA /* MPAppViewController.m */; };
|
||||||
|
93D39BD0F5C7C76678712500 /* MPAllSitesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39F16ADA770D8C13B4555 /* MPAllSitesViewController.m */; };
|
||||||
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
|
||||||
93D39DC7A7282137B08C8D82 /* MPAlgorithmV1.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E9D7B9005211E7D5262 /* MPAlgorithmV1.m */; };
|
93D39DC7A7282137B08C8D82 /* MPAlgorithmV1.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E9D7B9005211E7D5262 /* MPAlgorithmV1.m */; };
|
||||||
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
|
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
|
||||||
@ -972,6 +973,7 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
|
||||||
|
93D390B3209212B3049BEC2D /* MPAllSitesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAllSitesViewController.h; sourceTree = "<group>"; };
|
||||||
93D390DABAE4368E90E37340 /* MPAppsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppsViewController.m; sourceTree = "<group>"; };
|
93D390DABAE4368E90E37340 /* MPAppsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppsViewController.m; sourceTree = "<group>"; };
|
||||||
93D3938863322199C3E7E2E3 /* MPAlgorithmV0.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV0.m; sourceTree = "<group>"; };
|
93D3938863322199C3E7E2E3 /* MPAlgorithmV0.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV0.m; sourceTree = "<group>"; };
|
||||||
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
|
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
|
||||||
@ -989,6 +991,8 @@
|
|||||||
93D39E070BD3F45B3045A1DA /* MPAppViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppViewController.m; sourceTree = "<group>"; };
|
93D39E070BD3F45B3045A1DA /* MPAppViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppViewController.m; sourceTree = "<group>"; };
|
||||||
93D39E81EFABC6085AC8AE69 /* MPKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPKey.m; sourceTree = "<group>"; };
|
93D39E81EFABC6085AC8AE69 /* MPKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPKey.m; sourceTree = "<group>"; };
|
||||||
93D39E9D7B9005211E7D5262 /* MPAlgorithmV1.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV1.m; sourceTree = "<group>"; };
|
93D39E9D7B9005211E7D5262 /* MPAlgorithmV1.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV1.m; sourceTree = "<group>"; };
|
||||||
|
93D39F16ADA770D8C13B4555 /* MPAllSitesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAllSitesViewController.m; sourceTree = "<group>"; };
|
||||||
|
93D39F37240730C6311B8FBD /* MPElementPickerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementPickerDelegate.h; sourceTree = "<group>"; };
|
||||||
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlEMail.h; sourceTree = "<group>"; };
|
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlEMail.h; sourceTree = "<group>"; };
|
||||||
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||||
DA0A1D0315690A9A0092735D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/Default.png; sourceTree = SOURCE_ROOT; };
|
DA0A1D0315690A9A0092735D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/Default.png; sourceTree = SOURCE_ROOT; };
|
||||||
@ -2542,6 +2546,9 @@
|
|||||||
DAB8D45215036BCF00CED3BC /* MPUnlockViewController.h */,
|
DAB8D45215036BCF00CED3BC /* MPUnlockViewController.h */,
|
||||||
DAB8D45315036BCF00CED3BC /* MPUnlockViewController.m */,
|
DAB8D45315036BCF00CED3BC /* MPUnlockViewController.m */,
|
||||||
DAB8D45415036BCF00CED3BC /* Settings.bundle */,
|
DAB8D45415036BCF00CED3BC /* Settings.bundle */,
|
||||||
|
93D39F16ADA770D8C13B4555 /* MPAllSitesViewController.m */,
|
||||||
|
93D390B3209212B3049BEC2D /* MPAllSitesViewController.h */,
|
||||||
|
93D39F37240730C6311B8FBD /* MPElementPickerDelegate.h */,
|
||||||
);
|
);
|
||||||
path = iOS;
|
path = iOS;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -4716,6 +4723,7 @@
|
|||||||
DA81253816B8546B00F4732F /* MPElementStoredEntity.m in Sources */,
|
DA81253816B8546B00F4732F /* MPElementStoredEntity.m in Sources */,
|
||||||
DA81253B16B8546B00F4732F /* MPUserEntity.m in Sources */,
|
DA81253B16B8546B00F4732F /* MPUserEntity.m in Sources */,
|
||||||
DA81253E16B8546C00F4732F /* MPElementGeneratedEntity.m in Sources */,
|
DA81253E16B8546C00F4732F /* MPElementGeneratedEntity.m in Sources */,
|
||||||
|
93D39BD0F5C7C76678712500 /* MPAllSitesViewController.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
@property (strong, nonatomic) MPUserEntity *activeUser;
|
@property (strong, nonatomic) MPUserEntity *activeUser;
|
||||||
@property (strong, nonatomic) MPKey *key;
|
@property (strong, nonatomic) MPKey *key;
|
||||||
|
|
||||||
|
+ (instancetype)get;
|
||||||
|
|
||||||
- (MPUserEntity *)activeUserInContext:(NSManagedObjectContext *)moc;
|
- (MPUserEntity *)activeUserInContext:(NSManagedObjectContext *)moc;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -28,9 +28,4 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (MPConfig *)get {
|
|
||||||
|
|
||||||
return (MPConfig *)[super get];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -42,11 +42,6 @@ static EventHotKeyID MPLockHotKey = {.signature = 'lock', .id = 1};
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (MPAppDelegate *)get {
|
|
||||||
|
|
||||||
return (MPAppDelegate *)[super get];
|
|
||||||
}
|
|
||||||
|
|
||||||
static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData) {
|
static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData) {
|
||||||
|
|
||||||
// Extract the hotkey ID.
|
// Extract the hotkey ID.
|
||||||
|
@ -20,9 +20,4 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (MPMacConfig *)get {
|
|
||||||
|
|
||||||
return (MPMacConfig *)[super get];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
28
MasterPassword/iOS/MPAllSitesViewController.h
Normal file
28
MasterPassword/iOS/MPAllSitesViewController.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// MPAllSitesViewController
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2013-01-31.
|
||||||
|
// Copyright 2013 lhunath (Maarten Billemont). All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "MPElementPickerDelegate.h"
|
||||||
|
|
||||||
|
@interface MPAllSitesViewController : UITableViewController
|
||||||
|
|
||||||
|
@property (weak, nonatomic) IBOutlet id<MPElementPickerDelegate> delegate;
|
||||||
|
|
||||||
|
- (IBAction)close:(id)sender;
|
||||||
|
|
||||||
|
@end
|
240
MasterPassword/iOS/MPAllSitesViewController.m
Normal file
240
MasterPassword/iOS/MPAllSitesViewController.m
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// MPAllSitesViewController
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2013-01-31.
|
||||||
|
// Copyright 2013 lhunath (Maarten Billemont). All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPAllSitesViewController.h"
|
||||||
|
|
||||||
|
#import "MPAppDelegate.h"
|
||||||
|
#import "MPAppDelegate_Store.h"
|
||||||
|
|
||||||
|
|
||||||
|
@interface MPAllSitesViewController() <NSFetchedResultsControllerDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic,strong)NSDateFormatter *dateFormatter;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPAllSitesViewController {
|
||||||
|
|
||||||
|
NSFetchedResultsController *_fetchedResultsController;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
|
||||||
|
[super viewDidLoad];
|
||||||
|
|
||||||
|
self.dateFormatter = [NSDateFormatter new];
|
||||||
|
self.dateFormatter.dateStyle = NSDateFormatterShortStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)close:(id)sender {
|
||||||
|
|
||||||
|
[self dismissViewControllerAnimated:YES completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSFetchedResultsController *)fetchedResultsController {
|
||||||
|
|
||||||
|
if (!_fetchedResultsController) {
|
||||||
|
NSAssert([[NSThread currentThread] isMainThread], @"The fetchedResultsController must run on the main thread.");
|
||||||
|
NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextForThreadIfReady];
|
||||||
|
if (!moc)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
|
||||||
|
fetchRequest.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:@"uses_" ascending:NO]];
|
||||||
|
fetchRequest.fetchBatchSize = 20;
|
||||||
|
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc
|
||||||
|
sectionNameKeyPath:nil cacheName:nil];
|
||||||
|
_fetchedResultsController.delegate = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _fetchedResultsController;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)fetchData {
|
||||||
|
|
||||||
|
MPUserEntity *activeUser = [MPAppDelegate get].activeUser;
|
||||||
|
if (!activeUser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self.fetchedResultsController.fetchRequest.predicate = [NSPredicate predicateWithFormat:@"user == %@", activeUser];
|
||||||
|
|
||||||
|
NSError *error;
|
||||||
|
if (![self.fetchedResultsController performFetch:&error])
|
||||||
|
err(@"Couldn't fetch elements: %@", error);
|
||||||
|
|
||||||
|
[self.tableView reloadData];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
|
|
||||||
|
[super viewWillAppear:animated];
|
||||||
|
|
||||||
|
[self fetchData];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// See MP-14, also crashes easily on internal assertions etc..
|
||||||
|
//- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
|
||||||
|
//
|
||||||
|
// [self.searchDisplayController.searchResultsTableView beginUpdates];
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
|
||||||
|
// atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
|
||||||
|
//
|
||||||
|
// UITableView *tableView = self.searchDisplayController.searchResultsTableView;
|
||||||
|
// switch(type) {
|
||||||
|
//
|
||||||
|
// case NSFetchedResultsChangeInsert:
|
||||||
|
// [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case NSFetchedResultsChangeDelete:
|
||||||
|
// [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case NSFetchedResultsChangeUpdate:
|
||||||
|
// [self configureCell:[tableView cellForRowAtIndexPath:indexPath]
|
||||||
|
// inTableView:tableView atIndexPath:indexPath];
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case NSFetchedResultsChangeMove:
|
||||||
|
// [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
|
||||||
|
// withRowAnimation:UITableViewRowAnimationFade];
|
||||||
|
// [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
|
||||||
|
// withRowAnimation:UITableViewRowAnimationFade];
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo
|
||||||
|
// atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
|
||||||
|
//
|
||||||
|
// UITableView *tableView = self.searchDisplayController.searchResultsTableView;
|
||||||
|
// switch(type) {
|
||||||
|
//
|
||||||
|
// case NSFetchedResultsChangeInsert:
|
||||||
|
// [tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
|
||||||
|
// withRowAnimation:UITableViewRowAnimationFade];
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case NSFetchedResultsChangeDelete:
|
||||||
|
// [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
|
||||||
|
// withRowAnimation:UITableViewRowAnimationFade];
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
|
||||||
|
|
||||||
|
dbg(@"controllerDidChangeContent on thread: %@", [NSThread currentThread].name);
|
||||||
|
[self.tableView reloadData];
|
||||||
|
//[self.tableView endUpdates];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||||
|
|
||||||
|
return (NSInteger)[[self.fetchedResultsController sections] count];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||||
|
|
||||||
|
return (NSInteger)[[[self.fetchedResultsController sections] objectAtIndex:(unsigned)section] numberOfObjects];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
||||||
|
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MPElementSearch"];
|
||||||
|
if (!cell.backgroundView) {
|
||||||
|
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MPElementSearch"];
|
||||||
|
|
||||||
|
UIImage *backgroundImage = [[UIImage imageNamed:@"ui_list_middle"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)
|
||||||
|
resizingMode:UIImageResizingModeStretch];
|
||||||
|
UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:backgroundImage];
|
||||||
|
backgroundImageView.frame = CGRectMake(-5, 0, 330, 34);
|
||||||
|
backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 34)];
|
||||||
|
[backgroundView addSubview:backgroundImageView];
|
||||||
|
backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
|
||||||
|
cell.backgroundView = backgroundView;
|
||||||
|
// cell.textLabel.backgroundColor = [UIColor clearColor];
|
||||||
|
// cell.textLabel.textColor = [UIColor whiteColor];
|
||||||
|
// cell.detailTextLabel.backgroundColor = [UIColor clearColor];
|
||||||
|
// cell.detailTextLabel.textColor = [UIColor lightGrayColor];
|
||||||
|
// cell.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
// cell.clipsToBounds = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self configureCell:cell inTableView:tableView atIndexPath:indexPath];
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
||||||
|
MPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||||
|
|
||||||
|
cell.textLabel.text = element.name;
|
||||||
|
cell.detailTextLabel.text = PearlString(@"Used %d times, last on %@",
|
||||||
|
element.uses, [self.dateFormatter stringFromDate:element.lastUsed]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
||||||
|
[self.delegate didSelectElement:[self.fetchedResultsController objectAtIndexPath:indexPath]];
|
||||||
|
[self close:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
|
||||||
|
|
||||||
|
return [[[self.fetchedResultsController sections] objectAtIndex:(unsigned)section] name];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
|
||||||
|
|
||||||
|
return [self.fetchedResultsController sectionIndexTitles];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
|
||||||
|
|
||||||
|
return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
|
||||||
|
forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
|
|
||||||
|
if (editingStyle == UITableViewCellEditingStyleDelete)
|
||||||
|
[self.fetchedResultsController.managedObjectContext performBlock:^{
|
||||||
|
MPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||||
|
|
||||||
|
inf(@"Deleting element: %@", element.name);
|
||||||
|
[self.fetchedResultsController.managedObjectContext deleteObject:element];
|
||||||
|
|
||||||
|
#ifdef TESTFLIGHT_SDK_VERSION
|
||||||
|
[TestFlight passCheckpoint:MPCheckpointDeleteElement];
|
||||||
|
#endif
|
||||||
|
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointDeleteElement attributes:@{
|
||||||
|
@"type" : element.typeName,
|
||||||
|
@"version" : @(element.version)}];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
@ -92,6 +92,16 @@
|
|||||||
[super viewWillDisappear:animated];
|
[super viewWillDisappear:animated];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
|
||||||
|
|
||||||
|
return UIInterfaceOrientationPortrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)shouldAutorotate {
|
||||||
|
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
|
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
|
||||||
viewControllerBeforeViewController:(UIViewController *)viewController {
|
viewControllerBeforeViewController:(UIViewController *)viewController {
|
||||||
|
24
MasterPassword/iOS/MPElementPickerDelegate.h
Normal file
24
MasterPassword/iOS/MPElementPickerDelegate.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// MPElementPickerDelegate
|
||||||
|
//
|
||||||
|
// Created by Maarten Billemont on 2013-01-31.
|
||||||
|
// Copyright 2013 lhunath (Maarten Billemont). All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPElementEntity.h"
|
||||||
|
|
||||||
|
@protocol MPElementPickerDelegate<NSObject>
|
||||||
|
|
||||||
|
- (void)didSelectElement:(MPElementEntity *)element;
|
||||||
|
|
||||||
|
@end
|
@ -10,7 +10,7 @@
|
|||||||
#import "MPTypeViewController.h"
|
#import "MPTypeViewController.h"
|
||||||
#import "MPSearchDelegate.h"
|
#import "MPSearchDelegate.h"
|
||||||
|
|
||||||
@interface MPMainViewController : UIViewController<MPTypeDelegate, UITextFieldDelegate, MPSearchResultsDelegate, UIWebViewDelegate, UIGestureRecognizerDelegate>
|
@interface MPMainViewController : UIViewController<MPTypeDelegate, UITextFieldDelegate, MPElementPickerDelegate, UIWebViewDelegate, UIGestureRecognizerDelegate>
|
||||||
|
|
||||||
@property (assign, nonatomic) BOOL siteInfoHidden;
|
@property (assign, nonatomic) BOOL siteInfoHidden;
|
||||||
@property (strong, nonatomic) IBOutlet MPSearchDelegate *searchDelegate;
|
@property (strong, nonatomic) IBOutlet MPSearchDelegate *searchDelegate;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#import "MPAppDelegate.h"
|
#import "MPAppDelegate.h"
|
||||||
#import "MPAppDelegate_Key.h"
|
#import "MPAppDelegate_Key.h"
|
||||||
#import "MPAppDelegate_Store.h"
|
#import "MPAppDelegate_Store.h"
|
||||||
|
#import "MPAllSitesViewController.h"
|
||||||
|
|
||||||
|
|
||||||
@interface MPMainViewController()
|
@interface MPMainViewController()
|
||||||
@ -48,6 +49,8 @@
|
|||||||
|
|
||||||
if ([[segue identifier] isEqualToString:@"MP_ChooseType"])
|
if ([[segue identifier] isEqualToString:@"MP_ChooseType"])
|
||||||
((MPTypeViewController *)[segue destinationViewController]).delegate = self;
|
((MPTypeViewController *)[segue destinationViewController]).delegate = self;
|
||||||
|
if ([[segue identifier] isEqualToString:@"MP_AllSites"])
|
||||||
|
((MPAllSitesViewController *)[((UINavigationController *)[segue destinationViewController]) topViewController]).delegate = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
@ -753,12 +756,12 @@
|
|||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
inf(@"Action: Preferences");
|
inf(@"Action: Preferences");
|
||||||
[self performSegueWithIdentifier:@"UserProfile" sender:self];
|
[self performSegueWithIdentifier:@"MP_UserProfile" sender:self];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: {
|
case 3: {
|
||||||
inf(@"Action: Other Apps");
|
inf(@"Action: Other Apps");
|
||||||
[self performSegueWithIdentifier:@"OtherApps" sender:self];
|
[self performSegueWithIdentifier:@"MP_OtherApps" sender:self];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//#if defined(ADHOC) && defined(TESTFLIGHT_SDK_VERSION)
|
//#if defined(ADHOC) && defined(TESTFLIGHT_SDK_VERSION)
|
||||||
|
@ -7,27 +7,22 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#import "MPElementEntity.h"
|
#import "MPElementEntity.h"
|
||||||
|
#import "MPElementPickerDelegate.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MPSearchScopeAll,
|
MPSearchScopeAll,
|
||||||
MPSearchScopeOutdated,
|
MPSearchScopeOutdated,
|
||||||
} MPSearchScope;
|
} MPSearchScope;
|
||||||
|
|
||||||
@protocol MPSearchResultsDelegate<NSObject>
|
|
||||||
|
|
||||||
- (void)didSelectElement:(MPElementEntity *)element;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface MPSearchDelegate : NSObject<UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchDisplayDelegate, NSFetchedResultsControllerDelegate>
|
@interface MPSearchDelegate : NSObject<UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchDisplayDelegate, NSFetchedResultsControllerDelegate>
|
||||||
|
|
||||||
@property (strong, nonatomic) NSDateFormatter *dateFormatter;
|
@property (strong, nonatomic) NSDateFormatter *dateFormatter;
|
||||||
@property (strong, readonly) NSFetchedResultsController *fetchedResultsController;
|
@property (strong, readonly) NSFetchedResultsController *fetchedResultsController;
|
||||||
@property (strong, nonatomic) NSString *query;
|
|
||||||
@property (strong, nonatomic) UILabel *tipView;
|
@property (strong, nonatomic) UILabel *tipView;
|
||||||
|
|
||||||
@property (weak, nonatomic) IBOutlet id<MPSearchResultsDelegate> delegate;
|
@property (weak, nonatomic) IBOutlet id<MPElementPickerDelegate> delegate;
|
||||||
@property (strong, nonatomic) IBOutlet UISearchDisplayController *searchDisplayController;
|
@property (strong, nonatomic) IBOutlet UISearchDisplayController *searchDisplayController;
|
||||||
@property (weak, nonatomic) IBOutlet UIView *searchTipContainer;
|
@property (weak, nonatomic) IBOutlet UIView *searchTipContainer;
|
||||||
|
|
||||||
|
@ -9,12 +9,7 @@
|
|||||||
#import "MPSearchDelegate.h"
|
#import "MPSearchDelegate.h"
|
||||||
#import "MPAppDelegate.h"
|
#import "MPAppDelegate.h"
|
||||||
#import "MPAppDelegate_Store.h"
|
#import "MPAppDelegate_Store.h"
|
||||||
|
#import "MPMainViewController.h"
|
||||||
@interface MPSearchDelegate (Private)
|
|
||||||
|
|
||||||
- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation MPSearchDelegate {
|
@implementation MPSearchDelegate {
|
||||||
|
|
||||||
@ -28,7 +23,6 @@
|
|||||||
|
|
||||||
self.dateFormatter = [NSDateFormatter new];
|
self.dateFormatter = [NSDateFormatter new];
|
||||||
self.dateFormatter.dateStyle = NSDateFormatterShortStyle;
|
self.dateFormatter.dateStyle = NSDateFormatterShortStyle;
|
||||||
self.query = @"";
|
|
||||||
|
|
||||||
self.tipView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 170)];
|
self.tipView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 170)];
|
||||||
self.tipView.textAlignment = NSTextAlignmentCenter;
|
self.tipView.textAlignment = NSTextAlignmentCenter;
|
||||||
@ -60,6 +54,7 @@
|
|||||||
|
|
||||||
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
|
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
|
||||||
fetchRequest.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:@"uses_" ascending:NO]];
|
fetchRequest.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:@"uses_" ascending:NO]];
|
||||||
|
fetchRequest.fetchBatchSize = 20;
|
||||||
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc
|
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc
|
||||||
sectionNameKeyPath:nil cacheName:nil];
|
sectionNameKeyPath:nil cacheName:nil];
|
||||||
_fetchedResultsController.delegate = self;
|
_fetchedResultsController.delegate = self;
|
||||||
@ -68,6 +63,11 @@
|
|||||||
return _fetchedResultsController;
|
return _fetchedResultsController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar {
|
||||||
|
|
||||||
|
[((MPMainViewController *)self.delegate) performSegueWithIdentifier:@"MP_AllSites" sender:self];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
|
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
|
||||||
|
|
||||||
UITableView *tableView = self.searchDisplayController.searchResultsTableView;
|
UITableView *tableView = self.searchDisplayController.searchResultsTableView;
|
||||||
@ -89,12 +89,6 @@
|
|||||||
|
|
||||||
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
|
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
|
||||||
|
|
||||||
if (searchBar.searchResultsButtonSelected && !searchText.length)
|
|
||||||
searchBar.text = @" ";
|
|
||||||
|
|
||||||
self.query = [searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
|
||||||
if (!self.query)
|
|
||||||
self.query = @"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
|
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
|
||||||
@ -113,8 +107,6 @@
|
|||||||
|
|
||||||
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
|
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
|
||||||
|
|
||||||
controller.searchBar.text = controller.searchBar.searchResultsButtonSelected? @" ": @"";
|
|
||||||
self.query = @"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
|
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
|
||||||
@ -154,31 +146,30 @@
|
|||||||
|
|
||||||
- (void)fetchData {
|
- (void)fetchData {
|
||||||
|
|
||||||
|
|
||||||
|
NSString *query = [self.searchDisplayController.searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||||
|
if (!query)
|
||||||
|
return;
|
||||||
|
|
||||||
MPUserEntity *activeUser = [MPAppDelegate get].activeUser;
|
MPUserEntity *activeUser = [MPAppDelegate get].activeUser;
|
||||||
assert(self.query);
|
if (!activeUser)
|
||||||
assert(activeUser);
|
return;
|
||||||
|
|
||||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user == %@", activeUser];
|
|
||||||
if (self.query.length)
|
|
||||||
predicate = [NSCompoundPredicate
|
|
||||||
andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", self.query],
|
|
||||||
predicate]];
|
|
||||||
|
|
||||||
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user == %@ AND name BEGINSWITH[cd] %@", activeUser, query];
|
||||||
switch ((MPSearchScope)self.searchDisplayController.searchBar.selectedScopeButtonIndex) {
|
switch ((MPSearchScope)self.searchDisplayController.searchBar.selectedScopeButtonIndex) {
|
||||||
|
|
||||||
case MPSearchScopeAll:
|
case MPSearchScopeAll:
|
||||||
break;
|
break;
|
||||||
case MPSearchScopeOutdated:
|
case MPSearchScopeOutdated:
|
||||||
predicate = [NSCompoundPredicate
|
predicate = [NSCompoundPredicate
|
||||||
andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"requiresExplicitMigration_ == YES"],
|
andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"requiresExplicitMigration_ == YES"], predicate]];
|
||||||
predicate]];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self.fetchedResultsController.fetchRequest.predicate = predicate;
|
self.fetchedResultsController.fetchRequest.predicate = predicate;
|
||||||
|
|
||||||
NSError *error;
|
NSError *error;
|
||||||
if (![self.fetchedResultsController performFetch:&error])
|
if (![self.fetchedResultsController performFetch:&error])
|
||||||
err(@"Couldn't fetch elements: %@", error);
|
err(@"Couldn't fetch elements: %@", error);
|
||||||
|
|
||||||
[self.searchDisplayController.searchBar.superview enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) {
|
[self.searchDisplayController.searchBar.superview enumerateSubviews:^(UIView *subview, BOOL *stop, BOOL *recurse) {
|
||||||
CGRect searchBarFrame = self.searchDisplayController.searchBar.frame;
|
CGRect searchBarFrame = self.searchDisplayController.searchBar.frame;
|
||||||
@ -258,12 +249,13 @@
|
|||||||
NSArray *sections = [self.fetchedResultsController sections];
|
NSArray *sections = [self.fetchedResultsController sections];
|
||||||
NSUInteger sectionCount = [sections count];
|
NSUInteger sectionCount = [sections count];
|
||||||
|
|
||||||
if ([self.query length]) {
|
NSString *query = [self.searchDisplayController.searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||||
|
if ([query length]) {
|
||||||
__block BOOL hasExactQueryMatch = NO;
|
__block BOOL hasExactQueryMatch = NO;
|
||||||
[sections enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
[sections enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
||||||
id<NSFetchedResultsSectionInfo> sectionInfo = obj;
|
id<NSFetchedResultsSectionInfo> sectionInfo = obj;
|
||||||
[[sectionInfo objects] enumerateObjectsUsingBlock:^(id obj_, NSUInteger idx_, BOOL *stop_) {
|
[[sectionInfo objects] enumerateObjectsUsingBlock:^(id obj_, NSUInteger idx_, BOOL *stop_) {
|
||||||
if ([[obj_ name] isEqualToString:self.query]) {
|
if ([[obj_ name] isEqualToString:query]) {
|
||||||
hasExactQueryMatch = YES;
|
hasExactQueryMatch = YES;
|
||||||
*stop_ = YES;
|
*stop_ = YES;
|
||||||
}
|
}
|
||||||
@ -327,7 +319,8 @@
|
|||||||
element.uses, [self.dateFormatter stringFromDate:element.lastUsed]];
|
element.uses, [self.dateFormatter stringFromDate:element.lastUsed]];
|
||||||
} else {
|
} else {
|
||||||
// "New" section
|
// "New" section
|
||||||
cell.textLabel.text = self.query;
|
NSString *query = [self.searchDisplayController.searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||||
|
cell.textLabel.text = query;
|
||||||
cell.detailTextLabel.text = @"Create a new site.";
|
cell.detailTextLabel.text = @"Create a new site.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,7 +332,7 @@
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
// "New" section.
|
// "New" section.
|
||||||
NSString *siteName = self.query;
|
NSString *siteName = [self.searchDisplayController.searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||||
[PearlAlert showAlertWithTitle:@"New Site"
|
[PearlAlert showAlertWithTitle:@"New Site"
|
||||||
message:PearlString(@"Do you want to create a new site named:\n%@", siteName)
|
message:PearlString(@"Do you want to create a new site named:\n%@", siteName)
|
||||||
viewStyle:UIAlertViewStyleDefault
|
viewStyle:UIAlertViewStyleDefault
|
||||||
|
@ -496,7 +496,6 @@
|
|||||||
|
|
||||||
// Lay out user name label.
|
// Lay out user name label.
|
||||||
self.nameLabel.text = targetedAvatar? (targetedUser? targetedUser.name: @"New User"): nil;
|
self.nameLabel.text = targetedAvatar? (targetedUser? targetedUser.name: @"New User"): nil;
|
||||||
dbg(@"targetedAvatar: %@, targetedUser: %@, nameLabel: %@", targetedAvatar, targetedUser, self.nameLabel.text);
|
|
||||||
self.nameLabel.bounds = CGRectSetHeight(self.nameLabel.bounds,
|
self.nameLabel.bounds = CGRectSetHeight(self.nameLabel.bounds,
|
||||||
[self.nameLabel.text sizeWithFont:self.nameLabel.font
|
[self.nameLabel.text sizeWithFont:self.nameLabel.font
|
||||||
constrainedToSize:CGSizeMake(self.nameLabel.bounds.size.width - 10, 100)
|
constrainedToSize:CGSizeMake(self.nameLabel.bounds.size.width - 10, 100)
|
||||||
|
@ -25,9 +25,4 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (MPiOSConfig *)get {
|
|
||||||
|
|
||||||
return (MPiOSConfig *)[super get];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -633,7 +633,7 @@ Your passwords will be AES-encrypted with your master password.</string>
|
|||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
</view>
|
</view>
|
||||||
<searchBar contentMode="redraw" barStyle="blackOpaque" placeholder="Site name" showsSearchResultsButton="YES" id="qeo-n2-WVh">
|
<searchBar contentMode="redraw" barStyle="blackOpaque" placeholder="Site name" showsBookmarkButton="YES" id="qeo-n2-WVh">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
<gestureRecognizers/>
|
<gestureRecognizers/>
|
||||||
@ -643,25 +643,6 @@ Your passwords will be AES-encrypted with your master password.</string>
|
|||||||
<string>Outdated</string>
|
<string>Outdated</string>
|
||||||
</scopeButtonTitles>
|
</scopeButtonTitles>
|
||||||
</searchBar>
|
</searchBar>
|
||||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" id="zOR-Du-qRL" userLabel="View - Search Tip">
|
|
||||||
<rect key="frame" x="10" y="15" width="300" height="60"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black_top.png" id="ORD-Xv-bOQ">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="300" height="60"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<rect key="contentStretch" x="0.15000000000000002" y="0.15000000000000002" width="0.69999999999999973" height="0.69999999999999973"/>
|
|
||||||
</imageView>
|
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Begin by entering the name of your site." textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" id="21b-bH-lR9">
|
|
||||||
<rect key="frame" x="-20" y="26" width="340" height="21"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
|
||||||
<nil key="highlightedColor"/>
|
|
||||||
</label>
|
|
||||||
</subviews>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
|
||||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" id="foz-tW-xGw" userLabel="View - Action Tip">
|
<view userInteractionEnabled="NO" contentMode="scaleToFill" id="foz-tW-xGw" userLabel="View - Action Tip">
|
||||||
<rect key="frame" x="10" y="0.0" width="300" height="60"/>
|
<rect key="frame" x="10" y="0.0" width="300" height="60"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
@ -685,6 +666,25 @@ Your passwords will be AES-encrypted with your master password.</string>
|
|||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
</view>
|
</view>
|
||||||
|
<view userInteractionEnabled="NO" contentMode="scaleToFill" id="zOR-Du-qRL" userLabel="View - Search Tip">
|
||||||
|
<rect key="frame" x="10" y="15" width="300" height="60"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black_top.png" id="ORD-Xv-bOQ">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="300" height="60"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<rect key="contentStretch" x="0.15000000000000002" y="0.15000000000000002" width="0.69999999999999973" height="0.69999999999999973"/>
|
||||||
|
</imageView>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Begin by entering the name of your site." textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" id="21b-bH-lR9">
|
||||||
|
<rect key="frame" x="-20" y="26" width="340" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
|
</view>
|
||||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" id="UM8-56-kAO" userLabel="View - Tool Tip">
|
<view userInteractionEnabled="NO" contentMode="scaleToFill" id="UM8-56-kAO" userLabel="View - Tool Tip">
|
||||||
<rect key="frame" x="10" y="15" width="266" height="60"/>
|
<rect key="frame" x="10" y="15" width="266" height="60"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
@ -935,8 +935,9 @@ L4m3P4sSw0rD</string>
|
|||||||
<outlet property="toolTipEditIcon" destination="KEn-n3-qhX" id="zEV-tR-Egq"/>
|
<outlet property="toolTipEditIcon" destination="KEn-n3-qhX" id="zEV-tR-Egq"/>
|
||||||
<outlet property="typeButton" destination="xYM-e3-BMg" id="xvn-nR-MRV"/>
|
<outlet property="typeButton" destination="xYM-e3-BMg" id="xvn-nR-MRV"/>
|
||||||
<outlet property="typeTipContainer" destination="g55-0m-WjS" id="KZ9-KV-NMh"/>
|
<outlet property="typeTipContainer" destination="g55-0m-WjS" id="KZ9-KV-NMh"/>
|
||||||
<segue destination="oLN-6u-GLb" kind="push" identifier="UserProfile" id="tKN-Sw-S5J"/>
|
<segue destination="oLN-6u-GLb" kind="push" identifier="MP_UserProfile" id="tKN-Sw-S5J"/>
|
||||||
<segue destination="2Th-Tb-22a" kind="modal" identifier="OtherApps" id="Io5-cz-v9Y"/>
|
<segue destination="2Th-Tb-22a" kind="modal" identifier="MP_OtherApps" id="Io5-cz-v9Y"/>
|
||||||
|
<segue destination="KZ9-Bb-FN7" kind="modal" identifier="MP_AllSites" id="18w-AW-e8A"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="mK2-p1-3zC" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="mK2-p1-3zC" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
@ -1214,7 +1215,7 @@ Pink fluffy door frame.</string>
|
|||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="hkm-U7-Dm7" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="hkm-U7-Dm7" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="463" y="-381"/>
|
<point key="canvasLocation" x="455" y="-381"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Unlock View Controller-->
|
<!--Unlock View Controller-->
|
||||||
<scene sceneID="HkH-JR-Fhy">
|
<scene sceneID="HkH-JR-Fhy">
|
||||||
@ -1628,6 +1629,77 @@ You could use the word wall for inspiration in finding a memorable master passw
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="455" y="1425"/>
|
<point key="canvasLocation" x="455" y="1425"/>
|
||||||
</scene>
|
</scene>
|
||||||
|
<!--Navigation Controller-->
|
||||||
|
<scene sceneID="rAg-OU-9QV">
|
||||||
|
<objects>
|
||||||
|
<navigationController definesPresentationContext="YES" id="KZ9-Bb-FN7" sceneMemberID="viewController">
|
||||||
|
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="blackOpaque" prompted="NO"/>
|
||||||
|
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="blackOpaque" id="s0n-kY-htJ">
|
||||||
|
<rect key="frame" x="0.0" y="-44" width="0.0" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</navigationBar>
|
||||||
|
<connections>
|
||||||
|
<segue destination="idA-Pj-1U9" kind="relationship" relationship="rootViewController" id="dmZ-bA-SbA"/>
|
||||||
|
</connections>
|
||||||
|
</navigationController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="vJs-4S-qNG" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="996" y="1425"/>
|
||||||
|
</scene>
|
||||||
|
<!--All Sites View Controller - All Sites-->
|
||||||
|
<scene sceneID="I7c-vt-d2s">
|
||||||
|
<objects>
|
||||||
|
<tableViewController id="idA-Pj-1U9" customClass="MPAllSitesViewController" sceneMemberID="viewController">
|
||||||
|
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="48" sectionHeaderHeight="22" sectionFooterHeight="22" id="N83-sj-4tl">
|
||||||
|
<rect key="frame" x="0.0" y="64" width="320" height="416"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
<prototypes>
|
||||||
|
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="MPElementSearch" textLabel="UGt-vQ-i5K" detailTextLabel="Xv8-kG-Tap" style="IBUITableViewCellStyleSubtitle" id="3eb-mJ-xFj">
|
||||||
|
<rect key="frame" x="0.0" y="22" width="320" height="48"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="320" height="47"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UGt-vQ-i5K">
|
||||||
|
<rect key="frame" x="10" y="4" width="38" height="22"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
|
||||||
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
<color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Xv8-kG-Tap">
|
||||||
|
<rect key="frame" x="10" y="26" width="47" height="18"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
|
<color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||||
|
</view>
|
||||||
|
</tableViewCell>
|
||||||
|
</prototypes>
|
||||||
|
<connections>
|
||||||
|
<outlet property="dataSource" destination="idA-Pj-1U9" id="yPh-6k-Ba9"/>
|
||||||
|
<outlet property="delegate" destination="idA-Pj-1U9" id="bdk-Iu-Hpv"/>
|
||||||
|
</connections>
|
||||||
|
</tableView>
|
||||||
|
<navigationItem key="navigationItem" title="All Sites" id="Ipv-Tt-WPc">
|
||||||
|
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="Mnn-6X-DgP">
|
||||||
|
<connections>
|
||||||
|
<action selector="close:" destination="idA-Pj-1U9" id="qqC-U7-8Ci"/>
|
||||||
|
</connections>
|
||||||
|
</barButtonItem>
|
||||||
|
</navigationItem>
|
||||||
|
</tableViewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="abw-PC-pyQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="1537" y="1425"/>
|
||||||
|
</scene>
|
||||||
<!--Apps View Controller-->
|
<!--Apps View Controller-->
|
||||||
<scene sceneID="3cC-Qq-rgU">
|
<scene sceneID="3cC-Qq-rgU">
|
||||||
<objects>
|
<objects>
|
||||||
@ -2077,13 +2149,13 @@ You could use the word wall for inspiration in finding a memorable master passw
|
|||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="LHv-Mk-8Kp" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="LHv-Mk-8Kp" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="1004" y="-381"/>
|
<point key="canvasLocation" x="996" y="-381"/>
|
||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="Square-bottom.png" width="551" height="58"/>
|
<image name="Square-bottom.png" width="551" height="58"/>
|
||||||
<image name="avatar-0.png" width="110" height="110"/>
|
<image name="avatar-0.png" width="110" height="110"/>
|
||||||
<image name="background.png" width="480" height="480"/>
|
<image name="background.png" width="568" height="568"/>
|
||||||
<image name="book.png" width="320" height="480"/>
|
<image name="book.png" width="320" height="480"/>
|
||||||
<image name="guide_page_0.png" width="320" height="480"/>
|
<image name="guide_page_0.png" width="320" height="480"/>
|
||||||
<image name="guide_page_1.png" width="320" height="480"/>
|
<image name="guide_page_1.png" width="320" height="480"/>
|
||||||
@ -2121,6 +2193,146 @@ You could use the word wall for inspiration in finding a memorable master passw
|
|||||||
<image name="ui_spinner.png" width="75" height="75"/>
|
<image name="ui_spinner.png" width="75" height="75"/>
|
||||||
<image name="ui_textfield.png" width="158" height="34"/>
|
<image name="ui_textfield.png" width="158" height="34"/>
|
||||||
</resources>
|
</resources>
|
||||||
|
<classes>
|
||||||
|
<class className="MPAllSitesViewController" superclassName="UITableViewController">
|
||||||
|
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPAllSitesViewController.h"/>
|
||||||
|
<relationships>
|
||||||
|
<relationship kind="action" name="close:"/>
|
||||||
|
<relationship kind="outlet" name="delegate"/>
|
||||||
|
</relationships>
|
||||||
|
</class>
|
||||||
|
<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="MPGuideViewController" superclassName="UIViewController">
|
||||||
|
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPGuideViewController.h"/>
|
||||||
|
<relationships>
|
||||||
|
<relationship kind="action" name="close"/>
|
||||||
|
<relationship kind="outlet" name="pageControl" candidateClass="UIPageControl"/>
|
||||||
|
<relationship kind="outlet" name="scrollView" candidateClass="UIScrollView"/>
|
||||||
|
</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="MPSearchDelegate"/>
|
||||||
|
<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="MPSearchDelegate" superclassName="NSObject">
|
||||||
|
<source key="sourceIdentifier" type="project" relativePath="./Classes/MPSearchDelegate.h"/>
|
||||||
|
<relationships>
|
||||||
|
<relationship kind="outlet" name="delegate"/>
|
||||||
|
<relationship kind="outlet" name="searchDisplayController" candidateClass="UISearchDisplayController"/>
|
||||||
|
<relationship kind="outlet" name="searchTipContainer" candidateClass="UIView"/>
|
||||||
|
</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="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="loadingUsersIndicator" candidateClass="UIActivityIndicatorView"/>
|
||||||
|
<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>
|
||||||
|
</classes>
|
||||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||||
<nil key="statusBar"/>
|
<nil key="statusBar"/>
|
||||||
<simulatedOrientationMetrics key="orientation"/>
|
<simulatedOrientationMetrics key="orientation"/>
|
||||||
|
6
Resources/MasterPassword.sketch/fonts
Normal file
6
Resources/MasterPassword.sketch/fonts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
SourceCodePro-Light
|
||||||
|
LucidaGrande
|
||||||
|
HelveticaNeue-Medium
|
||||||
|
LucidaGrande
|
||||||
|
HelveticaNeue-Light
|
||||||
|
Inconsolata
|
@ -341,20 +341,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
By default, Master Password uses the <em>Long Password</em> type for any new passwords. The user is able to choose a different password type, which is normally only done if the site's password policy is incompatible with the output password produced by this type.
|
Where each of the letters above expand any of the characters in their respective character group:
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To create the create the output password, the bytes in the <code>seed</code> are encoded according to the template. The first <code>seed</code> byte is used to determine which of the type's templates to use for encoding an output password. We take the byte value of the first <code>seed</code> byte modulo the amount of templates set for the chosen password type and use the result as a zero-based index in the template list for the password type.
|
|
||||||
</p>
|
|
||||||
<code><pre>
|
|
||||||
templates = [ "CvcvCvcvnoCvcv", "CvcvnoCvcvCvcv", "CvcvCvcvCvcvno", ... ]
|
|
||||||
template = templates[ seed[0] % count( templates ) ]
|
|
||||||
</pre></code>
|
|
||||||
<p>
|
|
||||||
Now that we know what template to use for building our output password, all that's left is to iterate the template, and produce a character of password output for each step. When we iterate the template (index <code>i</code>), we look in the character group identified by the character (string <code>passChars</code>) in the template at index <code>i</code>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The following character groups (<code>passChars</code>) are defined:
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><p>Template character: <code>V</code>
|
<li><p>Template character: <code>V</code>
|
||||||
<ul>
|
<ul>
|
||||||
@ -403,6 +390,19 @@
|
|||||||
</p></li>
|
</p></li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
By default, Master Password uses the <em>Long Password</em> type for any new passwords. The user is able to choose a different password type, which is normally only done if the site's password policy is incompatible with the output password produced by this type.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
To create the output password, the bytes in the <code>seed</code> are encoded according to the template. The first <code>seed</code> byte is used to determine which of the type's templates to use for encoding an output password. We take the byte value of the first <code>seed</code> byte modulo the amount of templates set for the chosen password type and use the result as a zero-based index in the template list for the password type.
|
||||||
|
</p>
|
||||||
|
<code><pre>
|
||||||
|
templates = [ "CvcvCvcvnoCvcv", "CvcvnoCvcvCvcv", "CvcvCvcvCvcvno", ... ]
|
||||||
|
template = templates[ seed[0] % count( templates ) ]
|
||||||
|
</pre></code>
|
||||||
|
<p>
|
||||||
|
Now that we know what template to use for building our output password, all that's left is to iterate the template, and produce a character of password output for each step. When we iterate the template (index <code>i</code>), we look in the character group identified by the character (string <code>passChars</code>) in the template at index <code>i</code>.
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
We use the <code>seed</code>'s byte value at index <code>i + 1</code> modulo the amount of characters in the character class to determine which character (<code>passChar</code>) in the class to use for the output password at index <code>i</code>.
|
We use the <code>seed</code>'s byte value at index <code>i + 1</code> modulo the amount of characters in the character class to determine which character (<code>passChar</code>) in the class to use for the output password at index <code>i</code>.
|
||||||
</p>
|
</p>
|
||||||
|
Loading…
Reference in New Issue
Block a user