Blame client/iOS/Controllers/BookmarkListController.m

Packit 1fb8d4
/*
Packit 1fb8d4
 bookmarks and active session view controller
Packit Service 5a9772
Packit 1fb8d4
 Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
Packit Service 5a9772
Packit Service 5a9772
 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
Packit Service 5a9772
 If a copy of the MPL was not distributed with this file, You can obtain one at
Packit Service 5a9772
 http://mozilla.org/MPL/2.0/.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#import "BookmarkListController.h"
Packit 1fb8d4
#import "Utils.h"
Packit 1fb8d4
#import "BookmarkEditorController.h"
Packit 1fb8d4
#import "RDPSessionViewController.h"
Packit 1fb8d4
#import "Toast+UIView.h"
Packit 1fb8d4
#import "Reachability.h"
Packit 1fb8d4
#import "GlobalDefaults.h"
Packit 1fb8d4
#import "BlockAlertView.h"
Packit 1fb8d4
Packit Service 5a9772
#define SECTION_SESSIONS 0
Packit Service 5a9772
#define SECTION_BOOKMARKS 1
Packit Service 5a9772
#define NUM_SECTIONS 2
Packit 1fb8d4
Packit 1fb8d4
@interface BookmarkListController (Private)
Packit 1fb8d4
#pragma mark misc functions
Packit Service 5a9772
- (UIButton *)disclosureButtonWithImage:(UIImage *)image;
Packit Service 5a9772
- (void)performSearch:(NSString *)searchText;
Packit 1fb8d4
#pragma mark Persisting bookmarks
Packit 1fb8d4
- (void)scheduleWriteBookmarksToDataStore;
Packit 1fb8d4
- (void)writeBookmarksToDataStore;
Packit 1fb8d4
- (void)scheduleWriteManualBookmarksToDataStore;
Packit 1fb8d4
- (void)writeManualBookmarksToDataStore;
Packit 1fb8d4
- (void)readManualBookmarksFromDataStore;
Packit Service 5a9772
- (void)writeArray:(NSArray *)bookmarks toDataStoreURL:(NSURL *)url;
Packit Service 5a9772
- (NSMutableArray *)arrayFromDataStoreURL:(NSURL *)url;
Packit Service 5a9772
- (NSURL *)manualBookmarksDataStoreURL;
Packit Service 5a9772
- (NSURL *)connectionHistoryDataStoreURL;
Packit 1fb8d4
@end
Packit 1fb8d4
Packit 1fb8d4
@implementation BookmarkListController
Packit 1fb8d4
Packit Service 5a9772
@synthesize searchBar = _searchBar, tableView = _tableView, bmTableCell = _bmTableCell,
Packit Service 5a9772
            sessTableCell = _sessTableCell;
Packit 1fb8d4
Packit Service 5a9772
// The designated initializer.  Override if you create the controller programmatically and want to
Packit Service 5a9772
// perform customization that is not appropriate for viewDidLoad.
Packit Service 5a9772
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
Packit Service 5a9772
{
Packit Service 5a9772
	if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
Packit Service 5a9772
	{
Packit Service 5a9772
		// load bookmarks
Packit Service 5a9772
		[self readManualBookmarksFromDataStore];
Packit Service 5a9772
Packit Service 5a9772
		// load connection history
Packit Service 5a9772
		[self readConnectionHistoryFromDataStore];
Packit 1fb8d4
Packit 1fb8d4
		// init search result array
Packit Service 5a9772
		_manual_search_result = nil;
Packit Service 5a9772
Packit Service 5a9772
		// register for session notifications
Packit Service 5a9772
		[[NSNotificationCenter defaultCenter] addObserver:self
Packit Service 5a9772
		                                         selector:@selector(sessionDisconnected:)
Packit Service 5a9772
		                                             name:TSXSessionDidDisconnectNotification
Packit Service 5a9772
		                                           object:nil];
Packit Service 5a9772
		[[NSNotificationCenter defaultCenter] addObserver:self
Packit Service 5a9772
		                                         selector:@selector(sessionFailedToConnect:)
Packit Service 5a9772
		                                             name:TSXSessionDidFailToConnectNotification
Packit Service 5a9772
		                                           object:nil];
Packit Service 5a9772
Packit Service 5a9772
		// set title and tabbar controller image
Packit Service 5a9772
		[self setTitle:NSLocalizedString(@"Connections",
Packit Service 5a9772
		                                 @"'Connections': bookmark controller title")];
Packit Service 5a9772
		[self setTabBarItem:[[[UITabBarItem alloc]
Packit Service 5a9772
		                        initWithTabBarSystemItem:UITabBarSystemItemBookmarks
Packit Service 5a9772
		                                             tag:0] autorelease]];
Packit Service 5a9772
Packit Service 5a9772
		// load images
Packit Service 5a9772
		_star_on_img = [[UIImage
Packit Service 5a9772
		    imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"icon_accessory_star_on"
Packit Service 5a9772
		                                                            ofType:@"png"]] retain];
Packit Service 5a9772
		_star_off_img =
Packit Service 5a9772
		    [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
Packit Service 5a9772
		                                          pathForResource:@"icon_accessory_star_off"
Packit Service 5a9772
		                                                   ofType:@"png"]] retain];
Packit Service 5a9772
Packit Service 5a9772
		// init reachability detection
Packit Service 5a9772
		[[NSNotificationCenter defaultCenter] addObserver:self
Packit Service 5a9772
		                                         selector:@selector(reachabilityChanged:)
Packit Service 5a9772
		                                             name:kReachabilityChangedNotification
Packit Service 5a9772
		                                           object:nil];
Packit Service 5a9772
Packit Service 5a9772
		// init other properties
Packit Service 5a9772
		_active_sessions = [[NSMutableArray alloc] init];
Packit Service 5a9772
		_temporary_bookmark = nil;
Packit Service 5a9772
	}
Packit Service 5a9772
	return self;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)loadView
Packit 1fb8d4
{
Packit Service 5a9772
	[super loadView];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
Packit Service 5a9772
- (void)viewDidLoad
Packit Service 5a9772
{
Packit Service 5a9772
	[super viewDidLoad];
Packit 1fb8d4
Packit Service 5a9772
	// set edit button to allow bookmark list editing
Packit Service 5a9772
	[[self navigationItem] setRightBarButtonItem:[self editButtonItem]];
Packit Service 5a9772
}
Packit 1fb8d4
Packit Service 5a9772
- (void)viewWillAppear:(BOOL)animated
Packit 1fb8d4
{
Packit 1fb8d4
	[super viewWillAppear:animated];
Packit 1fb8d4
Packit Service 5a9772
	// in case we had a search - search again cause the bookmark searchable items could have changed
Packit Service 5a9772
	if ([[_searchBar text] length] > 0)
Packit Service 5a9772
		[self performSearch:[_searchBar text]];
Packit Service 5a9772
Packit Service 5a9772
	// to reflect any bookmark changes - reload table
Packit Service 5a9772
	[_tableView reloadData];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)viewWillDisappear:(BOOL)animated
Packit 1fb8d4
{
Packit Service 5a9772
	[super viewWillDisappear:animated];
Packit Service 5a9772
Packit Service 5a9772
	// clear any search
Packit Service 5a9772
	[_searchBar setText:@""];
Packit Service 5a9772
	[_searchBar resignFirstResponder];
Packit Service 5a9772
	[self performSearch:@""];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// Override to allow orientations other than the default portrait orientation.
Packit Service 5a9772
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
Packit Service 5a9772
{
Packit Service 5a9772
	// Return YES for supported orientations
Packit Service 5a9772
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)didReceiveMemoryWarning
Packit Service 5a9772
{
Packit Service 5a9772
	// Releases the view if it doesn't have a superview.
Packit Service 5a9772
	[super didReceiveMemoryWarning];
Packit 1fb8d4
Packit Service 5a9772
	// Release any cached data, images, etc that aren't in use.
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)viewDidUnload
Packit Service 5a9772
{
Packit Service 5a9772
	[super viewDidUnload];
Packit Service 5a9772
	// Release any retained subviews of the main view.
Packit Service 5a9772
	// e.g. self.myOutlet = nil;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)dealloc
Packit 1fb8d4
{
Packit Service 5a9772
	[[NSNotificationCenter defaultCenter] removeObserver:self];
Packit 1fb8d4
Packit Service 5a9772
	[_temporary_bookmark release];
Packit Service 5a9772
	[_connection_history release];
Packit Service 5a9772
	[_active_sessions release];
Packit 1fb8d4
	[_manual_search_result release];
Packit Service 5a9772
	[_manual_bookmarks release];
Packit 1fb8d4
Packit Service 5a9772
	[_star_on_img release];
Packit Service 5a9772
	[_star_off_img release];
Packit 1fb8d4
Packit Service 5a9772
	[super dealloc];
Packit Service 5a9772
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark -
Packit 1fb8d4
#pragma mark Table view data source
Packit 1fb8d4
Packit Service 5a9772
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
Packit Service 5a9772
{
Packit Service 5a9772
	// Return the number of sections.
Packit 1fb8d4
	return NUM_SECTIONS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
Packit Service 5a9772
{
Packit Service 5a9772
Packit Service 5a9772
	switch (section)
Packit 1fb8d4
	{
Packit Service 5a9772
		case SECTION_SESSIONS:
Packit Service 5a9772
			return 0;
Packit Service 5a9772
			break;
Packit Service 5a9772
Packit 1fb8d4
		case SECTION_BOOKMARKS:
Packit Service 5a9772
		{
Packit Service 5a9772
			// (+1 for Add Bookmark entry)
Packit Service 5a9772
			if (_manual_search_result != nil)
Packit Service 5a9772
				return ([_manual_search_result count] + [_history_search_result count] + 1);
Packit Service 5a9772
			return ([_manual_bookmarks count] + 1);
Packit Service 5a9772
		}
Packit Service 5a9772
		break;
Packit Service 5a9772
Packit 1fb8d4
		default:
Packit 1fb8d4
			break;
Packit 1fb8d4
	}
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (UITableViewCell *)cellForGenericListEntry
Packit 1fb8d4
{
Packit Service 5a9772
	static NSString *CellIdentifier = @"BookmarkListCell";
Packit Service 5a9772
	UITableViewCell *cell = [[self tableView] dequeueReusableCellWithIdentifier:CellIdentifier];
Packit Service 5a9772
	if (cell == nil)
Packit Service 5a9772
	{
Packit Service 5a9772
		cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
Packit Service 5a9772
		                              reuseIdentifier:CellIdentifier];
Packit Service 5a9772
		[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
Packit Service 5a9772
		[cell setAccessoryView:[self disclosureButtonWithImage:_star_off_img]];
Packit Service 5a9772
	}
Packit 1fb8d4
Packit Service 5a9772
	return cell;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (BookmarkTableCell *)cellForBookmark
Packit 1fb8d4
{
Packit Service 5a9772
	static NSString *BookmarkCellIdentifier = @"BookmarkCell";
Packit Service 5a9772
	BookmarkTableCell *cell = (BookmarkTableCell *)[[self tableView]
Packit Service 5a9772
	    dequeueReusableCellWithIdentifier:BookmarkCellIdentifier];
Packit Service 5a9772
	if (cell == nil)
Packit Service 5a9772
	{
Packit Service 5a9772
		[[NSBundle mainBundle] loadNibNamed:@"BookmarkTableViewCell" owner:self options:nil];
Packit Service 5a9772
		[_bmTableCell setAccessoryView:[self disclosureButtonWithImage:_star_on_img]];
Packit Service 5a9772
		cell = _bmTableCell;
Packit Service 5a9772
		_bmTableCell = nil;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return cell;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// Customize the appearance of table view cells.
Packit Service 5a9772
- (UITableViewCell *)tableView:(UITableView *)tableView
Packit Service 5a9772
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
Packit Service 5a9772
{
Packit Service 5a9772
Packit Service 5a9772
	switch ([indexPath section])
Packit Service 5a9772
	{
Packit Service 5a9772
		case SECTION_SESSIONS:
Packit Service 5a9772
		{
Packit Service 5a9772
			// get custom session cell
Packit Service 5a9772
			static NSString *SessionCellIdentifier = @"SessionCell";
Packit Service 5a9772
			SessionTableCell *cell = (SessionTableCell *)[tableView
Packit Service 5a9772
			    dequeueReusableCellWithIdentifier:SessionCellIdentifier];
Packit Service 5a9772
			if (cell == nil)
Packit Service 5a9772
			{
Packit Service 5a9772
				[[NSBundle mainBundle] loadNibNamed:@"SessionTableViewCell" owner:self options:nil];
Packit Service 5a9772
				cell = _sessTableCell;
Packit Service 5a9772
				_sessTableCell = nil;
Packit Service 5a9772
			}
Packit Service 5a9772
Packit Service 5a9772
			// set cell data
Packit Service 5a9772
			RDPSession *session = [_active_sessions objectAtIndex:[indexPath row]];
Packit Service 5a9772
			[[cell title] setText:[session sessionName]];
Packit Service 5a9772
			[[cell server] setText:[[session params] StringForKey:@"hostname"]];
Packit Service 5a9772
			[[cell username] setText:[[session params] StringForKey:@"username"]];
Packit Service 5a9772
			[[cell screenshot]
Packit Service 5a9772
			    setImage:[session getScreenshotWithSize:[[cell screenshot] bounds].size]];
Packit Service 5a9772
			[[cell disconnectButton] setTag:[indexPath row]];
Packit Service 5a9772
			return cell;
Packit Service 5a9772
		}
Packit Service 5a9772
Packit Service 5a9772
		case SECTION_BOOKMARKS:
Packit Service 5a9772
		{
Packit Service 5a9772
			// special handling for first cell - quick connect/quick create Bookmark cell
Packit Service 5a9772
			if ([indexPath row] == 0)
Packit Service 5a9772
			{
Packit Service 5a9772
				// if a search text is entered the cell becomes a quick connect/quick create
Packit Service 5a9772
				// bookmark cell - otherwise it's just an add bookmark cell
Packit Service 5a9772
				UITableViewCell *cell = [self cellForGenericListEntry];
Packit Service 5a9772
				if ([[_searchBar text] length] == 0)
Packit Service 5a9772
				{
Packit Service 5a9772
					[[cell textLabel]
Packit Service 5a9772
					    setText:[@"  " stringByAppendingString:
Packit Service 5a9772
					                       NSLocalizedString(@"Add Connection",
Packit Service 5a9772
					                                         @"'Add Connection': button label")]];
Packit Service 5a9772
					[((UIButton *)[cell accessoryView]) setHidden:YES];
Packit Service 5a9772
				}
Packit Service 5a9772
				else
Packit Service 5a9772
				{
Packit Service 5a9772
					[[cell textLabel] setText:[@"  " stringByAppendingString:[_searchBar text]]];
Packit Service 5a9772
					[((UIButton *)[cell accessoryView]) setHidden:NO];
Packit Service 5a9772
				}
Packit Service 5a9772
Packit Service 5a9772
				return cell;
Packit Service 5a9772
			}
Packit Service 5a9772
			else
Packit Service 5a9772
			{
Packit Service 5a9772
				// do we have a history cell or bookmark cell?
Packit Service 5a9772
				if ([self isIndexPathToHistoryItem:indexPath])
Packit Service 5a9772
				{
Packit Service 5a9772
					UITableViewCell *cell = [self cellForGenericListEntry];
Packit Service 5a9772
					[[cell textLabel]
Packit Service 5a9772
					    setText:[@"  " stringByAppendingString:
Packit Service 5a9772
					                       [_history_search_result
Packit Service 5a9772
					                           objectAtIndex:
Packit Service 5a9772
					                               [self historyIndexFromIndexPath:indexPath]]]];
Packit Service 5a9772
					[((UIButton *)[cell accessoryView]) setHidden:NO];
Packit Service 5a9772
					return cell;
Packit Service 5a9772
				}
Packit Service 5a9772
				else
Packit Service 5a9772
				{
Packit Service 5a9772
					// set cell properties
Packit Service 5a9772
					ComputerBookmark *entry;
Packit Service 5a9772
					BookmarkTableCell *cell = [self cellForBookmark];
Packit Service 5a9772
					if (_manual_search_result == nil)
Packit Service 5a9772
						entry = [_manual_bookmarks
Packit Service 5a9772
						    objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]];
Packit Service 5a9772
					else
Packit Service 5a9772
						entry = [[_manual_search_result
Packit Service 5a9772
						    objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]]
Packit Service 5a9772
						    valueForKey:@"bookmark"];
Packit Service 5a9772
Packit Service 5a9772
					[[cell title] setText:[entry label]];
Packit Service 5a9772
					[[cell subTitle] setText:[[entry params] StringForKey:@"hostname"]];
Packit Service 5a9772
					return cell;
Packit Service 5a9772
				}
Packit Service 5a9772
			}
Packit Service 5a9772
		}
Packit 1fb8d4
Packit Service 5a9772
		default:
Packit Service 5a9772
			break;
Packit Service 5a9772
	}
Packit 1fb8d4
Packit Service 5a9772
	NSAssert(0, @"Failed to create cell");
Packit Service 5a9772
	return nil;
Packit Service 5a9772
}
Packit 1fb8d4
Packit 1fb8d4
// Override to support conditional editing of the table view.
Packit Service 5a9772
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
Packit Service 5a9772
{
Packit 1fb8d4
	// dont allow to edit Add Bookmark item
Packit Service 5a9772
	if ([indexPath section] == SECTION_SESSIONS)
Packit 1fb8d4
		return NO;
Packit Service 5a9772
	if ([indexPath section] == SECTION_BOOKMARKS && [indexPath row] == 0)
Packit Service 5a9772
		return NO;
Packit Service 5a9772
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
// Override to support editing the table view.
Packit Service 5a9772
- (void)tableView:(UITableView *)tableView
Packit Service 5a9772
    commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
Packit Service 5a9772
     forRowAtIndexPath:(NSIndexPath *)indexPath
Packit 1fb8d4
{
Packit Service 5a9772
	if (editingStyle == UITableViewCellEditingStyleDelete)
Packit 1fb8d4
	{
Packit 1fb8d4
		// Delete the row from the data source
Packit Service 5a9772
		switch ([indexPath section])
Packit 1fb8d4
		{
Packit Service 5a9772
			case SECTION_BOOKMARKS:
Packit Service 5a9772
			{
Packit Service 5a9772
				if (_manual_search_result == nil)
Packit Service 5a9772
					[_manual_bookmarks
Packit Service 5a9772
					    removeObjectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]];
Packit Service 5a9772
				else
Packit Service 5a9772
				{
Packit Service 5a9772
					// history item or bookmark?
Packit Service 5a9772
					if ([self isIndexPathToHistoryItem:indexPath])
Packit Service 5a9772
					{
Packit Service 5a9772
						[_connection_history
Packit Service 5a9772
						    removeObject:
Packit Service 5a9772
						        [_history_search_result
Packit Service 5a9772
						            objectAtIndex:[self historyIndexFromIndexPath:indexPath]]];
Packit Service 5a9772
						[_history_search_result
Packit Service 5a9772
						    removeObjectAtIndex:[self historyIndexFromIndexPath:indexPath]];
Packit Service 5a9772
					}
Packit Service 5a9772
					else
Packit Service 5a9772
					{
Packit Service 5a9772
						[_manual_bookmarks
Packit Service 5a9772
						    removeObject:
Packit Service 5a9772
						        [[_manual_search_result
Packit Service 5a9772
						            objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]]
Packit Service 5a9772
						            valueForKey:@"bookmark"]];
Packit Service 5a9772
						[_manual_search_result
Packit Service 5a9772
						    removeObjectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]];
Packit Service 5a9772
					}
Packit Service 5a9772
				}
Packit Service 5a9772
				[self scheduleWriteManualBookmarksToDataStore];
Packit Service 5a9772
				break;
Packit Service 5a9772
			}
Packit 1fb8d4
		}
Packit 1fb8d4
Packit Service 5a9772
		[tableView reloadSections:[NSIndexSet indexSetWithIndex:[indexPath section]]
Packit Service 5a9772
		         withRowAnimation:UITableViewRowAnimationNone];
Packit Service 5a9772
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// Override to support rearranging the table view.
Packit Service 5a9772
- (void)tableView:(UITableView *)tableView
Packit Service 5a9772
    moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
Packit Service 5a9772
           toIndexPath:(NSIndexPath *)toIndexPath
Packit 1fb8d4
{
Packit Service 5a9772
	if ([fromIndexPath compare:toIndexPath] != NSOrderedSame)
Packit 1fb8d4
	{
Packit Service 5a9772
		switch ([fromIndexPath section])
Packit 1fb8d4
		{
Packit Service 5a9772
			case SECTION_BOOKMARKS:
Packit Service 5a9772
			{
Packit Service 5a9772
				int fromIdx = [self bookmarkIndexFromIndexPath:fromIndexPath];
Packit Service 5a9772
				int toIdx = [self bookmarkIndexFromIndexPath:toIndexPath];
Packit Service 5a9772
				ComputerBookmark *temp_bookmark =
Packit Service 5a9772
				    [[_manual_bookmarks objectAtIndex:fromIdx] retain];
Packit Service 5a9772
				[_manual_bookmarks removeObjectAtIndex:fromIdx];
Packit Service 5a9772
				if (toIdx >= [_manual_bookmarks count])
Packit Service 5a9772
					[_manual_bookmarks addObject:temp_bookmark];
Packit Service 5a9772
				else
Packit Service 5a9772
					[_manual_bookmarks insertObject:temp_bookmark atIndex:toIdx];
Packit Service 5a9772
				[temp_bookmark release];
Packit Service 5a9772
Packit Service 5a9772
				[self scheduleWriteManualBookmarksToDataStore];
Packit Service 5a9772
				break;
Packit Service 5a9772
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// prevent that an item is moved befoer the Add Bookmark item
Packit Service 5a9772
- (NSIndexPath *)tableView:(UITableView *)tableView
Packit Service 5a9772
    targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
Packit Service 5a9772
                         toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
Packit Service 5a9772
{
Packit Service 5a9772
	// don't allow to move:
Packit Service 5a9772
	//  - items between sections
Packit Service 5a9772
	//  - the quick connect/quick create bookmark cell
Packit Service 5a9772
	//  - any item while a search is applied
Packit Service 5a9772
	if ([proposedDestinationIndexPath row] == 0 ||
Packit Service 5a9772
	    ([sourceIndexPath section] != [proposedDestinationIndexPath section]) ||
Packit Service 5a9772
	    _manual_search_result != nil)
Packit Service 5a9772
	{
Packit Service 5a9772
		return sourceIndexPath;
Packit Service 5a9772
	}
Packit Service 5a9772
	else
Packit Service 5a9772
	{
Packit Service 5a9772
		return proposedDestinationIndexPath;
Packit Service 5a9772
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
// Override to support conditional rearranging of the table view.
Packit Service 5a9772
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
Packit Service 5a9772
{
Packit 1fb8d4
	// dont allow to reorder Add Bookmark item
Packit Service 5a9772
	if ([indexPath section] == SECTION_BOOKMARKS && [indexPath row] == 0)
Packit 1fb8d4
		return NO;
Packit Service 5a9772
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
Packit 1fb8d4
{
Packit Service 5a9772
	if (section == SECTION_SESSIONS && [_active_sessions count] > 0)
Packit 1fb8d4
		return NSLocalizedString(@"My Sessions", @"'My Session': section sessions header");
Packit Service 5a9772
	if (section == SECTION_BOOKMARKS)
Packit Service 5a9772
		return NSLocalizedString(@"Manual Connections",
Packit Service 5a9772
		                         @"'Manual Connections': section manual bookmarks header");
Packit 1fb8d4
	return nil;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
Packit 1fb8d4
{
Packit 1fb8d4
	return nil;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Packit 1fb8d4
{
Packit Service 5a9772
	if ([indexPath section] == SECTION_SESSIONS)
Packit Service 5a9772
		return 72;
Packit Service 5a9772
	return [tableView rowHeight];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark -
Packit 1fb8d4
#pragma mark Table view delegate
Packit 1fb8d4
Packit 1fb8d4
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
Packit 1fb8d4
{
Packit Service 5a9772
	[super setEditing:editing animated:animated];
Packit Service 5a9772
	[[self tableView] setEditing:editing animated:animated];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)accessoryButtonTapped:(UIControl *)button withEvent:(UIEvent *)event
Packit 1fb8d4
{
Packit Service 5a9772
	// forward a tap on our custom accessory button to the real accessory button handler
Packit Service 5a9772
	NSIndexPath *indexPath =
Packit Service 5a9772
	    [[self tableView] indexPathForRowAtPoint:[[[event touchesForView:button] anyObject]
Packit Service 5a9772
	                                                 locationInView:[self tableView]]];
Packit Service 5a9772
	if (indexPath == nil)
Packit Service 5a9772
		return;
Packit Service 5a9772
Packit Service 5a9772
	[[[self tableView] delegate] tableView:[self tableView]
Packit Service 5a9772
	    accessoryButtonTappedForRowWithIndexPath:indexPath];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Packit Service 5a9772
{
Packit Service 5a9772
	if ([indexPath section] == SECTION_SESSIONS)
Packit Service 5a9772
	{
Packit Service 5a9772
		// resume session
Packit Service 5a9772
		RDPSession *session = [_active_sessions objectAtIndex:[indexPath row]];
Packit Service 5a9772
		UIViewController *ctrl =
Packit Service 5a9772
		    [[[RDPSessionViewController alloc] initWithNibName:@"RDPSessionView"
Packit Service 5a9772
		                                                bundle:nil
Packit Service 5a9772
		                                               session:session] autorelease];
Packit Service 5a9772
		[ctrl setHidesBottomBarWhenPushed:YES];
Packit Service 5a9772
		[[self navigationController] pushViewController:ctrl animated:YES];
Packit Service 5a9772
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit Service 5a9772
		ComputerBookmark *bookmark = nil;
Packit Service 5a9772
		if ([indexPath section] == SECTION_BOOKMARKS)
Packit 1fb8d4
		{
Packit Service 5a9772
			// first row has either quick connect or add bookmark item
Packit Service 5a9772
			if ([indexPath row] == 0)
Packit Service 5a9772
			{
Packit Service 5a9772
				if ([[_searchBar text] length] == 0)
Packit Service 5a9772
				{
Packit Service 5a9772
					// show add bookmark controller
Packit Service 5a9772
					ComputerBookmark *bookmark =
Packit Service 5a9772
					    [[[ComputerBookmark alloc] initWithBaseDefaultParameters] autorelease];
Packit Service 5a9772
					BookmarkEditorController *bookmarkEditorController =
Packit Service 5a9772
					    [[[BookmarkEditorController alloc] initWithBookmark:bookmark] autorelease];
Packit Service 5a9772
					[bookmarkEditorController
Packit Service 5a9772
					    setTitle:NSLocalizedString(@"Add Connection", @"Add Connection title")];
Packit Service 5a9772
					[bookmarkEditorController setDelegate:self];
Packit Service 5a9772
					[bookmarkEditorController setHidesBottomBarWhenPushed:YES];
Packit Service 5a9772
					[[self navigationController] pushViewController:bookmarkEditorController
Packit Service 5a9772
					                                       animated:YES];
Packit Service 5a9772
				}
Packit Service 5a9772
				else
Packit Service 5a9772
				{
Packit Service 5a9772
					// create a quick connect bookmark and add an entry to the quick connect history
Packit Service 5a9772
					// (if not already in the history)
Packit Service 5a9772
					bookmark = [self bookmarkForQuickConnectTo:[_searchBar text]];
Packit Service 5a9772
					if (![_connection_history containsObject:[_searchBar text]])
Packit Service 5a9772
					{
Packit Service 5a9772
						[_connection_history addObject:[_searchBar text]];
Packit Service 5a9772
						[self scheduleWriteConnectionHistoryToDataStore];
Packit Service 5a9772
					}
Packit Service 5a9772
				}
Packit Service 5a9772
			}
Packit Service 5a9772
			else
Packit Service 5a9772
			{
Packit Service 5a9772
				if (_manual_search_result != nil)
Packit Service 5a9772
				{
Packit Service 5a9772
					if ([self isIndexPathToHistoryItem:indexPath])
Packit Service 5a9772
					{
Packit Service 5a9772
						// create a quick connect bookmark for a history item
Packit Service 5a9772
						NSString *item = [_history_search_result
Packit Service 5a9772
						    objectAtIndex:[self historyIndexFromIndexPath:indexPath]];
Packit Service 5a9772
						bookmark = [self bookmarkForQuickConnectTo:item];
Packit Service 5a9772
					}
Packit Service 5a9772
					else
Packit Service 5a9772
						bookmark = [[_manual_search_result
Packit Service 5a9772
						    objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]]
Packit Service 5a9772
						    valueForKey:@"bookmark"];
Packit Service 5a9772
				}
Packit Service 5a9772
				else
Packit Service 5a9772
					bookmark = [_manual_bookmarks
Packit Service 5a9772
					    objectAtIndex:[self bookmarkIndexFromIndexPath:
Packit Service 5a9772
					                            indexPath]]; // -1 because of ADD BOOKMARK entry
Packit Service 5a9772
			}
Packit Service 5a9772
Packit Service 5a9772
			// set reachability status
Packit Service 5a9772
			WakeUpWWAN();
Packit Service 5a9772
			[bookmark
Packit Service 5a9772
			    setConntectedViaWLAN:[[Reachability
Packit Service 5a9772
			                             reachabilityWithHostName:[[bookmark params]
Packit Service 5a9772
			                                                          StringForKey:@"hostname"]]
Packit Service 5a9772
			                             currentReachabilityStatus] == ReachableViaWiFi];
Packit 1fb8d4
		}
Packit Service 5a9772
Packit Service 5a9772
		if (bookmark != nil)
Packit Service 5a9772
		{
Packit 1fb8d4
			// create rdp session
Packit Service 5a9772
			RDPSession *session = [[[RDPSession alloc] initWithBookmark:bookmark] autorelease];
Packit Service 5a9772
			UIViewController *ctrl =
Packit Service 5a9772
			    [[[RDPSessionViewController alloc] initWithNibName:@"RDPSessionView"
Packit Service 5a9772
			                                                bundle:nil
Packit Service 5a9772
			                                               session:session] autorelease];
Packit Service 5a9772
			[ctrl setHidesBottomBarWhenPushed:YES];
Packit Service 5a9772
			[[self navigationController] pushViewController:ctrl animated:YES];
Packit Service 5a9772
			[_active_sessions addObject:session];
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)tableView:(UITableView *)tableView
Packit Service 5a9772
    accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
Packit Service 5a9772
{
Packit 1fb8d4
	// get the bookmark
Packit Service 5a9772
	NSString *bookmark_editor_title =
Packit Service 5a9772
	    NSLocalizedString(@"Edit Connection", @"Edit Connection title");
Packit Service 5a9772
	ComputerBookmark *bookmark = nil;
Packit 1fb8d4
	if ([indexPath section] == SECTION_BOOKMARKS)
Packit 1fb8d4
	{
Packit Service 5a9772
		if ([indexPath row] == 0)
Packit Service 5a9772
		{
Packit Service 5a9772
			// create a new bookmark and init hostname and label
Packit Service 5a9772
			bookmark = [self bookmarkForQuickConnectTo:[_searchBar text]];
Packit Service 5a9772
			bookmark_editor_title = NSLocalizedString(@"Add Connection", @"Add Connection title");
Packit Service 5a9772
		}
Packit Service 5a9772
		else
Packit Service 5a9772
		{
Packit Service 5a9772
			if (_manual_search_result != nil)
Packit Service 5a9772
			{
Packit Service 5a9772
				if ([self isIndexPathToHistoryItem:indexPath])
Packit Service 5a9772
				{
Packit Service 5a9772
					// create a new bookmark and init hostname and label
Packit Service 5a9772
					NSString *item = [_history_search_result
Packit Service 5a9772
					    objectAtIndex:[self historyIndexFromIndexPath:indexPath]];
Packit Service 5a9772
					bookmark = [self bookmarkForQuickConnectTo:item];
Packit Service 5a9772
					bookmark_editor_title =
Packit Service 5a9772
					    NSLocalizedString(@"Add Connection", @"Add Connection title");
Packit Service 5a9772
				}
Packit Service 5a9772
				else
Packit Service 5a9772
					bookmark = [[_manual_search_result
Packit Service 5a9772
					    objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]]
Packit Service 5a9772
					    valueForKey:@"bookmark"];
Packit Service 5a9772
			}
Packit Service 5a9772
			else
Packit Service 5a9772
				bookmark = [_manual_bookmarks
Packit Service 5a9772
				    objectAtIndex:[self bookmarkIndexFromIndexPath:indexPath]]; // -1 because of ADD
Packit Service 5a9772
				                                                                // BOOKMARK entry
Packit Service 5a9772
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	// bookmark found? - start the editor
Packit 1fb8d4
	if (bookmark != nil)
Packit 1fb8d4
	{
Packit Service 5a9772
		BookmarkEditorController *editBookmarkController =
Packit Service 5a9772
		    [[[BookmarkEditorController alloc] initWithBookmark:bookmark] autorelease];
Packit Service 5a9772
		[editBookmarkController setHidesBottomBarWhenPushed:YES];
Packit Service 5a9772
		[editBookmarkController setTitle:bookmark_editor_title];
Packit Service 5a9772
		[editBookmarkController setDelegate:self];
Packit Service 5a9772
		[[self navigationController] pushViewController:editBookmarkController animated:YES];
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark -
Packit 1fb8d4
#pragma mark Search Bar Delegates
Packit 1fb8d4
Packit Service 5a9772
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
Packit 1fb8d4
{
Packit 1fb8d4
	// show cancel button
Packit 1fb8d4
	[searchBar setShowsCancelButton:YES animated:YES];
Packit 1fb8d4
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
Packit 1fb8d4
{
Packit 1fb8d4
	// clear search result
Packit 1fb8d4
	[_manual_search_result release];
Packit 1fb8d4
	_manual_search_result = nil;
Packit Service 5a9772
Packit 1fb8d4
	// clear text and remove cancel button
Packit 1fb8d4
	[searchBar setText:@""];
Packit 1fb8d4
	[searchBar resignFirstResponder];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
Packit Service 5a9772
{
Packit 1fb8d4
	[searchBar setShowsCancelButton:NO animated:YES];
Packit Service 5a9772
Packit 1fb8d4
	// re-enable table selection
Packit 1fb8d4
	[_tableView setAllowsSelection:YES];
Packit Service 5a9772
Packit 1fb8d4
	return YES;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
Packit 1fb8d4
{
Packit 1fb8d4
	[_searchBar resignFirstResponder];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
Packit 1fb8d4
{
Packit Service 5a9772
	[self performSearch:searchText];
Packit 1fb8d4
	[_tableView reloadData];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark - Session handling
Packit 1fb8d4
Packit 1fb8d4
// session was added
Packit Service 5a9772
- (void)sessionDisconnected:(NSNotification *)notification
Packit Service 5a9772
{
Packit Service 5a9772
	// remove session from active sessions
Packit Service 5a9772
	RDPSession *session = (RDPSession *)[notification object];
Packit Service 5a9772
	[_active_sessions removeObject:session];
Packit Service 5a9772
Packit Service 5a9772
	// if this view is currently active refresh entries
Packit Service 5a9772
	if ([[self navigationController] visibleViewController] == self)
Packit Service 5a9772
		[_tableView reloadSections:[NSIndexSet indexSetWithIndex:SECTION_SESSIONS]
Packit Service 5a9772
		          withRowAnimation:UITableViewRowAnimationNone];
Packit Service 5a9772
Packit Service 5a9772
	// if session's bookmark is not in the bookmark list ask the user if he wants to add it
Packit Service 5a9772
	// (this happens if the session is created using the quick connect feature)
Packit Service 5a9772
	if (![_manual_bookmarks containsObject:[session bookmark]])
Packit Service 5a9772
	{
Packit Service 5a9772
		// retain the bookmark in case we want to save it later
Packit Service 5a9772
		_temporary_bookmark = [[session bookmark] retain];
Packit Service 5a9772
Packit Service 5a9772
		// ask the user if he wants to save the bookmark
Packit Service 5a9772
		NSString *title =
Packit Service 5a9772
		    NSLocalizedString(@"Save Connection Settings?", @"Save connection settings title");
Packit Service 5a9772
		NSString *message = NSLocalizedString(
Packit Service 5a9772
		    @"Your Connection Settings have not been saved. Do you want to save them?",
Packit Service 5a9772
		    @"Save connection settings message");
Packit Service 5a9772
		BlockAlertView *alert = [BlockAlertView alertWithTitle:title message:message];
Packit Service 5a9772
		[alert setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil];
Packit Service 5a9772
		[alert addButtonWithTitle:NSLocalizedString(@"Yes", @"Yes Button")
Packit Service 5a9772
		                    block:^{
Packit Service 5a9772
			                    if (_temporary_bookmark)
Packit Service 5a9772
			                    {
Packit Service 5a9772
				                    [_manual_bookmarks addObject:_temporary_bookmark];
Packit Service 5a9772
				                    [_tableView
Packit Service 5a9772
				                          reloadSections:[NSIndexSet
Packit Service 5a9772
				                                             indexSetWithIndex:SECTION_BOOKMARKS]
Packit Service 5a9772
				                        withRowAnimation:UITableViewRowAnimationNone];
Packit Service 5a9772
				                    [_temporary_bookmark autorelease];
Packit Service 5a9772
				                    _temporary_bookmark = nil;
Packit Service 5a9772
			                    }
Packit Service 5a9772
		                    }];
Packit Service 5a9772
		[alert show];
Packit Service 5a9772
	}
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
- (void)sessionFailedToConnect:(NSNotification *)notification
Packit Service 5a9772
{
Packit Service 5a9772
	// remove session from active sessions
Packit Service 5a9772
	RDPSession *session = (RDPSession *)[notification object];
Packit Service 5a9772
	[_active_sessions removeObject:session];
Packit Service 5a9772
Packit Service 5a9772
	// display error toast
Packit Service 5a9772
	[[self view] makeToast:NSLocalizedString(@"Failed to connect to session!",
Packit Service 5a9772
	                                         @"Failed to connect error message")
Packit Service 5a9772
	              duration:ToastDurationNormal
Packit Service 5a9772
	              position:@"center"];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark - Reachability notification
Packit Service 5a9772
- (void)reachabilityChanged:(NSNotification *)notification
Packit 1fb8d4
{
Packit Service 5a9772
	// no matter how the network changed - we will disconnect
Packit Service 5a9772
	// disconnect session (if there is any)
Packit Service 5a9772
	if ([_active_sessions count] > 0)
Packit Service 5a9772
	{
Packit Service 5a9772
		RDPSession *session = [_active_sessions objectAtIndex:0];
Packit Service 5a9772
		[session disconnect];
Packit Service 5a9772
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark - BookmarkEditorController delegate
Packit 1fb8d4
Packit 1fb8d4
- (void)commitBookmark:(ComputerBookmark *)bookmark
Packit 1fb8d4
{
Packit Service 5a9772
	// if we got a manual bookmark that is not in the list yet - add it otherwise replace it
Packit Service 5a9772
	BOOL found = NO;
Packit Service 5a9772
	for (int idx = 0; idx < [_manual_bookmarks count]; ++idx)
Packit Service 5a9772
	{
Packit Service 5a9772
		if ([[bookmark uuid] isEqualToString:[[_manual_bookmarks objectAtIndex:idx] uuid]])
Packit Service 5a9772
		{
Packit Service 5a9772
			[_manual_bookmarks replaceObjectAtIndex:idx withObject:bookmark];
Packit Service 5a9772
			found = YES;
Packit Service 5a9772
			break;
Packit Service 5a9772
		}
Packit Service 5a9772
	}
Packit Service 5a9772
	if (!found)
Packit Service 5a9772
		[_manual_bookmarks addObject:bookmark];
Packit Service 5a9772
Packit Service 5a9772
	// remove any quick connect history entry with the same hostname
Packit Service 5a9772
	NSString *hostname = [[bookmark params] StringForKey:@"hostname"];
Packit Service 5a9772
	if ([_connection_history containsObject:hostname])
Packit Service 5a9772
	{
Packit Service 5a9772
		[_connection_history removeObject:hostname];
Packit Service 5a9772
		[self scheduleWriteConnectionHistoryToDataStore];
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	[self scheduleWriteManualBookmarksToDataStore];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (IBAction)disconnectButtonPressed:(id)sender
Packit 1fb8d4
{
Packit Service 5a9772
	// disconnect session and refresh table view
Packit Service 5a9772
	RDPSession *session = [_active_sessions objectAtIndex:[sender tag]];
Packit Service 5a9772
	[session disconnect];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark - Misc functions
Packit 1fb8d4
Packit 1fb8d4
- (BOOL)hasNoBookmarks
Packit 1fb8d4
{
Packit Service 5a9772
	return ([_manual_bookmarks count] == 0);
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (UIButton *)disclosureButtonWithImage:(UIImage *)image
Packit 1fb8d4
{
Packit Service 5a9772
	// we make the button a little bit bigger (image widht * 2, height + 10) so that the user
Packit Service 5a9772
	// doesn't accidentally connect to the bookmark ...
Packit Service 5a9772
	UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
Packit Service 5a9772
	[button setFrame:CGRectMake(0, 0, [image size].width * 2, [image size].height + 10)];
Packit Service 5a9772
	[button setImage:image forState:UIControlStateNormal];
Packit Service 5a9772
	[button addTarget:self
Packit Service 5a9772
	              action:@selector(accessoryButtonTapped:withEvent:)
Packit Service 5a9772
	    forControlEvents:UIControlEventTouchUpInside];
Packit Service 5a9772
	[button setUserInteractionEnabled:YES];
Packit Service 5a9772
	return button;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)performSearch:(NSString *)searchText
Packit 1fb8d4
{
Packit Service 5a9772
	[_manual_search_result autorelease];
Packit Service 5a9772
Packit Service 5a9772
	if ([searchText length] > 0)
Packit 1fb8d4
	{
Packit Service 5a9772
		_manual_search_result = [FilterBookmarks(
Packit Service 5a9772
		    _manual_bookmarks,
Packit Service 5a9772
		    [searchText componentsSeparatedByCharactersInSet:[NSCharacterSet
Packit Service 5a9772
		                                                         whitespaceAndNewlineCharacterSet]])
Packit Service 5a9772
		    retain];
Packit Service 5a9772
		_history_search_result = [FilterHistory(_connection_history, searchText) retain];
Packit Service 5a9772
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit Service 5a9772
		_history_search_result = nil;
Packit 1fb8d4
		_manual_search_result = nil;
Packit Service 5a9772
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (int)bookmarkIndexFromIndexPath:(NSIndexPath *)indexPath
Packit 1fb8d4
{
Packit Service 5a9772
	return [indexPath row] -
Packit Service 5a9772
	       ((_history_search_result != nil) ? [_history_search_result count] : 0) - 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (int)historyIndexFromIndexPath:(NSIndexPath *)indexPath
Packit 1fb8d4
{
Packit Service 5a9772
	return [indexPath row] - 1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (BOOL)isIndexPathToHistoryItem:(NSIndexPath *)indexPath
Packit 1fb8d4
{
Packit Service 5a9772
	return (([indexPath row] - 1) < [_history_search_result count]);
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (ComputerBookmark *)bookmarkForQuickConnectTo:(NSString *)host
Packit 1fb8d4
{
Packit Service 5a9772
	ComputerBookmark *bookmark =
Packit Service 5a9772
	    [[[ComputerBookmark alloc] initWithBaseDefaultParameters] autorelease];
Packit Service 5a9772
	[bookmark setLabel:host];
Packit Service 5a9772
	[[bookmark params] setValue:host forKey:@"hostname"];
Packit Service 5a9772
	return bookmark;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#pragma mark - Persisting bookmarks
Packit 1fb8d4
Packit 1fb8d4
- (void)scheduleWriteBookmarksToDataStore
Packit 1fb8d4
{
Packit 1fb8d4
	[[NSOperationQueue mainQueue] addOperationWithBlock:^{
Packit 1fb8d4
		[self writeBookmarksToDataStore];
Packit 1fb8d4
	}];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)writeBookmarksToDataStore
Packit Service 5a9772
{
Packit Service 5a9772
	[self writeManualBookmarksToDataStore];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)scheduleWriteManualBookmarksToDataStore
Packit 1fb8d4
{
Packit Service 5a9772
	[[NSOperationQueue mainQueue]
Packit Service 5a9772
	    addOperation:[[[NSInvocationOperation alloc]
Packit Service 5a9772
	                     initWithTarget:self
Packit Service 5a9772
	                           selector:@selector(writeManualBookmarksToDataStore)
Packit Service 5a9772
	                             object:nil] autorelease]];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)writeManualBookmarksToDataStore
Packit Service 5a9772
{
Packit Service 5a9772
	[self writeArray:_manual_bookmarks toDataStoreURL:[self manualBookmarksDataStoreURL]];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)scheduleWriteConnectionHistoryToDataStore
Packit 1fb8d4
{
Packit Service 5a9772
	[[NSOperationQueue mainQueue]
Packit Service 5a9772
	    addOperation:[[[NSInvocationOperation alloc]
Packit Service 5a9772
	                     initWithTarget:self
Packit Service 5a9772
	                           selector:@selector(writeConnectionHistoryToDataStore)
Packit Service 5a9772
	                             object:nil] autorelease]];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)writeConnectionHistoryToDataStore
Packit Service 5a9772
{
Packit Service 5a9772
	[self writeArray:_connection_history toDataStoreURL:[self connectionHistoryDataStoreURL]];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (void)writeArray:(NSArray *)bookmarks toDataStoreURL:(NSURL *)url
Packit 1fb8d4
{
Packit Service 5a9772
	NSData *archived_data = [NSKeyedArchiver archivedDataWithRootObject:bookmarks];
Packit Service 5a9772
	[archived_data writeToURL:url atomically:YES];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)readManualBookmarksFromDataStore
Packit 1fb8d4
{
Packit Service 5a9772
	[_manual_bookmarks autorelease];
Packit Service 5a9772
	_manual_bookmarks = [self arrayFromDataStoreURL:[self manualBookmarksDataStoreURL]];
Packit 1fb8d4
Packit Service 5a9772
	if (_manual_bookmarks == nil)
Packit Service 5a9772
	{
Packit Service 5a9772
		_manual_bookmarks = [[NSMutableArray alloc] init];
Packit Service 5a9772
		[_manual_bookmarks
Packit Service 5a9772
		    addObject:[[[GlobalDefaults sharedGlobalDefaults] newTestServerBookmark] autorelease]];
Packit Service 5a9772
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
- (void)readConnectionHistoryFromDataStore
Packit 1fb8d4
{
Packit Service 5a9772
	[_connection_history autorelease];
Packit Service 5a9772
	_connection_history = [self arrayFromDataStoreURL:[self connectionHistoryDataStoreURL]];
Packit Service 5a9772
Packit Service 5a9772
	if (_connection_history == nil)
Packit Service 5a9772
		_connection_history = [[NSMutableArray alloc] init];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (NSMutableArray *)arrayFromDataStoreURL:(NSURL *)url
Packit 1fb8d4
{
Packit Service 5a9772
	NSData *archived_data = [NSData dataWithContentsOfURL:url];
Packit Service 5a9772
Packit 1fb8d4
	if (!archived_data)
Packit 1fb8d4
		return nil;
Packit Service 5a9772
Packit 1fb8d4
	return [[NSKeyedUnarchiver unarchiveObjectWithData:archived_data] retain];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (NSURL *)manualBookmarksDataStoreURL
Packit 1fb8d4
{
Packit Service 5a9772
	return [NSURL
Packit Service 5a9772
	    fileURLWithPath:[NSString stringWithFormat:@"%@/%@",
Packit Service 5a9772
	                                               [NSSearchPathForDirectoriesInDomains(
Packit Service 5a9772
	                                                   NSDocumentDirectory, NSUserDomainMask, YES)
Packit Service 5a9772
	                                                   lastObject],
Packit Service 5a9772
	                                               @"com.freerdp.ifreerdp.bookmarks.plist"]];
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
- (NSURL *)connectionHistoryDataStoreURL
Packit 1fb8d4
{
Packit Service 5a9772
	return [NSURL
Packit Service 5a9772
	    fileURLWithPath:[NSString
Packit Service 5a9772
	                        stringWithFormat:@"%@/%@",
Packit Service 5a9772
	                                         [NSSearchPathForDirectoriesInDomains(
Packit Service 5a9772
	                                             NSDocumentDirectory, NSUserDomainMask, YES)
Packit Service 5a9772
	                                             lastObject],
Packit Service 5a9772
	                                         @"com.freerdp.ifreerdp.connection_history.plist"]];
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
@end