Use search bar to show only folder objects that start with given filter
[pithos-ios] / Classes / AccountSettingsViewController.m
1 //
2 //  AccountSettingsViewController.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 12/14/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "AccountSettingsViewController.h"
10 #import "OpenStackAccount.h"
11 #import "ActivityIndicatorView.h"
12 #import "Provider.h"
13 #import "RSTextFieldCell.h"
14 #import "UIColor+MoreColors.h"
15 #import "OpenStackAppDelegate.h"
16 #import "UIViewController+Conveniences.h"
17 #import "OpenStackRequest.h"
18
19 #define kUsername 0
20 #define kAuthToken 1
21
22 @implementation AccountSettingsViewController
23
24 @synthesize account, username, authToken, activityIndicatorView;
25
26 #pragma mark - View lifecycle
27
28 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
29     return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
30 }
31
32 - (void)viewDidLoad {
33     [super viewDidLoad];
34     self.navigationItem.title = @"API Account Info";
35     userDetailsSection = 0;
36     getTokenSection = 1;
37     [self addSaveButton];
38     self.navigationItem.rightBarButtonItem.enabled = NO;
39 }
40
41 #pragma mark - Memory management
42
43 - (void)dealloc {
44     [username release];
45     [authToken release];
46     [activityIndicatorView release];
47     [account release];
48     [super dealloc];
49 }
50
51 #pragma mark - Internal
52
53 - (void) updateSaveButtonForUsername:(NSString *)checkUsername andAuthToken:(NSString *)checkAuthToken {
54     self.navigationItem.rightBarButtonItem.enabled = (checkUsername.length && checkAuthToken.length &&
55                                                       (![checkUsername isEqualToString:account.username] ||
56                                                        ![checkAuthToken isEqualToString:account.authToken]));
57 }
58
59 #pragma mark - Properties
60
61 - (void)setUsername:(NSString *)aUsername {
62     [username release];
63     username = [aUsername retain];
64     if (username)
65         [self updateSaveButtonForUsername:username andAuthToken:authTokenTextField.text];
66 }
67
68 - (void)setAuthToken:(NSString *)anAuthToken {
69     [authToken release];
70     authToken = [anAuthToken retain];
71     if (authToken)
72         [self updateSaveButtonForUsername:usernameTextField.text andAuthToken:authToken];
73 }
74
75 #pragma mark - UITableViewDataSource
76
77 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
78     return 2;
79 }
80
81 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
82     if (section == userDetailsSection)
83         return 2;
84     else
85         return 1;
86 }
87
88 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
89     if (section == userDetailsSection)
90         return [NSString stringWithFormat:@"%@ Login", self.account.provider.name];
91     else
92         return nil;
93 }
94
95 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
96     if (section == userDetailsSection)
97         return @"API Version 1.0";
98     else
99         return nil;
100 }
101
102 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
103     static NSString *CellIdentifier = @"Cell";
104     RSTextFieldCell *cell = nil;
105     if (indexPath.section == userDetailsSection) {
106         cell = (RSTextFieldCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
107         if (cell == nil) {
108             cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
109             cell.selectionStyle = UITableViewCellSelectionStyleNone;
110         }
111         
112         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
113             cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8];
114         }
115         
116         [cell.textLabel setBackgroundColor:[UIColor clearColor]];
117         
118         if (indexPath.row == kUsername) {
119             cell.textLabel.text = @"Username";
120             usernameTextField = cell.textField;
121             usernameTextField.delegate = self;
122             usernameTextField.secureTextEntry = NO;
123             usernameTextField.returnKeyType = UIReturnKeyNext;
124             if (username) {
125                 usernameTextField.text = username;
126             } else {
127                 usernameTextField.text = self.account.username;
128             }
129         } else if (indexPath.row == kAuthToken) {
130             cell.textLabel.text = @"Token";
131             authTokenTextField = cell.textField;
132             authTokenTextField.secureTextEntry = NO;
133             authTokenTextField.delegate = self;
134             authTokenTextField.returnKeyType = UIReturnKeyDone;
135             if (authToken) {
136                 authTokenTextField.text = authToken;
137             } else {
138                 authTokenTextField.text = self.account.authToken;
139             }
140         }
141     } else {
142         cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
143         if (cell == nil) {
144             cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
145         }
146         
147         cell.textLabel.text = @"Get Token";
148     }
149     return cell;
150 }
151
152 #pragma mark - UITableViewDelegate
153
154 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
155     if (indexPath.section == getTokenSection) {
156         NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login&force=", account.pithosLoginURLPrefix];
157         [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]];
158         [tableView deselectRowAtIndexPath:indexPath animated:NO];
159     }
160 }
161
162 #pragma mark - UITextFieldDelegate
163
164 - (BOOL)textFieldShouldReturn:(UITextField *)textField {
165     [textField resignFirstResponder];
166     if ([textField isEqual:usernameTextField]) {
167         [authTokenTextField becomeFirstResponder];
168     }
169     return NO;
170 }
171
172 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
173     NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string];
174     if ([textField isEqual:usernameTextField]) {
175         self.username = result;
176     } else if ([textField isEqual:authTokenTextField]) {
177         self.authToken = result;
178     }
179     return YES;
180 }
181
182 #pragma mark - Button Handlers
183
184 - (void)saveButtonPressed:(id)sender {
185     self.navigationItem.rightBarButtonItem.enabled = NO;
186     [self authenticate];
187 }
188
189 #pragma mark - HTTP Response Handlers
190
191 - (void)authenticationSucceded:(OpenStackRequest *)request {
192     [self.activityIndicatorView removeFromSuperview];
193     if ([request isSuccess]) {
194         account.username = request.account.username;
195         account.authToken = request.account.authToken;
196         NSString *storageURLString = [[request responseHeaders] objectForKey:@"X-Storage-Url"];
197         if (storageURLString) {
198             account.filesURL = [NSURL URLWithString:storageURLString];
199         } else {
200             account.filesURL = [[account.hostURL URLByAppendingPathComponent:@"v1"] URLByAppendingPathComponent:account.username];
201         }
202         [account persist];
203     } else {
204         self.navigationItem.rightBarButtonItem.enabled = YES;
205         [self alert:@"Authentication Failure" message:@"Please check your Username and Token."];
206     }
207 }
208
209 - (void)authenticationFailed:(OpenStackRequest *)request {
210     [self.activityIndicatorView removeFromSuperview];
211     self.navigationItem.rightBarButtonItem.enabled = YES;
212     if ([request responseStatusCode] == 401) {
213         [self alert:@"Authentication Failure" message:@"Please check your Username and Token."];
214     } else {
215         [self failOnBadConnection];
216     }
217 }
218
219 - (void)authenticate {
220     if (!usernameTextField.text || [usernameTextField.text isEqualToString:@""]) {
221         [self alert:nil message:@"Please enter your Username."];
222         self.navigationItem.rightBarButtonItem.enabled = YES;
223         [usernameTextField becomeFirstResponder];
224     } else if (!authTokenTextField.text || [authTokenTextField.text isEqualToString:@""]) {
225         [self alert:nil message:@"Please enter your Token."];
226         self.navigationItem.rightBarButtonItem.enabled = YES;
227         [authTokenTextField becomeFirstResponder];
228     } else {
229         OpenStackAccount *temporaryAccount = [[[OpenStackAccount alloc] init] autorelease];
230         temporaryAccount.provider = account.provider;
231         temporaryAccount.username = usernameTextField.text;
232         temporaryAccount.authToken = authTokenTextField.text;
233         
234         self.activityIndicatorView = [[[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Authenticating..."] text:@"Authenticating..."] autorelease];
235         [self.activityIndicatorView addToView:self.view];
236         
237         OpenStackRequest *request = [OpenStackRequest authenticationRequest:temporaryAccount];
238         request.delegate = self;
239         request.didFinishSelector = @selector(authenticationSucceded:);
240         request.didFailSelector = @selector(authenticationFailed:);
241         [request startAsynchronous];
242     }
243 }
244
245 @end
246