root / Classes / PasscodeViewController.m @ 7db1712d
History | View | Annotate | Download (33.3 kB)
1 |
// |
---|---|
2 |
// PasscodeViewController.m |
3 |
// OpenStack |
4 |
// |
5 |
// Created by Mike Mayo on 10/26/10. |
6 |
// The OpenStack project is provided under the Apache 2.0 license. |
7 |
// |
8 |
|
9 |
#import "PasscodeViewController.h" |
10 |
#import "UIViewController+Conveniences.h" |
11 |
#import "UIColor+MoreColors.h" |
12 |
#import "Keychain.h" |
13 |
#import "PasscodeLockViewController.h" |
14 |
#import "SettingsViewController.h" |
15 |
#import <QuartzCore/QuartzCore.h> |
16 |
#import "Archiver.h" |
17 |
#import "RootViewController.h" |
18 |
#import "OpenStackAccount.h" |
19 |
#import "AccountHomeViewController.h" |
20 |
#import "OpenStackAppDelegate.h" |
21 |
|
22 |
|
23 |
@implementation PasscodeViewController |
24 |
|
25 |
@synthesize mode, passcodeLockViewController, settingsViewController, rootViewController, accountHomeViewController; |
26 |
|
27 |
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { |
28 |
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); |
29 |
} |
30 |
|
31 |
- (UITextField *)allocAndInitPasscodeTextField { |
32 |
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(29.0, 13.0, 271.0, 24.0)]; |
33 |
textField.text = @""; |
34 |
textField.textColor = [UIColor value1DetailTextLabelColor]; |
35 |
textField.secureTextEntry = YES; |
36 |
textField.delegate = self; |
37 |
|
38 |
textField.keyboardAppearance = UIKeyboardAppearanceAlert; |
39 |
|
40 |
return textField; |
41 |
} |
42 |
|
43 |
- (void)addNextButton { |
44 |
if (!simplePasscodeOn) { |
45 |
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStyleBordered target:self action:@selector(nextButtonPressed:)]; |
46 |
self.navigationItem.rightBarButtonItem = nextButton; |
47 |
[nextButton release]; |
48 |
} |
49 |
} |
50 |
|
51 |
- (void)addDoneButton { |
52 |
if (!simplePasscodeOn) { |
53 |
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneButtonPressed:)]; |
54 |
self.navigationItem.rightBarButtonItem = doneButton; |
55 |
[doneButton release]; |
56 |
} |
57 |
} |
58 |
|
59 |
- (void)incrementAndShowFailedAttemptsLabel { |
60 |
enterPasscodeTextField.text = @""; |
61 |
if (simplePasscodeOn) { |
62 |
for (int i = 0; i < 4; i++) { |
63 |
[[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]]; |
64 |
} |
65 |
} |
66 |
|
67 |
failedAttemptsCount += 1; |
68 |
if (failedAttemptsCount == 1) { |
69 |
failedAttemptsLabel.text = @"1 Failed Passcode Attempt"; |
70 |
} else { |
71 |
failedAttemptsLabel.text = [NSString stringWithFormat:@"%i Failed Passcode Attempts", failedAttemptsCount]; |
72 |
} |
73 |
CGSize size = [failedAttemptsLabel.text sizeWithFont:[UIFont boldSystemFontOfSize:14.0]]; |
74 |
failedAttemptsView.frame = CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0); |
75 |
failedAttemptsLabel.frame = CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0); |
76 |
|
77 |
CAGradientLayer *gradient = [CAGradientLayer layer]; |
78 |
gradient.frame = failedAttemptsView.bounds; |
79 |
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.714 green:0.043 blue:0.043 alpha:1.0] CGColor], |
80 |
(id)[[UIColor colorWithRed:0.761 green:0.192 blue:0.192 alpha:1.0] CGColor], nil]; |
81 |
[failedAttemptsView.layer insertSublayer:gradient atIndex:0]; |
82 |
failedAttemptsView.layer.masksToBounds = YES; |
83 |
|
84 |
failedAttemptsLabel.hidden = NO; |
85 |
failedAttemptsView.hidden = NO; |
86 |
|
87 |
if (failedAttemptsCount == 10 && eraseData) { |
88 |
[Archiver deleteEverything]; |
89 |
[OpenStackAccount persist:[NSMutableArray array]]; |
90 |
if ([Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) { |
91 |
[Keychain setString:@"" forKey:@"passcode_lock_passcode"]; |
92 |
} |
93 |
[self dismissModalViewControllerAnimated:YES]; |
94 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
95 |
[UIView beginAnimations:@"fadeIn" context:nil]; |
96 |
[UIView setAnimationDelay:0.25]; |
97 |
[UIView setAnimationDuration:0.5]; |
98 |
OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate]; |
99 |
for (UIViewController *svc in app.splitViewController.viewControllers) { |
100 |
svc.view.alpha = 1.0; |
101 |
} |
102 |
[UIView commitAnimations]; |
103 |
} |
104 |
|
105 |
[self alert:@"" message:@"You have entered an incorrect passcode too many times. All account data in this app has been deleted."]; |
106 |
if (self.rootViewController) { |
107 |
[self.rootViewController.navigationController popToRootViewControllerAnimated:NO]; |
108 |
[self.rootViewController.tableView reloadData]; |
109 |
} |
110 |
} |
111 |
|
112 |
} |
113 |
|
114 |
- (void)moveToNextTableView { |
115 |
tableIndex += 1; |
116 |
UITableView *oldTableView = [tableViews objectAtIndex:tableIndex - 1]; |
117 |
UITableView *newTableView = [tableViews objectAtIndex:tableIndex]; |
118 |
newTableView.frame = CGRectMake(oldTableView.frame.origin.x + viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height); |
119 |
|
120 |
if (simplePasscodeOn) { |
121 |
for (int i = 0; i < 4; i++) { |
122 |
[[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]]; |
123 |
} |
124 |
} |
125 |
|
126 |
[UIView beginAnimations:@"" context:nil]; |
127 |
[UIView setAnimationDuration:0.25]; |
128 |
oldTableView.frame = CGRectMake(oldTableView.frame.origin.x - viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height); |
129 |
newTableView.frame = self.view.frame; |
130 |
[UIView commitAnimations]; |
131 |
|
132 |
if (tableIndex == [tableViews count] - 1) { |
133 |
[self addDoneButton]; |
134 |
} else { |
135 |
[self addNextButton]; |
136 |
} |
137 |
|
138 |
[[textFields objectAtIndex:tableIndex - 1] resignFirstResponder]; |
139 |
[[textFields objectAtIndex:tableIndex] becomeFirstResponder]; |
140 |
} |
141 |
|
142 |
- (void)moveToPreviousTableView { |
143 |
tableIndex -= 1; |
144 |
UITableView *oldTableView = [tableViews objectAtIndex:tableIndex + 1]; |
145 |
UITableView *newTableView = [tableViews objectAtIndex:tableIndex]; |
146 |
newTableView.frame = CGRectMake(oldTableView.frame.origin.x - viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height); |
147 |
|
148 |
if (simplePasscodeOn) { |
149 |
for (int i = 0; i < 4; i++) { |
150 |
[[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]]; |
151 |
} |
152 |
} |
153 |
|
154 |
[UIView beginAnimations:@"" context:nil]; |
155 |
[UIView setAnimationDuration:0.25]; |
156 |
oldTableView.frame = CGRectMake(oldTableView.frame.origin.x + viewWidth, oldTableView.frame.origin.y, oldTableView.frame.size.width, oldTableView.frame.size.height); |
157 |
newTableView.frame = self.view.frame; |
158 |
[UIView commitAnimations]; |
159 |
|
160 |
if (tableIndex == [tableViews count] - 1) { |
161 |
[self addDoneButton]; |
162 |
} else { |
163 |
[self addNextButton]; |
164 |
} |
165 |
|
166 |
[[textFields objectAtIndex:tableIndex + 1] resignFirstResponder]; |
167 |
[[textFields objectAtIndex:tableIndex] becomeFirstResponder]; |
168 |
} |
169 |
|
170 |
- (void)nextButtonPressed:(id)sender { |
171 |
|
172 |
UITextField *textField = [textFields objectAtIndex:tableIndex]; |
173 |
|
174 |
if (![textField.text isEqualToString:@""]) { |
175 |
|
176 |
if (mode == kModeSetPasscode) { |
177 |
if ([textField isEqual:setPasscodeTextField]) { |
178 |
[self moveToNextTableView]; |
179 |
} else if ([textField isEqual:confirmPasscodeTextField]) { |
180 |
if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) { |
181 |
confirmPasscodeTextField.text = @""; |
182 |
setPasscodeTextField.text = @""; |
183 |
passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again."; |
184 |
[self moveToPreviousTableView]; |
185 |
} else { |
186 |
if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) { |
187 |
[Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"]; |
188 |
} |
189 |
[self.passcodeLockViewController.tableView reloadData]; |
190 |
[self.settingsViewController.tableView reloadData]; |
191 |
[self dismissModalViewControllerAnimated:YES]; |
192 |
} |
193 |
} |
194 |
} else if (mode == kModeChangePasscode) { |
195 |
NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"]; |
196 |
if ([textField isEqual:enterPasscodeTextField]) { |
197 |
if ([passcode isEqualToString:enterPasscodeTextField.text]) { |
198 |
[self moveToNextTableView]; |
199 |
} else { |
200 |
[self incrementAndShowFailedAttemptsLabel]; |
201 |
} |
202 |
} else if ([textField isEqual:setPasscodeTextField]) { |
203 |
if ([passcode isEqualToString:setPasscodeTextField.text]) { |
204 |
setPasscodeTextField.text = @""; |
205 |
passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode."; |
206 |
passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, viewWidth, 60.0); |
207 |
} else { |
208 |
passcodeConfirmationWarningLabel.text = @""; |
209 |
passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, viewWidth, 30.0); |
210 |
[self moveToNextTableView]; |
211 |
} |
212 |
} else if ([textField isEqual:confirmPasscodeTextField]) { |
213 |
if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) { |
214 |
confirmPasscodeTextField.text = @""; |
215 |
setPasscodeTextField.text = @""; |
216 |
passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again."; |
217 |
[self moveToPreviousTableView]; |
218 |
} else { |
219 |
if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) { |
220 |
[Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"]; |
221 |
} |
222 |
[self.passcodeLockViewController.tableView reloadData]; |
223 |
[self.settingsViewController.tableView reloadData]; |
224 |
[self dismissModalViewControllerAnimated:YES]; |
225 |
} |
226 |
} |
227 |
} |
228 |
} |
229 |
} |
230 |
|
231 |
- (void)doneButtonPressed:(id)sender { |
232 |
|
233 |
UITextField *textField = [textFields objectAtIndex:tableIndex]; |
234 |
|
235 |
if (mode == kModeEnterPasscode) { |
236 |
NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"]; |
237 |
if ([enterPasscodeTextField.text isEqualToString:passcode]) { |
238 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
239 |
[UIView beginAnimations:@"fadeIn" context:nil]; |
240 |
[UIView setAnimationDelay:0.25]; |
241 |
[UIView setAnimationDuration:0.5]; |
242 |
OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate]; |
243 |
for (UIViewController *svc in app.splitViewController.viewControllers) { |
244 |
svc.view.alpha = 1.0; |
245 |
} |
246 |
[UIView commitAnimations]; |
247 |
} |
248 |
[self dismissModalViewControllerAnimated:YES]; |
249 |
} else { |
250 |
[self incrementAndShowFailedAttemptsLabel]; |
251 |
} |
252 |
} else if (mode == kModeSetPasscode) { |
253 |
if ([textField isEqual:setPasscodeTextField]) { |
254 |
[self moveToNextTableView]; |
255 |
} else if ([textField isEqual:confirmPasscodeTextField]) { |
256 |
if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) { |
257 |
confirmPasscodeTextField.text = @""; |
258 |
setPasscodeTextField.text = @""; |
259 |
passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again."; |
260 |
[self moveToPreviousTableView]; |
261 |
} else { |
262 |
if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) { |
263 |
[Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"]; |
264 |
} |
265 |
[self.passcodeLockViewController.tableView reloadData]; |
266 |
[self.settingsViewController.tableView reloadData]; |
267 |
[self dismissModalViewControllerAnimated:YES]; |
268 |
} |
269 |
} |
270 |
} else if (mode == kModeChangePasscode) { |
271 |
NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"]; |
272 |
if ([textField isEqual:enterPasscodeTextField]) { |
273 |
if ([passcode isEqualToString:enterPasscodeTextField.text]) { |
274 |
[self moveToNextTableView]; |
275 |
} else { |
276 |
[self incrementAndShowFailedAttemptsLabel]; |
277 |
} |
278 |
} else if ([textField isEqual:setPasscodeTextField]) { |
279 |
if ([passcode isEqualToString:setPasscodeTextField.text]) { |
280 |
setPasscodeTextField.text = @""; |
281 |
passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode."; |
282 |
passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, viewWidth, 60.0); |
283 |
} else { |
284 |
passcodeConfirmationWarningLabel.text = @""; |
285 |
passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, viewWidth, 30.0); |
286 |
[self moveToNextTableView]; |
287 |
} |
288 |
} else if ([textField isEqual:confirmPasscodeTextField]) { |
289 |
if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) { |
290 |
confirmPasscodeTextField.text = @""; |
291 |
setPasscodeTextField.text = @""; |
292 |
passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again."; |
293 |
[self moveToPreviousTableView]; |
294 |
} else { |
295 |
if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) { |
296 |
[Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"]; |
297 |
} |
298 |
[self.passcodeLockViewController.tableView reloadData]; |
299 |
[self.settingsViewController.tableView reloadData]; |
300 |
[self dismissModalViewControllerAnimated:YES]; |
301 |
} |
302 |
} |
303 |
} else if (mode == kModeDisablePasscode) { |
304 |
NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"]; |
305 |
if ([enterPasscodeTextField.text isEqualToString:passcode]) { |
306 |
if ([Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) { |
307 |
[Keychain setString:@"" forKey:@"passcode_lock_passcode"]; |
308 |
} |
309 |
[self.passcodeLockViewController.tableView reloadData]; |
310 |
[self.settingsViewController.tableView reloadData]; |
311 |
[self dismissModalViewControllerAnimated:YES]; |
312 |
} else { |
313 |
[self incrementAndShowFailedAttemptsLabel]; |
314 |
} |
315 |
} |
316 |
} |
317 |
|
318 |
#pragma mark - |
319 |
#pragma mark View lifecycle |
320 |
|
321 |
- (void)viewDidLoad { |
322 |
[super viewDidLoad]; |
323 |
simplePasscodeOn = [[Keychain getStringForKey:@"passcode_lock_simple_passcode_on"] isEqualToString:@"YES"]; |
324 |
passcodeLockOn = [[Keychain getStringForKey:@"passcode_lock_passcode_on"] isEqualToString:@"YES"]; |
325 |
eraseData = [[Keychain getStringForKey:@"passcode_lock_erase_data_on"] isEqualToString:@"YES"]; |
326 |
|
327 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
328 |
viewWidth = 540.0; |
329 |
} else { |
330 |
viewWidth = 320.0; |
331 |
} |
332 |
} |
333 |
|
334 |
- (UIView *)passwordHeaderViewForTextField:(UITextField *)textField { |
335 |
|
336 |
if (simplePasscodeOn) { |
337 |
textField.keyboardType = UIKeyboardTypeNumberPad; |
338 |
|
339 |
// hide the text field and add it to the view. we'll use the squares, but we need a text field |
340 |
textField.hidden = YES; |
341 |
[self.view addSubview:textField]; |
342 |
} else { |
343 |
textField.keyboardType = UIKeyboardTypeDefault; |
344 |
textField.returnKeyType = UIReturnKeyNext; |
345 |
} |
346 |
|
347 |
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, viewWidth, 70.0)] autorelease]; |
348 |
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 27.5, viewWidth, 30.0)]; |
349 |
headerLabel.textColor = [UIColor tableViewHeaderColor]; |
350 |
headerLabel.backgroundColor = [UIColor clearColor]; |
351 |
headerLabel.textAlignment = UITextAlignmentCenter; |
352 |
headerLabel.font = [UIFont boldSystemFontOfSize:17.0]; |
353 |
headerLabel.shadowOffset = CGSizeMake(0, 1.0); |
354 |
headerLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; |
355 |
|
356 |
if ([textField isEqual:setPasscodeTextField]) { |
357 |
passcodeConfirmationWarningLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 146.5, viewWidth, 30.0)]; |
358 |
passcodeConfirmationWarningLabel.textColor = [UIColor tableViewHeaderColor]; |
359 |
passcodeConfirmationWarningLabel.backgroundColor = [UIColor clearColor]; |
360 |
passcodeConfirmationWarningLabel.textAlignment = UITextAlignmentCenter; |
361 |
passcodeConfirmationWarningLabel.font = [UIFont systemFontOfSize:14.0]; |
362 |
passcodeConfirmationWarningLabel.shadowOffset = CGSizeMake(0, 1.0); |
363 |
passcodeConfirmationWarningLabel.shadowColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0]; |
364 |
passcodeConfirmationWarningLabel.text = @""; |
365 |
passcodeConfirmationWarningLabel.numberOfLines = 0; |
366 |
passcodeConfirmationWarningLabel.lineBreakMode = UILineBreakModeWordWrap; |
367 |
[headerView addSubview:passcodeConfirmationWarningLabel]; |
368 |
} |
369 |
|
370 |
if ([textField isEqual:enterPasscodeTextField]) { |
371 |
//UIView *failedAttemptsView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 146.5, viewWidth, 30.0)]; |
372 |
|
373 |
NSString *text = @"1 Failed Passcode Attempt"; |
374 |
CGSize size = [text sizeWithFont:[UIFont boldSystemFontOfSize:14.0]]; |
375 |
failedAttemptsView = [[UIView alloc] initWithFrame:CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0)]; |
376 |
failedAttemptsLabel = [[UILabel alloc] initWithFrame:CGRectMake((viewWidth - (size.width + 36.0)) / 2, 147.5, size.width + 36.0, size.height + 10.0)]; |
377 |
failedAttemptsLabel.backgroundColor = [UIColor clearColor]; |
378 |
failedAttemptsLabel.textColor = [UIColor whiteColor]; |
379 |
failedAttemptsLabel.text = text; |
380 |
failedAttemptsLabel.font = [UIFont boldSystemFontOfSize:14.0]; |
381 |
failedAttemptsLabel.textAlignment = UITextAlignmentCenter; |
382 |
failedAttemptsLabel.shadowOffset = CGSizeMake(0, -1.0); |
383 |
failedAttemptsLabel.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; |
384 |
failedAttemptsView.layer.cornerRadius = 14; |
385 |
failedAttemptsView.layer.borderWidth = 1.0; |
386 |
failedAttemptsView.layer.borderColor = [[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.25] CGColor]; |
387 |
|
388 |
failedAttemptsLabel.hidden = YES; |
389 |
failedAttemptsView.hidden = YES; |
390 |
|
391 |
CAGradientLayer *gradient = [CAGradientLayer layer]; |
392 |
gradient.frame = failedAttemptsView.bounds; |
393 |
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.714 green:0.043 blue:0.043 alpha:1.0] CGColor], |
394 |
(id)[[UIColor colorWithRed:0.761 green:0.192 blue:0.192 alpha:1.0] CGColor], nil]; |
395 |
[failedAttemptsView.layer insertSublayer:gradient atIndex:1]; |
396 |
failedAttemptsView.layer.masksToBounds = YES; |
397 |
|
398 |
[headerView addSubview:failedAttemptsView]; |
399 |
[headerView addSubview:failedAttemptsLabel]; |
400 |
|
401 |
[failedAttemptsView release]; |
402 |
[failedAttemptsLabel release]; |
403 |
} |
404 |
|
405 |
if (mode == kModeSetPasscode) { |
406 |
self.navigationItem.title = @"Set Passcode"; |
407 |
[self addCancelButton]; |
408 |
|
409 |
if ([textField isEqual:enterPasscodeTextField]) { |
410 |
headerLabel.text = @"Enter your passcode"; |
411 |
} else if ([textField isEqual:setPasscodeTextField]) { |
412 |
headerLabel.text = @"Enter a passcode"; |
413 |
[self addCancelButton]; |
414 |
} else if ([textField isEqual:confirmPasscodeTextField]) { |
415 |
headerLabel.text = @"Re-enter your passcode"; |
416 |
} |
417 |
} else if (mode == kModeDisablePasscode) { |
418 |
self.navigationItem.title = @"Turn off Passcode"; |
419 |
[self addCancelButton]; |
420 |
headerLabel.text = @"Enter your passcode"; |
421 |
} else if (mode == kModeChangePasscode) { |
422 |
self.navigationItem.title = @"Change Passcode"; |
423 |
[self addCancelButton]; |
424 |
if ([textField isEqual:enterPasscodeTextField]) { |
425 |
headerLabel.text = @"Enter your old passcode"; |
426 |
} else if ([textField isEqual:setPasscodeTextField]) { |
427 |
headerLabel.text = @"Enter your new passcode"; |
428 |
} else { |
429 |
headerLabel.text = @"Re-enter your new passcode"; |
430 |
} |
431 |
} else { |
432 |
self.navigationItem.title = @"Enter Passcode"; |
433 |
headerLabel.text = @"Enter your passcode"; |
434 |
} |
435 |
|
436 |
[headerView addSubview:headerLabel]; |
437 |
[headerLabel release]; |
438 |
|
439 |
return headerView; |
440 |
} |
441 |
|
442 |
- (NSArray *)squares { |
443 |
NSMutableArray *squareViews = [[NSMutableArray alloc] initWithCapacity:4]; |
444 |
NSInteger squareX = 23.0; |
445 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
446 |
squareX = 133.0; |
447 |
} |
448 |
|
449 |
for (int i = 0; i < 4; i++) { |
450 |
UIImageView *square = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"passcode_square_empty.png"]]; |
451 |
square.frame = CGRectMake(squareX, 74.0, 61.0, 53.0); |
452 |
[squareViews addObject:square]; |
453 |
[square release]; |
454 |
squareX += 71.0; |
455 |
} |
456 |
return [[NSArray alloc] initWithArray:squareViews]; |
457 |
} |
458 |
|
459 |
- (void)viewWillAppear:(BOOL)animated { |
460 |
[super viewWillAppear:animated]; |
461 |
|
462 |
enterPasscodeTextField = [self allocAndInitPasscodeTextField]; |
463 |
setPasscodeTextField = [self allocAndInitPasscodeTextField]; |
464 |
confirmPasscodeTextField = [self allocAndInitPasscodeTextField]; |
465 |
|
466 |
tableViews = [[NSMutableArray alloc] init]; |
467 |
textFields = [[NSMutableArray alloc] init]; |
468 |
squares = [[NSMutableArray alloc] init]; |
469 |
|
470 |
if (mode == kModeSetPasscode || mode == kModeChangePasscode) { |
471 |
// we're setting the passcode, so add possibly all of the table views |
472 |
if (passcodeLockOn) { |
473 |
enterPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:enterPasscodeTextField]; |
474 |
[tableViews addObject:enterPasscodeTableView]; |
475 |
[textFields addObject:enterPasscodeTextField]; |
476 |
if (simplePasscodeOn) { |
477 |
[squares addObject:[self squares]]; |
478 |
for (int i = 0; i < [[squares lastObject] count]; i++) { |
479 |
[enterPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]]; |
480 |
} |
481 |
} |
482 |
} |
483 |
setPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:setPasscodeTextField]; |
484 |
[tableViews addObject:setPasscodeTableView]; |
485 |
[textFields addObject:setPasscodeTextField]; |
486 |
if (simplePasscodeOn) { |
487 |
[squares addObject:[self squares]]; |
488 |
for (int i = 0; i < [[squares lastObject] count]; i++) { |
489 |
[setPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]]; |
490 |
} |
491 |
} |
492 |
confirmPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:confirmPasscodeTextField]; |
493 |
[tableViews addObject:confirmPasscodeTableView]; |
494 |
[textFields addObject:confirmPasscodeTextField]; |
495 |
if (simplePasscodeOn) { |
496 |
[squares addObject:[self squares]]; |
497 |
for (int i = 0; i < [[squares lastObject] count]; i++) { |
498 |
[confirmPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]]; |
499 |
} |
500 |
} |
501 |
} else { |
502 |
enterPasscodeTableView.tableHeaderView = [self passwordHeaderViewForTextField:enterPasscodeTextField]; |
503 |
[tableViews addObject:enterPasscodeTableView]; |
504 |
[textFields addObject:enterPasscodeTextField]; |
505 |
if (simplePasscodeOn) { |
506 |
[squares addObject:[self squares]]; |
507 |
for (int i = 0; i < [[squares lastObject] count]; i++) { |
508 |
[enterPasscodeTableView.tableHeaderView addSubview:[[squares lastObject] objectAtIndex:i]]; |
509 |
} |
510 |
} |
511 |
} |
512 |
|
513 |
[self.view addSubview:[tableViews objectAtIndex:0]]; |
514 |
|
515 |
// shift any extra table views away |
516 |
for (int i = 1; i < [tableViews count]; i++) { |
517 |
UITableView *tableView = [tableViews objectAtIndex:i]; |
518 |
tableView.frame = CGRectMake(tableView.frame.origin.x + viewWidth, tableView.frame.origin.y, tableView.frame.size.width, tableView.frame.size.height); |
519 |
[self.view addSubview:tableView]; |
520 |
} |
521 |
|
522 |
if (tableIndex == [tableViews count] - 1) { |
523 |
[self addDoneButton]; |
524 |
} else { |
525 |
[self addNextButton]; |
526 |
} |
527 |
|
528 |
[[textFields objectAtIndex:0] becomeFirstResponder]; |
529 |
[[tableViews objectAtIndex:0] reloadData]; |
530 |
[[textFields objectAtIndex:[tableViews count] - 1] setReturnKeyType:UIReturnKeyDone]; |
531 |
|
532 |
// table looks all screwy on iPad at first, so shuffle around to get the drawing right |
533 |
// yes, i know this is a dirty hack. |
534 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
535 |
if ([tableViews count] > 1) { |
536 |
[self moveToNextTableView]; |
537 |
[self moveToPreviousTableView]; |
538 |
} else { |
539 |
UITableView *tv = [tableViews objectAtIndex:0]; |
540 |
tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, 768.0, 960.0); |
541 |
} |
542 |
} |
543 |
} |
544 |
|
545 |
#pragma mark - |
546 |
#pragma mark Table view data source |
547 |
|
548 |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { |
549 |
return simplePasscodeOn ? 0 : 1; |
550 |
} |
551 |
|
552 |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { |
553 |
return 1; |
554 |
} |
555 |
|
556 |
// Customize the appearance of table view cells. |
557 |
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { |
558 |
|
559 |
static NSString *CellIdentifier = @"Cell"; |
560 |
|
561 |
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
562 |
if (cell == nil) { |
563 |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; |
564 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
565 |
} |
566 |
|
567 |
// Configure the cell... |
568 |
//cell.accessoryView = enterPasscodeTextField; //[textFields objectAtIndex:tableIndex]; |
569 |
if ([aTableView isEqual:enterPasscodeTableView]) { |
570 |
cell.accessoryView = enterPasscodeTextField; |
571 |
} else if ([aTableView isEqual:setPasscodeTableView]) { |
572 |
cell.accessoryView = setPasscodeTextField; |
573 |
} else if ([aTableView isEqual:confirmPasscodeTableView]) { |
574 |
cell.accessoryView = confirmPasscodeTextField; |
575 |
} |
576 |
|
577 |
return cell; |
578 |
} |
579 |
|
580 |
#pragma mark - |
581 |
#pragma mark Text Field Delegate |
582 |
|
583 |
/* |
584 |
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { |
585 |
// we don't want iPad users to be able to dismiss the keyboard at all |
586 |
return NO; |
587 |
} |
588 |
*/ |
589 |
|
590 |
- (BOOL)textFieldShouldReturn:(UITextField *)textField { |
591 |
if ([textField isEqual:[textFields lastObject]]) { |
592 |
[self doneButtonPressed:nil]; |
593 |
} else { |
594 |
[self nextButtonPressed:nil]; |
595 |
} |
596 |
return NO; |
597 |
} |
598 |
|
599 |
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { |
600 |
|
601 |
// if we're in simple passcode mode, update the squares to show entered numbers |
602 |
if (simplePasscodeOn) { |
603 |
NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string]; |
604 |
|
605 |
// we're setting here and returning no since i'm messing with the responder chain. |
606 |
// otherwise the last character will become the first character of the next textField |
607 |
textField.text = result; |
608 |
|
609 |
for (int i = 0; i < 4; i++) { |
610 |
UIImageView *square = [[squares objectAtIndex:tableIndex] objectAtIndex:i]; |
611 |
if (i < [result length]) { |
612 |
square.image = [UIImage imageNamed:@"passcode_square_filled.png"]; |
613 |
} else { |
614 |
square.image = [UIImage imageNamed:@"passcode_square_empty.png"]; |
615 |
} |
616 |
} |
617 |
|
618 |
// if we're at 4 characters, it could be time to move on to confirming |
619 |
if ([result length] == 4) { |
620 |
|
621 |
if (mode == kModeDisablePasscode) { |
622 |
NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"]; |
623 |
if ([enterPasscodeTextField.text isEqualToString:passcode]) { |
624 |
if ([Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"]) { |
625 |
[Keychain setString:@"" forKey:@"passcode_lock_passcode"]; |
626 |
} |
627 |
[self.passcodeLockViewController.tableView reloadData]; |
628 |
[self.settingsViewController.tableView reloadData]; |
629 |
[self dismissModalViewControllerAnimated:YES]; |
630 |
} else { |
631 |
[self incrementAndShowFailedAttemptsLabel]; |
632 |
} |
633 |
} else if (mode == kModeEnterPasscode) { |
634 |
NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"]; |
635 |
if ([enterPasscodeTextField.text isEqualToString:passcode]) { |
636 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
637 |
[UIView beginAnimations:@"fadeIn" context:nil]; |
638 |
[UIView setAnimationDelay:0.25]; |
639 |
[UIView setAnimationDuration:0.5]; |
640 |
OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate]; |
641 |
for (UIViewController *svc in app.splitViewController.viewControllers) { |
642 |
svc.view.alpha = 1.0; |
643 |
} |
644 |
[UIView commitAnimations]; |
645 |
} |
646 |
[self dismissModalViewControllerAnimated:YES]; |
647 |
} else { |
648 |
[self incrementAndShowFailedAttemptsLabel]; |
649 |
} |
650 |
} else if (mode == kModeChangePasscode) { |
651 |
NSString *passcode = [Keychain getStringForKey:@"passcode_lock_passcode"]; |
652 |
if ([textField isEqual:enterPasscodeTextField]) { |
653 |
if ([passcode isEqualToString:enterPasscodeTextField.text]) { |
654 |
[self moveToNextTableView]; |
655 |
} else { |
656 |
[self incrementAndShowFailedAttemptsLabel]; |
657 |
} |
658 |
} else if ([textField isEqual:setPasscodeTextField]) { |
659 |
if ([passcode isEqualToString:setPasscodeTextField.text]) { |
660 |
setPasscodeTextField.text = @""; |
661 |
for (int i = 0; i < 4; i++) { |
662 |
[[[squares objectAtIndex:tableIndex] objectAtIndex:i] setImage:[UIImage imageNamed:@"passcode_square_empty.png"]]; |
663 |
} |
664 |
passcodeConfirmationWarningLabel.text = @"Enter a different passcode. Cannot re-use the same passcode."; |
665 |
passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 131.5, viewWidth, 60.0); |
666 |
} else { |
667 |
passcodeConfirmationWarningLabel.text = @""; |
668 |
passcodeConfirmationWarningLabel.frame = CGRectMake(0.0, 146.5, viewWidth, 30.0); |
669 |
[self moveToNextTableView]; |
670 |
} |
671 |
} else if ([textField isEqual:confirmPasscodeTextField]) { |
672 |
if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) { |
673 |
confirmPasscodeTextField.text = @""; |
674 |
setPasscodeTextField.text = @""; |
675 |
passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again."; |
676 |
[self moveToPreviousTableView]; |
677 |
} else { |
678 |
if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) { |
679 |
[Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"]; |
680 |
} |
681 |
[self.passcodeLockViewController.tableView reloadData]; |
682 |
[self.settingsViewController.tableView reloadData]; |
683 |
[self dismissModalViewControllerAnimated:YES]; |
684 |
} |
685 |
} |
686 |
} else if ([textField isEqual:setPasscodeTextField]) { |
687 |
[self moveToNextTableView]; |
688 |
} else if ([textField isEqual:confirmPasscodeTextField]) { |
689 |
if (![confirmPasscodeTextField.text isEqualToString:setPasscodeTextField.text]) { |
690 |
confirmPasscodeTextField.text = @""; |
691 |
setPasscodeTextField.text = @""; |
692 |
passcodeConfirmationWarningLabel.text = @"Passcodes did not match. Try again."; |
693 |
[self moveToPreviousTableView]; |
694 |
} else { |
695 |
if ([Keychain setString:setPasscodeTextField.text forKey:@"passcode_lock_passcode"]) { |
696 |
[Keychain setString:@"YES" forKey:@"passcode_lock_passcode_on"]; |
697 |
} |
698 |
[self.passcodeLockViewController.tableView reloadData]; |
699 |
[self.settingsViewController.tableView reloadData]; |
700 |
[self dismissModalViewControllerAnimated:YES]; |
701 |
} |
702 |
} |
703 |
} |
704 |
|
705 |
return NO; |
706 |
} |
707 |
|
708 |
return YES; |
709 |
} |
710 |
|
711 |
#pragma mark - |
712 |
#pragma mark Memory management |
713 |
|
714 |
- (void)dealloc { |
715 |
|
716 |
[enterPasscodeTextField release]; |
717 |
[setPasscodeTextField release]; |
718 |
[confirmPasscodeTextField release]; |
719 |
[tableViews release]; |
720 |
[textFields release]; |
721 |
[squares release]; |
722 |
[passcodeLockViewController release]; |
723 |
[settingsViewController release]; |
724 |
[rootViewController release]; |
725 |
[accountHomeViewController release]; |
726 |
[super dealloc]; |
727 |
} |
728 |
|
729 |
@end |