From ee93412dd1e22773d2a0740cb7f734c354aa945a Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Mon, 15 Apr 2013 00:04:16 -0400 Subject: [PATCH] Search & AllSites improvements, sort by recency, rememberLogin setup. [UPDATED] Simplified AllSites VC in IB (removed the unused navVC). [UPDATED] Outdated sites are now shown in the AllSites VC. [ADDED] An update-all-sites button when showing outdated sites in the AllSites VC. [REMOVED] Search scopes. [ADDED] Sorting elements by recency and usage count now. [FIXED] Initial positioning of help container. [ADDED] Setup VC for rememberLogin. --- External/Pearl | 2 +- .../ObjC/iOS/MPElementListAllViewController.h | 1 + .../ObjC/iOS/MPElementListAllViewController.m | 124 +++++++++- .../ObjC/iOS/MPElementListController.h | 20 +- .../ObjC/iOS/MPElementListController.m | 185 +++++++++------ .../ObjC/iOS/MPElementListSearchController.m | 103 ++++---- .../ObjC/iOS/MPMainViewController.m | 16 +- .../ObjC/iOS/MPSetupViewController.h | 1 + .../ObjC/iOS/MPSetupViewController.m | 4 + .../ObjC/iOS/MPUnlockViewController.m | 14 +- .../ObjC/iOS/MainStoryboard_iPhone.storyboard | 219 ++++++++++++------ .../project.pbxproj | 8 + MasterPassword/Resources/Media/unlocked.png | Bin 0 -> 4109 bytes .../Resources/Media/unlocked@2x.png | Bin 0 -> 15997 bytes .../QuickLook/Preview.pdf | Bin 63735 -> 80240 bytes .../QuickLook/Thumbnail.jpg | Bin 19082 -> 21866 bytes .../Raw/Large Icons.vdesigner/VectorDesigner | Bin 29508 -> 35314 bytes 17 files changed, 451 insertions(+), 246 deletions(-) create mode 100644 MasterPassword/Resources/Media/unlocked.png create mode 100644 MasterPassword/Resources/Media/unlocked@2x.png diff --git a/External/Pearl b/External/Pearl index 99c73fd3..0d306934 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit 99c73fd3b37b4d2621548f5ae366c163231a346d +Subproject commit 0d30693440fd520715f22789d33d5551b3b681c4 diff --git a/MasterPassword/ObjC/iOS/MPElementListAllViewController.h b/MasterPassword/ObjC/iOS/MPElementListAllViewController.h index 984cf97b..ec1211cf 100644 --- a/MasterPassword/ObjC/iOS/MPElementListAllViewController.h +++ b/MasterPassword/ObjC/iOS/MPElementListAllViewController.h @@ -20,6 +20,7 @@ #import "MPElementListController.h" @interface MPElementListAllViewController : MPElementListController +@property (weak, nonatomic) IBOutlet UINavigationBar *navigationBar; - (IBAction)close:(id)sender; - (IBAction)add:(id)sender; diff --git a/MasterPassword/ObjC/iOS/MPElementListAllViewController.m b/MasterPassword/ObjC/iOS/MPElementListAllViewController.m index 2a06b214..ea313a25 100644 --- a/MasterPassword/ObjC/iOS/MPElementListAllViewController.m +++ b/MasterPassword/ObjC/iOS/MPElementListAllViewController.m @@ -16,9 +16,32 @@ // #import "MPElementListAllViewController.h" +#import "MPAppDelegate.h" +#import "MPAppDelegate_Store.h" + +#define MPElementUpgradeOldContentKey @"MPElementUpgradeOldContentKey" +#define MPElementUpgradeNewContentKey @"MPElementUpgradeNewContentKey" @implementation MPElementListAllViewController +- (void)viewWillAppear:(BOOL)animated { + + [super viewWillAppear:animated]; + + if ([self.filter isEqualToString:MPElementListFilterNone]) { + self.navigationBar.topItem.title = @"All Sites"; + self.navigationBar.topItem.rightBarButtonItem = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)]; + } + else if ([self.filter isEqualToString:MPElementListFilterOutdated]) { + self.navigationBar.topItem.title = @"Outdated"; + self.navigationBar.topItem.rightBarButtonItem = [[UIBarButtonItem alloc] + initWithTitle:@"Upgrade All" style:UIBarButtonItemStyleBordered target:self action:@selector(upgradeAll:)]; + } + + [self updateData]; +} + - (IBAction)close:(id)sender { [self dismissViewControllerAnimated:YES completion:nil]; @@ -40,11 +63,106 @@ cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonOkay, nil]; } -- (void)viewWillAppear:(BOOL)animated { +- (IBAction)upgradeAll:(id)sender { - [super viewWillAppear:animated]; + [PearlAlert showAlertWithTitle:@"Upgrading All Sites" + message:@"You are about to upgrade all outdated sites. This will cause passwords to change. " + @"Afterwards, you can get an overview of the changes." + viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock: + ^(UIAlertView *alert, NSInteger buttonIndex) { + if (buttonIndex == [alert cancelButtonIndex]) + return; - [self updateData]; + PearlAlert *activity = [PearlAlert showActivityWithTitle:@"Upgrading Sites"]; + [self performUpgradeAllWithCompletion:^(BOOL success, NSDictionary *changes) { + dispatch_async( dispatch_get_main_queue(), ^{ + [self showUpgradeChanges:changes]; + [activity cancelAlert]; + } ); + }]; + } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonContinue, nil]; +} + +- (void)performUpgradeAllWithCompletion:(void(^)(BOOL success, NSDictionary *changes))completion { + + [MPAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) { + NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; + fetchRequest.fetchBatchSize = 20; + + NSError *error = nil; + NSArray *elements = [moc executeFetchRequest:fetchRequest error:&error]; + if (!elements) { + err(@"Failed to fetch outdated sites for upgrade: %@", error); + completion(NO, nil); + return; + } + + NSMutableDictionary *elementChanges = [NSMutableDictionary dictionaryWithCapacity:[elements count]]; + for (MPElementEntity *element in elements) { + id oldContent = [element content]; + [element migrateExplicitly:YES]; + id newContent = [element content]; + + if (!(element.type & MPElementFeatureDevicePrivate) && (!oldContent || ![oldContent isEqual:newContent])) + [elementChanges setObject:@{ + MPElementUpgradeOldContentKey : oldContent, + MPElementUpgradeNewContentKey : newContent, + } forKey:element.name]; + } + + completion(YES, elementChanges); + }]; +} + +- (void)showUpgradeChanges:(NSDictionary *)changes { + + if (![changes count]) + return; + + NSMutableString *formattedChanges = [NSMutableString new]; + for (NSString *changedElementName in changes) { + NSDictionary *elementChanges = [changes objectForKey:changedElementName]; + id oldContent = [elementChanges objectForKey:MPElementUpgradeOldContentKey]; + id newContent = [elementChanges objectForKey:MPElementUpgradeNewContentKey]; + [formattedChanges appendFormat:@"%@: %@ -> %@\n", changedElementName, oldContent, newContent]; + } + + [PearlAlert showAlertWithTitle:@"Sites Upgraded" + message:PearlString( @"This upgrade has caused %d passwords to change.\n" + @"To make updating the actual passwords of these accounts easier, " + @"you can email a summary of these changes to yourself.", [changes count]) + viewStyle:UIAlertViewStyleDefault initAlert:nil + tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { + if (buttonIndex == [alert cancelButtonIndex]) + return; + + [PearlEMail sendEMailTo:nil subject:@"[Master Password] Upgrade Changes" body:formattedChanges]; + } cancelTitle:@"Don't Email" otherTitles:@"Send Email", nil]; +} + +- (NSFetchedResultsController *)fetchedResultsControllerByUses { + + return nil; +} + +- (void)configureFetchRequest:(NSFetchRequest *)fetchRequest { + + fetchRequest.fetchBatchSize = 10; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + + return 1; +} + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { + + return nil; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { + + return nil; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { diff --git a/MasterPassword/ObjC/iOS/MPElementListController.h b/MasterPassword/ObjC/iOS/MPElementListController.h index 53c1a0be..41f172fb 100644 --- a/MasterPassword/ObjC/iOS/MPElementListController.h +++ b/MasterPassword/ObjC/iOS/MPElementListController.h @@ -1,28 +1,22 @@ -// -// Created by lhunath on 2013-02-09. -// -// To change the template use AppCode | Preferences | File Templates. -// - - #import #import "MPElementListDelegate.h" -typedef enum { - MPSearchScopeAll, - MPSearchScopeOutdated, -} MPSearchScope; +#define MPElementListFilterNone @"MPElementListFilterNone" +#define MPElementListFilterOutdated @"MPElementListFilterOutdated" @interface MPElementListController : UITableViewController @property (weak, nonatomic) IBOutlet id delegate; -@property (readonly) NSFetchedResultsController *fetchedResultsController; +@property (strong, nonatomic) NSString *filter; + +@property (readonly) NSFetchedResultsController *fetchedResultsControllerByUses; +@property (readonly) NSFetchedResultsController *fetchedResultsControllerByLastUsed; @property (readonly) NSDateFormatter *dateFormatter; - (void)updateData; - (void)addElementNamed:(NSString *)siteName completion:(void (^)(BOOL success))completion; -- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath; +- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atTableIndexPath:(NSIndexPath *)indexPath; - (void)customTableViewUpdates; @end diff --git a/MasterPassword/ObjC/iOS/MPElementListController.m b/MasterPassword/ObjC/iOS/MPElementListController.m index c34c8648..f4111c84 100644 --- a/MasterPassword/ObjC/iOS/MPElementListController.m +++ b/MasterPassword/ObjC/iOS/MPElementListController.m @@ -1,10 +1,3 @@ -// -// Created by lhunath on 2013-02-09. -// -// To change the template use AppCode | Preferences | File Templates. -// - - #import "MPElementListController.h" #import "MPAppDelegate_Store.h" @@ -15,7 +8,8 @@ @implementation MPElementListController { - NSFetchedResultsController *_fetchedResultsController; + NSFetchedResultsController *_fetchedResultsControllerByUses; + NSFetchedResultsController *_fetchedResultsControllerByLastUsed; NSDateFormatter *_dateFormatter; } @@ -57,23 +51,47 @@ }]; } -- (NSFetchedResultsController *)fetchedResultsController { +- (NSFetchedResultsController *)fetchedResultsControllerByLastUsed { - if (!_fetchedResultsController) { - NSAssert([[NSThread currentThread] isMainThread], @"The fetchedResultsController must run on the main thread."); + if (!_fetchedResultsControllerByLastUsed) { + NSAssert([[NSThread currentThread] isMainThread], @"The fetchedResultsController must be accessed from 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 + fetchRequest.sortDescriptors = @[[[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector(lastUsed) ) ascending:NO]]; + [self configureFetchRequest:fetchRequest]; + _fetchedResultsControllerByLastUsed = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc sectionNameKeyPath:nil cacheName:nil]; - _fetchedResultsController.delegate = self; + _fetchedResultsControllerByLastUsed.delegate = self; } - return _fetchedResultsController; + return _fetchedResultsControllerByLastUsed; +} + +- (NSFetchedResultsController *)fetchedResultsControllerByUses { + + if (!_fetchedResultsControllerByUses) { + NSAssert([[NSThread currentThread] isMainThread], @"The fetchedResultsController must be accessed from the main thread."); + NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextForThreadIfReady]; + if (!moc) + return nil; + + NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; + fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector(uses_) ) ascending:NO] ]; + [self configureFetchRequest:fetchRequest]; + _fetchedResultsControllerByUses = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc + sectionNameKeyPath:nil cacheName:nil]; + _fetchedResultsControllerByUses.delegate = self; + } + + return _fetchedResultsControllerByUses; +} + +- (void)configureFetchRequest:(NSFetchRequest *)fetchRequest { + + fetchRequest.fetchLimit = 5; } - (NSDateFormatter *)dateFormatter { @@ -92,34 +110,33 @@ // Build predicate. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"user == %@", activeUser]; + + // Add query predicate. UISearchBar *searchBar = self.searchDisplayController.searchBar; if (searchBar) { NSString *query = [searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; if (!query) return; - // Add query predicate. predicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[predicate, [NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", query]]]; - - // Add scope predicate. - switch ((MPSearchScope) searchBar.selectedScopeButtonIndex) { - - case MPSearchScopeAll: - break; - case MPSearchScopeOutdated: - predicate = [NSCompoundPredicate andPredicateWithSubpredicates: - @[[NSPredicate predicateWithFormat:@"requiresExplicitMigration_ == YES"], predicate]]; - break; - } } - self.fetchedResultsController.fetchRequest.predicate = predicate; + + // Add filter predicate. + if ([self.filter isEqualToString:MPElementListFilterOutdated]) + predicate = [NSCompoundPredicate andPredicateWithSubpredicates: + @[[NSPredicate predicateWithFormat:@"requiresExplicitMigration_ == YES"], predicate]]; + // Fetch NSError *error; - if (![self.fetchedResultsController performFetch:&error]) + self.fetchedResultsControllerByLastUsed.fetchRequest.predicate = predicate; + self.fetchedResultsControllerByUses.fetchRequest.predicate = predicate; + if (![self.fetchedResultsControllerByLastUsed performFetch:&error]) err(@"Couldn't fetch elements: %@", error); - else - [self.tableView reloadData]; + if (![self.fetchedResultsControllerByUses performFetch:&error]) + err(@"Couldn't fetch elements: %@", error); + + [self.tableView reloadData]; } - (void)customTableViewUpdates { @@ -140,52 +157,32 @@ case NSFetchedResultsChangeInsert: dbg(@"%@ -- NSFetchedResultsChangeInsert:%@", NSStringFromSelector(_cmd), anObject); - [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; + [self.tableView insertRowsAtIndexPaths:@[ [self tableIndexPathForFetchController:controller indexPath:newIndexPath] ] + withRowAnimation:UITableViewRowAnimationAutomatic]; break; case NSFetchedResultsChangeDelete: dbg(@"%@ -- NSFetchedResultsChangeDelete:%@", NSStringFromSelector(_cmd), anObject); - [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; + [self.tableView deleteRowsAtIndexPaths:@[ [self tableIndexPathForFetchController:controller indexPath:indexPath] ] + withRowAnimation:UITableViewRowAnimationAutomatic]; break; case NSFetchedResultsChangeUpdate: dbg(@"%@ -- NSFetchedResultsChangeUpdate:%@", NSStringFromSelector(_cmd), anObject); - [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; + [self.tableView reloadRowsAtIndexPaths:@[ [self tableIndexPathForFetchController:controller indexPath:indexPath] ] + withRowAnimation:UITableViewRowAnimationAutomatic]; break; case NSFetchedResultsChangeMove: dbg(@"%@ -- NSFetchedResultsChangeMove:%@", NSStringFromSelector(_cmd), anObject); - [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] + [self.tableView deleteRowsAtIndexPaths:@[ [self tableIndexPathForFetchController:controller indexPath:indexPath] ] withRowAnimation:UITableViewRowAnimationAutomatic]; - [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] + [self.tableView insertRowsAtIndexPaths:@[ [self tableIndexPathForFetchController:controller indexPath:newIndexPath] ] withRowAnimation:UITableViewRowAnimationAutomatic]; break; } } -- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo - atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { - - switch (type) { - - case NSFetchedResultsChangeInsert: - dbg(@"%@ -- NSFetchedResultsChangeInsert:%d", NSStringFromSelector(_cmd), sectionIndex); - [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] - withRowAnimation:UITableViewRowAnimationAutomatic]; - break; - - case NSFetchedResultsChangeDelete: - dbg(@"%@ -- NSFetchedResultsChangeDelete:%d", NSStringFromSelector(_cmd), sectionIndex); - [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] - withRowAnimation:UITableViewRowAnimationAutomatic]; - break; - - case NSFetchedResultsChangeMove: - case NSFetchedResultsChangeUpdate: - Throw(@"Invalid change type for section changes: %d", type); - } -} - - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { dbg(@"%@ on %@", NSStringFromSelector(_cmd), [NSThread currentThread].name); @@ -195,16 +192,18 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - NSInteger integer = (NSInteger)[[self.fetchedResultsController sections] count]; - dbg(@"%@ = %d", NSStringFromSelector(_cmd), integer); - return integer; + return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - NSInteger integer = (NSInteger)[[[self.fetchedResultsController sections] objectAtIndex:(unsigned)section] numberOfObjects]; - dbg(@"%@%d = %d", NSStringFromSelector(_cmd), section, integer); - return integer; + if (section == 0) + return (NSInteger)[[[self.fetchedResultsControllerByLastUsed sections] lastObject] numberOfObjects]; + + if (section == 1) + return (NSInteger)[[[self.fetchedResultsControllerByUses sections] lastObject] numberOfObjects]; + + Throw(@"Unsupported section: %d", section); } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -213,50 +212,82 @@ if (!cell) cell = (UITableViewCell *) [[UIViewController alloc] initWithNibName:@"MPElementListCellView" bundle:nil].view; - [self configureCell:cell inTableView:tableView atIndexPath:indexPath]; + [self configureCell:cell inTableView:tableView atTableIndexPath:indexPath]; return cell; } -- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath { +- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atTableIndexPath:(NSIndexPath *)indexPath { - MPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath]; + MPElementEntity *element = [self elementForTableIndexPath:indexPath]; cell.textLabel.text = element.name; cell.detailTextLabel.text = PearlString(@"%d views, last on %@: %@", element.uses, [self.dateFormatter stringFromDate:element.lastUsed], [element.algorithm shortNameOfType:element.type]); } +- (NSIndexPath *)tableIndexPathForFetchController:(NSFetchedResultsController *)fetchedResultsController indexPath:(NSIndexPath *)indexPath { + + if (fetchedResultsController == self.fetchedResultsControllerByLastUsed) + return [NSIndexPath indexPathForRow:indexPath.row inSection:0]; + if (fetchedResultsController == self.fetchedResultsControllerByUses) + return [NSIndexPath indexPathForRow:indexPath.row inSection:1]; + + Throw(@"Unknown fetched results controller: %@, for index path: %@", fetchedResultsController, indexPath); +} + +- (NSIndexPath *)fetchedIndexPathForTableIndexPath:(NSIndexPath *)indexPath { + + return [NSIndexPath indexPathForRow:indexPath.row inSection:0]; +} + +- (MPElementEntity *)elementForTableIndexPath:(NSIndexPath *)indexPath { + + if (indexPath.section == 0) + return [self.fetchedResultsControllerByLastUsed objectAtIndexPath:[self fetchedIndexPathForTableIndexPath:indexPath]]; + + if (indexPath.section == 1) + return [self.fetchedResultsControllerByUses objectAtIndexPath:[self fetchedIndexPathForTableIndexPath:indexPath]]; + + Throw(@"Unsupported section: %d", indexPath.section); +} + - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [self.delegate didSelectElement:[self.fetchedResultsController objectAtIndexPath:indexPath]]; + [self.delegate didSelectElement:[self elementForTableIndexPath:indexPath]]; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return [[[self.fetchedResultsController sections] objectAtIndex:(unsigned)section] name]; + if (section == 0) + return @"Most Recently Used"; + + if (section == 1) + return @"Most Commonly Used"; + + Throw(@"Unsupported section: %d", section); } - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { - return [self.fetchedResultsController sectionIndexTitles]; + return @[@"recency", @"uses"]; } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { - return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index]; + return index; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { - NSManagedObjectContext *moc = self.fetchedResultsController.managedObjectContext; - [moc performBlock:^{ - MPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath]; + MPElementEntity *element = [self elementForTableIndexPath:indexPath]; + [element.managedObjectContext performBlockAndWait:^{ inf(@"Deleting element: %@", element.name); - [moc deleteObject:element]; + [element.managedObjectContext deleteObject:element]; + [element.managedObjectContext saveToStore]; #ifdef TESTFLIGHT_SDK_VERSION [TestFlight passCheckpoint:MPCheckpointDeleteElement]; diff --git a/MasterPassword/ObjC/iOS/MPElementListSearchController.m b/MasterPassword/ObjC/iOS/MPElementListSearchController.m index f90ae2c2..95512178 100644 --- a/MasterPassword/ObjC/iOS/MPElementListSearchController.m +++ b/MasterPassword/ObjC/iOS/MPElementListSearchController.m @@ -10,7 +10,6 @@ #import "MPMainViewController.h" #import "MPAppDelegate.h" - @interface MPElementListSearchController () @property (nonatomic) BOOL newSiteSectionWasNeeded; @@ -47,7 +46,7 @@ - (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar { - [((MPMainViewController *)self.delegate) performSegueWithIdentifier:@"MP_AllSites" sender:self]; + [((MPMainViewController *)self.delegate) performSegueWithIdentifier:@"MP_AllSites" sender:MPElementListFilterNone]; } - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { @@ -70,12 +69,7 @@ - (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller { - controller.searchBar.showsScopeBar = controller.searchBar.selectedScopeButtonIndex != MPSearchScopeAll; controller.searchBar.text = @""; - if (controller.searchBar.showsScopeBar) - controller.searchBar.scopeButtonTitles = @[@"All", @"Outdated"]; - else - controller.searchBar.scopeButtonTitles = nil; [UIView animateWithDuration:0.2f animations:^{ self.searchTipContainer.alpha = 0; @@ -91,8 +85,6 @@ controller.searchBar.prompt = nil; controller.searchBar.searchResultsButtonSelected = NO; - controller.searchBar.selectedScopeButtonIndex = MPSearchScopeAll; - controller.searchBar.showsScopeBar = NO; } - (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView { @@ -110,13 +102,6 @@ return NO; } -- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { - - [self updateData]; - return NO; -} - - - (void)updateData { [super updateData]; @@ -146,37 +131,39 @@ return NO; __block BOOL hasExactQueryMatch = NO; - [[self.fetchedResultsController sections] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - id sectionInfo = obj; - [[sectionInfo objects] enumerateObjectsUsingBlock:^(id obj_, NSUInteger idx_, BOOL *stop_) { - if ([[obj_ name] isEqualToString:query]) { - hasExactQueryMatch = YES; - *stop_ = YES; - } - }]; - if (hasExactQueryMatch) - *stop = YES; + id sectionInfo = [[self.fetchedResultsControllerByUses sections] lastObject]; + [[sectionInfo objects] enumerateObjectsUsingBlock:^(id obj_, NSUInteger idx_, BOOL *stop_) { + if ([[obj_ name] isEqualToString:query]) { + hasExactQueryMatch = YES; + *stop_ = YES; + } }]; + if (hasExactQueryMatch) + return NO; - return !hasExactQueryMatch; + sectionInfo = [[self.fetchedResultsControllerByLastUsed sections] lastObject]; + [[sectionInfo objects] enumerateObjectsUsingBlock:^(id obj_, NSUInteger idx_, BOOL *stop_) { + if ([[obj_ name] isEqualToString:query]) { + hasExactQueryMatch = YES; + *stop_ = YES; + } + }]; + if (hasExactQueryMatch) + return NO; + + return YES; } - (void)customTableViewUpdates { BOOL newSiteSectionIsNeeded = [self newSiteSectionNeeded]; - dbg(@"isNeeded:%d, wasNeeded:%d", newSiteSectionIsNeeded, self.newSiteSectionWasNeeded); - if (newSiteSectionIsNeeded && !self.newSiteSectionWasNeeded) { - dbg(@"%@ -- insertSection:%d", NSStringFromSelector(_cmd), [[self.fetchedResultsController sections] count]); - [self.tableView insertSections:[NSIndexSet indexSetWithIndex:[[self.fetchedResultsController sections] count]] + if (newSiteSectionIsNeeded && !self.newSiteSectionWasNeeded) + [self.tableView insertSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic]; - } - else if (!newSiteSectionIsNeeded && self.newSiteSectionWasNeeded) { - dbg(@"%@ -- deleteSection:%d", NSStringFromSelector(_cmd), [[self.fetchedResultsController sections] count]); - [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:[[self.fetchedResultsController sections] count]] + else if (!newSiteSectionIsNeeded && self.newSiteSectionWasNeeded) + [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic]; - } self.newSiteSectionWasNeeded = newSiteSectionIsNeeded; - dbg(@"wasNeeded->%d", self.newSiteSectionWasNeeded); } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -185,39 +172,37 @@ if ([self newSiteSectionNeeded]) ++sectionCount; - dbg(@"%@ (actually) = %d", NSStringFromSelector(_cmd), sectionCount); return sectionCount; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - NSUInteger fetchSections = [[self.fetchedResultsController sections] count]; - if (section < (NSInteger)fetchSections) + if (section < [super numberOfSectionsInTableView:tableView]) + // Section is one of super's sections. return [super tableView:tableView numberOfRowsInSection:section]; - dbg(@"%@%d = %d", NSStringFromSelector(_cmd), section, 1); return 1; } -- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath { +- (void)configureCell:(UITableViewCell *)cell inTableView:(UITableView *)tableView atTableIndexPath:(NSIndexPath *)indexPath { - NSUInteger fetchSections = [[self.fetchedResultsController sections] count]; - if (indexPath.section < (NSInteger)fetchSections) - [super configureCell:cell inTableView:tableView atIndexPath:indexPath]; - - else { - // "New" section - NSString *query = [self.searchDisplayController.searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; - cell.textLabel.text = query; - cell.detailTextLabel.text = PearlString(@"Add new site: %@", - [MPAlgorithmDefault shortNameOfType:[[MPAppDelegate get].activeUser defaultType]]); + if (indexPath.section < [super numberOfSectionsInTableView:tableView]) { + // Section is one of super's sections. + [super configureCell:cell inTableView:tableView atTableIndexPath:indexPath]; + return; } + + // "New" section + NSString *query = [self.searchDisplayController.searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + cell.textLabel.text = query; + cell.detailTextLabel.text = PearlString(@"New site: %@", + [MPAlgorithmDefault shortNameOfType:[[MPAppDelegate get].activeUser defaultType]]); } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSUInteger fetchSections = [[self.fetchedResultsController sections] count]; - if (indexPath.section < (NSInteger)fetchSections) { + if (indexPath.section < [super numberOfSectionsInTableView:tableView]) { + // Section is one of super's sections. [super tableView:tableView didSelectRowAtIndexPath:indexPath]; return; } @@ -240,18 +225,18 @@ - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - NSUInteger fetchSections = [[self.fetchedResultsController sections] count]; - if (section < (NSInteger)fetchSections) + if (section < [super numberOfSectionsInTableView:tableView]) + // Section is one of super's sections. return [super tableView:tableView titleForHeaderInSection:section]; - return @""; + return @"Create"; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { - NSUInteger fetchSections = [[self.fetchedResultsController sections] count]; - if (indexPath.section < (NSInteger)fetchSections) + if (indexPath.section < [super numberOfSectionsInTableView:tableView]) + // Section is one of super's sections. [super tableView:tableView commitEditingStyle:editingStyle forRowAtIndexPath:indexPath]; } diff --git a/MasterPassword/ObjC/iOS/MPMainViewController.m b/MasterPassword/ObjC/iOS/MPMainViewController.m index aa9949a5..11bfb20c 100644 --- a/MasterPassword/ObjC/iOS/MPMainViewController.m +++ b/MasterPassword/ObjC/iOS/MPMainViewController.m @@ -8,10 +8,8 @@ #import "MPMainViewController.h" #import "MPAppDelegate.h" -#import "MPAppDelegate_Key.h" #import "MPAppDelegate_Store.h" #import "MPElementListAllViewController.h" -#import "MPElementListSearchController.h" @interface MPMainViewController() @@ -50,8 +48,10 @@ if ([[segue identifier] isEqualToString:@"MP_ChooseType"]) ((MPTypeViewController *)[segue destinationViewController]).delegate = self; - if ([[segue identifier] isEqualToString:@"MP_AllSites"]) - ((MPElementListAllViewController *)[((UINavigationController *)[segue destinationViewController]) topViewController]).delegate = self; + if ([[segue identifier] isEqualToString:@"MP_AllSites"]) { + ((MPElementListAllViewController *)[segue destinationViewController]).delegate = self; + ((MPElementListAllViewController *)[segue destinationViewController]).filter = sender; + } } - (void)viewDidLoad { @@ -262,10 +262,10 @@ if ([[MPiOSConfig get].helpHidden boolValue]) { self.contentContainer.frame = CGRectSetHeight(self.contentContainer.frame, self.view.bounds.size.height - 44 /* search bar */); - self.helpContainer.frame = CGRectSetY(self.helpContainer.frame, self.view.bounds.size.height - 20); + self.helpContainer.frame = CGRectSetY(self.helpContainer.frame, self.view.bounds.size.height - 20 /* pull-up */); } else { self.contentContainer.frame = CGRectSetHeight(self.contentContainer.frame, 225); - self.helpContainer.frame = CGRectSetY(self.helpContainer.frame, 246); + [self.helpContainer setFrameFromCurrentSizeAndParentPaddingTop:CGFLOAT_MAX right:0 bottom:0 left:0]; } } @@ -690,9 +690,7 @@ - (IBAction)searchOutdatedElements { - self.searchDisplayController.searchBar.selectedScopeButtonIndex = MPSearchScopeOutdated; - self.searchDisplayController.searchBar.searchResultsButtonSelected = YES; - [self.searchDisplayController.searchBar becomeFirstResponder]; + [self performSegueWithIdentifier:@"MP_AllSites" sender:MPElementListFilterOutdated]; } - (IBAction)closeAlert { diff --git a/MasterPassword/ObjC/iOS/MPSetupViewController.h b/MasterPassword/ObjC/iOS/MPSetupViewController.h index 19160c17..950f2875 100644 --- a/MasterPassword/ObjC/iOS/MPSetupViewController.h +++ b/MasterPassword/ObjC/iOS/MPSetupViewController.h @@ -21,6 +21,7 @@ @interface MPSetupViewController : UIViewController @property (weak, nonatomic) IBOutlet UISwitch *cloudSwitch; +@property (weak, nonatomic) IBOutlet UISwitch *rememberLoginSwitch; - (IBAction)close:(UIBarButtonItem *)sender; diff --git a/MasterPassword/ObjC/iOS/MPSetupViewController.m b/MasterPassword/ObjC/iOS/MPSetupViewController.m index 2c85fc34..3977804f 100644 --- a/MasterPassword/ObjC/iOS/MPSetupViewController.m +++ b/MasterPassword/ObjC/iOS/MPSetupViewController.m @@ -30,6 +30,8 @@ if (self.cloudSwitch && [[MPiOSConfig get].iCloudDecided boolValue]) self.cloudSwitch.on = [MPAppDelegate get].storeManager.cloudEnabled; + if (self.rememberLoginSwitch) + self.rememberLoginSwitch.on = [[MPiOSConfig get].rememberLogin boolValue]; } - (void)viewWillDisappear:(BOOL)animated { @@ -40,6 +42,8 @@ [MPiOSConfig get].iCloudDecided = @YES; [MPAppDelegate get].storeManager.cloudEnabled = self.cloudSwitch.on; } + if (self.rememberLoginSwitch) + [MPiOSConfig get].rememberLogin = @(self.rememberLoginSwitch.on); } - (IBAction)close:(UIBarButtonItem *)sender { diff --git a/MasterPassword/ObjC/iOS/MPUnlockViewController.m b/MasterPassword/ObjC/iOS/MPUnlockViewController.m index e6325c6b..243d966f 100644 --- a/MasterPassword/ObjC/iOS/MPUnlockViewController.m +++ b/MasterPassword/ObjC/iOS/MPUnlockViewController.m @@ -212,7 +212,7 @@ if (!moc) return; - self.tip.text = @"Tap and hold to delete or reset."; + self.tip.text = @"Tap and hold to delete or reset user."; __block NSArray *users = nil; [moc performBlockAndWait:^{ @@ -266,15 +266,13 @@ avatar.backgroundColor = [UIColor clearColor]; } options:0]; [avatar onSelect:^(BOOL selected) { - if (selected) { - if ((self.selectedUser = user)) - [self didToggleUserSelection]; - else - [self didSelectNewUserAvatar:avatar]; - } else { + if (!selected) { self.selectedUser = nil; [self didToggleUserSelection]; - } + } else if ((self.selectedUser = user)) + [self didToggleUserSelection]; + else + [self didSelectNewUserAvatar:avatar]; } options:0]; [self.avatarToUserOID setObject:NilToNSNull([user objectID]) forKey:[NSValue valueWithNonretainedObject:avatar]]; diff --git a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard index f8fee226..14e9bab1 100644 --- a/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard +++ b/MasterPassword/ObjC/iOS/MainStoryboard_iPhone.storyboard @@ -705,10 +705,6 @@ Your passwords will be AES-encrypted with your master password. - - All - Outdated - @@ -1006,7 +1002,7 @@ L4m3P4sSw0rD - + @@ -1101,7 +1097,7 @@ L4m3P4sSw0rD - + @@ -1254,11 +1250,11 @@ L4m3P4sSw0rD - - + - - The passwords created by this app are not stored anywhere but created on the spot. - -It is vital that you + - + + + + + + + + + . + +You don't need to remember any password generated by this app, but + + + + + + + - + - + + - + @@ -2122,28 +2126,29 @@ It is vital that you - -Cgo - + and that it is secure. + +Don't reuse an old password! +Don't give out your master password. +A small nonsense sentence is a great password. - - Don't reuse an old password! - + + - Don't give out your master password, no matter how close you think you are with the other person. + -You can make passwords for all sorts of things, like email addresses, sites or real-world objects like your bike lock: if you can name it, you can get a password for it. +You can make passwords for anything, like email addresses, sites or real-world things like a bike lock: if you can name it, you can get a password for it. @@ -2160,13 +2165,13 @@ You can make passwords for all sorts of things, like email addresses, sites or r - + - + @@ -2175,7 +2180,7 @@ You can make passwords for all sorts of things, like email addresses, sites or r - + @@ -2527,7 +2532,66 @@ You can make passwords for all sorts of things, like email addresses, sites or r - + + + + + + + + + + + + + + + + + + + + + + + + The right balance between security and convenience is often very personal. + +To make getting to your passwords faster, you can remain logged in after you close Master Password. This allows you to skip having to log in the next time. + +However, it means that anyone who finds your device unlocked can do the same. + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2567,6 +2631,7 @@ You can make passwords for all sorts of things, like email addresses, sites or r + @@ -2588,6 +2653,7 @@ You can make passwords for all sorts of things, like email addresses, sites or r + @@ -2700,6 +2766,7 @@ You can make passwords for all sorts of things, like email addresses, sites or r + @@ -2742,7 +2809,7 @@ You can make passwords for all sorts of things, like email addresses, sites or r + - \ No newline at end of file diff --git a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj index 7a652394..af57d1de 100644 --- a/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -38,6 +38,8 @@ DA4DA1DA1564471F00F6F596 /* libuicolor-utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6325D1486805C0075AEA5 /* libuicolor-utilities.a */; }; DA5A09DF171A70E4005284AB /* play.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5A09DD171A70E4005284AB /* play.png */; }; DA5A09E0171A70E4005284AB /* play@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5A09DE171A70E4005284AB /* play@2x.png */; }; + DA5A09EA171BB0F7005284AB /* unlocked.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5A09E8171BB0F7005284AB /* unlocked.png */; }; + DA5A09EB171BB0F7005284AB /* unlocked@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA5A09E9171BB0F7005284AB /* unlocked@2x.png */; }; DA5BFA49147E415C00F98B1E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA48147E415C00F98B1E /* UIKit.framework */; }; DA5BFA4B147E415C00F98B1E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DA5BFA4D147E415C00F98B1E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4C147E415C00F98B1E /* CoreGraphics.framework */; }; @@ -1036,6 +1038,8 @@ DA497B9715E8C90E00B52167 /* libGoogle+.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libGoogle+.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DA5A09DD171A70E4005284AB /* play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = play.png; sourceTree = ""; }; DA5A09DE171A70E4005284AB /* play@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "play@2x.png"; sourceTree = ""; }; + DA5A09E8171BB0F7005284AB /* unlocked.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = unlocked.png; sourceTree = ""; }; + DA5A09E9171BB0F7005284AB /* unlocked@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "unlocked@2x.png"; sourceTree = ""; }; DA5BFA44147E415C00F98B1E /* MasterPassword.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MasterPassword.app; sourceTree = BUILT_PRODUCTS_DIR; }; DA5BFA48147E415C00F98B1E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; DA5BFA4A147E415C00F98B1E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -2206,6 +2210,8 @@ DABD360D1711E29400CF925C /* Media */ = { isa = PBXGroup; children = ( + DA5A09E8171BB0F7005284AB /* unlocked.png */, + DA5A09E9171BB0F7005284AB /* unlocked@2x.png */, DA5A09DD171A70E4005284AB /* play.png */, DA5A09DE171A70E4005284AB /* play@2x.png */, DABD360E1711E29400CF925C /* Automaton */, @@ -4596,6 +4602,8 @@ DABD3FCF1714F45C00CF925C /* identity@2x.png in Resources */, DA5A09DF171A70E4005284AB /* play.png in Resources */, DA5A09E0171A70E4005284AB /* play@2x.png in Resources */, + DA5A09EA171BB0F7005284AB /* unlocked.png in Resources */, + DA5A09EB171BB0F7005284AB /* unlocked@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MasterPassword/Resources/Media/unlocked.png b/MasterPassword/Resources/Media/unlocked.png new file mode 100644 index 0000000000000000000000000000000000000000..58b6296206ced27d1bc71dd8cebe56315335d779 GIT binary patch literal 4109 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 QZ~=g(s-8-{vTfY|0R4KBa{vGU literal 0 HcmV?d00001 diff --git a/MasterPassword/Resources/Media/unlocked@2x.png b/MasterPassword/Resources/Media/unlocked@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6d4945069df73cf299b660325480091206612697 GIT binary patch literal 15997 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 AasU7T literal 0 HcmV?d00001 diff --git a/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Preview.pdf b/MasterPassword/Resources/Raw/Large Icons.vdesigner/QuickLook/Preview.pdf index 14fb92935fa7a0993b779d9d60fb44b9cd95b3e6..87739826f0592a5faa6d2bb7f53fb1d20252ac61 100644 GIT binary patch delta 17535 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 q4-poE*noPt=2zKq+oIib_kAYDIdH zqEZ411OY)n5eN`^3nf5E{_OpqG0r#_=W1Q7i?!bIz4MuKevh6&=3YZSWS}MYr>Lf= z(Xj_AR?k@+##jQd)hh-f#CL$c*cC0o^z+!WAcQin`ucXuQYT=N3u0z_2`YvW##TS` zYU#HXh64D0N?EjZ`)*~2k4EZ?Dd4a3H+lAZ#bpR?eSpwkm+V{(GZ*!iJLsYr14vw)N4gb4 z2+Ru!lYA}e3WYXpvw@9Gl8~2oN#zx=+)>=V)pG87cs(1~pMc1`B}K5mBJ?f02iSyh zQPh8YZvQovV8Uh4K7v%a2Xtm{UhCmLb*9sETIWo^^rQmexs!}kaC*j!W=r%D3cQ$0 z=biP?`NM+KUo7-;BdZdUAM1-xCwANdB(I!VTRc-oP!m_1d7o+_CfTflq*CmxiPm)N z;hA(_#3@jH2Ku>Ces0;J$VRo+w3xOA+u{5v>oL&C`*GLpLH(6LV@s+|Uy;VN;q70< z&fE}Mc6JZ^KI~cBK8i#_vh{&(|Gp+mz$%MBtm)~g z-6@>f&~ZCY2APZ1M`Z$3{DpAmUcB(kz-qIX)Qbs0t;T3(%O@1@<$5GKU5pFMrngy_nhLmm75jI16&=+ zGF(;3)N_wC1nLZbW9$YFIo%JcuBpqN?!6BaedOsetnZwJ<@<0UyF`l@21I;Z$)j?| zwsfh6dAof?14!$cCzWQFs55i;v!hHq6?etQF9H`y1CkTXB zuYUgNajSm)5pEJ}BV1}cYQP3WkkQ)6?TiZB5cRv#m=e^W)H-Cww+=fg?#K2{gE0mCu~!iQ5Nx zw_`;h1FdL(ITw3>7RU!={;yj8M>JFQCLx=Kr^Ex#$F7X6foLMGn}8;dPxUlt9P59c zwAFvC6#i<>F`+v!*N0#KVZ(PEycpivs9Xv*aE{NvCFshD$?CFxp(ifl;a~U-g(u_s zBYKXS$XE5ecwVNd@(Z#a`v8xy_**$4V?O5*o(A4!S?6NeKo}s3zOfS8wJ>$+UM+u; zNYL`1674@lDo|;p{H&@GjnH^v=I~~l{>yaJq_%~#dRZR9qt}W*-RG}$mc%=osuI)y zjiyzvuNLHdyHm$+Zyc`vE${&Xnw$62yDF<=KjCbc9~ax;j29?w=s&K z&T}e~io(RIgA(+OIlpERh_ADH@{4&EyqFAvW-0p~v^ez*%4)Cy%IqQ*o*jWP8${Z2 z_+-2XNE5%-;7*T=UY&fuB$Gg-#%RVSl9h)8(?Gn7LpDL%8w@M_a6xT!#5wH&vQjHg z!7uN)GasUpc!As*|D+x6SvX%cSX|%?TSuXzXF{{1M^;Hfk+;vctB3#Ur@lmCo(}F zd_AqY7#7{~lvYs72AWFQ!0I3Rb`Sj6#GB;(cLvg$UGBU?y)tQ>=B-N#aceUUqxQI| z037Z%+sIn?1iZT`i02)vtNk&$#QkVO{)wk+RlG<>{B!eIUDLNgPGVFN{Mif}K-60~ zOe}ie%KXwZWIH$bG;oc7-qkfK1RT}>oi}PD?s4R%c%-tj^cZwDN7g*!>yT3ofuv)z zP+(&YiRv^@A^8|6L*MI@1ZUqbR`Tnez7c6ghS9foqbbGnsaWLkaQ*Mcs|May9!}W4 z`EDrX`K}pL4f9kgIx)N;>sD zE;ZkWtY}{Xk4~VaAo4Yka4Ruwx1|krhW5?|vl!av&VjZpxPKj^jYTRjec3?DjjcVu z^zEYnF4hlhE}wcR6*D1?B)2R>}U1J>PDPJlWizv!7rS z)c)*^9a|hvs`>GXHguMu?LhUqv=v%G&b;Vuv#M5ovZw>A=p9QB}^d? zC{@Ys= zYOe7Z7}m6gXEo#NG%VAvO-9RL#u9a@l92IrluwLQ7=AkSLum=J7!Yj@(9IE z5wD}Z16PW{Ogbp%l?5>vK41(F{jr6;vO3YdHzr zi>Ui|)V+}9B{;m%zY8#=O>SU_v_0Rx{!J23#kM4l&M`rH!p7(2J`o6{#$HoE6JG5^ zvE36wSg-M_%Rx`8d)&Q5`QZJ5y=M9u5VDb=eymZwT8)fY9DiT`4=543Y!aI z`u=H}VgvI`K!&b&cO{~3lg%MfA|T~XBjSwxRNa`-%UHpSax|5V4jPlj+#(4Dwd9`e zL7&L~J>Ph8KtV|zJl$~I?wOd2|SUs@NZ z7T~3;*;mDZT|+VSdm2_>n$EzhQ)uh7RIF&)-5`#O&X4^wXCXnc{>H>d1U%TT#a7`5 ztjvQY@x4;;&f>ApneKPb)g(b$Kyo*W5E#`e}=*P-!8< zNz)3<$ZY-+n2YQ!31}^|xT51#{OgYBQ`JOfi5S27Hyd4x=L!7x3d{lgD^_>Y5m(0G z%J8?=(4;J>#1hNjl)T_rT(z60Qvae;jBZUConLj>RvYc#Dv~UdQky24x+z}+uY0cN zzq|q4;0*j15ML;nj4>e&63LRmJA@EK9J8y#IOT?>%>@kA+szF3y># z4@{DR!xoLXrsxhWx6qskSx)ZXQ{ADB5>6gW{e{HQmoS(Dz7A}0pF+E{Q)+tB&SZxzd`%o zO*;?zG}i*Vx5jAAp5TK~1RHn|sDjF6Et}N*sPuU8>)4g_wd4ld~GK*_$NZVN?I~B%(EyPJ0Igmprn=2rK#RYwxwE&C7?flpvcy z4>8ownBQ!G511?dZ_oH|a!QXtNTug!34=mvpD5LzS%+yXdrLPstKs-8D|Gh}FhAg^ zN?qMx29rx>DM}D!Vi5|-%9~}@F8BxnAz%v|NNnU{=oP)A{C(g4lK8V>qbtpserJ~B zF6kX1552wdWXXhi@_fI@b*^ei9E8|M_K9n%9Jr) zl`a4u#XyapBl#)SpR@cun@}zO55HpSSjC-S&@T|3EGj( z7||w!;aAh@vbv0?=YB*EfB%$5EaRTMd*MqeLG=_A#`#7K8sR!ogSHx1N7zN_I7K)T z@9_DTu>?l!WQ}?29+?r&L&T&=lA760CE+w?XvD=i+~ff8J+Rn~urP)dH7D48S&9rup2t1O9Q-axY?8L|b29v-Mm z^^Gb&7WaJw(`AaXNFKtc44vsLoMseVz^(ZBxY?|u+{6$!dYdq4iG+rM&@=PEXs|ubECE|*z zsYF|UtiVM?31f3-b%20Qvf7Psng~_UbDuCN7`7VvRhM$z8j-8t%;nc^fRyADf@4l?d1{>l+|oG&V3|Og%>E(@fpO z!r8jYxU`^B8(sOtO~q?d&tx*zbm^M)<#94-waa8|%YFp$5)u}EjX^GHeZ|VCt1v>k!0!&}%{Wcldkn|mCR3;%ztIA@Av|d6I0(L+m$GXn`+buZf z{15hTeoXFsIGCOSrgHRb2{33>FmlAQtd9SH*W6y@Bn`eH9eN0s2{6uj#}khK$85EnghvC0u%Uv>B7B|#`8MI>=-vk zB~WOvXf6V?{GGPCr`ZnUM2^bk)~Bd0hVS?k#in|vFqD?i8l{KNrY~Z}<##Q^4M);B zyMMKVqub=gt9v19WLfo63I;2%OB~*s0P926@RBo#LGk6vbL|rfNz|rEIjA!JCn%P~ zsXKgsnx9eZs^_8;*uWqXAAyto34Kw?*jjCFYp;taOw41Lsy#X78&cHlABI0rx0e|< zaACL>QhFTQ``&mE&O^|sVjLP1|9C*~$8y%C{_c~xA%Alc8ZFEKrD0fp+2XlGl9fz~ zZziz2YY^RDsne!m!UpDK`-Rjv$-i7!VukZ#L!Cu_1o zwq{hX^ZdM?2RQy4{QhfH|G*lCl8zoFs3dx8#hS$b=(#+m2@CUQ;c(zr0vgKU7?0AT z$)szg*6s98dsYMPUK8gM;0rkP?OKrRf=PCo!G$D0{9_1$c`+u7W9^(N{%{cvvyPCB zIo(Bx4K#8Cvj69u1hG8knHaKEZ;%zjiQ>N*VPm#AMePY^P+};IG-Xhk713y0L_kQt zKx4+OBF-wA$DRGl|Iz SK|TZwddp1^N?cGVd+0w7h&t{7 delta 2220 zcmV;d2vhg!ssW0X0kD=llVA@te*>S^byTs5-IxHQJpO;vr2ul4`kc41M|0+|S+eLA zuspMkoa65}`Mm;=Fj)Mc7k<~M+Yu}q?_dMxRbTXo_NXl0P$bHO4BO(|LX5gbF^~=I zJ6*QCQHcib;GRM54st;RV2`hS&<66du*f<806+bD0CfNq08jxy1ppKPldC#He+Rt) zcsIp;UFb=zfNPK3n+U>@=(1dPOJlKjT0e-wh=H0E!R6p^yB_S}#1Fwh$lJk?W6o z0Q5NI!5)Xd;(7XiKDppf2845Z{d@kWzBwK7*QqoCX=WHBDpiz+Mgh^m{uhnGM+c9U z!5PO>&;u##S_d=fGX0uDz_p~Ve#;>(f?{?#w<9(ou;ruRlISp?15;1&79=dYlk4?&7xc*xJ;&tJzp{d%0R#Q%yIJ~WpV-9>ALN; z>M2EB3cmjUu2O#^Knd{f zPxzsHAPMQ=%^(l2*kSy0*VJdd0C#C29r8WD&-0)QD{=0BAFesa)MWG99XJ4-TzZq9 zzg+j=9C!SBjL-mXIO=oH)8F&#J?H`^oREHF&wT#?^}6=slg$8DXVFaSH>3~Q^YK#jj7fuBx)KKcA} z$-y)M+h;ub^OKP}M3bXP6MuKZ`3Ue&gu%}q9?}Q?Nki8^=dU@S4&^RA`;Sla$G>yU z09X^L=kdpW{{WZ&0I%=>lg%Bo!S?Ih{QCYh0C}UHeLXqI>7Visy#O@Kqnzj0C!h15 z^WK0t-x7GMK=786cdq!GSg_Fai#08AsA^X!ZEm<35u-Th?0q7olXE-H}01V7Y z00kLhNyq>w8;K_al6V=Q50Snue%GE3@I==>9q>dk{6X=W?}eb#=g)_Tqh4Lr*x;pNLUzc>K+;ru=EPvgeDZ?Aks)o!&Ql6jhbj|w%mg``I835!nC zRG6dV8|RqKcPdN9+~{fO8lfDl(e?!py4FG(z@yGr_SKsx@PvmF= zj_@<>@PCE*{{Wa4nZf@6uSmLop1$IMI`x>2xcq&89x?0sbIkxwC+Wz?{{X1^e=d6* z13(^M@jv5lfW8sw>vQ7WSPe$zHj_>8=A4Ur;tf&8arSE!b!cH``C9t%t?d&$%*}-$ zAD`YdfB3)ghvV$>==y5hco)F81)@48l{BB)dZoVMkL}H21anNXFZ#Q^z_TEaSoGDyRGu1*ptgUuu1V@G3(0Qg(t7wv1}KNU|uhkgm^QrcQb z&2KM`b$dc?n^bLo#P=G8x2x(B ziSKnSR%x$qE@W}@G_%|@$iaFlTpn4I|W7FKw2VopZ5CK#SPz1C9Pys*%leRiSe|4Y_3izj^ zKBHlBiiNi$j-IM|de8^w-lyXqi2nc&Qu9dBwB0vWu@X-9E2zbBzQ#$MvjmdfNZx2S zmT?4!hi2I57=i)w=A+<`iJutt__aSC>bIJdP|Lc@Nr?@vho=M7S!r<*ZxgW2`Q2o> zlP7%4FaQVG-wVHITTMPYJ!g{5M%|rb@7K_EQ>fJ+bC2(F^->4^ZfhJ1SzPS zwV#D{I)v>b+o2@nAHKX3uwUy`+y!WeGmEd>p&j2r|7oUNUE`@ u+A+|7o_+cblmWIBD8Lw?1(UH4Pz)MTPgN8EpaIYd09vzQ4^;vK1OM6DdQ-3f diff --git a/MasterPassword/Resources/Raw/Large Icons.vdesigner/VectorDesigner b/MasterPassword/Resources/Raw/Large Icons.vdesigner/VectorDesigner index a4b9441f2a84d69e8da9ab005c563b733cfc22f7..7b750ff54823303151f76092e9db331827a062b8 100644 GIT binary patch delta 9357 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 delta 6222 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