2 // PasscodeViewController.m
5 // Created by Mike Mayo on 10/26/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "PasscodeViewController.h"
10 #import "UIViewController+Conveniences.h"
11 #import "UIColor+MoreColors.h"
13 #import "PasscodeLockViewController.h"
14 #import "SettingsViewController.h"
15 #import <QuartzCore/QuartzCore.h>
17 #import "RootViewController.h"
18 #import "OpenStackAccount.h"
19 #import "OpenStackAppDelegate.h"
21 @implementation PasscodeViewController
23 @synthesize mode, passcodeLockViewController, settingsViewController, rootViewController;
25 #pragma mark - View lifecycle
27 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
28 return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
33 simplePasscodeOn = [[Keychain getStringForKey:@"passcode_lock_simple_passcode_on"] isEqualToString:@"YES"];
34 passcodeLockOn = [[Keychain getStringForKey:@"passcode_lock_passcode_on"] isEqualToString:@"YES"];
35 eraseData = [[Keychain getStringForKey:@"passcode_lock_erase_data_on"] isEqualToString:@"YES"];
37 if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
44 - (void)viewWillAppear:(BOOL)animated {
45 [super viewWillAppear:animated];
47 enterPasscodeTextField = [self allocAndInitPasscodeTextField];
48 setPasscodeTextField = [self allocAndInitPasscodeTextField];
49 confirmPasscodeTextField = [self allocAndInitPasscodeTextField];
51 tableViews = [[NSMutableArray alloc] init];
52 textFields = [[NSMutableArray alloc] init];
53 squares = [[NSMutableArray alloc] init];
55 if (mode == kModeSetPasscode || mode == kModeChangePasscode) {
56 // we're setting the passcode, so add possibly all of the table views
58 enterPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:enterPasscodeTextField];
59 [tableViews addObject:enterPasscodeTableView];
60 [textFields addObject:enterPasscodeTextField];
61 if (simplePasscodeOn) {
62 [squares addObject:[self createSquares]];
63 for (int i = 0; i < [[squares lastObject] count]; i++) {
64 [enterPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]];
68 setPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:setPasscodeTextField];
69 [tableViews addObject:setPasscodeTableView];
70 [textFields addObject:setPasscodeTextField];
71 if (simplePasscodeOn) {
72 [squares addObject:[self createSquares]];
73 for (int i = 0; i < [[squares lastObject] count]; i++) {
74 [setPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]];
77 confirmPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:confirmPasscodeTextField];
78 [tableViews addObject:confirmPasscodeTableView];
79 [textFields addObject:confirmPasscodeTextField];
80 if (simplePasscodeOn) {
81 [squares addObject:[self createSquares]];
82 for (int i = 0; i < [[squares lastObject] count]; i++) {
83 [confirmPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]];
87 enterPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:enterPasscodeTextField];
88 [tableViews addObject:enterPasscodeTableView];
89 [textFields addObject:enterPasscodeTextField];
90 if (simplePasscodeOn) {
91 [squares addObject:[self createSquares]];
92 for (int i = 0; i < [[squares lastObject] count]; i++) {
93 [enterPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]];
98 [self.view addSubview:[tableViews objectAtIndex:0]];
100 // shift any extra table views away
101 for (int i = 1; i < [tableViews count]; i++) {
102 UITableView *tableView = [tableViews objectAtIndex:i];
103 tableView.frame = CGRectMake(tableView.frame.origin.x + viewWidth, tableView.frame.origin.y, tableView.frame.size.width, tableView.frame.size.height);
104 [self.view addSubview:tableView];
107 if (!simplePasscodeOn) {
108 if (tableIndex == [tableViews count] - 1) {
109 [self addDoneButton];
111 [self addNextButton];
115 [[textFields objectAtIndex:0] becomeFirstResponder];
116 [[tableViews objectAtIndex:0] reloadData];
117 [[textFields objectAtIndex:[tableViews count] - 1] setReturnKeyType:UIReturnKeyDone];
119 // table looks all screwy on iPad at first, so shuffle around to get the drawing right
120 // yes, i know this is a dirty hack.
121 if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
122 if ([tableViews count] > 1) {
123 [self moveToNextTableView];
124 [self moveToPreviousTableView];
126 UITableView *tv = [tableViews objectAtIndex:0];
127 tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, 768.0, 960.0);
132 #pragma mark - Memory management
136 [enterPasscodeTextField release];
137 [setPasscodeTextField release];
138 [confirmPasscodeTextField release];
139 [tableViews release];
140 [textFields release];
142 [passcodeLockViewController release];
143 [settingsViewController release];
144 [rootViewController release];
148 #pragma mark - Internal
150 - (UITextField *)allocAndInitPasscodeTextField {
151 UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(29.0, 13.0, 271.0, 24.0)];
152 textField.text = @"";
153 textField.textColor = [UIColor value1DetailTextLabelColor];
154 textField.secureTextEntry = YES;
155 textField.delegate = self;
156 textField.keyboardAppearance = UIKeyboardAppearanceAlert;
160 - (UIView *)passwordHeaderViewForTextField:(UITextField *)textField {
161 if (simplePasscodeOn) {
162 textField.keyboardType = UIKeyboardTypeNumberPad;
163 // hide the text field and add it to the view. we'll use the squares, but we need a text field
164 textField.hidden = YES;
165 [self.view addSubview:textField];
167 textField.keyboardType = UIKeyboardTypeDefault;
168 textField.returnKeyType = UIReturnKeyNext;
171 UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, viewWidth, 70.0)] autorelease];
172 UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 27.5, viewWidth, 30.0)];
173 headerLabel.textColor = [UIColor tableViewHeaderColor];
174 headerLabel.backgroundColor = [UIColor clearColor];
175 headerLabel.textAlignment = UITextAlignmentCenter;
176 headerLabel.font = [UIFont boldSystemFontOfSize:17.0];
177 headerLabel.shadowOffset = CGSizeMake(0, 1.0);
178 headerLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
180 if ([textField isEqual:enterPasscodeTextField]) {
181 NSString *text = @"1 Failed Passcode Attempt";
182 CGSize size = [text sizeWithFont:[UIFont boldSystemFontOfSize:14.0]];
183 failedAttemptsView = [[UIView alloc] initWithFrame:CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0)];
184 failedAttemptsLabel = [[UILabel alloc] initWithFrame:CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0)];
185 failedAttemptsLabel.backgroundColor = [UIColor clearColor];
186 failedAttemptsLabel.textColor = [UIColor whiteColor];
187 failedAttemptsLabel.text = text;
188 failedAttemptsLabel.font = [UIFont boldSystemFontOfSize:14.0];
189 failedAttemptsLabel.textAlignment = UITextAlignmentCenter;
190 failedAttemptsLabel.shadowOffset = CGSizeMake(0, -1.0);
191 failedAttemptsLabel.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];
192 failedAttemptsView.layer.cornerRadius = 14;
193 failedAttemptsView.layer.borderWidth = 1.0;
194 failedAttemptsView.layer.borderColor = [[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.25] CGColor];
196 failedAttemptsLabel.hidden = YES;
197 failedAttemptsView.hidden = YES;
199 CAGradientLayer *gradient = [CAGradientLayer layer];
200 gradient.frame = failedAttemptsView.bounds;
201 gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.714 green:0.043 blue:0.043 alpha:1.0] CGColor],
202 (id)[[UIColor colorWithRed:0.761 green:0.192 blue:0.192 alpha:1.0] CGColor], nil];
203 [failedAttemptsView.layer insertSublayer:gradient atIndex:1];
204 failedAttemptsView.layer.masksToBounds = YES;
206 [headerView addSubview:failedAttemptsView];
207 [headerView addSubview:failedAttemptsLabel];
209 [failedAttemptsView release];
210 [failedAttemptsLabel release];
211 } else if ([textField isEqual:setPasscodeTextField]) {
212 passcodeConfirmationWarningLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 146.5, viewWidth, 30.0)];
213 passcodeConfirmationWarningLabel.textColor = [UIColor tableViewHeaderColor];
214 passcodeConfirmationWarningLabel.backgroundColor = [UIColor clearColor];
215 passcodeConfirmationWarningLabel.textAlignment = UITextAlignmentCenter;
216 passcodeConfirmationWarningLabel.font = [UIFont systemFontOfSize:14.0];
217 passcodeConfirmationWarningLabel.shadowOffset = CGSizeMake(0, 1.0);
218 passcodeConfirmationWarningLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
219 passcodeConfirmationWarningLabel.text = @"";
220 passcodeConfirmationWarningLabel.numberOfLines = 0;
221 passcodeConfirmationWarningLabel.lineBreakMode = UILineBreakModeWordWrap;
222 [headerView addSubview:passcodeConfirmationWarningLabel];
225 if (mode == kModeSetPasscode) {
226 self.navigationItem.title = @"Set Passcode";
227 [self addCancelButton];
228 if ([textField isEqual:enterPasscodeTextField]) {
229 headerLabel.text = @"Enter your passcode";
230 } else if ([textField isEqual:setPasscodeTextField]) {
231 headerLabel.text = @"Enter a passcode";
232 [self addCancelButton];
233 } else if ([textField isEqual:confirmPasscodeTextField]) {
234 headerLabel.text = @"Re-enter your passcode";
236 } else if (mode == kModeDisablePasscode) {
237 self.navigationItem.title = @"Turn off Passcode";
238 [self addCancelButton];
239 headerLabel.text = @"Enter your passcode";
240 } else if (mode == kModeChangePasscode) {
241 self.navigationItem.title = @"Change Passcode";
242 [self addCancelButton];
243 if ([textField isEqual:enterPasscodeTextField]) {
244 headerLabel.text = @"Enter your old passcode";
245 } else if ([textField isEqual:setPasscodeTextField]) {
246 headerLabel.text = @"Enter your new passcode";
248 headerLabel.text = @"Re-enter your new passcode";
251 self.navigationItem.title = @"Enter Passcode";
252 headerLabel.text = @"Enter your passcode";
255 [headerView addSubview:headerLabel];
256 [headerLabel release];
261 - (NSArray *)createSquares {
262 NSMutableArray *squareViews = [[NSMutableArray alloc] initWithCapacity:4];
263 NSInteger squareX = 23.0;
264 if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
268 for (int i = 0; i < 4; i++) {
269 UIImageView *square = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
270 square.frame = CGRectMake(squareX, 74.0, 61.0, 53.0);
271 [squareViews addObject:square];
275 return [NSArray arrayWithArray:squareViews];
278 - (void)moveToNextTableView {
280 UITableView *oldTableView = [tableViews objectAtIndex:tableIndex - 1];
281 UITableView *newTableView = [tableViews objectAtIndex:tableIndex];
282 newTableView.frame = CGRectMake(oldTableView.frame.origin.x + viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
284 if (simplePasscodeOn) {
285 for (int i = 0; i < 4; i++) {
286 [[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
290 [UIView animateWithDuration:0.25 animations:^{
291 oldTableView.frame = CGRectMake(oldTableView.frame.origin.x - viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
292 newTableView.frame = self.view.frame;
295 if (!simplePasscodeOn) {
296 if (tableIndex == [tableViews count] - 1) {
297 [self addDoneButton];
299 [self addNextButton];
303 [[textFields objectAtIndex:tableIndex - 1] resignFirstResponder];
304 [[textFields objectAtIndex:tableIndex] becomeFirstResponder];
307 - (void)moveToPreviousTableView {
309 UITableView *oldTableView = [tableViews objectAtIndex:tableIndex + 1];
310 UITableView *newTableView = [tableViews objectAtIndex:tableIndex];
311 newTableView.frame = CGRectMake(oldTableView.frame.origin.x - viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
313 if (simplePasscodeOn) {
314 for (int i = 0; i < 4; i++) {
315 [[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
319 [UIView animateWithDuration:0.25 animations:^{
320 oldTableView.frame = CGRectMake(oldTableView.frame.origin.x + viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height);
321 newTableView.frame = self.view.frame;
324 if (!simplePasscodeOn) {
325 if (tableIndex == [tableViews count] - 1) {
326 [self addDoneButton];
328 [self addNextButton];
332 [[textFields objectAtIndex:tableIndex + 1] resignFirstResponder];
333 [[textFields objectAtIndex:tableIndex] becomeFirstResponder];
336 - (void)incrementAndShowFailedAttemptsLabel {
337 enterPasscodeTextField.text = @"";
338 if (simplePasscodeOn) {
339 for (int i = 0; i < 4; i++) {
340 [[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
344 failedAttemptsCount += 1;
345 if (failedAttemptsCount == 1) {
346 failedAttemptsLabel.text = @"1 Failed Passcode Attempt";
348 failedAttemptsLabel.text = [NSString stringWithFormat:@"%i Failed Passcode Attempts", failedAttemptsCount];
350 CGSize size = [failedAttemptsLabel.text sizeWithFont:[UIFont boldSystemFontOfSize:14.0]];
351 failedAttemptsView.frame = CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0);
352 failedAttemptsLabel.frame = CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0);
354 CAGradientLayer *gradient = [CAGradientLayer layer];
355 gradient.frame = failedAttemptsView.bounds;
356 gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.714 green:0.043 blue:0.043 alpha:1.0] CGColor],
357 (id)[[UIColor colorWithRed:0.761 green:0.192 blue:0.192 alpha:1.0] CGColor], nil];
358 [failedAttemptsView.layer insertSublayer:gradient atIndex:0];
359 failedAttemptsView.layer.masksToBounds = YES;
361 failedAttemptsLabel.hidden = NO;
362 failedAttemptsView.hidden = NO;
364 if (failedAttemptsCount == 10 && eraseData) {
365 [Archiver deleteEverything];
366 [OpenStackAccount persist:[NSMutableArray array]];
367 if ([Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) {
368 [Keychain setString:@"" forKey:@"passcode_lock_passcode"];
370 [self dismissModalViewControllerAnimated:YES];
371 if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
372 [UIView animateWithDuration:0.5 delay:0.25 options:0 animations:^{
373 OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
374 for (UIViewController *svc in app.splitViewController.viewControllers) {
375 svc.view.alpha = 1.0;
377 } completion:^(BOOL finished){}];
380 [self alert:@"" message:@"You have entered an incorrect passcode too many times. All account data in this app have been deleted."];
381 if (self.rootViewController) {
382 [[self.rootViewController navigationController] popToRootViewControllerAnimated:NO];
383 [[self.rootViewController tableView] reloadData];
388 #pragma mark - UITableViewDataSource
390 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
391 return simplePasscodeOn ? 0 : 1;
394 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
398 - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
399 static NSString *CellIdentifier = @"Cell";
401 UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
403 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
404 cell.selectionStyle = UITableViewCellSelectionStyleNone;
407 // Configure the cell...
408 if ([aTableView isEqual:enterPasscodeTableView]) {
409 cell.accessoryView = enterPasscodeTextField;
410 } else if ([aTableView isEqual:setPasscodeTableView]) {
411 cell.accessoryView = setPasscodeTextField;
412 } else if ([aTableView isEqual:confirmPasscodeTableView]) {
413 cell.accessoryView = confirmPasscodeTextField;
419 #pragma mark - UITextFieldDelegate
421 //- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
422 // // we don't want iPad users to be able to dismiss the keyboard at all
426 - (BOOL)textFieldShouldReturn:(UITextField *)textField {
427 if ([textField isEqual:[textFields lastObject]]) {
428 [self doneButtonPressed:nil];
430 [self nextButtonPressed:nil];
435 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
436 // if we're in simple passcode mode, update the squares to show entered numbers
437 if (simplePasscodeOn) {
438 NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string];
440 // we're setting here and returning no since i'm messing with the responder chain.
441 // otherwise the last character will become the first character of the next textField
442 textField.text = result;
444 for (int i = 0; i < 4; i++) {
445 UIImageView *square = [[squares objectAtIndex:tableIndex] objectAtIndex:i];
446 if (i < [result length]) {
447 square.image = [UIImage imageNamed:@"passcode_square_filled.png"];
449 square.image = [UIImage imageNamed:@"passcode_square_empty.png"];
453 // if we're at 4 characters, it could be time to move on to confirming
454 if ([result length] == 4) {
455 if (mode == kModeDisablePasscode) {
456 NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"];
457 if ([enterPasscodeTextField.text isEqualToString:passcode]) {
458 if ([Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) {
459 [Keychain setString:@"" forKey:@"passcode_lock_passcode"];
461 [self.passcodeLockViewController.tableView reloadData];
462 [self.settingsViewController.tableView reloadData];
463 [self dismissModalViewControllerAnimated:YES];
465 [self incrementAndShowFailedAttemptsLabel];
467 } else if (mode == kModeEnterPasscode) {
468 NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"];
469 if ([enterPasscodeTextField.text isEqualToString:passcode]) {
470 if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
471 [UIView animateWithDuration:0.5 delay:0.25 options:0 animations:^{
472 OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
473 for (UIViewController *svc in app.splitViewController.viewControllers) {
474 svc.view.alpha = 1.0;
476 } completion:^(BOOL finished){}];
478 [self dismissModalViewControllerAnimated:YES];
480 [self incrementAndShowFailedAttemptsLabel];
482 } else if (mode == kModeChangePasscode) {
483 NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"];
484 if ([textField isEqual:enterPasscodeTextField]) {
485 if ([passcode isEqualToString:enterPasscodeTextField.text]) {
486 [self moveToNextTableView];
488 [self incrementAndShowFailedAttemptsLabel];
490 } else if ([textField isEqual:setPasscodeTextField]) {
491 if ([passcode isEqualToString:setPasscodeTextField.text]) {
492 setPasscodeTextField.text = @"";
493 for (int i = 0; i < 4; i++) {
494 [[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]];
496 passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode.";
497 passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, viewWidth, 60.0);
499 passcodeConfirmationWarningLabel.text = @"";
500 passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, viewWidth, 30.0);
501 [self moveToNextTableView];
503 } else if ([textField isEqual:confirmPasscodeTextField]) {
504 if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) {
505 confirmPasscodeTextField.text = @"";
506 setPasscodeTextField.text = @"";
507 passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
508 [self moveToPreviousTableView];
510 if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
511 [Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
513 [self.passcodeLockViewController.tableView reloadData];
514 [self.settingsViewController.tableView reloadData];
515 [self dismissModalViewControllerAnimated:YES];
518 } else if ([textField isEqual:setPasscodeTextField]) {
519 [self moveToNextTableView];
520 } else if ([textField isEqual:confirmPasscodeTextField]) {
521 if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) {
522 confirmPasscodeTextField.text = @"";
523 setPasscodeTextField.text = @"";
524 passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
525 [self moveToPreviousTableView];
527 if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
528 [Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
530 [self.passcodeLockViewController.tableView reloadData];
531 [self.settingsViewController.tableView reloadData];
532 [self dismissModalViewControllerAnimated:YES];
543 #pragma mark - Button Handlers
545 - (void)nextButtonPressed:(id)sender {
546 UITextField *textField = [textFields objectAtIndex:tableIndex];
547 if (![textField.text isEqualToString:@""]) {
548 if (mode == kModeSetPasscode) {
549 if ([textField isEqual:setPasscodeTextField]) {
550 [self moveToNextTableView];
551 } else if ([textField isEqual:confirmPasscodeTextField]) {
552 if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) {
553 confirmPasscodeTextField.text = @"";
554 setPasscodeTextField.text = @"";
555 passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
556 [self moveToPreviousTableView];
558 if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
559 [Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
561 [self.passcodeLockViewController.tableView reloadData];
562 [self.settingsViewController.tableView reloadData];
563 [self dismissModalViewControllerAnimated:YES];
566 } else if (mode == kModeChangePasscode) {
567 NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"];
568 if ([textField isEqual:enterPasscodeTextField]) {
569 if ([passcode isEqualToString:enterPasscodeTextField.text]) {
570 [self moveToNextTableView];
572 [self incrementAndShowFailedAttemptsLabel];
574 } else if ([textField isEqual:setPasscodeTextField]) {
575 if ([passcode isEqualToString:setPasscodeTextField.text]) {
576 setPasscodeTextField.text = @"";
577 passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode.";
578 passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, viewWidth, 60.0);
580 passcodeConfirmationWarningLabel.text = @"";
581 passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, viewWidth, 30.0);
582 [self moveToNextTableView];
584 } else if ([textField isEqual:confirmPasscodeTextField]) {
585 if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) {
586 confirmPasscodeTextField.text = @"";
587 setPasscodeTextField.text = @"";
588 passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
589 [self moveToPreviousTableView];
591 if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
592 [Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
594 [self.passcodeLockViewController.tableView reloadData];
595 [self.settingsViewController.tableView reloadData];
596 [self dismissModalViewControllerAnimated:YES];
603 - (void)doneButtonPressed:(id)sender {
604 UITextField *textField = [textFields objectAtIndex:tableIndex];
605 if (mode == kModeEnterPasscode) {
606 NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"];
607 if ([enterPasscodeTextField.text isEqualToString:passcode]) {
608 if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
609 [UIView animateWithDuration:0.5 delay:0.25 options:0 animations:^{
610 OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
611 for (UIViewController *svc in app.splitViewController.viewControllers) {
612 svc.view.alpha = 1.0;
614 } completion:^(BOOL finished){}];
616 [self dismissModalViewControllerAnimated:YES];
618 [self incrementAndShowFailedAttemptsLabel];
620 } else if (mode == kModeSetPasscode) {
621 if ([textField isEqual:setPasscodeTextField]) {
622 [self moveToNextTableView];
623 } else if ([textField isEqual:confirmPasscodeTextField]) {
624 if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) {
625 confirmPasscodeTextField.text = @"";
626 setPasscodeTextField.text = @"";
627 passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
628 [self moveToPreviousTableView];
630 if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
631 [Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
633 [self.passcodeLockViewController.tableView reloadData];
634 [self.settingsViewController.tableView reloadData];
635 [self dismissModalViewControllerAnimated:YES];
638 } else if (mode == kModeChangePasscode) {
639 NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"];
640 if ([textField isEqual:enterPasscodeTextField]) {
641 if ([passcode isEqualToString:enterPasscodeTextField.text]) {
642 [self moveToNextTableView];
644 [self incrementAndShowFailedAttemptsLabel];
646 } else if ([textField isEqual:setPasscodeTextField]) {
647 if ([passcode isEqualToString:setPasscodeTextField.text]) {
648 setPasscodeTextField.text = @"";
649 passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode.";
650 passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, viewWidth, 60.0);
652 passcodeConfirmationWarningLabel.text = @"";
653 passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, viewWidth, 30.0);
654 [self moveToNextTableView];
656 } else if ([textField isEqual:confirmPasscodeTextField]) {
657 if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) {
658 confirmPasscodeTextField.text = @"";
659 setPasscodeTextField.text = @"";
660 passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again.";
661 [self moveToPreviousTableView];
663 if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) {
664 [Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"];
666 [self.passcodeLockViewController.tableView reloadData];
667 [self.settingsViewController.tableView reloadData];
668 [self dismissModalViewControllerAnimated:YES];
671 } else if (mode == kModeDisablePasscode) {
672 NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"];
673 if ([enterPasscodeTextField.text isEqualToString:passcode]) {
674 if ([Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) {
675 [Keychain setString:@"" forKey:@"passcode_lock_passcode"];
677 [self.passcodeLockViewController.tableView reloadData];
678 [self.settingsViewController.tableView reloadData];
679 [self dismissModalViewControllerAnimated:YES];
681 [self incrementAndShowFailedAttemptsLabel];