Developer Area

root/apps/iphone/my.tel/trunk/Classes/RecordEditController.m @ 254

Revision 250, 11.9 kB (checked in by henri, 5 years ago)

Moved record editing to use a navigation controller, in preparation for adding profile selection to record editing.

Line 
1//
2//  RecordEditController.m
3//  VIP.tel
4//
5//  Created by Henri Asseily on 11/21/08.
6//  Copyright 2008 Telnic Ltd.. All rights reserved.
7//
8// TODO: Handle NTNs by disabling the second row of the pickerview
9// and disabling the "visible" toggle. Also increase acceptable length of label
10// (check with engineers first)
11
12#import "RecordEditController.h"
13
14#define kRTransitionDuration    0.3
15
16#define kNTNLabelLength 100             // NTN label length             TODO: verify with engineers
17#define kTLabelLength 20                // Terminal label length
18
19@implementation RecordEditController
20
21@synthesize barHeader;
22@synthesize barButtonSave;
23@synthesize rPicker;
24@synthesize rValue;
25@synthesize rLabel;
26@synthesize rVisibility;
27@synthesize saveIndicator;
28@synthesize caller;
29
30#pragma mark ----- Calling methods
31
32- (void)presentViewForRecord:(NSDictionary *)aRec {
33        if (!self.navigationController.view) {
34                NSLog(@"Fatal error: record edit view wasn't properly loaded");
35                return;
36                //[self loadView];
37                // TODO: rpicker doesn't have any data here.
38                // Either exit this method without showing the view, or add to the RecordEditDelegate
39                // protocol a method for a callback to fill the rpicker.
40        }
41        [theRecord release];
42        if (!aRec) { // new
43                theRecord = [[NSMutableDictionary dictionaryWithCapacity:8] retain];
44                barHeader.title = @"New Item";
45                rValue.text = @"";
46                rLabel.text = @"";
47                rVisibility.on = TRUE;
48                [theRecord setObject:@"0" forKey:@"apiId"];
49                [theRecord setObject:[VIPConnect sharedInstance].selectedDomain forKey:@"domainName"];
50        } else { // edit
51                if (!aRec) {
52                        NSLog(@"Missing record for RecordEditController");
53                        return;
54                }
55                theRecord = [[NSMutableDictionary dictionaryWithDictionary:aRec] retain];
56                barHeader.title = @"Edit Item";
57                [theRecord setObject:[VIPConnect sharedInstance].selectedDomain forKey:@"domainName"];
58                // An NTN may not have the below items
59                if ([[theRecord objectForKey:@"label"] isKindOfClass:[NSNull class]])
60                        [theRecord setObject:@"" forKey:@"label"];
61                if ([[theRecord objectForKey:@"locations"] isKindOfClass:[NSNull class]])
62                        [theRecord setObject:[NSArray array] forKey:@"locations"];
63                if ([[theRecord objectForKey:@"serviceKeys"] isKindOfClass:[NSNull class]]) {
64                        if ([[theRecord objectForKey:@"terminal"] integerValue] == 0) {
65                                [theRecord setObject:[NSArray arrayWithObject:@"ntn"] forKey:@"serviceKeys"];
66                        } else {
67                                [theRecord setObject:[NSArray arrayWithObject:@""] forKey:@"serviceKeys"];
68                        }
69                }
70               
71                rValue.text = [theRecord objectForKey:@"value"];
72                rLabel.text = [theRecord objectForKey:@"label"];
73                if ([(NSArray *)[theRecord objectForKey:@"profiles"] containsObject:[VIPConnect sharedInstance].selectedProfileId]) {
74                        rVisibility.on = TRUE;
75                } else {
76                        rVisibility.on = FALSE;
77                }
78        }
79        // We only respect the first LIH and service types.
80        NSString *theService = [(NSArray *)[theRecord objectForKey:@"serviceKeys"] objectAtIndex:0];
81        NSString *theLi;
82        if ([(NSArray *)[theRecord objectForKey:@"locations"] count] == 0) {
83                theLi = @"";
84        } else {
85                theLi = [(NSArray *)[theRecord objectForKey:@"locations"] objectAtIndex:0];
86        }
87       
88        [rPicker selectRow:[sArrKey indexOfObject:theService] inComponent:0 animated:NO];
89        [rPicker selectRow:[liArrKey indexOfObject:theLi] inComponent:1 animated:NO];
90        [self viewWillAppear:YES];
91        // Insert our view at the absolute top
92        [[(UIViewController *)caller view].window addSubview:self.navigationController.view];
93        // Set up the animation
94    CATransition *animation = [CATransition animation];
95    [animation setDelegate:self];
96   
97        [animation setType:kCATransitionMoveIn];
98        [animation setSubtype:kCATransitionFromRight];
99   
100    // Set the duration and timing function of the transtion -- duration is passed in as a parameter, use ease in/ease out as the timing function
101    [animation setDuration:kRTransitionDuration];
102    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
103   
104    [[[(UIViewController *)caller view].window layer] addAnimation:animation forKey:@"kEditAnimation"];
105}
106
107- (void)setPickerCol1:(NSDictionary *)pickerData1 col2:(NSDictionary *)pickerData2 {
108        // Sets picker data and sorts the columns
109        NSUInteger i, count;
110
111        // Do first column
112        // First set the keys and related strings
113        [sArrKey setArray:[pickerData1 allKeys]];
114        [sArrVal removeAllObjects];
115        for (NSString *aK in sArrKey) {
116                [sArrVal addObject:[pickerData1 objectForKey:aK]];
117        }
118        // Create a reverse lookup to find the service keys from the strings
119        NSDictionary *pickerDict1 = [NSDictionary dictionaryWithObjects:sArrKey forKeys:sArrVal];
120        // Sort the string arrays as the picker strings
121        [sArrVal sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
122        // Resort the key arrays based on the strings arrays
123        count = [sArrVal count];
124        for (i = 0; i < count; i++) {
125                [sArrKey replaceObjectAtIndex:i
126                                                   withObject:[pickerDict1 objectForKey:[sArrVal objectAtIndex:i]]];
127        }
128        // and finally reload the picker component
129        [rPicker reloadComponent:0];
130       
131        // Same for second column, but also add a "None" entry
132        [liArrKey setArray:[pickerData2 allKeys]];
133        [liArrVal removeAllObjects];
134        for (NSString *aK in liArrKey) {
135                [liArrVal addObject:[pickerData2 objectForKey:aK]];
136        }
137        NSDictionary *pickerDict2 = [NSDictionary dictionaryWithObjects:liArrKey forKeys:liArrVal];
138        [liArrVal sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
139        count = [liArrVal count];
140        for (i = 0; i < count; i++) {
141                [liArrKey replaceObjectAtIndex:i
142                                                        withObject:[pickerDict2 objectForKey:[liArrVal objectAtIndex:i]]];
143        }
144        if ([(NSString *)[liArrKey objectAtIndex:0] length] != 0) {
145                // There isn't an "empty" choice, add it
146                [liArrKey insertObject:@"" atIndex:0];
147                [liArrVal insertObject:@"" atIndex:0];
148        }
149       
150        [rPicker reloadComponent:1];   
151}
152
153#pragma mark ------ Standard View Methods
154- (void)viewDidLoad {
155    [super viewDidLoad];
156        sArrKey = [[NSMutableArray arrayWithCapacity:30] retain];
157        sArrVal = [[NSMutableArray arrayWithCapacity:30] retain];
158        liArrKey = [[NSMutableArray arrayWithCapacity:10] retain];
159        liArrVal = [[NSMutableArray arrayWithCapacity:10] retain];
160}
161
162- (void)viewWillAppear:(BOOL)animated {
163//      [rPicker reloadComponent:0];
164//      [rPicker reloadComponent:1];
165}
166
167- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
168    // Return YES for supported orientations
169    return (interfaceOrientation == UIInterfaceOrientationPortrait);
170}
171
172
173- (void)didReceiveMemoryWarning {
174    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
175    // Release anything that's not essential, such as cached data
176}
177
178
179- (void)dealloc {
180        [sArrKey release];
181        [sArrVal release];
182        [liArrKey release];
183        [liArrVal release];
184        [naptrValuePlaceholders release];
185    [super dealloc];
186}
187
188#pragma mark ------ Actions
189
190- (IBAction)didClickCancel:(id)sender {
191        [self.navigationController.view removeFromSuperview];
192}
193
194- (IBAction)didClickSave:(id)sender {
195        // store value, label, profiles.
196        // servicekey and LI are set when the user selects the pickerViews
197        // apiId and domainName are set at the start in presentView
198        [theRecord setObject:rValue.text forKey:@"value"];
199        [theRecord setObject:rLabel.text forKey:@"label"];
200
201        NSMutableArray *newProfilesArray = [NSMutableArray arrayWithArray:[theRecord objectForKey:@"profiles"]];
202        [newProfilesArray removeObjectIdenticalTo:[VIPConnect sharedInstance].selectedProfileId];
203        if (rVisibility.on) {
204                [newProfilesArray addObject:[VIPConnect sharedInstance].selectedProfileId];
205        }
206        [theRecord setObject:newProfilesArray forKey:@"profiles"];
207       
208        // Store the record
209        barButtonSave.enabled = NO;
210        [saveIndicator startAnimating];
211        Record *conn = [[[Record alloc] init] autorelease];
212        [conn setTheDelegate:self];
213        [conn setActionSel:@selector(afterSaveAction:)];
214        [conn setConnectionUrl:[conn urlFromAction:@"storerecord"]];
215        [conn setPayload:theRecord];
216        [conn performLookup:TRUE];
217}
218
219- (void)afterSaveAction:(NSDictionary *)parsedJson {
220        if ([[parsedJson valueForKey:@"success"] integerValue] == 1) {
221                [caller didStoreRecord:theRecord];
222                [self.navigationController.view removeFromSuperview];
223        } else {
224                [JsonConnection throwJsonErrorAlert:parsedJson];
225        }
226        [saveIndicator stopAnimating];
227        barButtonSave.enabled = YES;   
228}
229
230#pragma mark ------ TextField delegate methods
231- (void)textFieldDidBeginEditing:(UITextField *)textField {
232        if (self.view.frame.origin.y >=0) {
233                CGRect newFrame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y -230,
234                                                                         self.view.frame.size.width, self.view.frame.size.height + 230);
235                self.view.frame = newFrame;
236        }
237        return;
238}
239- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
240        return YES;
241}
242- (BOOL)textFieldShouldReturn:(UITextField *)textField {
243        [textField resignFirstResponder];
244        if (self.view.frame.origin.y <0) {
245                CGRect newFrame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + 230,
246                                                                         self.view.frame.size.width, self.view.frame.size.height - 230);
247               
248                self.view.frame = newFrame;
249        }
250        return YES;
251}
252- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
253                                                                                        replacementString:(NSString *)string {
254        // Check length of fields. Terminal labels should be very short
255        if (textField == rLabel) {
256                if ([[theRecord objectForKey:@"terminal"] integerValue] == 0) {
257                        if ((range.location + range.length) >= kNTNLabelLength)
258                                return NO;
259                } else {
260                        if ((range.location + range.length) >= kTLabelLength)
261                                return NO;
262                }
263        }
264        return YES;
265}
266
267
268
269#pragma mark ------ Picker data source methods
270
271- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
272        return 2;
273}
274
275- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
276        if (component == 0) {
277                return [sArrVal count];
278        }
279        if (component == 1) {
280                if (!self.navigationController.view.superview) {        // View hasn't been loaded yet, check for ntn directly from record
281                        if ([[theRecord objectForKey:@"terminal"] integerValue] == 0)
282                                return 0;
283                } else {
284                        if ([[sArrKey objectAtIndex:[rPicker selectedRowInComponent:0]] isEqualToString:@"ntn"] )       // ntn: disable locations
285                                return 0;
286                }
287                return [liArrVal count];
288        }
289        return 0;
290}
291
292#pragma mark ------ Picker delegate methods
293
294- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
295        if (component == 0) {
296                [theRecord setObject:[NSArray arrayWithObject:[sArrKey objectAtIndex:row]]
297                                          forKey:@"serviceKeys"];
298                // Set the placeholder text in the value field to a nice example
299                if (!naptrValuePlaceholders) {
300                        naptrValuePlaceholders = [[NSDictionary dictionaryWithContentsOfFile:
301                                                 [[[NSBundle mainBundle] resourcePath]
302                                                  stringByAppendingPathComponent:@"NaptrValuePlaceholders.plist"]] retain];
303                }
304                rValue.placeholder = [naptrValuePlaceholders objectForKey:[sArrKey objectAtIndex:row]];
305                rValue.text = @"";
306                //  Synchronize the locations component for NTNs in service component
307                if ([[sArrKey objectAtIndex:row] isEqualToString:@"ntn"]) {
308                        if ([pickerView numberOfRowsInComponent:1] > 0)
309                                [pickerView reloadComponent:1];
310                } else {
311                        if ([pickerView numberOfRowsInComponent:1] == 0)
312                                [pickerView reloadComponent:1];
313                }
314        }
315        if (component == 1) {
316                if (row > -1) { // Not an ntn
317                        [theRecord setObject:[NSArray arrayWithObject:[liArrKey objectAtIndex:row]]
318                                                  forKey:@"locations"];
319                } else {
320                        [theRecord removeObjectForKey:@"locations"];
321
322                }
323
324        }
325}
326
327/*
328- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
329}
330 */
331
332- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
333        if (component == 0) {
334                return 200;
335        }
336        if (component == 1) {
337                return 100;
338        }
339        return 0;
340}
341
342
343- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
344        if (component == 0) {
345                return [sArrVal objectAtIndex:row];
346        }
347        if (component == 1) {
348                return [liArrVal objectAtIndex:row];
349        }
350        return @"";
351}
352
353/*
354- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row
355                  forComponent:(NSInteger)component reusingView:(UIView *)view {
356}
357 */
358                               
359@end
Note: See TracBrowser for help on using the browser.
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us