FreeRDP
BookmarkEditorController.m
1 /*
2  Bookmark editor controller
3 
4  Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
5 
6  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
7  If a copy of the MPL was not distributed with this file, You can obtain one at
8  http://mozilla.org/MPL/2.0/.
9  */
10 
11 #import "BookmarkEditorController.h"
12 #import "Bookmark.h"
13 #import "Utils.h"
14 #import "ScreenSelectionController.h"
15 #import "PerformanceEditorController.h"
16 #import "CredentialsEditorController.h"
17 #import "AdvancedBookmarkEditorController.h"
18 #import "BlockAlertView.h"
19 
20 @implementation BookmarkEditorController
21 
22 @synthesize delegate;
23 
24 #define SECTION_SERVER 0
25 #define SECTION_CREDENTIALS 1
26 #define SECTION_SETTINGS 2
27 #define SECTION_COUNT 3
28 
29 #pragma mark -
30 #pragma mark Initialization
31 
32 - (id)initWithBookmark:(ComputerBookmark *)bookmark
33 {
34  if ((self = [super initWithStyle:UITableViewStyleGrouped]))
35  {
36  // set additional settings state according to bookmark data
37  if ([[bookmark uuid] length] == 0)
38  _bookmark = [bookmark copy];
39  else
40  _bookmark = [bookmark copyWithUUID];
41  _params = [_bookmark params];
42 
43  _display_server_settings = YES;
44  }
45  return self;
46 }
47 
48 #pragma mark -
49 #pragma mark View lifecycle
50 
51 - (void)viewDidLoad
52 {
53  [super viewDidLoad];
54 
55  // replace back button with a custom handler that checks if the required bookmark settings were
56  // specified
57  UIBarButtonItem *saveButton =
58  [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Save", @"Save Button title")
59  style:UIBarButtonItemStyleDone
60  target:self
61  action:@selector(handleSave:)] autorelease];
62  UIBarButtonItem *cancelButton =
63  [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", @"Cancel Button title")
64  style:UIBarButtonItemStyleBordered
65  target:self
66  action:@selector(handleCancel:)] autorelease];
67  [[self navigationItem] setLeftBarButtonItem:cancelButton];
68  [[self navigationItem] setRightBarButtonItem:saveButton];
69 }
70 
71 - (void)viewWillAppear:(BOOL)animated
72 {
73  [super viewWillAppear:animated];
74 
75  // we need to reload the table view data here to have up-to-date data for the
76  // advanced settings accessory items (like for resolution/color mode settings)
77  [[self tableView] reloadData];
78 }
79 
80 // Override to allow orientations other than the default portrait orientation.
81 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
82 {
83  return YES;
84 }
85 
86 #pragma mark -
87 #pragma mark Table view data source
88 
89 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
90 {
91  // Return the number of sections.
92  return SECTION_COUNT;
93 }
94 
95 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
96 {
97  // Return the number of rows in the section.
98  switch (section)
99  {
100  case SECTION_SERVER: // server settings
101  return (_display_server_settings ? 3 : 0);
102  case SECTION_CREDENTIALS: // credentials
103  return 1;
104  case SECTION_SETTINGS: // session settings
105  return 3;
106  default:
107  break;
108  }
109 
110  return 0;
111 }
112 
113 // set section headers
114 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
115 {
116  switch (section)
117  {
118  case SECTION_SERVER:
119  return (_display_server_settings
120  ? NSLocalizedString(@"Host", @"'Host': host settings header")
121  : nil);
122  case SECTION_CREDENTIALS:
123  return NSLocalizedString(@"Credentials", @"'Credentials': credentials settings header");
124  case SECTION_SETTINGS:
125  return NSLocalizedString(@"Settings", @"'Session Settings': session settings header");
126  }
127  return @"unknown";
128 }
129 
130 // Customize the appearance of table view cells.
131 - (UITableViewCell *)tableView:(UITableView *)tableView
132  cellForRowAtIndexPath:(NSIndexPath *)indexPath
133 {
134 
135  // determine the required cell type
136  NSString *cellType = nil;
137  switch ([indexPath section])
138  {
139  case SECTION_SERVER:
140  cellType = TableCellIdentifierText;
141  break;
142 
143  case SECTION_CREDENTIALS:
144  cellType = TableCellIdentifierSelection;
145  break;
146 
147  case SECTION_SETTINGS: // settings
148  {
149  switch ([indexPath row])
150  {
151  case 0: // screen/color depth
152  cellType = TableCellIdentifierSelection;
153  break;
154  case 1: // performance settings
155  case 2: // advanced settings
156  cellType = TableCellIdentifierSubEditor;
157  break;
158  default:
159  break;
160  }
161  }
162  break;
163 
164  default:
165  break;
166  }
167  NSAssert(cellType != nil, @"Couldn't determine cell type");
168 
169  // get the table view cell
170  UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
171  NSAssert(cell, @"Invalid cell");
172 
173  // set cell values
174  switch ([indexPath section])
175  {
176  // server settings
177  case SECTION_SERVER:
178  [self initServerSettings:indexPath cell:cell];
179  break;
180 
181  // credentials
182  case SECTION_CREDENTIALS:
183  [self initCredentialSettings:indexPath cell:cell];
184  break;
185 
186  // session settings
187  case SECTION_SETTINGS:
188  [self initSettings:indexPath cell:cell];
189  break;
190 
191  default:
192  break;
193  }
194 
195  return cell;
196 }
197 
198 // updates server settings in the UI
199 - (void)initServerSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
200 {
201  EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
202  [[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
203  switch ([indexPath row])
204  {
205  case 0:
206  [[textCell label] setText:NSLocalizedString(@"Label", @"'Label': Bookmark label")];
207  [[textCell textfield] setText:[_bookmark label]];
208  [[textCell textfield]
209  setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
210  break;
211  case 1:
212  [[textCell label] setText:NSLocalizedString(@"Host", @"'Host': Bookmark hostname")];
213  [[textCell textfield] setText:[_params StringForKey:@"hostname"]];
214  [[textCell textfield]
215  setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
216  break;
217  case 2:
218  [[textCell label] setText:NSLocalizedString(@"Port", @"'Port': Bookmark port")];
219  [[textCell textfield]
220  setText:[NSString stringWithFormat:@"%d", [_params intForKey:@"port"]]];
221  [[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
222  break;
223  default:
224  NSLog(@"Invalid row index in settings table!");
225  break;
226  }
227 
228  [self adjustEditTextTableViewCell:textCell];
229 }
230 
231 // updates credentials in the UI
232 - (void)initCredentialSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
233 {
235  switch (indexPath.row)
236  {
237  case 0:
238  [[selCell label]
239  setText:NSLocalizedString(@"Credentials", @"'Credentials': Bookmark credentials")];
240  [[selCell selection] setText:[_params StringForKey:@"username"]];
241  break;
242  default:
243  NSLog(@"Invalid row index in settings table!");
244  break;
245  }
246 }
247 
248 // updates session settings in the UI
249 - (void)initSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
250 {
251  switch (indexPath.row)
252  {
253  case 0:
254  {
256  [[selCell label]
257  setText:NSLocalizedString(@"Screen", @"'Screen': Bookmark Screen settings")];
258  NSString *resolution = ScreenResolutionDescription(
259  [_params intForKey:@"screen_resolution_type"], [_params intForKey:@"width"],
260  [_params intForKey:@"height"]);
261  int colorBits = [_params intForKey:@"colors"];
262  [[selCell selection]
263  setText:[NSString stringWithFormat:@"%@@%d", resolution, colorBits]];
264  break;
265  }
266  case 1:
267  {
269  [[editCell label]
270  setText:NSLocalizedString(@"Performance",
271  @"'Performance': Bookmark Performance Settings")];
272  break;
273  }
274  case 2:
275  {
277  [[editCell label]
278  setText:NSLocalizedString(@"Advanced", @"'Advanced': Bookmark Advanced Settings")];
279  break;
280  }
281  default:
282  NSLog(@"Invalid row index in settings table!");
283  break;
284  }
285 }
286 
287 #pragma mark -
288 #pragma mark Table view delegate
289 
290 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
291 {
292  UIViewController *viewCtrl = nil;
293 
294  // determine view
295  switch ([indexPath section])
296  {
297  case SECTION_CREDENTIALS:
298  {
299  if ([indexPath row] == 0)
300  viewCtrl =
301  [[[CredentialsEditorController alloc] initWithBookmark:_bookmark] autorelease];
302  break;
303  }
304 
305  case SECTION_SETTINGS:
306  {
307  switch ([indexPath row])
308  {
309  case 0:
310  viewCtrl = [[[ScreenSelectionController alloc] initWithConnectionParams:_params]
311  autorelease];
312  break;
313  case 1:
314  viewCtrl = [[[PerformanceEditorController alloc]
315  initWithConnectionParams:_params] autorelease];
316  break;
317  case 2:
318  viewCtrl = [[[AdvancedBookmarkEditorController alloc]
319  initWithBookmark:_bookmark] autorelease];
320  break;
321  default:
322  break;
323  }
324 
325  break;
326  }
327  }
328 
329  // display view
330  if (viewCtrl)
331  [[self navigationController] pushViewController:viewCtrl animated:YES];
332 }
333 
334 #pragma mark -
335 #pragma mark Text Field delegate
336 
337 - (BOOL)textFieldShouldReturn:(UITextField *)textField
338 {
339  [textField resignFirstResponder];
340  return NO;
341 }
342 
343 - (BOOL)textFieldShouldEndEditing:(UITextField *)textField
344 {
345  switch (textField.tag)
346  {
347  // update server settings
348  case GET_TAG(SECTION_SERVER, 0):
349  [_bookmark setLabel:[textField text]];
350  break;
351 
352  case GET_TAG(SECTION_SERVER, 1):
353  [_params setValue:[textField text] forKey:@"hostname"];
354  break;
355 
356  case GET_TAG(SECTION_SERVER, 2):
357  [_params setInt:[[textField text] intValue] forKey:@"port"];
358  break;
359 
360  default:
361  break;
362  }
363  return YES;
364 }
365 
366 #pragma mark -
367 #pragma mark Action Handlers
368 
369 - (void)handleSave:(id)sender
370 {
371  // resign any first responder (so that we finish editing any bookmark parameter that might be
372  // currently edited)
373  [[self view] endEditing:NO];
374 
375  // verify that bookmark is complete (only for manual bookmarks)
376  if ([[_bookmark label] length] == 0 || [[_params StringForKey:@"hostname"] length] == 0 ||
377  [_params intForKey:@"port"] == 0)
378  {
379  BlockAlertView *alertView = [BlockAlertView
380  alertWithTitle:NSLocalizedString(@"Cancel without saving?",
381  @"Incomplete bookmark error title")
382  message:NSLocalizedString(@"Press 'Cancel' to abort!\nPress 'Continue' to "
383  @"specify the required fields!",
384  @"Incomplete bookmark error message")];
385  [alertView
386  setCancelButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel Button")
387  block:^{
388  // cancel bookmark editing and return to previous view controller
389  [[self navigationController] popViewControllerAnimated:YES];
390  }];
391  [alertView addButtonWithTitle:NSLocalizedString(@"Continue", @"Continue Button") block:nil];
392  [alertView show];
393  return;
394  }
395 
396  // commit bookmark
397  if ([[self delegate] respondsToSelector:@selector(commitBookmark:)])
398  [[self delegate] commitBookmark:_bookmark];
399 
400  // return to previous view controller
401  [[self navigationController] popViewControllerAnimated:YES];
402 }
403 
404 - (void)handleCancel:(id)sender
405 {
406  // return to previous view controller
407  [[self navigationController] popViewControllerAnimated:YES];
408 }
409 
410 #pragma mark -
411 #pragma mark Memory management
412 
413 - (void)didReceiveMemoryWarning
414 {
415  // Releases the view if it doesn't have a superview.
416  [super didReceiveMemoryWarning];
417 
418  // Relinquish ownership any cached data, images, etc that aren't in use.
419 }
420 
421 - (void)dealloc
422 {
423  [super dealloc];
424  [_bookmark autorelease];
425 }
426 
427 @end