Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -0,0 +1,40 @@
//
// OrderedDictionary.h
// OrderedDictionary
//
// Modified version (Added indexForKey/Value functions)
//
// Created by Matt Gallagher on 19/12/08.
// Copyright 2008 Matt Gallagher. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. Permission is granted to anyone to
// use this software for any purpose, including commercial applications, and to
// alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//
#import <Foundation/Foundation.h>
@interface OrderedDictionary : NSMutableDictionary
{
NSMutableDictionary *dictionary;
NSMutableArray *array;
}
- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex;
- (id)keyAtIndex:(NSUInteger)anIndex;
- (NSUInteger)indexForValue:(id)value;
- (NSUInteger)indexForKey:(id)key;
- (NSEnumerator *)reverseKeyEnumerator;
@end

View File

@@ -0,0 +1,167 @@
//
// OrderedDictionary.m
// OrderedDictionary
//
// Modified version (Added indexForKey/Value functions)
//
// Created by Matt Gallagher on 19/12/08.
// Copyright 2008 Matt Gallagher. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. Permission is granted to anyone to
// use this software for any purpose, including commercial applications, and to
// alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//
#import "OrderedDictionary.h"
NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent)
{
NSString *objectString;
if ([object isKindOfClass:[NSString class]])
{
objectString = (NSString *)[[object retain] autorelease];
}
else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)])
{
objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent];
}
else if ([object respondsToSelector:@selector(descriptionWithLocale:)])
{
objectString = [(NSSet *)object descriptionWithLocale:locale];
}
else
{
objectString = [object description];
}
return objectString;
}
@implementation OrderedDictionary
- (id)init
{
return [self initWithCapacity:0];
}
- (id)initWithCapacity:(NSUInteger)capacity
{
self = [super init];
if (self != nil)
{
dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
array = [[NSMutableArray alloc] initWithCapacity:capacity];
}
return self;
}
- (void)dealloc
{
[dictionary release];
[array release];
[super dealloc];
}
- (id)copy
{
return [self mutableCopy];
}
- (void)setObject:(id)anObject forKey:(id)aKey
{
if (![dictionary objectForKey:aKey])
{
[array addObject:aKey];
}
[dictionary setObject:anObject forKey:aKey];
}
- (void)removeObjectForKey:(id)aKey
{
[dictionary removeObjectForKey:aKey];
[array removeObject:aKey];
}
- (NSUInteger)count
{
return [dictionary count];
}
- (id)objectForKey:(id)aKey
{
return [dictionary objectForKey:aKey];
}
- (NSEnumerator *)keyEnumerator
{
return [array objectEnumerator];
}
- (NSEnumerator *)reverseKeyEnumerator
{
return [array reverseObjectEnumerator];
}
- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex
{
if ([dictionary objectForKey:aKey])
{
[self removeObjectForKey:aKey];
}
[array insertObject:aKey atIndex:anIndex];
[dictionary setObject:anObject forKey:aKey];
}
- (id)keyAtIndex:(NSUInteger)anIndex
{
return [array objectAtIndex:anIndex];
}
- (NSUInteger)indexForKey:(id)key
{
return [array indexOfObject:key];
}
- (NSUInteger)indexForValue:(id)value
{
NSArray *keys = [self allKeysForObject:value];
if ([keys count] > 0)
{
return [self indexForKey:[keys objectAtIndex:0]];
}
return NSNotFound;
}
- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *indentString = [NSMutableString string];
NSUInteger count = level;
for (NSUInteger i = 0; i < count; i++)
{
[indentString appendFormat:@" "];
}
NSMutableString *description = [NSMutableString string];
[description appendFormat:@"%@{\n", indentString];
for (NSObject *key in self)
{
[description appendFormat:@"%@ %@ = %@;\n", indentString,
DescriptionForObject(key, locale, level),
DescriptionForObject([self objectForKey:key], locale, level)];
}
[description appendFormat:@"%@}\n", indentString];
return description;
}
@end

View File

@@ -0,0 +1,34 @@
/*
Additions to Cocoa touch classes
Copyright 2013 Thincast Technologies GmbH, Authors: Dorian Johnson, Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
@interface NSObject (TSXAdditions)
- (void)setValuesForKeyPathsWithDictionary:(NSDictionary *)keyedValues;
@end
#pragma mark -
@interface NSString (TSXAdditions)
+ (NSString *)stringWithUUID;
- (NSData *)dataFromHexString;
+ (NSString *)hexStringFromData:(const unsigned char *)data
ofSize:(unsigned int)size
withSeparator:(NSString *)sep
afterNthChar:(int)sepnth;
@end
@interface NSDictionary (TSXAdditions)
- (id)mutableDeepCopy;
@end
@interface NSData (TSXAdditions)
- (NSString *)hexadecimalString;
- (NSString *)base64EncodedString;
@end

View File

@@ -0,0 +1,239 @@
/*
Additions to Cocoa touch classes
Copyright 2013 Thincast Technologies GmbH, Authors: Dorian Johnson, Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "TSXAdditions.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/err.h>
@implementation NSObject (TSXAdditions)
- (void)setValuesForKeyPathsWithDictionary:(NSDictionary *)keyedValues
{
for (id keyPath in keyedValues)
[self setValue:[keyedValues objectForKey:keyPath] forKeyPath:keyPath];
}
- mutableDeepCopy
{
if ([self respondsToSelector:@selector(mutableCopyWithZone:)])
return [self mutableCopy];
else if ([self respondsToSelector:@selector(copyWithZone:)])
return [self copy];
else
return [self retain];
}
@end
#pragma mark -
@implementation NSString (TSXAdditions)
#pragma mark Creation routines
+ (NSString *)stringWithUUID
{
CFUUIDRef uuidObj = CFUUIDCreate(nil);
NSString *uuidString = (NSString *)CFUUIDCreateString(nil, uuidObj);
CFRelease(uuidObj);
return [uuidString autorelease];
}
/* Code from
* http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMNSData%2BHex.m?r=344
*/
- (NSData *)dataFromHexString
{
NSData *hexData = [self dataUsingEncoding:NSASCIIStringEncoding];
const char *hexBuf = [hexData bytes];
NSUInteger hexLen = [hexData length];
// This indicates an error converting to ASCII.
if (!hexData)
return nil;
if ((hexLen % 2) != 0)
{
return nil;
}
NSMutableData *binaryData = [NSMutableData dataWithLength:(hexLen / 2)];
unsigned char *binaryPtr = [binaryData mutableBytes];
unsigned char value = 0;
for (NSUInteger i = 0; i < hexLen; i++)
{
char c = hexBuf[i];
if (!isxdigit(c))
{
return nil;
}
if (isdigit(c))
{
value += c - '0';
}
else if (islower(c))
{
value += 10 + c - 'a';
}
else
{
value += 10 + c - 'A';
}
if (i & 1)
{
*binaryPtr++ = value;
value = 0;
}
else
{
value <<= 4;
}
}
return [NSData dataWithData:binaryData];
}
+ (NSString *)hexStringFromData:(const unsigned char *)data
ofSize:(unsigned int)size
withSeparator:(NSString *)sep
afterNthChar:(int)sepnth
{
NSMutableString *result;
NSString *immutableResult;
result = [[NSMutableString alloc] init];
for (int i = 0; i < size; i++)
{
if (i && sep && sepnth && i % sepnth == 0)
[result appendString:sep];
[result appendFormat:@"%02X", data[i]];
}
immutableResult = [NSString stringWithString:result];
[result release];
return immutableResult;
}
@end
#pragma mark Mutable deep copy for dictionary, array and set
@implementation NSDictionary (TSXAdditions)
- mutableDeepCopy
{
NSMutableDictionary *newDictionary = [[NSMutableDictionary alloc] init];
NSEnumerator *enumerator = [self keyEnumerator];
id key;
while ((key = [enumerator nextObject]))
{
id obj = [[self objectForKey:key] mutableDeepCopy];
[newDictionary setObject:obj forKey:key];
[obj release];
}
return newDictionary;
}
@end
@implementation NSArray (TSXAdditions)
- mutableDeepCopy
{
NSMutableArray *newArray = [[NSMutableArray alloc] init];
NSEnumerator *enumerator = [self objectEnumerator];
id obj;
while ((obj = [enumerator nextObject]))
{
obj = [obj mutableDeepCopy];
[newArray addObject:obj];
[obj release];
}
return newArray;
}
@end
@implementation NSSet (TSXAdditions)
- mutableDeepCopy
{
NSMutableSet *newSet = [[NSMutableSet alloc] init];
NSEnumerator *enumerator = [self objectEnumerator];
id obj;
while ((obj = [enumerator nextObject]))
{
obj = [obj mutableDeepCopy];
[newSet addObject:obj];
[obj release];
}
return newSet;
}
@end
#pragma mark -
/* Code from
* http://stackoverflow.com/questions/1305225/best-way-to-serialize-a-nsdata-into-an-hexadeximal-string
*/
@implementation NSData (TSXAdditions)
#pragma mark - String Conversion
- (NSString *)hexadecimalString
{
/* Returns hexadecimal string of NSData. Empty string if data is empty. */
const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
if (!dataBuffer)
return [NSString string];
NSUInteger dataLength = [self length];
NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
for (int i = 0; i < dataLength; ++i)
[hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
return [NSString stringWithString:hexString];
}
/* Code from http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html */
- (NSString *)base64EncodedString
{
// Construct an OpenSSL context
BIO *context = BIO_new(BIO_s_mem());
// Tell the context to encode base64
BIO *command = BIO_new(BIO_f_base64());
context = BIO_push(command, context);
BIO_set_flags(context, BIO_FLAGS_BASE64_NO_NL);
// Encode all the data
ERR_clear_error();
BIO_write(context, [self bytes], [self length]);
(void)BIO_flush(context);
// Get the data out of the context
char *outputBuffer;
long outputLength = BIO_get_mem_data(context, &outputBuffer);
NSString *encodedString = [[NSString alloc] initWithBytes:outputBuffer
length:outputLength
encoding:NSASCIIStringEncoding];
BIO_free_all(context);
return encodedString;
}
@end

View File

@@ -0,0 +1,60 @@
/***************************************************************************
Toast+UIView.h
Toast
Version 0.1
Copyright (c) 2011 Charles Scalesse.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface UIView (Toast)
#define ToastDurationLong 5.0
#define ToastDurationNormal 3.0
#define ToastDurationShort 1.0
// each makeToast method creates a view and displays it as toast
- (void)makeToast:(NSString *)message;
- (void)makeToast:(NSString *)message duration:(float)interval position:(id)point;
- (void)makeToast:(NSString *)message
duration:(float)interval
position:(id)point
title:(NSString *)title;
- (void)makeToast:(NSString *)message
duration:(float)interval
position:(id)point
title:(NSString *)title
image:(UIImage *)image;
- (void)makeToast:(NSString *)message
duration:(float)interval
position:(id)point
image:(UIImage *)image;
// the showToast method displays an existing view as toast
- (void)showToast:(UIView *)toast;
- (void)showToast:(UIView *)toast duration:(float)interval position:(id)point;
@end

View File

@@ -0,0 +1,367 @@
/***************************************************************************
Toast+UIView.h
Toast
Version 0.1
Copyright (c) 2011 Charles Scalesse.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#import "Toast+UIView.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>
#define kMaxWidth 0.8
#define kMaxHeight 0.8
#define kHorizontalPadding 10.0
#define kVerticalPadding 10.0
#define kCornerRadius 10.0
#define kOpacity 0.8
#define kFontSize 16.0
#define kMaxTitleLines 999
#define kMaxMessageLines 999
#define kFadeDuration 0.2
#define kDefaultLength 3
#define kDefaultPosition @"bottom"
#define kImageWidth 80.0
#define kImageHeight 80.0
static NSString *kDurationKey = @"duration";
@interface UIView (ToastPrivate)
- (CGPoint)getPositionFor:(id)position toast:(UIView *)toast;
- (UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;
@end
@implementation UIView (Toast)
#pragma mark -
#pragma mark Toast Methods
- (void)makeToast:(NSString *)message
{
[self makeToast:message duration:kDefaultLength position:kDefaultPosition];
}
- (void)makeToast:(NSString *)message duration:(float)interval position:(id)point
{
UIView *toast = [self makeViewForMessage:message title:nil image:nil];
[self showToast:toast duration:interval position:point];
}
- (void)makeToast:(NSString *)message
duration:(float)interval
position:(id)point
title:(NSString *)title
{
UIView *toast = [self makeViewForMessage:message title:title image:nil];
[self showToast:toast duration:interval position:point];
}
- (void)makeToast:(NSString *)message
duration:(float)interval
position:(id)point
image:(UIImage *)image
{
UIView *toast = [self makeViewForMessage:message title:nil image:image];
[self showToast:toast duration:interval position:point];
}
- (void)makeToast:(NSString *)message
duration:(float)interval
position:(id)point
title:(NSString *)title
image:(UIImage *)image
{
UIView *toast = [self makeViewForMessage:message title:title image:image];
[self showToast:toast duration:interval position:point];
}
- (void)showToast:(UIView *)toast
{
[self showToast:toast duration:kDefaultLength position:kDefaultPosition];
}
- (void)showToast:(UIView *)toast duration:(float)interval position:(id)point
{
/****************************************************
* *
* Displays a view for a given duration & position. *
* *
****************************************************/
CGPoint toastPoint = [self getPositionFor:point toast:toast];
// use an associative reference to associate the toast view with the display interval
objc_setAssociatedObject(toast, &kDurationKey, [NSNumber numberWithFloat:interval],
OBJC_ASSOCIATION_RETAIN);
[toast setCenter:toastPoint];
[toast setAlpha:0.0];
[self addSubview:toast];
[UIView beginAnimations:@"fade_in" context:toast];
[UIView setAnimationDuration:kFadeDuration];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[toast setAlpha:1.0];
[UIView commitAnimations];
}
#pragma mark -
#pragma mark Animation Delegate Method
- (void)animationDidStop:(NSString *)animationID finished:(BOOL)finished context:(void *)context
{
UIView *toast = (UIView *)context;
// retrieve the display interval associated with the view
float interval = [(NSNumber *)objc_getAssociatedObject(toast, &kDurationKey) floatValue];
if ([animationID isEqualToString:@"fade_in"])
{
[UIView beginAnimations:@"fade_out" context:toast];
[UIView setAnimationDelay:interval];
[UIView setAnimationDuration:kFadeDuration];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[toast setAlpha:0.0];
[UIView commitAnimations];
}
else if ([animationID isEqualToString:@"fade_out"])
{
[toast removeFromSuperview];
}
}
#pragma mark -
#pragma mark Private Methods
- (CGPoint)getPositionFor:(id)point toast:(UIView *)toast
{
/*************************************************************************************
* *
* Converts string literals @"top", @"bottom", @"center", or any point wrapped in an *
* NSValue object into a CGPoint *
* *
*************************************************************************************/
if ([point isKindOfClass:[NSString class]])
{
if ([point caseInsensitiveCompare:@"top"] == NSOrderedSame)
{
return CGPointMake(self.bounds.size.width / 2,
(toast.frame.size.height / 2) + kVerticalPadding);
}
else if ([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame)
{
return CGPointMake(self.bounds.size.width / 2,
(self.bounds.size.height - (toast.frame.size.height / 2)) -
kVerticalPadding);
}
else if ([point caseInsensitiveCompare:@"center"] == NSOrderedSame)
{
return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
}
}
else if ([point isKindOfClass:[NSValue class]])
{
return [point CGPointValue];
}
NSLog(@"Error: Invalid position for toast.");
return [self getPositionFor:kDefaultPosition toast:toast];
}
- (UIView *)makeViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image
{
/***********************************************************************************
* *
* Dynamically build a toast view with any combination of message, title, & image. *
* *
***********************************************************************************/
if ((message == nil) && (title == nil) && (image == nil))
return nil;
UILabel *messageLabel = nil;
UILabel *titleLabel = nil;
UIImageView *imageView = nil;
// create the parent view
UIView *wrapperView = [[[UIView alloc] init] autorelease];
[wrapperView.layer setCornerRadius:kCornerRadius];
[wrapperView setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:kOpacity]];
wrapperView.autoresizingMask =
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
if (image != nil)
{
imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView
setFrame:CGRectMake(kHorizontalPadding, kVerticalPadding, kImageWidth, kImageHeight)];
}
float imageWidth, imageHeight, imageLeft;
// the imageView frame values will be used to size & position the other views
if (imageView != nil)
{
imageWidth = imageView.bounds.size.width;
imageHeight = imageView.bounds.size.height;
imageLeft = kHorizontalPadding;
}
else
{
imageWidth = imageHeight = imageLeft = 0;
}
if (title != nil)
{
titleLabel = [[[UILabel alloc] init] autorelease];
[titleLabel setNumberOfLines:kMaxTitleLines];
[titleLabel setFont:[UIFont boldSystemFontOfSize:kFontSize]];
[titleLabel setTextAlignment:UITextAlignmentLeft];
[titleLabel setLineBreakMode:UILineBreakModeWordWrap];
[titleLabel setTextColor:[UIColor whiteColor]];
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setAlpha:1.0];
[titleLabel setText:title];
// size the title label according to the length of the text
CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth,
self.bounds.size.height * kMaxHeight);
CGSize expectedSizeTitle = [title sizeWithFont:titleLabel.font
constrainedToSize:maxSizeTitle
lineBreakMode:titleLabel.lineBreakMode];
[titleLabel setFrame:CGRectMake(0, 0, expectedSizeTitle.width, expectedSizeTitle.height)];
}
if (message != nil)
{
messageLabel = [[[UILabel alloc] init] autorelease];
[messageLabel setNumberOfLines:kMaxMessageLines];
[messageLabel setFont:[UIFont systemFontOfSize:kFontSize]];
[messageLabel setLineBreakMode:UILineBreakModeWordWrap];
[messageLabel setTextColor:[UIColor whiteColor]];
[messageLabel setTextAlignment:UITextAlignmentCenter];
[messageLabel setBackgroundColor:[UIColor clearColor]];
[messageLabel setAlpha:1.0];
[messageLabel setText:message];
// size the message label according to the length of the text
CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * kMaxWidth) - imageWidth,
self.bounds.size.height * kMaxHeight);
CGSize expectedSizeMessage = [message sizeWithFont:messageLabel.font
constrainedToSize:maxSizeMessage
lineBreakMode:messageLabel.lineBreakMode];
[messageLabel
setFrame:CGRectMake(0, 0, expectedSizeMessage.width, expectedSizeMessage.height)];
}
// titleLabel frame values
float titleWidth, titleHeight, titleTop, titleLeft;
if (titleLabel != nil)
{
titleWidth = titleLabel.bounds.size.width;
titleHeight = titleLabel.bounds.size.height;
titleTop = kVerticalPadding;
titleLeft = imageLeft + imageWidth + kHorizontalPadding;
}
else
{
titleWidth = titleHeight = titleTop = titleLeft = 0;
}
// messageLabel frame values
float messageWidth, messageHeight, messageLeft, messageTop;
if (messageLabel != nil)
{
messageWidth = messageLabel.bounds.size.width;
messageHeight = messageLabel.bounds.size.height;
messageLeft = imageLeft + imageWidth + kHorizontalPadding;
messageTop = titleTop + titleHeight + kVerticalPadding;
}
else
{
messageWidth = messageHeight = messageLeft = messageTop = 0;
}
// compare the title & message widths and use the longer value to calculate the size of the
// wrapper width the same logic applies to the x value (left)
float longerWidth = (messageWidth < titleWidth) ? titleWidth : messageWidth;
float longerLeft = (messageLeft < titleLeft) ? titleLeft : messageLeft;
// if the image width is larger than longerWidth, use the image width to calculate the wrapper
// width. the same logic applies to the wrapper height
float wrapperWidth =
((longerLeft + longerWidth + kHorizontalPadding) < imageWidth + (kHorizontalPadding * 2))
? imageWidth + (kHorizontalPadding * 2)
: (longerLeft + longerWidth + kHorizontalPadding);
float wrapperHeight =
((messageTop + messageHeight + kVerticalPadding) < imageHeight + (kVerticalPadding * 2))
? imageHeight + (kVerticalPadding * 2)
: (messageTop + messageHeight + kVerticalPadding);
[wrapperView setFrame:CGRectMake(0, 0, wrapperWidth, wrapperHeight)];
if (titleLabel != nil)
{
[titleLabel setFrame:CGRectMake(titleLeft, titleTop, titleWidth, titleHeight)];
[wrapperView addSubview:titleLabel];
}
if (messageLabel != nil)
{
[messageLabel setFrame:CGRectMake(messageLeft, messageTop, messageWidth, messageHeight)];
[wrapperView addSubview:messageLabel];
}
if (imageView != nil)
{
[wrapperView addSubview:imageView];
}
return wrapperView;
}
@end

View File

@@ -0,0 +1,24 @@
/*
App delegate
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
@class MainTabBarController;
@interface AppDelegate : NSObject <UIApplicationDelegate>
{
MainTabBarController *_tabBarController;
}
@property(nonatomic, retain) IBOutlet UIWindow *window;
@property(nonatomic, retain) IBOutlet MainTabBarController *tabBarController;
@end

View File

@@ -0,0 +1,127 @@
/*
App delegate
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "AppDelegate.h"
#import "AboutController.h"
#import "HelpController.h"
#import "BookmarkListController.h"
#import "AppSettingsController.h"
#import "MainTabBarController.h"
#import "Utils.h"
@implementation AppDelegate
@synthesize window = _window, tabBarController = _tabBarController;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Set default values for most NSUserDefaults
[[NSUserDefaults standardUserDefaults]
registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@"Defaults"
ofType:@"plist"]]];
// init global settings
SetSwapMouseButtonsFlag(
[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.swap_mouse_buttons"]);
SetInvertScrollingFlag(
[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.invert_scrolling"]);
// create bookmark view and navigation controller
BookmarkListController *bookmarkListController =
[[[BookmarkListController alloc] initWithNibName:@"BookmarkListView"
bundle:nil] autorelease];
UINavigationController *bookmarkNavigationController = [[[UINavigationController alloc]
initWithRootViewController:bookmarkListController] autorelease];
// create app settings view and navigation controller
AppSettingsController *appSettingsController =
[[[AppSettingsController alloc] initWithStyle:UITableViewStyleGrouped] autorelease];
UINavigationController *appSettingsNavigationController = [[[UINavigationController alloc]
initWithRootViewController:appSettingsController] autorelease];
// create help view controller
HelpController *helpViewController = [[[HelpController alloc] initWithNibName:nil
bundle:nil] autorelease];
// create about view controller
AboutController *aboutViewController =
[[[AboutController alloc] initWithNibName:nil bundle:nil] autorelease];
// add tab-bar controller to the main window and display everything
NSArray *tabItems =
[NSArray arrayWithObjects:bookmarkNavigationController, appSettingsNavigationController,
helpViewController, aboutViewController, nil];
[_tabBarController setViewControllers:tabItems];
if ([_window respondsToSelector:@selector(setRootViewController:)])
[_window setRootViewController:_tabBarController];
else
[_window addSubview:[_tabBarController view]];
[_window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for
certain types of temporary interruptions (such as an incoming phone call or SMS message) or
when the user quits the application and it begins the transition to the background state. Use
this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates.
Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store
enough application state information to restore your application to its current state in case
it is terminated later. If your application supports background execution, this method is
called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the inactive state; here you can undo
many of the changes made on entering the background.
*/
// cancel disconnect timer
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If
the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
- (void)dealloc
{
[_window release];
[super dealloc];
}
@end

View File

@@ -0,0 +1,163 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP X11 Client
#
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.13)
if(NOT FREERDP_DEFAULT_PROJECT_VERSION)
set(FREERDP_DEFAULT_PROJECT_VERSION "1.0.0.0")
endif()
project(iFreeRDP VERSION ${FREERDP_DEFAULT_PROJECT_VERSION})
message("project ${PROJECT_NAME} is using version ${PROJECT_VERSION}")
list(APPEND CMAKE_MODULE_PATH ${PROJECT_CURRENT_SOURCE_DIR}/../../cmake/)
include(CommonConfigOptions)
include(WarnUnmaintained)
warn_unmaintained(${PROJECT_NAME} "-DWITH_CLIENT_IOS=OFF")
set(MODULE_NAME "iFreeRDP")
set(MODULE_PREFIX "IFREERDP_CLIENT")
set(APP_TYPE MACOSX_BUNDLE)
set(IOS_CLIENT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(IOS_CLIENT_ADDITIONS_DIR ${IOS_CLIENT_DIR}/Additions)
set(IOS_CLIENT_CONTROLLERS_DIR ${IOS_CLIENT_DIR}/Controllers)
set(IOS_CLIENT_FREERDP_DIR ${IOS_CLIENT_DIR}/FreeRDP)
set(IOS_CLIENT_MISC_DIR ${IOS_CLIENT_DIR}/Misc)
set(IOS_CLIENT_MODELS_DIR ${IOS_CLIENT_DIR}/Models)
set(IOS_CLIENT_VIEWS_DIR ${IOS_CLIENT_DIR}/Views)
set(IOS_CLIENT_RESOURCES_DIR ${IOS_CLIENT_DIR}/Resources)
include_directories(SYSTEM ${IOS_CLIENT_DIR})
include_directories(SYSTEM ${IOS_CLIENT_ADDITIONS_DIR})
include_directories(SYSTEM ${IOS_CLIENT_CONTROLLERS_DIR})
include_directories(SYSTEM ${IOS_CLIENT_FREERDP_DIR})
include_directories(SYSTEM ${IOS_CLIENT_MISC_DIR})
include_directories(SYSTEM ${IOS_CLIENT_MODELS_DIR})
include_directories(SYSTEM ${IOS_CLIENT_VIEWS_DIR})
include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR})
# Add sources
set(${MODULE_PREFIX}_SRCS AppDelegate.m AppDelegate.h main.m)
file(GLOB IOS_CLIENT_ADDITIONS_SRCS ${IOS_CLIENT_ADDITIONS_DIR}/*.m)
file(GLOB IOS_CLIENT_ADDITIONS_HDRS ${IOS_CLIENT_ADDITIONS_DIR}/*.h)
file(GLOB IOS_CLIENT_CONTROLLERS_SRCS ${IOS_CLIENT_CONTROLLERS_DIR}/*.m)
file(GLOB IOS_CLIENT_CONTROLLERS_HDRS ${IOS_CLIENT_CONTROLLERS_DIR}/*.h)
file(GLOB IOS_CLIENT_FREERDP_SRCS ${IOS_CLIENT_FREERDP_DIR}/*.m)
file(GLOB IOS_CLIENT_FREERDP_HDRS ${IOS_CLIENT_FREERDP_DIR}/*.h)
file(GLOB IOS_CLIENT_MISC_SRCS ${IOS_CLIENT_MISC_DIR}/*.m)
file(GLOB IOS_CLIENT_MISC_HDRS ${IOS_CLIENT_MISC_DIR}/*.h)
file(GLOB IOS_CLIENT_MODELS_SRCS ${IOS_CLIENT_MODELS_DIR}/*.m)
file(GLOB IOS_CLIENT_MODELS_HDRS ${IOS_CLIENT_MODELS_DIR}/*.h)
file(GLOB IOS_CLIENT_VIEWS_SRCS ${IOS_CLIENT_VIEWS_DIR}/*.m)
file(GLOB IOS_CLIENT_VIEWS_HDRS ${IOS_CLIENT_VIEWS_DIR}/*.h)
# add resources
file(GLOB IOS_CLIENT_RESOURCES_XIBS ${IOS_CLIENT_RESOURCES_DIR}/*.xib)
file(GLOB IOS_CLIENT_RESOURCES_PNGS ${IOS_CLIENT_RESOURCES_DIR}/*.png)
# Specify source grouping
source_group(Additions FILES ${IOS_CLIENT_ADDITIONS_SRCS} ${IOS_CLIENT_ADDITIONS_HDRS})
source_group(Controllers FILES ${IOS_CLIENT_CONTROLLERS_SRCS} ${IOS_CLIENT_CONTROLLERS_HDRS})
source_group(FreeRDP FILES ${IOS_CLIENT_FREERDP_SRCS} ${IOS_CLIENT_FREERDP_HDRS})
source_group(Misc FILES ${IOS_CLIENT_MISC_SRCS} ${IOS_CLIENT_MISC_HDRS})
source_group(Models FILES ${IOS_CLIENT_MODELS_SRCS} ${IOS_CLIENT_MODELS_HDRS})
source_group(Views FILES ${IOS_CLIENT_RESOURCES_XIBS} ${IOS_CLIENT_VIEWS_SRCS} ${IOS_CLIENT_VIEWS_HDRS})
source_group(
Resources FILES ${IOS_CLIENT_RESOURCES_PNGS} ${IOS_CLIENT_RESOURCES_DIR}/about_page
${IOS_CLIENT_RESOURCES_DIR}/help_page ${IOS_CLIENT_RESOURCES_DIR}/en.lproj
)
# import libraries
find_library(FOUNDATION_FRAMEWORK Foundation)
find_library(COREGRAPHICS_FRAMEWORK CoreGraphics)
find_library(SECURITY_FRAMEWORK Security)
find_library(UIKIT_FRAMEWORK UIKit)
find_library(SYSTEMCONFIGURATION_FRAMEWORK SystemConfiguration)
mark_as_advanced(
FOUNDATION_FRAMEWORK COREGRAPHICS_FRAMEWORK SECURITY_FRAMEWORK UIKIT_FRAMEWORK SYSTEMCONFIGURATION_FRAMEWORK
)
set(EXTRA_LIBS ${FOUNDATION_FRAMEWORK} ${COREGRAPHICS_FRAMEWORK} ${SECURITY_FRAMEWORK} ${UIKIT_FRAMEWORK}
${SYSTEMCONFIGURATION_FRAMEWORK}
)
set(${MODULE_NAME}_RESOURCES ${IOS_CLIENT_RESOURCES_XIBS})
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${IOS_CLIENT_RESOURCES_PNGS})
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${IOS_CLIENT_RESOURCES_DIR}/about_page
${IOS_CLIENT_RESOURCES_DIR}/help_page ${IOS_CLIENT_RESOURCES_DIR}/en.lproj
)
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${IOS_CLIENT_DIR}/Defaults.plist)
add_executable(
${MODULE_NAME}
${APP_TYPE}
${${MODULE_PREFIX}_SRCS}
${IOS_CLIENT_ADDITIONS_SRCS}
${IOS_CLIENT_ADDITIONS_HDRS}
${IOS_CLIENT_CONTROLLERS_SRCS}
${IOS_CLIENT_CONTROLLERS_HDRS}
${IOS_CLIENT_FREERDP_SRCS}
${IOS_CLIENT_FREERDP_HDRS}
${IOS_CLIENT_MISC_SRCS}
${IOS_CLIENT_MISC_HDRS}
${IOS_CLIENT_MODELS_SRCS}
${IOS_CLIENT_MODELS_HDRS}
${IOS_CLIENT_VIEWS_SRCS}
${IOS_CLIENT_VIEWS_HDRS}
${${MODULE_NAME}_RESOURCES}
)
if(WITH_BINARY_VERSIONING)
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_NAME}${PROJECT_VERSION_MAJOR}")
endif()
set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOURCES}")
set(EXECUTABLE_NAME "\${EXECUTABLE_NAME}")
set_target_properties(${MODULE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${IOS_CLIENT_DIR}/iFreeRDP.plist)
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "${IOS_TARGET_SDK}")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "gnu++0x")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO)
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_GCC_C_LANGUAGE_STANDARD "gnu99")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_COMBINE_HIDPI_IMAGES "NO")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_SKIP_INSTALL NO)
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_INSTALL_PATH "/Applications")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS YES)
if(CODE_SIGN_IDENTITY)
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${CODE_SIGN_IDENTITY}")
endif()
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${EXTRA_LIBS})
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr freerdp)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/iOS")

View File

@@ -0,0 +1,19 @@
/*
Application info controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
@interface AboutController : UIViewController <UIWebViewDelegate>
{
NSString *last_link_clicked;
UIWebView *webView;
}
@end

View File

@@ -0,0 +1,120 @@
/*
Application info controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "AboutController.h"
#import "Utils.h"
#import "BlockAlertView.h"
@implementation AboutController
// The designated initializer. Override if you create the controller programmatically and want to
// perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
{
// set title and tab-bar image
[self setTitle:NSLocalizedString(@"About", @"About Controller title")];
UIImage *tabBarIcon = [UIImage
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tabbar_icon_about"
ofType:@"png"]];
[self setTabBarItem:[[[UITabBarItem alloc]
initWithTitle:NSLocalizedString(@"About", @"Tabbar item about")
image:tabBarIcon
tag:0] autorelease]];
last_link_clicked = nil;
}
return self;
}
- (void)dealloc
{
[super dealloc];
[last_link_clicked release];
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
webView = [[[UIWebView alloc] initWithFrame:CGRectZero] autorelease];
[webView
setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[webView setAutoresizesSubviews:YES];
[webView setDelegate:self];
[webView setDataDetectorTypes:UIDataDetectorTypeNone];
[self setView:webView];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filename = (IsPhone() ? @"about_phone" : @"about");
NSString *htmlString = [[[NSString alloc]
initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename
ofType:@"html"
inDirectory:@"about_page"]
encoding:NSUTF8StringEncoding
error:nil] autorelease];
[webView
loadHTMLString:[NSString stringWithFormat:htmlString, TSXAppFullVersion(),
[[UIDevice currentDevice] systemName],
[[UIDevice currentDevice] systemVersion],
[[UIDevice currentDevice] model]]
baseURL:[NSURL fileURLWithPath:[[[NSBundle mainBundle] bundlePath]
stringByAppendingPathComponent:@"about_page"]]];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark -
#pragma mark UIWebView callbacks
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
if ([[request URL] isFileURL])
return YES;
if (navigationType == UIWebViewNavigationTypeLinkClicked)
{
[last_link_clicked release];
last_link_clicked = [[[request URL] absoluteString] retain];
BlockAlertView *alert = [BlockAlertView
alertWithTitle:NSLocalizedString(@"External Link", @"External Link Alert Title")
message:[NSString stringWithFormat:
NSLocalizedString(
@"Open [%@] in Browser?",
@"Open link in browser (with link as parameter)"),
last_link_clicked]];
[alert setCancelButtonWithTitle:NSLocalizedString(@"No", @"No Button") block:nil];
[alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK Button")
block:^{
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:last_link_clicked]];
}];
[alert show];
return NO;
}
return YES;
}
@end

View File

@@ -0,0 +1,26 @@
/*
Controller to edit advanced bookmark settings
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@class ComputerBookmark;
@class ConnectionParams;
@interface AdvancedBookmarkEditorController : EditorBaseController
{
@private
ComputerBookmark *_bookmark;
ConnectionParams *_params;
}
// init for the given bookmark
- (id)initWithBookmark:(ComputerBookmark *)bookmark;
@end

View File

@@ -0,0 +1,407 @@
/*
Controller to edit advanced bookmark settings
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "AdvancedBookmarkEditorController.h"
#import "Bookmark.h"
#import "Utils.h"
#import "EditorSelectionController.h"
#import "ScreenSelectionController.h"
#import "PerformanceEditorController.h"
#import "BookmarkGatewaySettingsController.h"
@interface AdvancedBookmarkEditorController ()
@end
#define SECTION_ADVANCED_SETTINGS 0
#define SECTION_COUNT 1
@implementation AdvancedBookmarkEditorController
- (id)initWithBookmark:(ComputerBookmark *)bookmark
{
if ((self = [super initWithStyle:UITableViewStyleGrouped]))
{
// set additional settings state according to bookmark data
_bookmark = [bookmark retain];
_params = [bookmark params];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:NSLocalizedString(@"Advanced Settings", @"Advanced Settings title")];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// we need to reload the table view data here to have up-to-date data for the
// advanced settings accessory items (like for resolution/color mode settings)
[[self tableView] reloadData];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return SECTION_COUNT;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
switch (section)
{
case SECTION_ADVANCED_SETTINGS: // advanced settings
return 9;
default:
break;
}
return 0;
}
// set section headers
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
switch (section)
{
case SECTION_ADVANCED_SETTINGS:
return NSLocalizedString(@"Advanced", @"'Advanced': advanced settings header");
}
return @"unknown";
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// determine the required cell type
NSString *cellType = nil;
switch ([indexPath section])
{
case SECTION_ADVANCED_SETTINGS: // advanced settings
{
switch ([indexPath row])
{
case 0: // Enable/Disable TSG Settings
cellType = TableCellIdentifierYesNo;
break;
case 1: // TS Gateway Settings
cellType = TableCellIdentifierSubEditor;
break;
case 2: // 3G Settings
cellType = TableCellIdentifierYesNo;
break;
case 3: // 3G screen/color depth
cellType = TableCellIdentifierSelection;
break;
case 4: // 3G performance settings
cellType = TableCellIdentifierSubEditor;
break;
case 5: // security mode
cellType = TableCellIdentifierSelection;
break;
case 6: // remote program
case 7: // work dir
cellType = TableCellIdentifierText;
break;
case 8: // console mode
cellType = TableCellIdentifierYesNo;
break;
default:
break;
}
break;
}
}
NSAssert(cellType != nil, @"Couldn't determine cell type");
// get the table view cell
UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
NSAssert(cell, @"Invalid cell");
// set cell values
switch ([indexPath section])
{
// advanced settings
case SECTION_ADVANCED_SETTINGS:
[self initAdvancedSettings:indexPath cell:cell];
break;
default:
break;
}
return cell;
}
// updates advanced settings in the UI
- (void)initAdvancedSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
BOOL enable_3G_settings = [_params boolForKey:@"enable_3g_settings"];
switch (indexPath.row)
{
case 0:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label]
setText:NSLocalizedString(@"Enable TS Gateway",
@"'Enable TS Gateway': Bookmark enable TSG settings")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle] setOn:[_params boolForKey:@"enable_tsg_settings"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
case 1:
{
BOOL enable_tsg_settings = [_params boolForKey:@"enable_tsg_settings"];
EditSubEditTableViewCell *editCell = (EditSubEditTableViewCell *)cell;
[[editCell label]
setText:NSLocalizedString(@"TS Gateway Settings",
@"'TS Gateway Settings': Bookmark TS Gateway Settings")];
[[editCell label] setEnabled:enable_tsg_settings];
[editCell setSelectionStyle:enable_tsg_settings ? UITableViewCellSelectionStyleBlue
: UITableViewCellSelectionStyleNone];
break;
}
case 2:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label]
setText:NSLocalizedString(@"3G Settings",
@"'3G Settings': Bookmark enable 3G settings")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle] setOn:[_params boolForKey:@"enable_3g_settings"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
case 3:
{
EditSelectionTableViewCell *selCell = (EditSelectionTableViewCell *)cell;
[[selCell label]
setText:NSLocalizedString(@"3G Screen",
@"'3G Screen': Bookmark 3G Screen settings")];
NSString *resolution = ScreenResolutionDescription(
[_params intForKeyPath:@"settings_3g.screen_resolution_type"],
[_params intForKeyPath:@"settings_3g.width"],
[_params intForKeyPath:@"settings_3g.height"]);
int colorBits = [_params intForKeyPath:@"settings_3g.colors"];
[[selCell selection]
setText:[NSString stringWithFormat:@"%@@%d", resolution, colorBits]];
[[selCell label] setEnabled:enable_3G_settings];
[[selCell selection] setEnabled:enable_3G_settings];
[selCell setSelectionStyle:enable_3G_settings ? UITableViewCellSelectionStyleBlue
: UITableViewCellSelectionStyleNone];
break;
}
case 4:
{
EditSubEditTableViewCell *editCell = (EditSubEditTableViewCell *)cell;
[[editCell label]
setText:NSLocalizedString(@"3G Performance",
@"'3G Performance': Bookmark 3G Performance Settings")];
[[editCell label] setEnabled:enable_3G_settings];
[editCell setSelectionStyle:enable_3G_settings ? UITableViewCellSelectionStyleBlue
: UITableViewCellSelectionStyleNone];
break;
}
case 5:
{
EditSelectionTableViewCell *selCell = (EditSelectionTableViewCell *)cell;
[[selCell label]
setText:NSLocalizedString(@"Security",
@"'Security': Bookmark protocol security settings")];
[[selCell selection]
setText:ProtocolSecurityDescription([_params intForKey:@"security"])];
break;
}
case 6:
{
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell label]
setText:NSLocalizedString(@"Remote Program",
@"'Remote Program': Bookmark remote program settings")];
[[textCell textfield] setText:[_params StringForKey:@"remote_program"]];
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
[self adjustEditTextTableViewCell:textCell];
break;
}
case 7:
{
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell label]
setText:NSLocalizedString(
@"Working Directory",
@"'Working Directory': Bookmark working directory settings")];
[[textCell textfield] setText:[_params StringForKey:@"working_dir"]];
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
[self adjustEditTextTableViewCell:textCell];
break;
}
case 8:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label]
setText:NSLocalizedString(@"Console Mode",
@"'Console Mode': Bookmark console mode settings")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle] setOn:[_params boolForKey:@"console"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
default:
NSLog(@"Invalid row index in settings table!");
break;
}
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *viewCtrl = nil;
// determine view
switch ([indexPath row])
{
case 1:
if ([_params boolForKey:@"enable_tsg_settings"])
viewCtrl = [[[BookmarkGatewaySettingsController alloc] initWithBookmark:_bookmark]
autorelease];
break;
case 3:
if ([_params boolForKey:@"enable_3g_settings"])
viewCtrl = [[[ScreenSelectionController alloc]
initWithConnectionParams:_params
keyPath:@"settings_3g"] autorelease];
break;
case 4:
if ([_params boolForKey:@"enable_3g_settings"])
viewCtrl = [[[PerformanceEditorController alloc]
initWithConnectionParams:_params
keyPath:@"settings_3g"] autorelease];
break;
case 5:
viewCtrl = [[[EditorSelectionController alloc]
initWithConnectionParams:_params
entries:[NSArray arrayWithObject:@"security"]
selections:[NSArray arrayWithObject:SelectionForSecuritySetting()]]
autorelease];
break;
default:
break;
}
// display view
if (viewCtrl)
[[self navigationController] pushViewController:viewCtrl animated:YES];
}
#pragma mark -
#pragma mark Text Field delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
switch (textField.tag)
{
// update remote program/work dir settings
case GET_TAG(SECTION_ADVANCED_SETTINGS, 6):
{
[_params setValue:[textField text] forKey:@"remote_program"];
break;
}
case GET_TAG(SECTION_ADVANCED_SETTINGS, 7):
{
[_params setValue:[textField text] forKey:@"working_dir"];
break;
}
default:
break;
}
return YES;
}
#pragma mark - Action handlers
- (void)toggleSettingValue:(id)sender
{
UISwitch *valueSwitch = (UISwitch *)sender;
switch (valueSwitch.tag)
{
case GET_TAG(SECTION_ADVANCED_SETTINGS, 0):
{
[_params setBool:[valueSwitch isOn] forKey:@"enable_tsg_settings"];
NSArray *indexPaths =
[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:1
inSection:SECTION_ADVANCED_SETTINGS],
[NSIndexPath indexPathForRow:2
inSection:SECTION_ADVANCED_SETTINGS],
nil];
[[self tableView] reloadRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationNone];
break;
}
case GET_TAG(SECTION_ADVANCED_SETTINGS, 2):
{
[_params setBool:[valueSwitch isOn] forKey:@"enable_3g_settings"];
NSArray *indexPaths =
[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:3
inSection:SECTION_ADVANCED_SETTINGS],
[NSIndexPath indexPathForRow:2
inSection:SECTION_ADVANCED_SETTINGS],
nil];
[[self tableView] reloadRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationNone];
break;
}
case GET_TAG(SECTION_ADVANCED_SETTINGS, 8):
[_params setBool:[valueSwitch isOn] forKey:@"console"];
break;
default:
break;
}
}
@end

View File

@@ -0,0 +1,15 @@
/*
Controller to specify application wide settings
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@interface AppSettingsController : EditorBaseController
@end

View File

@@ -0,0 +1,360 @@
/*
Controller to specify application wide settings
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "AppSettingsController.h"
#import "Utils.h"
#import "Toast+UIView.h"
@implementation AppSettingsController
// keep this up-to-date for correct section display/hiding
#define SECTION_UI_SETTINGS 0
#define SECTION_CERTIFICATE_HANDLING_SETTINGS 1
#define SECTION_NUM_SECTIONS 2
#pragma mark -
#pragma mark Initialization
- (id)initWithStyle:(UITableViewStyle)style
{
if ((self = [super initWithStyle:style]))
{
UIImage *tabBarIcon = [UIImage
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tabbar_icon_settings"
ofType:@"png"]];
[self
setTabBarItem:[[[UITabBarItem alloc]
initWithTitle:NSLocalizedString(@"Settings", @"Tabbar item settings")
image:tabBarIcon
tag:0] autorelease]];
}
return self;
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// set title
[self setTitle:NSLocalizedString(@"Settings", @"App Settings title")];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return SECTION_NUM_SECTIONS;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
switch (section)
{
case SECTION_UI_SETTINGS: // UI settings
return 5;
case SECTION_CERTIFICATE_HANDLING_SETTINGS: // certificate handling settings
return 2;
default:
break;
}
return 0;
}
// set section headers
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
switch (section)
{
case SECTION_UI_SETTINGS:
return NSLocalizedString(@"User Interface", @"UI settings section title");
case SECTION_CERTIFICATE_HANDLING_SETTINGS:
return NSLocalizedString(@"Server Certificate Handling",
@"Server Certificate Handling section title");
default:
return nil;
}
return @"unknown";
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// determine the required cell type
NSString *cellIdentifier = nil;
switch ([indexPath section])
{
case SECTION_UI_SETTINGS:
{
switch ([indexPath row])
{
case 0:
case 1:
case 2:
case 3:
case 4:
cellIdentifier = TableCellIdentifierYesNo;
break;
}
break;
}
case SECTION_CERTIFICATE_HANDLING_SETTINGS:
{
switch ([indexPath row])
{
case 0:
cellIdentifier = TableCellIdentifierYesNo;
break;
case 1:
cellIdentifier = TableCellIdentifierSubEditor;
break;
}
break;
}
}
NSAssert(cellIdentifier != nil, @"Couldn't determine cell type");
// get the table view cell
UITableViewCell *cell = [self tableViewCellFromIdentifier:cellIdentifier];
NSAssert(cell, @"Invalid cell");
// set cell values
switch ([indexPath section])
{
case SECTION_UI_SETTINGS:
[self initUISettings:indexPath cell:cell];
break;
case SECTION_CERTIFICATE_HANDLING_SETTINGS:
[self initCertificateHandlingSettings:indexPath cell:cell];
break;
default:
break;
}
return cell;
}
#pragma mark - Initialization helpers
// updates UI settings in the UI
- (void)initUISettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
switch ([indexPath row])
{
case 0:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label] setText:NSLocalizedString(@"Hide Status Bar",
"Show/Hide Phone Status Bar setting")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle]
setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.hide_status_bar"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
case 1:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label]
setText:NSLocalizedString(@"Hide Tool Bar", "Show/Hide Tool Bar setting")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle]
setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.hide_tool_bar"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
case 2:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label]
setText:NSLocalizedString(@"Swap Mouse Buttons", "Swap Mouse Button UI setting")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle]
setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.swap_mouse_buttons"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
case 3:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label]
setText:NSLocalizedString(@"Invert Scrolling", "Invert Scrolling UI setting")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle]
setOn:[[NSUserDefaults standardUserDefaults] boolForKey:@"ui.invert_scrolling"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
case 4:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label] setText:NSLocalizedString(@"Touch Pointer Auto Scroll",
"Touch Pointer Auto Scroll UI setting")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults]
boolForKey:@"ui.auto_scroll_touchpointer"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
default:
NSLog(@"Invalid row index in settings table!");
break;
}
}
// updates certificate handling settings in the UI
- (void)initCertificateHandlingSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
switch ([indexPath row])
{
case 0:
{
EditFlagTableViewCell *flagCell = (EditFlagTableViewCell *)cell;
[[flagCell label] setText:NSLocalizedString(@"Accept all Certificates",
"Accept All Certificates setting")];
[[flagCell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[flagCell toggle] setOn:[[NSUserDefaults standardUserDefaults]
boolForKey:@"security.accept_certificates"]];
[[flagCell toggle] addTarget:self
action:@selector(toggleSettingValue:)
forControlEvents:UIControlEventValueChanged];
break;
}
case 1:
{
EditSubEditTableViewCell *subCell = (EditSubEditTableViewCell *)cell;
[[subCell label] setText:NSLocalizedString(@"Erase Certificate Cache",
@"Erase certificate cache button")];
break;
}
default:
NSLog(@"Invalid row index in settings table!");
break;
}
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// deselect any row to fake a button-pressed like effect
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// ensure everything is stored in our settings before we proceed
[[self view] endEditing:NO];
// clear certificate cache
if ([indexPath section] == SECTION_CERTIFICATE_HANDLING_SETTINGS && [indexPath row] == 1)
{
// delete certificates cache
NSError *err;
if ([[NSFileManager defaultManager]
removeItemAtPath:[[NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:@"/.freerdp"]
error:&err])
[[self view] makeToast:NSLocalizedString(@"Certificate Cache cleared!",
@"Clear Certificate cache success message")
duration:ToastDurationNormal
position:@"center"];
else
[[self view] makeToast:NSLocalizedString(@"Error clearing the Certificate Cache!",
@"Clear Certificate cache failed message")
duration:ToastDurationNormal
position:@"center"];
}
}
#pragma mark -
#pragma mark Action Handlers
- (void)toggleSettingValue:(id)sender
{
UISwitch *valueSwitch = (UISwitch *)sender;
switch ([valueSwitch tag])
{
case GET_TAG(SECTION_UI_SETTINGS, 0):
[[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn]
forKey:@"ui.hide_status_bar"];
break;
case GET_TAG(SECTION_UI_SETTINGS, 1):
[[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn]
forKey:@"ui.hide_tool_bar"];
break;
case GET_TAG(SECTION_UI_SETTINGS, 2):
[[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn]
forKey:@"ui.swap_mouse_buttons"];
SetSwapMouseButtonsFlag([valueSwitch isOn]);
break;
case GET_TAG(SECTION_UI_SETTINGS, 3):
[[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn]
forKey:@"ui.invert_scrolling"];
SetInvertScrollingFlag([valueSwitch isOn]);
break;
case GET_TAG(SECTION_UI_SETTINGS, 4):
[[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn]
forKey:@"ui.auto_scroll_touchpointer"];
SetInvertScrollingFlag([valueSwitch isOn]);
break;
case GET_TAG(SECTION_CERTIFICATE_HANDLING_SETTINGS, 0):
[[NSUserDefaults standardUserDefaults] setBool:[valueSwitch isOn]
forKey:@"security.accept_certificates"];
break;
default:
break;
}
}
@end

View File

@@ -0,0 +1,38 @@
/*
Bookmark editor controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
#import "EditorBaseController.h"
@class ComputerBookmark;
@class ConnectionParams;
@protocol BookmarkEditorDelegate <NSObject>
// bookmark editing finished
- (void)commitBookmark:(ComputerBookmark *)bookmark;
@end
@interface BookmarkEditorController : EditorBaseController
{
@private
ComputerBookmark *_bookmark;
ConnectionParams *_params;
BOOL _display_server_settings;
id<BookmarkEditorDelegate> delegate;
}
@property(nonatomic, assign) id<BookmarkEditorDelegate> delegate;
// init for the given bookmark
- (id)initWithBookmark:(ComputerBookmark *)bookmark;
@end

View File

@@ -0,0 +1,427 @@
/*
Bookmark editor controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "BookmarkEditorController.h"
#import "Bookmark.h"
#import "Utils.h"
#import "ScreenSelectionController.h"
#import "PerformanceEditorController.h"
#import "CredentialsEditorController.h"
#import "AdvancedBookmarkEditorController.h"
#import "BlockAlertView.h"
@implementation BookmarkEditorController
@synthesize delegate;
#define SECTION_SERVER 0
#define SECTION_CREDENTIALS 1
#define SECTION_SETTINGS 2
#define SECTION_COUNT 3
#pragma mark -
#pragma mark Initialization
- (id)initWithBookmark:(ComputerBookmark *)bookmark
{
if ((self = [super initWithStyle:UITableViewStyleGrouped]))
{
// set additional settings state according to bookmark data
if ([[bookmark uuid] length] == 0)
_bookmark = [bookmark copy];
else
_bookmark = [bookmark copyWithUUID];
_params = [_bookmark params];
_display_server_settings = YES;
}
return self;
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// replace back button with a custom handler that checks if the required bookmark settings were
// specified
UIBarButtonItem *saveButton =
[[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Save", @"Save Button title")
style:UIBarButtonItemStyleDone
target:self
action:@selector(handleSave:)] autorelease];
UIBarButtonItem *cancelButton =
[[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel", @"Cancel Button title")
style:UIBarButtonItemStyleBordered
target:self
action:@selector(handleCancel:)] autorelease];
[[self navigationItem] setLeftBarButtonItem:cancelButton];
[[self navigationItem] setRightBarButtonItem:saveButton];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// we need to reload the table view data here to have up-to-date data for the
// advanced settings accessory items (like for resolution/color mode settings)
[[self tableView] reloadData];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return SECTION_COUNT;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
switch (section)
{
case SECTION_SERVER: // server settings
return (_display_server_settings ? 3 : 0);
case SECTION_CREDENTIALS: // credentials
return 1;
case SECTION_SETTINGS: // session settings
return 3;
default:
break;
}
return 0;
}
// set section headers
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
switch (section)
{
case SECTION_SERVER:
return (_display_server_settings
? NSLocalizedString(@"Host", @"'Host': host settings header")
: nil);
case SECTION_CREDENTIALS:
return NSLocalizedString(@"Credentials", @"'Credentials': credentials settings header");
case SECTION_SETTINGS:
return NSLocalizedString(@"Settings", @"'Session Settings': session settings header");
}
return @"unknown";
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// determine the required cell type
NSString *cellType = nil;
switch ([indexPath section])
{
case SECTION_SERVER:
cellType = TableCellIdentifierText;
break;
case SECTION_CREDENTIALS:
cellType = TableCellIdentifierSelection;
break;
case SECTION_SETTINGS: // settings
{
switch ([indexPath row])
{
case 0: // screen/color depth
cellType = TableCellIdentifierSelection;
break;
case 1: // performance settings
case 2: // advanced settings
cellType = TableCellIdentifierSubEditor;
break;
default:
break;
}
}
break;
default:
break;
}
NSAssert(cellType != nil, @"Couldn't determine cell type");
// get the table view cell
UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
NSAssert(cell, @"Invalid cell");
// set cell values
switch ([indexPath section])
{
// server settings
case SECTION_SERVER:
[self initServerSettings:indexPath cell:cell];
break;
// credentials
case SECTION_CREDENTIALS:
[self initCredentialSettings:indexPath cell:cell];
break;
// session settings
case SECTION_SETTINGS:
[self initSettings:indexPath cell:cell];
break;
default:
break;
}
return cell;
}
// updates server settings in the UI
- (void)initServerSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
switch ([indexPath row])
{
case 0:
[[textCell label] setText:NSLocalizedString(@"Label", @"'Label': Bookmark label")];
[[textCell textfield] setText:[_bookmark label]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
case 1:
[[textCell label] setText:NSLocalizedString(@"Host", @"'Host': Bookmark hostname")];
[[textCell textfield] setText:[_params StringForKey:@"hostname"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
case 2:
[[textCell label] setText:NSLocalizedString(@"Port", @"'Port': Bookmark port")];
[[textCell textfield]
setText:[NSString stringWithFormat:@"%d", [_params intForKey:@"port"]]];
[[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
break;
default:
NSLog(@"Invalid row index in settings table!");
break;
}
[self adjustEditTextTableViewCell:textCell];
}
// updates credentials in the UI
- (void)initCredentialSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
EditSelectionTableViewCell *selCell = (EditSelectionTableViewCell *)cell;
switch (indexPath.row)
{
case 0:
[[selCell label]
setText:NSLocalizedString(@"Credentials", @"'Credentials': Bookmark credentials")];
[[selCell selection] setText:[_params StringForKey:@"username"]];
break;
default:
NSLog(@"Invalid row index in settings table!");
break;
}
}
// updates session settings in the UI
- (void)initSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
switch (indexPath.row)
{
case 0:
{
EditSelectionTableViewCell *selCell = (EditSelectionTableViewCell *)cell;
[[selCell label]
setText:NSLocalizedString(@"Screen", @"'Screen': Bookmark Screen settings")];
NSString *resolution = ScreenResolutionDescription(
[_params intForKey:@"screen_resolution_type"], [_params intForKey:@"width"],
[_params intForKey:@"height"]);
int colorBits = [_params intForKey:@"colors"];
[[selCell selection]
setText:[NSString stringWithFormat:@"%@@%d", resolution, colorBits]];
break;
}
case 1:
{
EditSubEditTableViewCell *editCell = (EditSubEditTableViewCell *)cell;
[[editCell label]
setText:NSLocalizedString(@"Performance",
@"'Performance': Bookmark Performance Settings")];
break;
}
case 2:
{
EditSubEditTableViewCell *editCell = (EditSubEditTableViewCell *)cell;
[[editCell label]
setText:NSLocalizedString(@"Advanced", @"'Advanced': Bookmark Advanced Settings")];
break;
}
default:
NSLog(@"Invalid row index in settings table!");
break;
}
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *viewCtrl = nil;
// determine view
switch ([indexPath section])
{
case SECTION_CREDENTIALS:
{
if ([indexPath row] == 0)
viewCtrl =
[[[CredentialsEditorController alloc] initWithBookmark:_bookmark] autorelease];
break;
}
case SECTION_SETTINGS:
{
switch ([indexPath row])
{
case 0:
viewCtrl = [[[ScreenSelectionController alloc] initWithConnectionParams:_params]
autorelease];
break;
case 1:
viewCtrl = [[[PerformanceEditorController alloc]
initWithConnectionParams:_params] autorelease];
break;
case 2:
viewCtrl = [[[AdvancedBookmarkEditorController alloc]
initWithBookmark:_bookmark] autorelease];
break;
default:
break;
}
break;
}
}
// display view
if (viewCtrl)
[[self navigationController] pushViewController:viewCtrl animated:YES];
}
#pragma mark -
#pragma mark Text Field delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
switch (textField.tag)
{
// update server settings
case GET_TAG(SECTION_SERVER, 0):
[_bookmark setLabel:[textField text]];
break;
case GET_TAG(SECTION_SERVER, 1):
[_params setValue:[textField text] forKey:@"hostname"];
break;
case GET_TAG(SECTION_SERVER, 2):
[_params setInt:[[textField text] intValue] forKey:@"port"];
break;
default:
break;
}
return YES;
}
#pragma mark -
#pragma mark Action Handlers
- (void)handleSave:(id)sender
{
// resign any first responder (so that we finish editing any bookmark parameter that might be
// currently edited)
[[self view] endEditing:NO];
// verify that bookmark is complete (only for manual bookmarks)
if ([[_bookmark label] length] == 0 || [[_params StringForKey:@"hostname"] length] == 0 ||
[_params intForKey:@"port"] == 0)
{
BlockAlertView *alertView = [BlockAlertView
alertWithTitle:NSLocalizedString(@"Cancel without saving?",
@"Incomplete bookmark error title")
message:NSLocalizedString(@"Press 'Cancel' to abort!\nPress 'Continue' to "
@"specify the required fields!",
@"Incomplete bookmark error message")];
[alertView
setCancelButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel Button")
block:^{
// cancel bookmark editing and return to previous view controller
[[self navigationController] popViewControllerAnimated:YES];
}];
[alertView addButtonWithTitle:NSLocalizedString(@"Continue", @"Continue Button") block:nil];
[alertView show];
return;
}
// commit bookmark
if ([[self delegate] respondsToSelector:@selector(commitBookmark:)])
[[self delegate] commitBookmark:_bookmark];
// return to previous view controller
[[self navigationController] popViewControllerAnimated:YES];
}
- (void)handleCancel:(id)sender
{
// return to previous view controller
[[self navigationController] popViewControllerAnimated:YES];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)dealloc
{
[super dealloc];
[_bookmark autorelease];
}
@end

View File

@@ -0,0 +1,26 @@
/*
Controller to edit ts gateway bookmark settings
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@class ComputerBookmark;
@class ConnectionParams;
@interface BookmarkGatewaySettingsController : EditorBaseController
{
@private
ComputerBookmark *_bookmark;
ConnectionParams *_params;
}
// init for the given bookmark
- (id)initWithBookmark:(ComputerBookmark *)bookmark;
@end

View File

@@ -0,0 +1,242 @@
//
// BookmarkGatewaySettingsController.m
// FreeRDP
//
// Created by a Thincast Developer on 4/30/13.
//
//
#import "BookmarkGatewaySettingsController.h"
#import "Bookmark.h"
#import "Utils.h"
#import "EditorSelectionController.h"
#define SECTION_TSGATEWAY_SETTINGS 0
#define SECTION_COUNT 1
@interface BookmarkGatewaySettingsController ()
@end
@implementation BookmarkGatewaySettingsController
- (id)initWithBookmark:(ComputerBookmark *)bookmark
{
if ((self = [super initWithStyle:UITableViewStyleGrouped]))
{
// set additional settings state according to bookmark data
_bookmark = [bookmark retain];
_params = [bookmark params];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:NSLocalizedString(@"TS Gateway Settings", @"TS Gateway Settings title")];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// we need to reload the table view data here to have up-to-date data for the
// advanced settings accessory items (like for resolution/color mode settings)
[[self tableView] reloadData];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)dealloc
{
[super dealloc];
[_bookmark release];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return SECTION_COUNT;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
switch (section)
{
case SECTION_TSGATEWAY_SETTINGS: // ts gateway settings
return 5;
default:
break;
}
return 0;
}
// set section headers
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
switch (section)
{
case SECTION_TSGATEWAY_SETTINGS:
return NSLocalizedString(@"TS Gateway", @"'TS Gateway': ts gateway settings header");
}
return @"unknown";
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// determine the required cell type
NSString *cellType = nil;
switch ([indexPath section])
{
case SECTION_TSGATEWAY_SETTINGS: // advanced settings
{
switch ([indexPath row])
{
case 0: // hostname
case 1: // port
case 2: // username
case 4: // domain
cellType = TableCellIdentifierText;
break;
case 3: // password
cellType = TableCellIdentifierSecretText;
break;
default:
break;
}
break;
}
}
NSAssert(cellType != nil, @"Couldn't determine cell type");
// get the table view cell
UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
NSAssert(cell, @"Invalid cell");
// set cell values
switch ([indexPath section])
{
// advanced settings
case SECTION_TSGATEWAY_SETTINGS:
[self initGatewaySettings:indexPath cell:cell];
break;
default:
break;
}
return cell;
}
// updates server settings in the UI
- (void)initGatewaySettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
switch ([indexPath row])
{
case 0:
{
[[textCell label] setText:NSLocalizedString(@"Host", @"'Host': Bookmark hostname")];
[[textCell textfield] setText:[_params StringForKey:@"tsg_hostname"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
}
case 1:
{
int port = [_params intForKey:@"tsg_port"];
if (port == 0)
port = 443;
[[textCell label] setText:NSLocalizedString(@"Port", @"'Port': Bookmark port")];
[[textCell textfield] setText:[NSString stringWithFormat:@"%d", port]];
[[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
break;
}
case 2:
{
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell label]
setText:NSLocalizedString(@"Username", @"'Username': Bookmark username")];
[[textCell textfield] setText:[_params StringForKey:@"tsg_username"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
}
case 3:
{
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell label]
setText:NSLocalizedString(@"Password", @"'Password': Bookmark password")];
[[textCell textfield] setText:[_params StringForKey:@"tsg_password"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
}
case 4:
{
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell label] setText:NSLocalizedString(@"Domain", @"'Domain': Bookmark domain")];
[[textCell textfield] setText:[_params StringForKey:@"tsg_domain"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
}
default:
NSLog(@"Invalid row index in settings table!");
break;
}
[self adjustEditTextTableViewCell:textCell];
}
#pragma mark -
#pragma mark Text Field delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
switch (textField.tag)
{
// update server settings
case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 0):
[_params setValue:[textField text] forKey:@"tsg_hostname"];
break;
case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 1):
[_params setInt:[[textField text] intValue] forKey:@"tsg_port"];
break;
case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 2):
[_params setValue:[textField text] forKey:@"tsg_username"];
break;
case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 3):
[_params setValue:[textField text] forKey:@"tsg_password"];
break;
case GET_TAG(SECTION_TSGATEWAY_SETTINGS, 4):
[_params setValue:[textField text] forKey:@"tsg_domain"];
break;
default:
break;
}
return YES;
}
@end

View File

@@ -0,0 +1,56 @@
/*
bookmarks and active session view controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
#import "Bookmark.h"
#import "BookmarkTableCell.h"
#import "SessionTableCell.h"
#import "BookmarkEditorController.h"
#import "Reachability.h"
@interface BookmarkListController : UIViewController <UISearchBarDelegate, UITableViewDelegate,
UITableViewDataSource, BookmarkEditorDelegate>
{
// custom bookmark and session table cells
BookmarkTableCell *_bmTableCell;
SessionTableCell *_sessTableCell;
// child views
UISearchBar *_searchBar;
UITableView *_tableView;
// array with search results (or nil if no search active)
NSMutableArray *_manual_search_result;
NSMutableArray *_history_search_result;
// bookmark arrays
NSMutableArray *_manual_bookmarks;
// bookmark star images
UIImage *_star_on_img;
UIImage *_star_off_img;
// array with active sessions
NSMutableArray *_active_sessions;
// array with connection history entries
NSMutableArray *_connection_history;
// temporary bookmark when asking if the user wants to store a bookmark for a session initiated
// by a quick connect
ComputerBookmark *_temporary_bookmark;
}
@property(nonatomic, retain) IBOutlet UISearchBar *searchBar;
@property(nonatomic, retain) IBOutlet UITableView *tableView;
@property(nonatomic, retain) IBOutlet BookmarkTableCell *bmTableCell;
@property(nonatomic, retain) IBOutlet SessionTableCell *sessTableCell;
@end

View File

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

View File

@@ -0,0 +1,26 @@
/*
Controller to edit bookmark credentials
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@class ComputerBookmark;
@class ConnectionParams;
@interface CredentialsEditorController : EditorBaseController
{
@private
ComputerBookmark *_bookmark;
ConnectionParams *_params;
}
// init for the given bookmark
- (id)initWithBookmark:(ComputerBookmark *)bookmark;
@end

View File

@@ -0,0 +1,215 @@
/*
Controller to edit bookmark credentials
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "CredentialsEditorController.h"
#import "Bookmark.h"
#import "Utils.h"
@interface CredentialsEditorController ()
@end
#define SECTION_CREDENTIALS 0
#define SECTION_COUNT 1
@implementation CredentialsEditorController
- (id)initWithBookmark:(ComputerBookmark *)bookmark
{
if ((self = [super initWithStyle:UITableViewStyleGrouped]))
{
// set additional settings state according to bookmark data
_bookmark = [bookmark retain];
_params = [bookmark params];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setTitle:NSLocalizedString(@"Credentials", @"Credentials title")];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// foce any active editing to stop
[[self view] endEditing:NO];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)dealloc
{
[super dealloc];
[_bookmark release];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return SECTION_COUNT;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
switch (section)
{
case SECTION_CREDENTIALS: // credentials
return 3;
default:
break;
}
return 0;
}
// set section headers
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
switch (section)
{
case SECTION_CREDENTIALS:
return NSLocalizedString(@"Credentials", @"'Credentials': credentials settings header");
}
return @"unknown";
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// determine the required cell type
NSString *cellType = nil;
switch ([indexPath section])
{
case SECTION_CREDENTIALS: // credentials
if ([indexPath row] == 1)
cellType = TableCellIdentifierSecretText; // password field
else
cellType = TableCellIdentifierText;
break;
default:
break;
}
NSAssert(cellType != nil, @"Couldn't determine cell type");
// get the table view cell
UITableViewCell *cell = [self tableViewCellFromIdentifier:cellType];
NSAssert(cell, @"Invalid cell");
// set cell values
switch ([indexPath section])
{
// credentials
case SECTION_CREDENTIALS:
[self initCredentialSettings:indexPath cell:cell];
break;
default:
break;
}
return cell;
}
// updates credentials in the UI
- (void)initCredentialSettings:(NSIndexPath *)indexPath cell:(UITableViewCell *)cell
{
switch (indexPath.row)
{
case 0:
{
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell label]
setText:NSLocalizedString(@"Username", @"'Username': Bookmark username")];
[[textCell textfield] setText:[_params StringForKey:@"username"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
}
case 1:
{
EditSecretTextTableViewCell *textCell = (EditSecretTextTableViewCell *)cell;
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell label]
setText:NSLocalizedString(@"Password", @"'Password': Bookmark password")];
[[textCell textfield] setText:[_params StringForKey:@"password"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
}
case 2:
{
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell textfield] setTag:GET_TAG_FROM_PATH(indexPath)];
[[textCell label] setText:NSLocalizedString(@"Domain", @"'Domain': Bookmark domain")];
[[textCell textfield] setText:[_params StringForKey:@"domain"]];
[[textCell textfield]
setPlaceholder:NSLocalizedString(@"not set", @"not set placeholder")];
break;
}
default:
NSLog(@"Invalid row index in settings table!");
break;
}
}
#pragma mark -
#pragma mark Text Field delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
switch (textField.tag)
{
// update credentials settings
case GET_TAG(SECTION_CREDENTIALS, 0):
[_params setValue:[textField text] forKey:@"username"];
break;
case GET_TAG(SECTION_CREDENTIALS, 1):
[_params setValue:[textField text] forKey:@"password"];
break;
case GET_TAG(SECTION_CREDENTIALS, 2):
[_params setValue:[textField text] forKey:@"domain"];
break;
default:
break;
}
return YES;
}
@end

View File

@@ -0,0 +1,35 @@
/*
Credentials input controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
@class RDPSession;
@interface CredentialsInputController : UIViewController
{
@private
IBOutlet UITextField *_textfield_username;
IBOutlet UITextField *_textfield_password;
IBOutlet UITextField *_textfield_domain;
IBOutlet UIButton *_btn_login;
IBOutlet UIButton *_btn_cancel;
IBOutlet UIScrollView *_scroll_view;
IBOutlet UILabel *_lbl_message;
RDPSession *_session;
NSMutableDictionary *_params;
}
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
session:(RDPSession *)session
params:(NSMutableDictionary *)params;
@end

View File

@@ -0,0 +1,160 @@
/*
Credentials input controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "CredentialsInputController.h"
#import "RDPSession.h"
#import "Utils.h"
@implementation CredentialsInputController
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
session:(RDPSession *)session
params:(NSMutableDictionary *)params
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
_session = session;
_params = params;
[self setModalPresentationStyle:UIModalPresentationFormSheet];
// on iphone we have the problem that the buttons are hidden by the keyboard
// we solve this issue by registering keyboard notification handlers and adjusting the
// scrollview accordingly
if (IsPhone())
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// set localized strings
[_lbl_message
setText:NSLocalizedString(
@"Please provide the missing user information in order to proceed and login.",
@"Credentials input view message")];
[_textfield_username
setPlaceholder:NSLocalizedString(@"Username", @"Credentials Input Username hint")];
[_textfield_password
setPlaceholder:NSLocalizedString(@"Password", @"Credentials Input Password hint")];
[_textfield_domain
setPlaceholder:NSLocalizedString(@"Domain", @"Credentials Input Domain hint")];
[_btn_login setTitle:NSLocalizedString(@"Login", @"Login Button")
forState:UIControlStateNormal];
[_btn_cancel setTitle:NSLocalizedString(@"Cancel", @"Cancel Button")
forState:UIControlStateNormal];
// init scrollview content size
[_scroll_view setContentSize:[_scroll_view frame].size];
// set params in the view
[_textfield_username setText:[_params valueForKey:@"username"]];
[_textfield_password setText:[_params valueForKey:@"password"]];
[_textfield_domain setText:[_params valueForKey:@"domain"]];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
// set signal
[[_session uiRequestCompleted] signal];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)dealloc
{
[super dealloc];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark -
#pragma mark iOS Keyboard Notification Handlers
- (void)keyboardWillShow:(NSNotification *)notification
{
CGRect keyboardEndFrame =
[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrame = [[self view] convertRect:keyboardEndFrame toView:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:[[[notification userInfo]
objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
[UIView
setAnimationDuration:[[[notification userInfo]
objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
CGRect frame = [_scroll_view frame];
frame.size.height -= keyboardFrame.size.height;
[_scroll_view setFrame:frame];
[UIView commitAnimations];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
CGRect keyboardEndFrame =
[[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrame = [[self view] convertRect:keyboardEndFrame toView:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:[[[notification userInfo]
objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
[UIView
setAnimationDuration:[[[notification userInfo]
objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
CGRect frame = [_scroll_view frame];
frame.size.height += keyboardFrame.size.height;
[_scroll_view setFrame:frame];
[UIView commitAnimations];
}
#pragma mark - Action handlers
- (IBAction)loginPressed:(id)sender
{
// read input back in
[_params setValue:[_textfield_username text] forKey:@"username"];
[_params setValue:[_textfield_password text] forKey:@"password"];
[_params setValue:[_textfield_domain text] forKey:@"domain"];
[_params setValue:[NSNumber numberWithBool:YES] forKey:@"result"];
// dismiss controller
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)cancelPressed:(id)sender
{
[_params setValue:[NSNumber numberWithBool:NO] forKey:@"result"];
// dismiss controller
[self dismissModalViewControllerAnimated:YES];
}
@end

View File

@@ -0,0 +1,44 @@
/*
Basic interface for settings editors
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
#import "EditTextTableViewCell.h"
#import "EditFlagTableViewCell.h"
#import "EditSelectionTableViewCell.h"
#import "EditSubEditTableViewCell.h"
#import "EditSecretTextTableViewCell.h"
#import "EditButtonTableViewCell.h"
extern NSString *TableCellIdentifierText;
extern NSString *TableCellIdentifierSecretText;
extern NSString *TableCellIdentifierYesNo;
extern NSString *TableCellIdentifierSelection;
extern NSString *TableCellIdentifierSubEditor;
extern NSString *TableCellIdentifierMultiChoice;
extern NSString *TableCellIdentifierButton;
@interface EditorBaseController : UITableViewController <UITextFieldDelegate>
{
@private
IBOutlet EditTextTableViewCell *_textTableViewCell;
IBOutlet EditSecretTextTableViewCell *_secretTextTableViewCell;
IBOutlet EditFlagTableViewCell *_flagTableViewCell;
IBOutlet EditSelectionTableViewCell *_selectionTableViewCell;
IBOutlet EditSubEditTableViewCell *_subEditTableViewCell;
IBOutlet EditButtonTableViewCell *_buttonTableViewCell;
}
// returns one of the requested table view cells
- (UITableViewCell *)tableViewCellFromIdentifier:(NSString *)identifier;
// Adjust text input cells label/textfield width according to the label's text size
- (void)adjustEditTextTableViewCell:(EditTextTableViewCell *)cell;
@end

View File

@@ -0,0 +1,110 @@
/*
Basic interface for settings editors
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@interface EditorBaseController ()
@end
NSString *TableCellIdentifierText = @"cellIdText";
NSString *TableCellIdentifierSecretText = @"cellIdSecretText";
NSString *TableCellIdentifierYesNo = @"cellIdYesNo";
NSString *TableCellIdentifierSelection = @"cellIdSelection";
NSString *TableCellIdentifierSubEditor = @"cellIdSubEditor";
NSString *TableCellIdentifierMultiChoice = @"cellIdMultiChoice";
NSString *TableCellIdentifierButton = @"cellIdButton";
@implementation EditorBaseController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark - Create table view cells
- (UITableViewCell *)tableViewCellFromIdentifier:(NSString *)identifier
{
// try to reuse a cell
UITableViewCell *cell = [[self tableView] dequeueReusableCellWithIdentifier:identifier];
if (cell != nil)
return cell;
// we have to create a new cell
if ([identifier isEqualToString:TableCellIdentifierText])
{
[[NSBundle mainBundle] loadNibNamed:@"EditTextTableViewCell" owner:self options:nil];
cell = _textTableViewCell;
_textTableViewCell = nil;
}
else if ([identifier isEqualToString:TableCellIdentifierSecretText])
{
[[NSBundle mainBundle] loadNibNamed:@"EditSecretTextTableViewCell" owner:self options:nil];
cell = _secretTextTableViewCell;
_secretTextTableViewCell = nil;
}
else if ([identifier isEqualToString:TableCellIdentifierYesNo])
{
[[NSBundle mainBundle] loadNibNamed:@"EditFlagTableViewCell" owner:self options:nil];
cell = _flagTableViewCell;
_flagTableViewCell = nil;
}
else if ([identifier isEqualToString:TableCellIdentifierSelection])
{
[[NSBundle mainBundle] loadNibNamed:@"EditSelectionTableViewCell" owner:self options:nil];
cell = _selectionTableViewCell;
_selectionTableViewCell = nil;
}
else if ([identifier isEqualToString:TableCellIdentifierSubEditor])
{
[[NSBundle mainBundle] loadNibNamed:@"EditSubEditTableViewCell" owner:self options:nil];
cell = _subEditTableViewCell;
_subEditTableViewCell = nil;
}
else if ([identifier isEqualToString:TableCellIdentifierButton])
{
[[NSBundle mainBundle] loadNibNamed:@"EditButtonTableViewCell" owner:self options:nil];
cell = _buttonTableViewCell;
_buttonTableViewCell = nil;
}
else if ([identifier isEqualToString:TableCellIdentifierMultiChoice])
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:identifier] autorelease];
}
else
{
NSAssert(false, @"Unknown table cell identifier");
}
return cell;
}
#pragma mark - Utility functions
- (void)adjustEditTextTableViewCell:(EditTextTableViewCell *)cell
{
UILabel *label = [cell label];
UITextField *textField = [cell textfield];
// adjust label
CGFloat width = [[label text] sizeWithFont:[label font]].width;
CGRect frame = [label frame];
CGFloat delta = width - frame.size.width;
frame.size.width = width;
[label setFrame:frame];
// adjust text field
frame = [textField frame];
frame.origin.x += delta;
frame.size.width -= delta;
[textField setFrame:frame];
}
@end

View File

@@ -0,0 +1,34 @@
/*
Generic controller to select a single item from a list of options
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@class ConnectionParams;
@interface EditorSelectionController : EditorBaseController
{
ConnectionParams *_params;
// array with entries in connection parameters that are altered
NSArray *_entries;
// array with dictionaries containing label/value pairs that represent the available values for
// each entry
NSArray *_selections;
// current selections
NSMutableArray *_cur_selections;
}
- (id)initWithConnectionParams:(ConnectionParams *)params
entries:(NSArray *)entries
selections:(NSArray *)selections;
@end

View File

@@ -0,0 +1,143 @@
/*
Generic controller to select a single item from a list of options
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorSelectionController.h"
#import "ConnectionParams.h"
#import "OrderedDictionary.h"
@interface EditorSelectionController (Private)
- (OrderedDictionary *)selectionForIndex:(int)index;
@end
@implementation EditorSelectionController
- (id)initWithConnectionParams:(ConnectionParams *)params
entries:(NSArray *)entries
selections:(NSArray *)selections
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self)
{
_params = [params retain];
_entries = [entries retain];
_selections = [selections retain];
// allocate and init current selections array
_cur_selections = [[NSMutableArray alloc] initWithCapacity:[_entries count]];
for (int i = 0; i < [entries count]; ++i)
{
NSString *entry = [entries objectAtIndex:i];
if ([_params hasValueForKeyPath:entry])
{
NSUInteger idx = [(OrderedDictionary *)[selections objectAtIndex:i]
indexForValue:[NSNumber numberWithInt:[_params intForKeyPath:entry]]];
[_cur_selections addObject:[NSNumber numberWithInt:(idx != NSNotFound ? idx : 0)]];
}
else
[_cur_selections addObject:[NSNumber numberWithInt:0]];
}
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
[_params autorelease];
[_entries autorelease];
[_selections autorelease];
[_cur_selections autorelease];
}
#pragma mark - View lifecycle
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [_entries count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[self selectionForIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];
// get selection
OrderedDictionary *selection = [self selectionForIndex:[indexPath section]];
// set cell properties
[[cell textLabel] setText:[selection keyAtIndex:[indexPath row]]];
// set default checkmark
if ([indexPath row] == [[_cur_selections objectAtIndex:[indexPath section]] intValue])
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
else
[cell setAccessoryType:UITableViewCellAccessoryNone];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// has selection change?
int cur_selection = [[_cur_selections objectAtIndex:[indexPath section]] intValue];
if ([indexPath row] != cur_selection)
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:cur_selection
inSection:[indexPath section]];
// clear old checkmark
UITableViewCell *old_sel_cell = [tableView cellForRowAtIndexPath:oldIndexPath];
old_sel_cell.accessoryType = UITableViewCellAccessoryNone;
// set new checkmark
UITableViewCell *new_sel_cell = [tableView cellForRowAtIndexPath:indexPath];
new_sel_cell.accessoryType = UITableViewCellAccessoryCheckmark;
// get value from selection dictionary
OrderedDictionary *dict = [self selectionForIndex:[indexPath section]];
int sel_value = [[dict valueForKey:[dict keyAtIndex:[indexPath row]]] intValue];
// update selection index and params value
[_cur_selections replaceObjectAtIndex:[indexPath section]
withObject:[NSNumber numberWithInt:[indexPath row]]];
[_params setInt:sel_value forKeyPath:[_entries objectAtIndex:[indexPath section]]];
}
}
#pragma mark - Convenience functions
- (OrderedDictionary *)selectionForIndex:(int)index
{
return (OrderedDictionary *)[_selections objectAtIndex:index];
}
@end

View File

@@ -0,0 +1,25 @@
/*
Password Encryption Controller
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import "Encryptor.h"
@interface EncryptionController : NSObject
{
Encryptor *_shared_encryptor;
}
+ (EncryptionController *)sharedEncryptionController;
// Return a Encryptor suitable for encrypting or decrypting with the master password
- (Encryptor *)decryptor;
- (Encryptor *)encryptor;
@end

View File

@@ -0,0 +1,155 @@
/*
Password Encryption Controller
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EncryptionController.h"
#import "SFHFKeychainUtils.h"
#import "TSXAdditions.h"
@interface EncryptionController (Private)
- (BOOL)verifyPassword:(Encryptor *)decryptor;
- (NSData *)encryptedVerificationData;
- (void)setEncryptedVerificationData:(Encryptor *)encryptor;
- (NSString *)keychainServerName;
- (NSString *)keychainUsername;
- (void)setKeychainPassword:(NSString *)password;
- (NSString *)keychainPassword;
- (NSString *)keychainDefaultPassword;
@end
static EncryptionController *_shared_encryption_controller = nil;
#pragma mark -
@implementation EncryptionController
+ (EncryptionController *)sharedEncryptionController
{
@synchronized(self)
{
if (_shared_encryption_controller == nil)
_shared_encryption_controller = [[EncryptionController alloc] init];
}
return _shared_encryption_controller;
}
#pragma mark Getting an encryptor or decryptor
- (Encryptor *)encryptor
{
if (_shared_encryptor)
return _shared_encryptor;
NSString *saved_password = [self keychainPassword];
if (saved_password == nil)
{
saved_password = [self keychainDefaultPassword];
Encryptor *encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
[self setEncryptedVerificationData:encryptor];
_shared_encryptor = [encryptor retain];
}
else
{
Encryptor *encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
if ([self verifyPassword:encryptor])
_shared_encryptor = [encryptor retain];
}
return _shared_encryptor;
}
// For the current implementation, decryptors and encryptors are equivalent.
- (Encryptor *)decryptor
{
return [self encryptor];
}
@end
#pragma mark -
@implementation EncryptionController (Private)
#pragma mark -
#pragma mark Keychain password storage
- (NSString *)keychainServerName
{
return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
}
- (NSString *)keychainUsername
{
return @"master.password";
}
- (void)setKeychainPassword:(NSString *)password
{
NSError *error;
if (password == nil)
{
[SFHFKeychainUtils deleteItemForUsername:[self keychainUsername]
andServerName:[self keychainServerName]
error:&error];
return;
}
[SFHFKeychainUtils storeUsername:[self keychainUsername]
andPassword:password
forServerName:[self keychainServerName]
updateExisting:YES
error:&error];
}
- (NSString *)keychainPassword
{
NSError *error;
return [SFHFKeychainUtils getPasswordForUsername:[self keychainUsername]
andServerName:[self keychainServerName]
error:&error];
}
- (NSString *)keychainDefaultPassword
{
NSString *password = [[NSUserDefaults standardUserDefaults] stringForKey:@"UUID"];
if ([password length] == 0)
{
password = [NSString stringWithUUID];
[[NSUserDefaults standardUserDefaults] setObject:password forKey:@"UUID"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"TSXMasterPasswordVerification"];
}
return password;
}
#pragma mark -
#pragma mark Verification of encryption key against verification data
- (BOOL)verifyPassword:(Encryptor *)decryptor
{
return [[decryptor plaintextPassword]
isEqualToString:[decryptor decryptString:[self encryptedVerificationData]]];
}
- (NSData *)encryptedVerificationData
{
return [[NSUserDefaults standardUserDefaults] dataForKey:@"TSXMasterPasswordVerification"];
}
- (void)setEncryptedVerificationData:(Encryptor *)encryptor
{
[[NSUserDefaults standardUserDefaults]
setObject:[encryptor encryptString:[encryptor plaintextPassword]]
forKey:@"TSXMasterPasswordVerification"];
}
@end

View File

@@ -0,0 +1,17 @@
/*
Application help controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
@interface HelpController : UIViewController <UIWebViewDelegate>
{
UIWebView *webView;
}
@end

View File

@@ -0,0 +1,76 @@
/*
Application help controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "HelpController.h"
#import "Utils.h"
@implementation HelpController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// set title and tab-bar image
[self setTitle:NSLocalizedString(@"Help", @"Help Controller title")];
UIImage *tabBarIcon = [UIImage
imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tabbar_icon_help"
ofType:@"png"]];
[self setTabBarItem:[[[UITabBarItem alloc]
initWithTitle:NSLocalizedString(@"Help", @"Tabbar item help")
image:tabBarIcon
tag:0] autorelease]];
}
return self;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
webView = [[[UIWebView alloc] initWithFrame:CGRectZero] autorelease];
[webView
setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[webView setAutoresizesSubviews:YES];
[webView setDelegate:self];
[webView setDataDetectorTypes:UIDataDetectorTypeNone];
[self setView:webView];
}
- (void)dealloc
{
[super dealloc];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *filename = (IsPhone() ? @"gestures_phone" : @"gestures");
NSString *htmlString = [[[NSString alloc]
initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename
ofType:@"html"
inDirectory:@"help_page"]
encoding:NSUTF8StringEncoding
error:nil] autorelease];
[webView
loadHTMLString:htmlString
baseURL:[NSURL fileURLWithPath:[[[NSBundle mainBundle] bundlePath]
stringByAppendingPathComponent:@"help_page"]]];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
@end

View File

@@ -0,0 +1,18 @@
/*
main tabbar controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface MainTabBarController : UITabBarController
{
}
@end

View File

@@ -0,0 +1,20 @@
/*
main tabbar controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "MainTabBarController.h"
@implementation MainTabBarController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
@end

View File

@@ -0,0 +1,25 @@
/*
controller for performance settings selection
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@class ConnectionParams;
@interface PerformanceEditorController : EditorBaseController
{
@private
ConnectionParams *_params;
NSString *_keyPath;
}
- (id)initWithConnectionParams:(ConnectionParams *)params;
- (id)initWithConnectionParams:(ConnectionParams *)params keyPath:(NSString *)keyPath;
@end

View File

@@ -0,0 +1,244 @@
/*
controller for performance settings selection
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "PerformanceEditorController.h"
#import "ConnectionParams.h"
#import "Utils.h"
@interface PerformanceEditorController (Private)
- (NSString *)keyPathForKey:(NSString *)key;
@end
@implementation PerformanceEditorController
- (id)initWithConnectionParams:(ConnectionParams *)params
{
return [self initWithConnectionParams:params keyPath:nil];
}
- (id)initWithConnectionParams:(ConnectionParams *)params keyPath:(NSString *)keyPath;
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self)
{
_params = [params retain];
_keyPath = (keyPath != nil ? [keyPath retain] : nil);
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (NSString *)keyPathForKey:(NSString *)key
{
if (_keyPath)
return [_keyPath stringByAppendingFormat:@".%@", key];
return key;
}
- (void)dealloc
{
[super dealloc];
[_params release];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 7;
}
// set section headers
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return NSLocalizedString(@"Performance Settings",
@"'Performance Settings': performance settings header");
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// get the table view cell
EditFlagTableViewCell *cell =
(EditFlagTableViewCell *)[self tableViewCellFromIdentifier:TableCellIdentifierYesNo];
NSAssert(cell, @"Invalid cell");
switch ([indexPath row])
{
case 0:
{
[[cell label] setText:NSLocalizedString(@"RemoteFX", @"RemoteFX performance setting")];
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_remotefx"]]];
break;
}
case 1:
{
[[cell label] setText:NSLocalizedString(@"GFX", @"GFX performance setting")];
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_gfx"]]];
break;
}
case 2:
{
[[cell label] setText:NSLocalizedString(@"H264", @"H264 performance setting")];
[[cell toggle] setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_h264"]]];
break;
}
case 3:
{
[[cell label] setText:NSLocalizedString(@"Desktop Background",
@"Desktop background performance setting")];
[[cell toggle]
setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_show_desktop"]]];
break;
}
case 4:
{
[[cell label] setText:NSLocalizedString(@"Font Smoothing",
@"Font smoothing performance setting")];
[[cell toggle]
setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_font_smoothing"]]];
break;
}
case 5:
{
[[cell label] setText:NSLocalizedString(@"Desktop Composition",
@"Desktop composition performance setting")];
[[cell toggle]
setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_desktop_composition"]]];
break;
}
case 6:
{
[[cell label] setText:NSLocalizedString(@"Window contents while dragging",
@"Window Dragging performance setting")];
[[cell toggle]
setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_window_dragging"]]];
break;
}
case 7:
{
[[cell label] setText:NSLocalizedString(@"Menu Animation",
@"Menu Animations performance setting")];
[[cell toggle]
setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_menu_animation"]]];
break;
}
case 8:
{
[[cell label]
setText:NSLocalizedString(@"Visual Styles", @"Use Themes performance setting")];
[[cell toggle]
setOn:[_params boolForKeyPath:[self keyPathForKey:@"perf_windows_themes"]]];
break;
}
default:
break;
}
[[cell toggle] setTag:GET_TAG_FROM_PATH(indexPath)];
[[cell toggle] addTarget:self
action:@selector(togglePerformanceSetting:)
forControlEvents:UIControlEventValueChanged];
return cell;
}
#pragma mark -
#pragma mark Action Handlers
- (void)togglePerformanceSetting:(id)sender
{
UISwitch *valueSwitch = (UISwitch *)sender;
switch (valueSwitch.tag)
{
case GET_TAG(0, 0):
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_remotefx"]];
break;
case GET_TAG(0, 1):
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_gfx"]];
break;
case GET_TAG(0, 2):
[_params setBool:[valueSwitch isOn] forKeyPath:[self keyPathForKey:@"perf_h264"]];
break;
case GET_TAG(0, 3):
[_params setBool:[valueSwitch isOn]
forKeyPath:[self keyPathForKey:@"perf_show_desktop"]];
break;
case GET_TAG(0, 4):
[_params setBool:[valueSwitch isOn]
forKeyPath:[self keyPathForKey:@"perf_font_smoothing"]];
break;
case GET_TAG(0, 5):
[_params setBool:[valueSwitch isOn]
forKeyPath:[self keyPathForKey:@"perf_desktop_composition"]];
break;
case GET_TAG(0, 6):
[_params setBool:[valueSwitch isOn]
forKeyPath:[self keyPathForKey:@"perf_window_dragging"]];
break;
case GET_TAG(0, 7):
[_params setBool:[valueSwitch isOn]
forKeyPath:[self keyPathForKey:@"perf_menu_animation"]];
break;
case GET_TAG(0, 8):
[_params setBool:[valueSwitch isOn]
forKeyPath:[self keyPathForKey:@"perf_windows_themes"]];
break;
default:
break;
}
}
@end

View File

@@ -0,0 +1,75 @@
/*
RDP Session View Controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
#import "RDPSession.h"
#import "RDPKeyboard.h"
#import "RDPSessionView.h"
#import "TouchPointerView.h"
#import "AdvancedKeyboardView.h"
@interface RDPSessionViewController
: UIViewController <RDPSessionDelegate, TouchPointerDelegate, AdvancedKeyboardDelegate,
RDPKeyboardDelegate, UIScrollViewDelegate, UITextFieldDelegate>
{
// scrollview that hosts the rdp session view
IBOutlet UIScrollView *_session_scrollview;
// rdp session view
IBOutlet RDPSessionView *_session_view;
// touch pointer view
IBOutlet TouchPointerView *_touchpointer_view;
BOOL _autoscroll_with_touchpointer;
BOOL _is_autoscrolling;
// rdp session toolbar
IBOutlet UIToolbar *_session_toolbar;
BOOL _session_toolbar_visible;
// dummy text field used to display the keyboard
IBOutlet UITextField *_dummy_textfield;
// connecting view and the controls within that view
IBOutlet UIView *_connecting_view;
IBOutlet UILabel *_lbl_connecting;
IBOutlet UIActivityIndicatorView *_connecting_indicator_view;
IBOutlet UIButton *_cancel_connect_button;
// extended keyboard toolbar
UIToolbar *_keyboard_toolbar;
// rdp session
RDPSession *_session;
BOOL _session_initilized;
// flag that indicates whether the keyboard is visible or not
BOOL _keyboard_visible;
// flag to switch between left/right mouse button mode
BOOL _toggle_mouse_button;
// keyboard extension view
AdvancedKeyboardView *_advanced_keyboard_view;
BOOL _advanced_keyboard_visible;
BOOL _requesting_advanced_keyboard;
CGFloat _keyboard_last_height;
// delayed mouse move event sending
NSTimer *_mouse_move_event_timer;
int _mouse_move_events_skipped;
CGPoint _prev_long_press_position;
}
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
session:(RDPSession *)session;
@end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
/*
controller for screen settings selection
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "EditorBaseController.h"
@class ConnectionParams;
@class OrderedDictionary;
@interface ScreenSelectionController : EditorBaseController
{
@private
NSString *_keyPath;
ConnectionParams *_params;
// available options
OrderedDictionary *_color_options;
NSArray *_resolution_modes;
// current selections
int _selection_color;
int _selection_resolution;
}
- (id)initWithConnectionParams:(ConnectionParams *)params;
- (id)initWithConnectionParams:(ConnectionParams *)params keyPath:(NSString *)keyPath;
@end

View File

@@ -0,0 +1,253 @@
/*
controller for screen settings selection
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "ScreenSelectionController.h"
#import "Utils.h"
#import "OrderedDictionary.h"
#import "ConnectionParams.h"
@interface ScreenSelectionController (Private)
- (NSString *)keyPathForKey:(NSString *)key;
@end
@implementation ScreenSelectionController
- (id)initWithConnectionParams:(ConnectionParams *)params
{
return [self initWithConnectionParams:params keyPath:nil];
}
- (id)initWithConnectionParams:(ConnectionParams *)params keyPath:(NSString *)keyPath
{
self = [super initWithStyle:UITableViewStyleGrouped];
if (self)
{
_params = [params retain];
_keyPath = (keyPath != nil ? [keyPath retain] : nil);
_color_options = (OrderedDictionary *)[SelectionForColorSetting() retain];
_resolution_modes = [ResolutionModes() retain];
// init current selections
NSUInteger idx = [_color_options
indexForValue:[NSNumber
numberWithInt:[_params
intForKeyPath:[self keyPathForKey:@"colors"]]]];
_selection_color = (idx != NSNotFound) ? idx : 0;
idx = [_resolution_modes
indexOfObject:ScreenResolutionDescription(
[_params
intForKeyPath:[self keyPathForKey:@"screen_resolution_type"]],
[_params intForKeyPath:[self keyPathForKey:@"width"]],
[_params intForKeyPath:[self keyPathForKey:@"height"]])];
_selection_resolution = (idx != NSNotFound) ? idx : 0;
}
return self;
}
- (void)dealloc
{
[super dealloc];
[_params autorelease];
[_keyPath autorelease];
[_color_options autorelease];
[_resolution_modes autorelease];
}
- (NSString *)keyPathForKey:(NSString *)key
{
if (_keyPath)
return [_keyPath stringByAppendingFormat:@".%@", key];
return key;
}
#pragma mark - View lifecycle
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (section == 0)
return [_color_options count];
return [_resolution_modes count] + 2; // +2 for custom width/height input fields
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
switch ([indexPath section])
{
case 0:
cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];
[[cell textLabel] setText:[_color_options keyAtIndex:[indexPath row]]];
break;
case 1:
if ([indexPath row] < [_resolution_modes count])
{
cell = [self tableViewCellFromIdentifier:TableCellIdentifierMultiChoice];
[[cell textLabel] setText:[_resolution_modes objectAtIndex:[indexPath row]]];
}
else
cell = [self tableViewCellFromIdentifier:TableCellIdentifierText];
break;
default:
break;
}
if ([indexPath section] == 1)
{
BOOL enabled = ([_params intForKeyPath:[self keyPathForKey:@"screen_resolution_type"]] ==
TSXScreenOptionCustom);
if ([indexPath row] == [_resolution_modes count])
{
int value = [_params intForKeyPath:[self keyPathForKey:@"width"]];
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell label] setText:NSLocalizedString(@"Width", @"Custom Screen Width")];
[[textCell textfield] setText:[NSString stringWithFormat:@"%d", value ? value : 800]];
[[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
[[textCell label] setEnabled:enabled];
[[textCell textfield] setEnabled:enabled];
[[textCell textfield] setTag:1];
}
else if ([indexPath row] == ([_resolution_modes count] + 1))
{
int value = [_params intForKeyPath:[self keyPathForKey:@"height"]];
EditTextTableViewCell *textCell = (EditTextTableViewCell *)cell;
[[textCell label] setText:NSLocalizedString(@"Height", @"Custom Screen Height")];
[[textCell textfield] setText:[NSString stringWithFormat:@"%d", value ? value : 600]];
[[textCell textfield] setKeyboardType:UIKeyboardTypeNumberPad];
[[textCell label] setEnabled:enabled];
[[textCell textfield] setEnabled:enabled];
[[textCell textfield] setTag:2];
}
}
// set default checkmark
if ([indexPath row] == ([indexPath section] == 0 ? _selection_color : _selection_resolution))
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
else
[cell setAccessoryType:UITableViewCellAccessoryNone];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// custom width/height cells are not selectable
if ([indexPath section] == 1 && [indexPath row] >= [_resolution_modes count])
return;
// has selection change?
int cur_selection = ([indexPath section] == 0 ? _selection_color : _selection_resolution);
if ([indexPath row] != cur_selection)
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:cur_selection
inSection:[indexPath section]];
// clear old checkmark
UITableViewCell *old_sel_cell = [tableView cellForRowAtIndexPath:oldIndexPath];
old_sel_cell.accessoryType = UITableViewCellAccessoryNone;
// set new checkmark
UITableViewCell *new_sel_cell = [tableView cellForRowAtIndexPath:indexPath];
new_sel_cell.accessoryType = UITableViewCellAccessoryCheckmark;
if ([indexPath section] == 0)
{
// get value from color dictionary
int sel_value =
[[_color_options valueForKey:[_color_options keyAtIndex:[indexPath row]]] intValue];
// update selection index and params value
[_params setInt:sel_value forKeyPath:[self keyPathForKey:@"colors"]];
_selection_color = [indexPath row];
}
else
{
// update selection index and params value
int width, height;
TSXScreenOptions mode;
ScanScreenResolution([_resolution_modes objectAtIndex:[indexPath row]], &width, &height,
&mode);
[_params setInt:mode forKeyPath:[self keyPathForKey:@"screen_resolution_type"]];
if (mode != TSXScreenOptionCustom)
{
[_params setInt:width forKeyPath:[self keyPathForKey:@"width"]];
[_params setInt:height forKeyPath:[self keyPathForKey:@"height"]];
}
_selection_resolution = [indexPath row];
// refresh width/height edit fields if custom selection changed
NSArray *indexPaths = [NSArray
arrayWithObjects:[NSIndexPath indexPathForRow:[_resolution_modes count]
inSection:1],
[NSIndexPath indexPathForRow:([_resolution_modes count] + 1)
inSection:1],
nil];
[[self tableView] reloadRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationNone];
}
}
}
#pragma mark -
#pragma mark Text Field delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
switch ([textField tag])
{
// update resolution settings (and check for invalid input)
case 1:
if ([[textField text] intValue] < 640)
[textField setText:@"640"];
[_params setInt:[[textField text] intValue] forKeyPath:[self keyPathForKey:@"width"]];
break;
case 2:
if ([[textField text] intValue] < 480)
[textField setText:@"480"];
[_params setInt:[[textField text] intValue] forKeyPath:[self keyPathForKey:@"height"]];
break;
default:
break;
}
return YES;
}
@end

View File

@@ -0,0 +1,33 @@
/*
Certificate verification controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <UIKit/UIKit.h>
@class RDPSession;
@interface VerifyCertificateController : UIViewController
{
@private
IBOutlet UILabel *_label_issuer;
IBOutlet UIButton *_btn_accept;
IBOutlet UIButton *_btn_decline;
IBOutlet UILabel *_label_message;
IBOutlet UILabel *_label_for_issuer;
RDPSession *_session;
NSMutableDictionary *_params;
}
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
session:(RDPSession *)session
params:(NSMutableDictionary *)params;
@end

View File

@@ -0,0 +1,86 @@
/*
Certificate verification controller
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "VerifyCertificateController.h"
#import "RDPSession.h"
@implementation VerifyCertificateController
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
session:(RDPSession *)session
params:(NSMutableDictionary *)params
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
_session = session;
_params = params;
[self setModalPresentationStyle:UIModalPresentationFormSheet];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *message = NSLocalizedString(
@"The identity of the remote computer cannot be verified. Do you want to connect anyway?",
@"Verify certificate view message");
// init strings
[_label_message setText:message];
[_label_for_issuer
setText:NSLocalizedString(@"Issuer:", @"Verify certificate view issuer label")];
[_btn_accept setTitle:NSLocalizedString(@"Yes", @"Yes Button") forState:UIControlStateNormal];
[_btn_decline setTitle:NSLocalizedString(@"No", @"No Button") forState:UIControlStateNormal];
[_label_issuer setText:[_params valueForKey:@"issuer"]];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
// set signal
[[_session uiRequestCompleted] signal];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#pragma mark - Action handlers
- (IBAction)acceptPressed:(id)sender
{
[_params setValue:[NSNumber numberWithBool:YES] forKey:@"result"];
// dismiss controller
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)declinePressed:(id)sender
{
[_params setValue:[NSNumber numberWithBool:NO] forKey:@"result"];
// dismiss controller
[self dismissModalViewControllerAnimated:YES];
}
@end

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>TSXDefaultComputerBookmarkSettings</key>
<dict>
<key>hostname</key>
<string></string>
<key>port</key>
<integer>3389</integer>
<key>screen_resolution_type</key>
<integer>1</integer>
<key>width</key>
<integer>0</integer>
<key>height</key>
<integer>0</integer>
<key>colors</key>
<integer>16</integer>
<key>perf_font_smoothing</key>
<false/>
<key>perf_menu_animation</key>
<false/>
<key>perf_show_desktop</key>
<false/>
<key>perf_window_dragging</key>
<false/>
<key>perf_windows_themes</key>
<false/>
<key>perf_remotefx</key>
<false/>
<key>perf_gfx</key>
<false/>
<key>perf_h264</key>
<false/>
<key>perf_desktop_composition</key>
<false/>
<key>enable_3g_settings</key>
<false/>
<key>settings_3g</key>
<dict>
<key>screen_resolution_type</key>
<integer>0</integer>
<key>width</key>
<integer>800</integer>
<key>height</key>
<integer>600</integer>
<key>colors</key>
<integer>16</integer>
<key>perf_remotefx</key>
<false/>
<key>perf_gfx</key>
<false/>
<key>perf_h264</key>
<false/>
<key>perf_desktop_composition</key>
<false/>
<key>perf_windows_themes</key>
<false/>
<key>perf_window_dragging</key>
<false/>
<key>perf_show_desktop</key>
<false/>
<key>perf_menu_animation</key>
<false/>
<key>perf_font_smoothing</key>
<false/>
</dict>
<key>security</key>
<integer>0</integer>
<key>remote_program</key>
<string></string>
<key>working_dir</key>
<string></string>
<key>console</key>
<false/>
<key>enable_tsg_settings</key>
<false/>
<key>tsg_hostname</key>
<string></string>
<key>tsg_port</key>
<integer>443</integer>
<key>tsg_username</key>
<string></string>
<key>tsg_password</key>
<string></string>
<key>tsg_domain</key>
<string></string>
</dict>
<key>ui.auto_scroll_touchpointer</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,34 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Android Clipboard Redirection
*
* Copyright 2013 Felix Long
* Copyright 2023 Iordan Iordanov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_CLIENT_IOS_CLIPRDR_H
#define FREERDP_CLIENT_IOS_CLIPRDR_H
#include <freerdp/client/cliprdr.h>
#include <freerdp/api.h>
#include "ios_freerdp.h"
FREERDP_LOCAL UINT ios_cliprdr_send_client_format_list(CliprdrClientContext* cliprdr);
FREERDP_LOCAL BOOL ios_cliprdr_init(mfContext* context, CliprdrClientContext* cliprdr);
FREERDP_LOCAL BOOL ios_cliprdr_uninit(mfContext* context, CliprdrClientContext* cliprdr);
#endif /* FREERDP_CLIENT_IOS_CLIPRDR_H */

View File

@@ -0,0 +1,499 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Android Clipboard Redirection
*
* Copyright 2013 Felix Long
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* Copyright 2023 Iordan Iordanov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <freerdp/config.h>
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/clipboard.h>
#include <freerdp/client/channels.h>
#include <freerdp/client/cliprdr.h>
#include "ios_cliprdr.h"
UINT ios_cliprdr_send_client_format_list(CliprdrClientContext *cliprdr)
{
UINT rc = ERROR_INTERNAL_ERROR;
UINT32 formatId;
UINT32 numFormats;
UINT32 *pFormatIds;
const char *formatName;
CLIPRDR_FORMAT *formats;
CLIPRDR_FORMAT_LIST formatList = WINPR_C_ARRAY_INIT;
if (!cliprdr)
return ERROR_INVALID_PARAMETER;
mfContext *afc = (mfContext *)cliprdr->custom;
if (!afc || !afc->cliprdr)
return ERROR_INVALID_PARAMETER;
pFormatIds = nullptr;
numFormats = ClipboardGetFormatIds(afc->clipboard, &pFormatIds);
formats = (CLIPRDR_FORMAT *)calloc(numFormats, sizeof(CLIPRDR_FORMAT));
if (!formats)
goto fail;
for (UINT32 index = 0; index < numFormats; index++)
{
formatId = pFormatIds[index];
formatName = ClipboardGetFormatName(afc->clipboard, formatId);
formats[index].formatId = formatId;
formats[index].formatName = nullptr;
if ((formatId > CF_MAX) && formatName)
{
formats[index].formatName = _strdup(formatName);
if (!formats[index].formatName)
goto fail;
}
}
formatList.common.msgFlags = 0;
formatList.numFormats = numFormats;
formatList.formats = formats;
formatList.common.msgType = CB_FORMAT_LIST;
if (!afc->cliprdr->ClientFormatList)
goto fail;
rc = afc->cliprdr->ClientFormatList(afc->cliprdr, &formatList);
fail:
free(pFormatIds);
free(formats);
return rc;
}
static UINT ios_cliprdr_send_client_format_data_request(CliprdrClientContext *cliprdr,
UINT32 formatId)
{
UINT rc = ERROR_INVALID_PARAMETER;
CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest = WINPR_C_ARRAY_INIT;
mfContext *afc;
if (!cliprdr)
goto fail;
afc = (mfContext *)cliprdr->custom;
if (!afc || !afc->clipboardRequestEvent || !cliprdr->ClientFormatDataRequest)
goto fail;
formatDataRequest.common.msgType = CB_FORMAT_DATA_REQUEST;
formatDataRequest.common.msgFlags = 0;
formatDataRequest.requestedFormatId = formatId;
afc->requestedFormatId = formatId;
(void)ResetEvent(afc->clipboardRequestEvent);
rc = cliprdr->ClientFormatDataRequest(cliprdr, &formatDataRequest);
fail:
return rc;
}
static UINT ios_cliprdr_send_client_capabilities(CliprdrClientContext *cliprdr)
{
CLIPRDR_CAPABILITIES capabilities;
CLIPRDR_GENERAL_CAPABILITY_SET generalCapabilitySet;
if (!cliprdr || !cliprdr->ClientCapabilities)
return ERROR_INVALID_PARAMETER;
capabilities.cCapabilitiesSets = 1;
capabilities.capabilitySets = (CLIPRDR_CAPABILITY_SET *)&(generalCapabilitySet);
generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
generalCapabilitySet.capabilitySetLength = 12;
generalCapabilitySet.version = CB_CAPS_VERSION_2;
generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
return cliprdr->ClientCapabilities(cliprdr, &capabilities);
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT ios_cliprdr_monitor_ready(CliprdrClientContext *cliprdr,
const CLIPRDR_MONITOR_READY *monitorReady)
{
UINT rc;
mfContext *afc;
if (!cliprdr || !monitorReady)
return ERROR_INVALID_PARAMETER;
afc = (mfContext *)cliprdr->custom;
if (!afc)
return ERROR_INVALID_PARAMETER;
if ((rc = ios_cliprdr_send_client_capabilities(cliprdr)) != CHANNEL_RC_OK)
return rc;
if ((rc = ios_cliprdr_send_client_format_list(cliprdr)) != CHANNEL_RC_OK)
return rc;
afc->clipboardSync = TRUE;
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT ios_cliprdr_server_capabilities(CliprdrClientContext *cliprdr,
const CLIPRDR_CAPABILITIES *capabilities)
{
CLIPRDR_CAPABILITY_SET *capabilitySet;
mfContext *afc;
if (!cliprdr || !capabilities)
return ERROR_INVALID_PARAMETER;
afc = (mfContext *)cliprdr->custom;
if (!afc)
return ERROR_INVALID_PARAMETER;
for (UINT32 index = 0; index < capabilities->cCapabilitiesSets; index++)
{
capabilitySet = &(capabilities->capabilitySets[index]);
if ((capabilitySet->capabilitySetType == CB_CAPSTYPE_GENERAL) &&
(capabilitySet->capabilitySetLength >= CB_CAPSTYPE_GENERAL_LEN))
{
CLIPRDR_GENERAL_CAPABILITY_SET *generalCapabilitySet =
(CLIPRDR_GENERAL_CAPABILITY_SET *)capabilitySet;
afc->clipboardCapabilities = generalCapabilitySet->generalFlags;
break;
}
}
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT ios_cliprdr_server_format_list(CliprdrClientContext *cliprdr,
const CLIPRDR_FORMAT_LIST *formatList)
{
UINT rc;
CLIPRDR_FORMAT *format;
mfContext *afc;
if (!cliprdr || !formatList)
return ERROR_INVALID_PARAMETER;
afc = (mfContext *)cliprdr->custom;
if (!afc)
return ERROR_INVALID_PARAMETER;
if (afc->serverFormats)
{
for (UINT32 index = 0; index < afc->numServerFormats; index++)
free(afc->serverFormats[index].formatName);
free(afc->serverFormats);
afc->serverFormats = nullptr;
afc->numServerFormats = 0;
}
if (formatList->numFormats < 1)
return CHANNEL_RC_OK;
afc->numServerFormats = formatList->numFormats;
afc->serverFormats = (CLIPRDR_FORMAT *)calloc(afc->numServerFormats, sizeof(CLIPRDR_FORMAT));
if (!afc->serverFormats)
return CHANNEL_RC_NO_MEMORY;
for (UINT32 index = 0; index < afc->numServerFormats; index++)
{
afc->serverFormats[index].formatId = formatList->formats[index].formatId;
afc->serverFormats[index].formatName = nullptr;
if (formatList->formats[index].formatName)
{
afc->serverFormats[index].formatName = _strdup(formatList->formats[index].formatName);
if (!afc->serverFormats[index].formatName)
return CHANNEL_RC_NO_MEMORY;
}
}
BOOL unicode = FALSE;
BOOL text = FALSE;
for (UINT32 index = 0; index < afc->numServerFormats; index++)
{
format = &(afc->serverFormats[index]);
if (format->formatId == CF_UNICODETEXT)
unicode = TRUE;
else if (format->formatId == CF_TEXT)
text = TRUE;
}
if (unicode)
return ios_cliprdr_send_client_format_data_request(cliprdr, CF_UNICODETEXT);
if (text)
return ios_cliprdr_send_client_format_data_request(cliprdr, CF_TEXT);
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT
ios_cliprdr_server_format_list_response(CliprdrClientContext *cliprdr,
const CLIPRDR_FORMAT_LIST_RESPONSE *formatListResponse)
{
if (!cliprdr || !formatListResponse)
return ERROR_INVALID_PARAMETER;
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT
ios_cliprdr_server_lock_clipboard_data(CliprdrClientContext *cliprdr,
const CLIPRDR_LOCK_CLIPBOARD_DATA *lockClipboardData)
{
if (!cliprdr || !lockClipboardData)
return ERROR_INVALID_PARAMETER;
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT
ios_cliprdr_server_unlock_clipboard_data(CliprdrClientContext *cliprdr,
const CLIPRDR_UNLOCK_CLIPBOARD_DATA *unlockClipboardData)
{
if (!cliprdr || !unlockClipboardData)
return ERROR_INVALID_PARAMETER;
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT
ios_cliprdr_server_format_data_request(CliprdrClientContext *cliprdr,
const CLIPRDR_FORMAT_DATA_REQUEST *formatDataRequest)
{
UINT rc;
BYTE *data;
UINT32 size;
UINT32 formatId;
CLIPRDR_FORMAT_DATA_RESPONSE response = WINPR_C_ARRAY_INIT;
mfContext *afc;
if (!cliprdr || !formatDataRequest || !cliprdr->ClientFormatDataResponse)
return ERROR_INVALID_PARAMETER;
afc = (mfContext *)cliprdr->custom;
if (!afc)
return ERROR_INVALID_PARAMETER;
formatId = formatDataRequest->requestedFormatId;
data = (BYTE *)ClipboardGetData(afc->clipboard, formatId, &size);
response.common.msgFlags = CB_RESPONSE_OK;
response.common.dataLen = size;
response.requestedFormatData = data;
if (!data)
{
response.common.msgFlags = CB_RESPONSE_FAIL;
response.common.dataLen = 0;
response.requestedFormatData = nullptr;
}
rc = cliprdr->ClientFormatDataResponse(cliprdr, &response);
free(data);
return rc;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT
ios_cliprdr_server_format_data_response(CliprdrClientContext *cliprdr,
const CLIPRDR_FORMAT_DATA_RESPONSE *formatDataResponse)
{
BYTE *data;
UINT32 size;
UINT32 formatId;
CLIPRDR_FORMAT *format = nullptr;
mfContext *afc;
freerdp *instance;
if (!cliprdr || !formatDataResponse)
return ERROR_INVALID_PARAMETER;
afc = (mfContext *)cliprdr->custom;
if (!afc)
return ERROR_INVALID_PARAMETER;
instance = ((rdpContext *)afc)->instance;
if (!instance)
return ERROR_INVALID_PARAMETER;
for (UINT32 index = 0; index < afc->numServerFormats; index++)
{
if (afc->requestedFormatId == afc->serverFormats[index].formatId)
format = &(afc->serverFormats[index]);
}
if (!format)
{
(void)SetEvent(afc->clipboardRequestEvent);
return ERROR_INTERNAL_ERROR;
}
if (format->formatName)
formatId = ClipboardRegisterFormat(afc->clipboard, format->formatName);
else
formatId = format->formatId;
size = formatDataResponse->common.dataLen;
ClipboardLock(afc->clipboard);
if (!ClipboardSetData(afc->clipboard, formatId, formatDataResponse->requestedFormatData, size))
return ERROR_INTERNAL_ERROR;
(void)SetEvent(afc->clipboardRequestEvent);
if ((formatId == CF_TEXT) || (formatId == CF_UNICODETEXT))
{
formatId = ClipboardRegisterFormat(afc->clipboard, "UTF8_STRING");
data = (BYTE *)ClipboardGetData(afc->clipboard, formatId, &size);
size = (UINT32)strnlen(data, size);
if (afc->ServerCutText != nullptr)
{
afc->ServerCutText((rdpContext *)afc, (uint8_t *)data, size);
}
}
ClipboardUnlock(afc->clipboard);
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT
ios_cliprdr_server_file_contents_request(CliprdrClientContext *cliprdr,
const CLIPRDR_FILE_CONTENTS_REQUEST *fileContentsRequest)
{
if (!cliprdr || !fileContentsRequest)
return ERROR_INVALID_PARAMETER;
return CHANNEL_RC_OK;
}
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT ios_cliprdr_server_file_contents_response(
CliprdrClientContext *cliprdr, const CLIPRDR_FILE_CONTENTS_RESPONSE *fileContentsResponse)
{
if (!cliprdr || !fileContentsResponse)
return ERROR_INVALID_PARAMETER;
return CHANNEL_RC_OK;
}
BOOL ios_cliprdr_init(mfContext *afc, CliprdrClientContext *cliprdr)
{
wClipboard *clipboard;
HANDLE hevent;
if (!afc || !cliprdr)
return FALSE;
if (!(hevent = CreateEvent(nullptr, TRUE, FALSE, nullptr)))
return FALSE;
if (!(clipboard = ClipboardCreate()))
{
(void)CloseHandle(hevent);
return FALSE;
}
afc->cliprdr = cliprdr;
afc->clipboard = clipboard;
afc->clipboardRequestEvent = hevent;
cliprdr->custom = (void *)afc;
cliprdr->MonitorReady = ios_cliprdr_monitor_ready;
cliprdr->ServerCapabilities = ios_cliprdr_server_capabilities;
cliprdr->ServerFormatList = ios_cliprdr_server_format_list;
cliprdr->ServerFormatListResponse = ios_cliprdr_server_format_list_response;
cliprdr->ServerLockClipboardData = ios_cliprdr_server_lock_clipboard_data;
cliprdr->ServerUnlockClipboardData = ios_cliprdr_server_unlock_clipboard_data;
cliprdr->ServerFormatDataRequest = ios_cliprdr_server_format_data_request;
cliprdr->ServerFormatDataResponse = ios_cliprdr_server_format_data_response;
cliprdr->ServerFileContentsRequest = ios_cliprdr_server_file_contents_request;
cliprdr->ServerFileContentsResponse = ios_cliprdr_server_file_contents_response;
return TRUE;
}
BOOL ios_cliprdr_uninit(mfContext *afc, CliprdrClientContext *cliprdr)
{
if (!afc || !cliprdr)
return FALSE;
cliprdr->custom = nullptr;
afc->cliprdr = nullptr;
ClipboardDestroy(afc->clipboard);
(void)CloseHandle(afc->clipboardRequestEvent);
return TRUE;
}

View File

@@ -0,0 +1,87 @@
/*
RDP run-loop
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
Copyright 2023 Iordan Iordanov
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <CoreGraphics/CoreGraphics.h>
#import <freerdp/freerdp.h>
#import <freerdp/channels/channels.h>
#import "TSXTypes.h"
#import <winpr/clipboard.h>
#import <freerdp/client/cliprdr.h>
@class RDPSession, RDPSessionView;
typedef BOOL (*pServerCutText)(rdpContext *context, UINT8 *data, UINT32 size);
// FreeRDP extended structs
typedef struct mf_info mfInfo;
typedef struct mf_context
{
rdpContext _p;
mfInfo *mfi;
rdpSettings *settings;
BOOL clipboardSync;
wClipboard *clipboard;
UINT32 numServerFormats;
UINT32 requestedFormatId;
HANDLE clipboardRequestEvent;
CLIPRDR_FORMAT *serverFormats;
CliprdrClientContext *cliprdr;
UINT32 clipboardCapabilities;
WINPR_ATTR_NODISCARD pServerCutText ServerCutText;
} mfContext;
struct mf_info
{
// RDP
freerdp *instance;
mfContext *context;
rdpContext *_context;
// UI
RDPSession *session;
// Graphics
CGContextRef bitmap_context;
// Events
int event_pipe_producer;
int event_pipe_consumer;
HANDLE handle;
// Tracking connection state
volatile TSXConnectionState connection_state;
volatile BOOL
unwanted; // set when controlling Session no longer wants the connection to continue
};
#define MFI_FROM_INSTANCE(inst) (((mfContext *)((inst)->context))->mfi)
enum MF_EXIT_CODE
{
MF_EXIT_SUCCESS = 0,
MF_EXIT_CONN_FAILED = 128,
MF_EXIT_CONN_CANCELED = 129,
MF_EXIT_LOGON_TIMEOUT = 130,
MF_EXIT_UNKNOWN = 255
};
void ios_init_freerdp(void);
void ios_uninit_freerdp(void);
freerdp *ios_freerdp_new(void);
int ios_run_freerdp(freerdp *instance);
void ios_freerdp_free(freerdp *instance);
void ios_send_clipboard_data(void *context, const void *data, UINT32 size);

View File

@@ -0,0 +1,443 @@
/*
RDP run-loop
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include <winpr/assert.h>
#import <winpr/clipboard.h>
#import <freerdp/gdi/gdi.h>
#import <freerdp/channels/channels.h>
#import <freerdp/client/channels.h>
#import <freerdp/client/cmdline.h>
#import <freerdp/freerdp.h>
#import <freerdp/gdi/gfx.h>
#import <freerdp/client/cliprdr.h>
#import "ios_freerdp.h"
#import "ios_freerdp_ui.h"
#import "ios_freerdp_events.h"
#import "ios_cliprdr.h"
#import "RDPSession.h"
#import "Utils.h"
#include <errno.h>
#define TAG FREERDP_TAG("iOS")
#pragma mark Connection helpers
static void ios_OnChannelConnectedEventHandler(void *context, const ChannelConnectedEventArgs *e)
{
WLog_INFO(TAG, "ios_OnChannelConnectedEventHandler, channel %s", e->name);
rdpSettings *settings;
mfContext *afc;
if (!context || !e)
{
WLog_FATAL(TAG, "(context=%p, EventArgs=%p", context, (void *)e);
return;
}
afc = (mfContext *)context;
settings = afc->_p.settings;
if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (freerdp_settings_get_bool(settings, FreeRDP_SoftwareGdi))
{
gdi_graphics_pipeline_init(afc->_p.gdi, (RdpgfxClientContext *)e->pInterface);
}
else
{
WLog_WARN(TAG, "GFX without software GDI requested. "
" This is not supported, add /gdi:sw");
}
}
else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
{
ios_cliprdr_init(afc, (CliprdrClientContext *)e->pInterface);
}
}
static void ios_OnChannelDisconnectedEventHandler(void *context,
const ChannelDisconnectedEventArgs *e)
{
WLog_INFO(TAG, "ios_OnChannelConnectedEventHandler, channel %s", e->name);
rdpSettings *settings;
mfContext *afc;
if (!context || !e)
{
WLog_FATAL(TAG, "(context=%p, EventArgs=%p", context, (void *)e);
return;
}
afc = (mfContext *)context;
settings = afc->_p.settings;
if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (freerdp_settings_get_bool(settings, FreeRDP_SoftwareGdi))
{
gdi_graphics_pipeline_uninit(afc->_p.gdi, (RdpgfxClientContext *)e->pInterface);
}
else
{
WLog_WARN(TAG, "GFX without software GDI requested. "
" This is not supported, add /gdi:sw");
}
}
else if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) == 0)
{
ios_cliprdr_uninit(afc, (CliprdrClientContext *)e->pInterface);
}
}
static BOOL ios_pre_connect(freerdp *instance)
{
int rc;
rdpSettings *settings;
if (!instance || !instance->context)
return FALSE;
settings = instance->context->settings;
WINPR_ASSERT(settings);
const char *Password = freerdp_settings_get_string(settings, FreeRDP_Password);
if (!freerdp_settings_set_bool(settings, FreeRDP_AutoLogonEnabled,
Password && (Password && (strlen(Password) > 0))))
return FALSE;
// Verify screen width/height are sane
if ((freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth) < 64) ||
(freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight) < 64) ||
(freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth) > 4096) ||
(freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight) > 4096))
{
NSLog(@"%s: invalid dimensions %d %d", __func__,
freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth),
freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight));
return FALSE;
}
rc = PubSub_SubscribeChannelConnected(instance->context->pubSub,
ios_OnChannelConnectedEventHandler);
if (rc != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Could not subscribe to connect event handler [%l08X]", rc);
return FALSE;
}
rc = PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
ios_OnChannelDisconnectedEventHandler);
if (rc != CHANNEL_RC_OK)
{
WLog_ERR(TAG, "Could not subscribe to disconnect event handler [%l08X]", rc);
return FALSE;
}
if (!freerdp_client_load_addins(instance->context->channels, settings))
{
WLog_ERR(TAG, "Failed to load addins [%l08X]", GetLastError());
return FALSE;
}
return TRUE;
}
static BOOL ios_Pointer_New(rdpContext *context, rdpPointer *pointer)
{
if (!context || !pointer || !context->gdi)
return FALSE;
return TRUE;
}
static void ios_Pointer_Free(rdpContext *context, rdpPointer *pointer)
{
if (!context || !pointer)
return;
}
static BOOL ios_Pointer_Set(rdpContext *context, rdpPointer *pointer)
{
if (!context)
return FALSE;
return TRUE;
}
static BOOL ios_Pointer_SetPosition(rdpContext *context, UINT32 x, UINT32 y)
{
if (!context)
return FALSE;
return TRUE;
}
static BOOL ios_Pointer_SetNull(rdpContext *context)
{
if (!context)
return FALSE;
return TRUE;
}
static BOOL ios_Pointer_SetDefault(rdpContext *context)
{
if (!context)
return FALSE;
return TRUE;
}
static BOOL ios_register_pointer(rdpGraphics *graphics)
{
rdpPointer pointer = WINPR_C_ARRAY_INIT;
if (!graphics)
return FALSE;
pointer.size = sizeof(pointer);
pointer.New = ios_Pointer_New;
pointer.Free = ios_Pointer_Free;
pointer.Set = ios_Pointer_Set;
pointer.SetNull = ios_Pointer_SetNull;
pointer.SetDefault = ios_Pointer_SetDefault;
pointer.SetPosition = ios_Pointer_SetPosition;
graphics_register_pointer(graphics, &pointer);
return TRUE;
}
static BOOL ios_post_connect(freerdp *instance)
{
mfInfo *mfi;
if (!instance)
return FALSE;
mfi = MFI_FROM_INSTANCE(instance);
if (!mfi)
return FALSE;
if (!gdi_init(instance, PIXEL_FORMAT_BGRA32))
return FALSE;
if (!ios_register_pointer(instance->context->graphics))
return FALSE;
ios_allocate_display_buffer(mfi);
instance->context->update->BeginPaint = ios_ui_begin_paint;
instance->context->update->EndPaint = ios_ui_end_paint;
instance->context->update->DesktopResize = ios_ui_resize_window;
[mfi->session performSelectorOnMainThread:@selector(sessionDidConnect)
withObject:nil
waitUntilDone:YES];
return TRUE;
}
static void ios_post_disconnect(freerdp *instance)
{
gdi_free(instance);
}
#pragma mark -
#pragma mark Running the connection
int ios_run_freerdp(freerdp *instance)
{
mfContext *context = (mfContext *)instance->context;
mfInfo *mfi = context->mfi;
rdpChannels *channels = instance->context->channels;
mfi->connection_state = TSXConnectionConnecting;
if (!freerdp_connect(instance))
{
NSLog(@"%s: inst->rdp_connect failed", __func__);
return mfi->unwanted ? MF_EXIT_CONN_CANCELED : MF_EXIT_CONN_FAILED;
}
if (mfi->unwanted)
return MF_EXIT_CONN_CANCELED;
mfi->connection_state = TSXConnectionConnected;
// Connection main loop
NSAutoreleasePool *pool;
while (!freerdp_shall_disconnect_context(instance->context))
{
DWORD status;
DWORD nCount = 0;
HANDLE handles[MAXIMUM_WAIT_OBJECTS] = WINPR_C_ARRAY_INIT;
pool = [[NSAutoreleasePool alloc] init];
nCount = freerdp_get_event_handles(instance->context, handles, ARRAYSIZE(handles));
if (nCount == 0)
{
NSLog(@"%s: freerdp_get_event_handles failed", __func__);
break;
}
handles[nCount++] = ios_events_get_handle(mfi);
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
if (WAIT_FAILED == status)
{
NSLog(@"%s: WaitForMultipleObjects failed!", __func__);
break;
}
// Check the libfreerdp fds
if (!freerdp_check_event_handles(instance->context))
{
NSLog(@"%s: freerdp_check_event_handles failed.", __func__);
break;
}
// Check input event fds
if (ios_events_check_handle(mfi) != TRUE)
{
// This event will fail when the app asks for a disconnect.
// NSLog(@"%s: ios_events_check_fds failed: terminating connection.", __func__);
break;
}
[pool release];
pool = nil;
}
CGContextRelease(mfi->bitmap_context);
mfi->bitmap_context = nullptr;
mfi->connection_state = TSXConnectionDisconnected;
// Cleanup
freerdp_disconnect(instance);
gdi_free(instance);
cache_free(instance->context->cache);
[pool release];
pool = nil;
return MF_EXIT_SUCCESS;
}
#pragma mark -
#pragma mark Context callbacks
static BOOL ios_client_new(freerdp *instance, rdpContext *context)
{
mfContext *ctx = (mfContext *)context;
if (!instance || !context)
return FALSE;
if ((ctx->mfi = calloc(1, sizeof(mfInfo))) == nullptr)
return FALSE;
ctx->mfi->context = (mfContext *)context;
ctx->mfi->_context = context;
ctx->mfi->instance = instance;
if (!ios_events_create_pipe(ctx->mfi))
return FALSE;
instance->PreConnect = ios_pre_connect;
instance->PostConnect = ios_post_connect;
instance->PostDisconnect = ios_post_disconnect;
instance->Authenticate = ios_ui_authenticate;
instance->GatewayAuthenticate = ios_ui_gw_authenticate;
instance->VerifyCertificateEx = ios_ui_verify_certificate_ex;
instance->VerifyChangedCertificateEx = ios_ui_verify_changed_certificate_ex;
instance->LogonErrorInfo = nullptr;
return TRUE;
}
static void ios_client_free(freerdp *instance, rdpContext *context)
{
mfInfo *mfi;
if (!context)
return;
mfi = ((mfContext *)context)->mfi;
ios_events_free_pipe(mfi);
free(mfi);
}
static int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS *pEntryPoints)
{
WINPR_ASSERT(pEntryPoints);
ZeroMemory(pEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
pEntryPoints->Version = RDP_CLIENT_INTERFACE_VERSION;
pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
pEntryPoints->GlobalInit = nullptr;
pEntryPoints->GlobalUninit = nullptr;
pEntryPoints->ContextSize = sizeof(mfContext);
pEntryPoints->ClientNew = ios_client_new;
pEntryPoints->ClientFree = ios_client_free;
pEntryPoints->ClientStart = nullptr;
pEntryPoints->ClientStop = nullptr;
return 0;
}
#pragma mark -
#pragma mark Initialization and cleanup
freerdp *ios_freerdp_new()
{
rdpContext *context;
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
RdpClientEntry(&clientEntryPoints);
context = freerdp_client_context_new(&clientEntryPoints);
if (!context)
return nullptr;
return context->instance;
}
void ios_freerdp_free(freerdp *instance)
{
if (!instance || !instance->context)
return;
freerdp_client_context_free(instance->context);
}
void ios_init_freerdp()
{
signal(SIGPIPE, SIG_IGN);
}
void ios_uninit_freerdp()
{
}
/* compatibility functions */
size_t fwrite$UNIX2003(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return fwrite(ptr, size, nmemb, stream);
}
void ios_send_clipboard_data(void *context, const void *data, UINT32 size)
{
mfContext *afc = (mfContext *)context;
ClipboardLock(afc->clipboard);
UINT32 formatId = ClipboardRegisterFormat(afc->clipboard, "UTF8_STRING");
if (size)
ClipboardSetData(afc->clipboard, formatId, data, size);
else
ClipboardEmpty(afc->clipboard);
ClipboardUnlock(afc->clipboard);
ios_cliprdr_send_client_format_list(afc->cliprdr);
}

View File

@@ -0,0 +1,27 @@
/*
RDP event queuing
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#ifndef IOS_RDP_EVENT_H
#define IOS_RDP_EVENT_H
#import <Foundation/Foundation.h>
#import "ios_freerdp.h"
// For UI: use to send events
BOOL ios_events_send(mfInfo *mfi, NSDictionary *event_description);
// For connection runloop: use to poll for queued input events
HANDLE ios_events_get_handle(mfInfo *mfi);
BOOL ios_events_check_handle(mfInfo *mfi);
BOOL ios_events_create_pipe(mfInfo *mfi);
void ios_events_free_pipe(mfInfo *mfi);
#endif /* IOS_RDP_EVENT_H */

View File

@@ -0,0 +1,174 @@
/*
RDP event queuing
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include <winpr/assert.h>
#include "ios_freerdp_events.h"
#pragma mark -
#pragma mark Sending compacted input events (from main thread)
// While this function may be called from any thread that has an autorelease pool allocated, it is
// not threadsafe: caller is responsible for synchronization
BOOL ios_events_send(mfInfo *mfi, NSDictionary *event_description)
{
NSData *encoded_description = [NSKeyedArchiver archivedDataWithRootObject:event_description];
WINPR_ASSERT(mfi);
if ([encoded_description length] > 32000 || (mfi->event_pipe_producer == -1))
return FALSE;
uint32_t archived_data_len = (uint32_t)[encoded_description length];
// NSLog(@"writing %d bytes to input event pipe", archived_data_len);
if (write(mfi->event_pipe_producer, &archived_data_len, 4) == -1)
{
NSLog(@"%s: Failed to write length descriptor to pipe.", __func__);
return FALSE;
}
if (write(mfi->event_pipe_producer, [encoded_description bytes], archived_data_len) == -1)
{
NSLog(@"%s: Failed to write %d bytes into the event queue (event type: %@).", __func__,
(int)[encoded_description length], [event_description objectForKey:@"type"]);
return FALSE;
}
return TRUE;
}
#pragma mark -
#pragma mark Processing compacted input events (from connection thread runloop)
static BOOL ios_events_handle_event(mfInfo *mfi, NSDictionary *event_description)
{
NSString *event_type = [event_description objectForKey:@"type"];
BOOL should_continue = TRUE;
rdpInput *input;
WINPR_ASSERT(mfi);
freerdp *instance = mfi->instance;
WINPR_ASSERT(instance);
WINPR_ASSERT(instance->context);
input = instance->context->input;
WINPR_ASSERT(input);
if ([event_type isEqualToString:@"mouse"])
{
input->MouseEvent(input, [[event_description objectForKey:@"flags"] unsignedShortValue],
[[event_description objectForKey:@"coord_x"] unsignedShortValue],
[[event_description objectForKey:@"coord_y"] unsignedShortValue]);
}
else if ([event_type isEqualToString:@"keyboard"])
{
if ([[event_description objectForKey:@"subtype"] isEqualToString:@"scancode"])
freerdp_input_send_keyboard_event(
input, [[event_description objectForKey:@"flags"] unsignedShortValue],
[[event_description objectForKey:@"scancode"] unsignedShortValue]);
else if ([[event_description objectForKey:@"subtype"] isEqualToString:@"unicode"])
freerdp_input_send_unicode_keyboard_event(
input, [[event_description objectForKey:@"flags"] unsignedShortValue],
[[event_description objectForKey:@"unicode_char"] unsignedShortValue]);
else
NSLog(@"%s: doesn't know how to send keyboard input with subtype %@", __func__,
[event_description objectForKey:@"subtype"]);
}
else if ([event_type isEqualToString:@"disconnect"])
should_continue = FALSE;
else
NSLog(@"%s: unrecognized event type: %@", __func__, event_type);
return should_continue;
}
BOOL ios_events_check_handle(mfInfo *mfi)
{
WINPR_ASSERT(mfi);
if (WaitForSingleObject(mfi->handle, 0) != WAIT_OBJECT_0)
return TRUE;
if (mfi->event_pipe_consumer == -1)
return TRUE;
uint32_t archived_data_length = 0;
ssize_t bytes_read;
// First, read the length of the blob
bytes_read = read(mfi->event_pipe_consumer, &archived_data_length, 4);
if (bytes_read == -1 || archived_data_length < 1 || archived_data_length > 32000)
{
NSLog(@"%s: just read length descriptor. bytes_read=%ld, archived_data_length=%u", __func__,
bytes_read, archived_data_length);
return FALSE;
}
// NSLog(@"reading %d bytes from input event pipe", archived_data_length);
NSMutableData *archived_object_data =
[[NSMutableData alloc] initWithLength:archived_data_length];
bytes_read =
read(mfi->event_pipe_consumer, [archived_object_data mutableBytes], archived_data_length);
if (bytes_read != archived_data_length)
{
NSLog(@"%s: attempted to read data; read %ld bytes but wanted %d bytes.", __func__,
bytes_read, archived_data_length);
[archived_object_data release];
return FALSE;
}
id unarchived_object_data = [NSKeyedUnarchiver unarchiveObjectWithData:archived_object_data];
[archived_object_data release];
return ios_events_handle_event(mfi, unarchived_object_data);
}
HANDLE ios_events_get_handle(mfInfo *mfi)
{
WINPR_ASSERT(mfi);
return mfi->handle;
}
// Sets up the event pipe
BOOL ios_events_create_pipe(mfInfo *mfi)
{
int pipe_fds[2];
WINPR_ASSERT(mfi);
if (pipe(pipe_fds) == -1)
{
NSLog(@"%s: pipe failed.", __func__);
return FALSE;
}
mfi->event_pipe_consumer = pipe_fds[0];
mfi->event_pipe_producer = pipe_fds[1];
mfi->handle = CreateFileDescriptorEvent(nullptr, FALSE, FALSE, mfi->event_pipe_consumer,
WINPR_FD_READ | WINPR_FD_WRITE);
return TRUE;
}
void ios_events_free_pipe(mfInfo *mfi)
{
WINPR_ASSERT(mfi);
int consumer_fd = mfi->event_pipe_consumer, producer_fd = mfi->event_pipe_producer;
mfi->event_pipe_consumer = mfi->event_pipe_producer = -1;
close(producer_fd);
close(consumer_fd);
(void)CloseHandle(mfi->handle);
}

View File

@@ -0,0 +1,29 @@
/*
RDP ui callbacks
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "ios_freerdp.h"
BOOL ios_ui_begin_paint(rdpContext* context);
BOOL ios_ui_end_paint(rdpContext* context);
BOOL ios_ui_resize_window(rdpContext* context);
BOOL ios_ui_authenticate(freerdp* instance, char** username, char** password, char** domain);
BOOL ios_ui_gw_authenticate(freerdp* instance, char** username, char** password, char** domain);
DWORD ios_ui_verify_certificate_ex(freerdp* instance, const char* host, UINT16 port,
const char* common_name, const char* subject, const char* issuer,
const char* fingerprint, DWORD flags);
DWORD ios_ui_verify_changed_certificate_ex(freerdp* instance, const char* host, UINT16 port,
const char* common_name, const char* subject,
const char* issuer, const char* fingerprint,
const char* old_subject, const char* old_issuer,
const char* old_fingerprint, DWORD flags);
void ios_allocate_display_buffer(mfInfo* mfi);

View File

@@ -0,0 +1,241 @@
/*
RDP ui callbacks
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import <freerdp/gdi/gdi.h>
#import "ios_freerdp_ui.h"
#import "RDPSession.h"
#pragma mark -
#pragma mark Certificate authentication
static void ios_resize_display_buffer(mfInfo *mfi);
static BOOL ios_ui_authenticate_raw(freerdp *instance, char **username, char **password,
char **domain, const char *title)
{
mfInfo *mfi = MFI_FROM_INSTANCE(instance);
NSMutableDictionary *params = [NSMutableDictionary
dictionaryWithObjectsAndKeys:(*username) ? [NSString stringWithUTF8String:*username] : @"",
@"username",
(*password) ? [NSString stringWithUTF8String:*password] : @"",
@"password",
(*domain) ? [NSString stringWithUTF8String:*domain] : @"",
@"domain",
[NSString stringWithUTF8String:freerdp_settings_get_string(
instance->context->settings,
FreeRDP_ServerHostname)],
@"hostname", // used for the auth prompt message; not changed
nil];
// request auth UI
[mfi->session performSelectorOnMainThread:@selector(sessionRequestsAuthenticationWithParams:)
withObject:params
waitUntilDone:YES];
// wait for UI request to be completed
[[mfi->session uiRequestCompleted] lock];
[[mfi->session uiRequestCompleted] wait];
[[mfi->session uiRequestCompleted] unlock];
if (![[params valueForKey:@"result"] boolValue])
{
mfi->unwanted = YES;
return FALSE;
}
// Free old values
free(*username);
free(*password);
free(*domain);
// set values back
*username = _strdup([[params objectForKey:@"username"] UTF8String]);
*password = _strdup([[params objectForKey:@"password"] UTF8String]);
*domain = _strdup([[params objectForKey:@"domain"] UTF8String]);
if (!(*username) || !(*password) || !(*domain))
{
free(*username);
free(*password);
free(*domain);
return FALSE;
}
return TRUE;
}
BOOL ios_ui_authenticate(freerdp *instance, char **username, char **password, char **domain)
{
return ios_ui_authenticate_raw(instance, username, password, domain, "");
}
BOOL ios_ui_gw_authenticate(freerdp *instance, char **username, char **password, char **domain)
{
return ios_ui_authenticate_raw(instance, username, password, domain, "gateway");
}
DWORD ios_ui_verify_certificate_ex(freerdp *instance, const char *host, UINT16 port,
const char *common_name, const char *subject, const char *issuer,
const char *fingerprint, DWORD flags)
{
// check whether we accept all certificates
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES)
return 2;
mfInfo *mfi = MFI_FROM_INSTANCE(instance);
NSMutableDictionary *params = [NSMutableDictionary
dictionaryWithObjectsAndKeys:(subject) ? [NSString stringWithUTF8String:subject] : @"",
@"subject",
(issuer) ? [NSString stringWithUTF8String:issuer] : @"",
@"issuer",
(fingerprint) ? [NSString stringWithUTF8String:subject] : @"",
@"fingerprint", nil];
// request certificate verification UI
[mfi->session performSelectorOnMainThread:@selector(sessionVerifyCertificateWithParams:)
withObject:params
waitUntilDone:YES];
// wait for UI request to be completed
[[mfi->session uiRequestCompleted] lock];
[[mfi->session uiRequestCompleted] wait];
[[mfi->session uiRequestCompleted] unlock];
if (![[params valueForKey:@"result"] boolValue])
{
mfi->unwanted = YES;
return 0;
}
return 1;
}
DWORD ios_ui_verify_changed_certificate_ex(freerdp *instance, const char *host, UINT16 port,
const char *common_name, const char *subject,
const char *issuer, const char *fingerprint,
const char *old_subject, const char *old_issuer,
const char *old_fingerprint, DWORD flags)
{
return ios_ui_verify_certificate_ex(instance, host, port, common_name, subject, issuer,
fingerprint, flags);
}
#pragma mark -
#pragma mark Graphics updates
BOOL ios_ui_begin_paint(rdpContext *context)
{
WINPR_ASSERT(context);
rdpGdi *gdi = context->gdi;
WINPR_ASSERT(gdi);
WINPR_ASSERT(gdi->primary);
HGDI_DC hdc = gdi->primary->hdc;
WINPR_ASSERT(hdc);
if (!hdc->hwnd)
return TRUE;
HGDI_WND hwnd = hdc->hwnd;
if (!hwnd->invalid)
return TRUE;
hwnd->invalid->null = TRUE;
return TRUE;
}
BOOL ios_ui_end_paint(rdpContext *context)
{
WINPR_ASSERT(context);
mfInfo *mfi = MFI_FROM_INSTANCE(context->instance);
WINPR_ASSERT(mfi);
rdpGdi *gdi = context->gdi;
WINPR_ASSERT(gdi);
WINPR_ASSERT(gdi->primary);
HGDI_DC hdc = gdi->primary->hdc;
WINPR_ASSERT(hdc);
if (!hdc->hwnd)
return TRUE;
HGDI_WND hwnd = hdc->hwnd;
WINPR_ASSERT(hwnd->invalid || (hwnd->ninvalid == 0));
if (hwnd->invalid->null)
return TRUE;
CGRect dirty_rect =
CGRectMake(hwnd->invalid->x, hwnd->invalid->y, hwnd->invalid->w, hwnd->invalid->h);
if (!hwnd->invalid->null)
[mfi->session performSelectorOnMainThread:@selector(setNeedsDisplayInRectAsValue:)
withObject:[NSValue valueWithCGRect:dirty_rect]
waitUntilDone:NO];
return TRUE;
}
BOOL ios_ui_resize_window(rdpContext *context)
{
rdpSettings *settings;
rdpGdi *gdi;
if (!context || !context->settings)
return FALSE;
settings = context->settings;
gdi = context->gdi;
if (!gdi_resize(gdi, freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth),
freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight)))
return FALSE;
ios_resize_display_buffer(MFI_FROM_INSTANCE(context->instance));
return TRUE;
}
#pragma mark -
#pragma mark Exported
static void ios_create_bitmap_context(mfInfo *mfi)
{
[mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextWillChange)
withObject:nil
waitUntilDone:YES];
rdpGdi *gdi = mfi->instance->context->gdi;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (FreeRDPGetBytesPerPixel(gdi->dstFormat) == 2)
mfi->bitmap_context = CGBitmapContextCreate(
gdi->primary_buffer, gdi->width, gdi->height, 5, gdi->stride, colorSpace,
kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
else
mfi->bitmap_context = CGBitmapContextCreate(
gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->stride, colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
CGColorSpaceRelease(colorSpace);
[mfi->session performSelectorOnMainThread:@selector(sessionBitmapContextDidChange)
withObject:nil
waitUntilDone:YES];
}
void ios_allocate_display_buffer(mfInfo *mfi)
{
ios_create_bitmap_context(mfi);
}
void ios_resize_display_buffer(mfInfo *mfi)
{
// Release the old context in a thread-safe manner
CGContextRef old_context = mfi->bitmap_context;
mfi->bitmap_context = nullptr;
CGContextRelease(old_context);
// Create the new context
ios_create_bitmap_context(mfi);
}

View File

@@ -0,0 +1,87 @@
/*
File: Reachability.h
Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
Version: 2.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under
Apple's copyrights in this original Apple software (the "Apple Software"), to
use, reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions
of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may be used
to endorse or promote products derived from the Apple Software without specific
prior written permission from Apple. Except as expressly stated in this notice,
no other rights or licenses, express or implied, are granted by Apple herein,
including but not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may be
incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2010 Apple Inc. All Rights Reserved.
*/
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>
typedef enum
{
NotReachable = 0,
ReachableViaWiFi = 1,
ReachableViaWWAN = 2
} NetworkStatus;
#define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification"
@interface Reachability : NSObject
{
BOOL localWiFiRef;
SCNetworkReachabilityRef reachabilityRef;
}
// reachabilityWithHostName- Use to check the reachability of a particular host name.
+ (Reachability *)reachabilityWithHostName:(NSString *)hostName;
// reachabilityWithAddress- Use to check the reachability of a particular IP address.
+ (Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;
// reachabilityForInternetConnection- checks whether the default route is available.
// Should be used by applications that do not connect to a particular host
+ (Reachability *)reachabilityForInternetConnection;
// reachabilityForLocalWiFi- checks whether a local wifi connection is available.
+ (Reachability *)reachabilityForLocalWiFi;
// Start listening for reachability notifications on the current run loop
- (BOOL)startNotifier;
- (void)stopNotifier;
- (NetworkStatus)currentReachabilityStatus;
// WWAN may be available, but not active until a connection has been established.
// WiFi may require a connection for VPN on Demand.
- (BOOL)connectionRequired;
@end

View File

@@ -0,0 +1,278 @@
/*
File: Reachability.m
Abstract: Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
Version: 2.2
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under
Apple's copyrights in this original Apple software (the "Apple Software"), to
use, reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions
of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may be used
to endorse or promote products derived from the Apple Software without specific
prior written permission from Apple. Except as expressly stated in this notice,
no other rights or licenses, express or implied, are granted by Apple herein,
including but not limited to any patent rights that may be infringed by your
derivative works or by other works in which the Apple Software may be
incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2010 Apple Inc. All Rights Reserved.
*/
#import <sys/socket.h>
#import <netinet/in.h>
#import <netinet6/in6.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h>
#import <CoreFoundation/CoreFoundation.h>
#import "Reachability.h"
#define kShouldPrintReachabilityFlags 1
static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char *comment)
{
#if kShouldPrintReachabilityFlags
NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
(flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
(flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
(flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
(flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
(flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
(flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
(flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
(flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-', comment);
#endif
}
@implementation Reachability
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags,
void *info)
{
#pragma unused(target, flags)
NSCAssert(info != nullptr, @"info was nullptr in ReachabilityCallback");
NSCAssert([(NSObject *)info isKindOfClass:[Reachability class]],
@"info was wrong class in ReachabilityCallback");
// We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
// in case someone uses the Reachablity object in a different thread.
NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];
Reachability *noteObject = (Reachability *)info;
// Post a notification to notify the client that the network reachability changed.
[[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification
object:noteObject];
[myPool release];
}
- (BOOL)startNotifier
{
BOOL retVal = NO;
SCNetworkReachabilityContext context = { 0, self, nullptr, nullptr, nullptr };
if (SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
{
if (SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(),
kCFRunLoopDefaultMode))
{
retVal = YES;
}
}
return retVal;
}
- (void)stopNotifier
{
if (reachabilityRef != nullptr)
{
SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(),
kCFRunLoopDefaultMode);
}
}
- (void)dealloc
{
[self stopNotifier];
if (reachabilityRef != nullptr)
{
CFRelease(reachabilityRef);
}
[super dealloc];
}
+ (Reachability *)reachabilityWithHostName:(NSString *)hostName;
{
Reachability *retVal = nullptr;
SCNetworkReachabilityRef reachability =
SCNetworkReachabilityCreateWithName(nullptr, [hostName UTF8String]);
if (reachability != nullptr)
{
retVal = [[[self alloc] init] autorelease];
if (retVal != nullptr)
{
retVal->reachabilityRef = reachability;
retVal->localWiFiRef = NO;
}
}
return retVal;
}
+ (Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;
{
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(
kCFAllocatorDefault, (const struct sockaddr *)hostAddress);
Reachability *retVal = nullptr;
if (reachability != nullptr)
{
retVal = [[[self alloc] init] autorelease];
if (retVal != nullptr)
{
retVal->reachabilityRef = reachability;
retVal->localWiFiRef = NO;
}
}
return retVal;
}
+ (Reachability *)reachabilityForInternetConnection;
{
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
return [self reachabilityWithAddress:&zeroAddress];
}
+ (Reachability *)reachabilityForLocalWiFi;
{
struct sockaddr_in localWifiAddress;
bzero(&localWifiAddress, sizeof(localWifiAddress));
localWifiAddress.sin_len = sizeof(localWifiAddress);
localWifiAddress.sin_family = AF_INET;
// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
Reachability *retVal = [self reachabilityWithAddress:&localWifiAddress];
if (retVal != nullptr)
{
retVal->localWiFiRef = YES;
}
return retVal;
}
#pragma mark Network Flag Handling
- (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags
{
PrintReachabilityFlags(flags, "localWiFiStatusForFlags");
BOOL retVal = NotReachable;
if ((flags & kSCNetworkReachabilityFlagsReachable) &&
(flags & kSCNetworkReachabilityFlagsIsDirect))
{
retVal = ReachableViaWiFi;
}
return retVal;
}
- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
{
PrintReachabilityFlags(flags, "networkStatusForFlags");
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
{
// if target host is not reachable
return NotReachable;
}
BOOL retVal = NotReachable;
if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
{
// if target host is reachable and no connection is required
// then we'll assume (for now) that your on Wi-Fi
retVal = ReachableViaWiFi;
}
if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0) ||
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
{
// ... and the connection is on-demand (or on-traffic) if the
// calling application is using the CFSocketStream or higher APIs
if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
{
// ... and no [user] intervention is needed
retVal = ReachableViaWiFi;
}
}
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
{
// ... but WWAN connections are OK if the calling application
// is using the CFNetwork (CFSocketStream?) APIs.
retVal = ReachableViaWWAN;
}
return retVal;
}
- (BOOL)connectionRequired;
{
NSAssert(reachabilityRef != nullptr, @"connectionRequired called with nullptr reachabilityRef");
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
{
return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
}
return NO;
}
- (NetworkStatus)currentReachabilityStatus
{
NSAssert(reachabilityRef != nullptr,
@"currentNetworkStatus called with nullptr reachabilityRef");
NetworkStatus retVal = NotReachable;
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
{
if (localWiFiRef)
{
retVal = [self localWiFiStatusForFlags:flags];
}
else
{
retVal = [self networkStatusForFlags:flags];
}
}
return retVal;
}
@end

View File

@@ -0,0 +1,48 @@
//
// SFHFKeychainUtils.h
//
// Created by Buzz Andersen on 10/20/08.
// Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone.
// Copyright 2008 Sci-Fi Hi-Fi. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import <UIKit/UIKit.h>
@interface SFHFKeychainUtils : NSObject
{
}
+ (NSString *)getPasswordForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error;
+ (BOOL)storeUsername:(NSString *)username
andPassword:(NSString *)password
forServerName:(NSString *)serverName
updateExisting:(BOOL)updateExisting
error:(NSError **)error;
+ (BOOL)deleteItemForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error;
@end

View File

@@ -0,0 +1,501 @@
//
// SFHFKeychainUtils.m
//
// Created by Buzz Andersen on 10/20/08.
// Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone.
// Copyright 2008 Sci-Fi Hi-Fi. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import "SFHFKeychainUtils.h"
#import <Security/Security.h>
static NSString *SFHFKeychainUtilsErrorDomain = @"SFHFKeychainUtilsErrorDomain";
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 30000 && TARGET_IPHONE_SIMULATOR
@interface SFHFKeychainUtils (PrivateMethods)
+ (SecKeychainItemRef)getKeychainItemReferenceForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error;
@end
#endif
@implementation SFHFKeychainUtils
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 30000 && TARGET_IPHONE_SIMULATOR
+ (NSString *)getPasswordForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error
{
if (!username || !serviceName)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:-2000 userInfo:nil];
return nil;
}
SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername:username
andServerName:serverName
error:error];
if (*error || !item)
{
return nil;
}
// from Advanced Mac OS X Programming, ch. 16
UInt32 length;
char *password;
SecKeychainAttribute attributes[8];
SecKeychainAttributeList list;
attributes[0].tag = kSecAccountItemAttr;
attributes[1].tag = kSecDescriptionItemAttr;
attributes[2].tag = kSecLabelItemAttr;
attributes[3].tag = kSecModDateItemAttr;
list.count = 4;
list.attr = attributes;
OSStatus status = SecKeychainItemCopyContent(item, nullptr, &list, &length, (void **)&password);
if (status != noErr)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:status userInfo:nil];
return nil;
}
NSString *passwordString = nil;
if (password != nullptr)
{
char passwordBuffer[1024];
if (length > 1023)
{
length = 1023;
}
strncpy(passwordBuffer, password, length);
passwordBuffer[length] = '\0';
passwordString = [NSString stringWithCString:passwordBuffer encoding:NSUTF8StringEncoding];
}
SecKeychainItemFreeContent(&list, password);
CFRelease(item);
return passwordString;
}
+ (void)storeUsername:(NSString *)username
andPassword:(NSString *)password
forServerName:(NSString *)serverName
updateExisting:(BOOL)updateExisting
error:(NSError **)error
{
if (!username || !password || !serverName)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:-2000 userInfo:nil];
return;
}
OSStatus status = noErr;
SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername:username
andServerName:serverName
error:error];
if (*error && [*error code] != noErr)
{
return;
}
*error = nil;
if (item)
{
status = SecKeychainItemModifyAttributesAndData(
item, nullptr, strlen([password UTF8String]), [password UTF8String]);
CFRelease(item);
}
else
{
status = SecKeychainAddGenericPassword(
nullptr, strlen([serverName UTF8String]), [serverName UTF8String],
strlen([username UTF8String]), [username UTF8String], strlen([password UTF8String]),
[password UTF8String], nullptr);
}
if (status != noErr)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:status userInfo:nil];
}
}
+ (void)deleteItemForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error
{
if (!username || !serverName)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:2000 userInfo:nil];
return;
}
*error = nil;
SecKeychainItemRef item = [SFHFKeychainUtils getKeychainItemReferenceForUsername:username
andServerName:serverName
error:error];
if (*error && [*error code] != noErr)
{
return;
}
OSStatus status;
if (item)
{
status = SecKeychainItemDelete(item);
CFRelease(item);
}
if (status != noErr)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:status userInfo:nil];
}
}
+ (SecKeychainItemRef)getKeychainItemReferenceForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error
{
if (!username || !serverName)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:-2000 userInfo:nil];
return nil;
}
*error = nil;
SecKeychainItemRef item;
OSStatus status = SecKeychainFindGenericPassword(
nullptr, strlen([serverName UTF8String]), [serverName UTF8String],
strlen([username UTF8String]), [username UTF8String], nullptr, nullptr, &item);
if (status != noErr)
{
if (status != errSecItemNotFound)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain
code:status
userInfo:nil];
}
return nil;
}
return item;
}
#else
+ (NSString *)getPasswordForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error
{
if (!username || !serverName)
{
if (error != nil)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:-2000 userInfo:nil];
}
return nil;
}
if (error != nil)
{
*error = nil;
}
// Set up a query dictionary with the base query attributes: item type (generic), username, and
// service
NSArray *keys = [[[NSArray alloc]
initWithObjects:(NSString *)kSecClass, kSecAttrAccount, kSecAttrService, nil] autorelease];
NSArray *objects = [[[NSArray alloc] initWithObjects:(NSString *)kSecClassGenericPassword,
username, serverName, nil] autorelease];
NSMutableDictionary *query = [[[NSMutableDictionary alloc] initWithObjects:objects
forKeys:keys] autorelease];
// First do a query for attributes, in case we already have a Keychain item with no password
// data set. One likely way such an incorrect item could have come about is due to the previous
// (incorrect) version of this code (which set the password as a generic attribute instead of
// password data).
NSDictionary *attributeResult = nullptr;
NSMutableDictionary *attributeQuery = [query mutableCopy];
[attributeQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
OSStatus status =
SecItemCopyMatching((CFDictionaryRef)attributeQuery, (CFTypeRef *)&attributeResult);
[attributeResult release];
[attributeQuery release];
if (status != noErr)
{
// No existing item found--simply return nil for the password
if (error != nil && status != errSecItemNotFound)
{
// Only return an error if a real exception happened--not simply for "not found."
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain
code:status
userInfo:nil];
}
return nil;
}
// We have an existing item, now query for the password data associated with it.
NSData *resultData = nil;
NSMutableDictionary *passwordQuery = [query mutableCopy];
[passwordQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
status = SecItemCopyMatching((CFDictionaryRef)passwordQuery, (CFTypeRef *)&resultData);
[resultData autorelease];
[passwordQuery release];
if (status != noErr)
{
if (status == errSecItemNotFound)
{
// We found attributes for the item previously, but no password now, so return a special
// error. Users of this API will probably want to detect this error and prompt the user
// to re-enter their credentials. When you attempt to store the re-entered credentials
// using storeUsername:andPassword:forServiceName:updateExisting:error
// the old, incorrect entry will be deleted and a new one with a properly encrypted
// password will be added.
if (error != nil)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain
code:-1999
userInfo:nil];
}
}
else
{
// Something else went wrong. Simply return the normal Keychain API error code.
if (error != nil)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain
code:status
userInfo:nil];
}
}
return nil;
}
NSString *password = nil;
if (resultData)
{
password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
}
else
{
// There is an existing item, but we weren't able to get password data for it for some
// reason, Possibly as a result of an item being incorrectly entered by the previous code.
// Set the -1999 error so the code above us can prompt the user again.
if (error != nil)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:-1999 userInfo:nil];
}
}
return [password autorelease];
}
+ (BOOL)storeUsername:(NSString *)username
andPassword:(NSString *)password
forServerName:(NSString *)serverName
updateExisting:(BOOL)updateExisting
error:(NSError **)error
{
if (!username || !password || !serverName)
{
if (error != nil)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:-2000 userInfo:nil];
}
return NO;
}
// See if we already have a password entered for these credentials.
NSError *getError = nil;
NSString *existingPassword = [SFHFKeychainUtils getPasswordForUsername:username
andServerName:serverName
error:&getError];
if ([getError code] == -1999)
{
// There is an existing entry without a password properly stored (possibly as a result of
// the previous incorrect version of this code. Delete the existing item before moving on
// entering a correct one.
getError = nil;
[self deleteItemForUsername:username andServerName:serverName error:&getError];
if ([getError code] != noErr)
{
if (error != nil)
{
*error = getError;
}
return NO;
}
}
else if ([getError code] != noErr)
{
if (error != nil)
{
*error = getError;
}
return NO;
}
if (error != nil)
{
*error = nil;
}
OSStatus status = noErr;
if (existingPassword)
{
// We have an existing, properly entered item with a password.
// Update the existing item.
if (![existingPassword isEqualToString:password] && updateExisting)
{
// Only update if we're allowed to update existing. If not, simply do nothing.
NSArray *keys =
[[[NSArray alloc] initWithObjects:(NSString *)kSecClass, kSecAttrService,
kSecAttrLabel, kSecAttrAccount, nil] autorelease];
NSArray *objects =
[[[NSArray alloc] initWithObjects:(NSString *)kSecClassGenericPassword, serverName,
serverName, username, nil] autorelease];
NSDictionary *query = [[[NSDictionary alloc] initWithObjects:objects
forKeys:keys] autorelease];
status = SecItemUpdate(
(CFDictionaryRef)query,
(CFDictionaryRef)[NSDictionary
dictionaryWithObject:[password dataUsingEncoding:NSUTF8StringEncoding]
forKey:(NSString *)kSecValueData]);
}
}
else
{
// No existing entry (or an existing, improperly entered, and therefore now
// deleted, entry). Create a new entry.
NSArray *keys =
[[[NSArray alloc] initWithObjects:(NSString *)kSecClass, kSecAttrService, kSecAttrLabel,
kSecAttrAccount, kSecValueData, nil] autorelease];
NSArray *objects = [[[NSArray alloc]
initWithObjects:(NSString *)kSecClassGenericPassword, serverName, serverName, username,
[password dataUsingEncoding:NSUTF8StringEncoding], nil] autorelease];
NSDictionary *query = [[[NSDictionary alloc] initWithObjects:objects
forKeys:keys] autorelease];
status = SecItemAdd((CFDictionaryRef)query, nullptr);
}
if (error != nil && status != noErr)
{
// Something went wrong with adding the new item. Return the Keychain error code.
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:status userInfo:nil];
return NO;
}
return YES;
}
+ (BOOL)deleteItemForUsername:(NSString *)username
andServerName:(NSString *)serverName
error:(NSError **)error
{
if (!username || !serverName)
{
if (error != nil)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:-2000 userInfo:nil];
}
return NO;
}
if (error != nil)
{
*error = nil;
}
NSArray *keys =
[[[NSArray alloc] initWithObjects:(NSString *)kSecClass, kSecAttrAccount, kSecAttrService,
kSecReturnAttributes, nil] autorelease];
NSArray *objects =
[[[NSArray alloc] initWithObjects:(NSString *)kSecClassGenericPassword, username,
serverName, kCFBooleanTrue, nil] autorelease];
NSDictionary *query = [[[NSDictionary alloc] initWithObjects:objects forKeys:keys] autorelease];
OSStatus status = SecItemDelete((CFDictionaryRef)query);
if (error != nil && status != noErr)
{
*error = [NSError errorWithDomain:SFHFKeychainUtilsErrorDomain code:status userInfo:nil];
return NO;
}
return YES;
}
#endif
@end

View File

@@ -0,0 +1,57 @@
/*
Basic type defines for TSX RDC
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#ifndef TSXRemoteDesktop_TSXTypes_h
#define TSXRemoteDesktop_TSXTypes_h
#pragma mark Internal state
// Represents the underlying state of a TWSession RDP connection.
typedef enum
{
TSXConnectionClosed =
0, // Session either hasn't begun connecting, or its connection has finished disconnecting.
TSXConnectionConnecting =
1, // Session is in the process of establishing an RDP connection. A TCP or SSL connection
// might be established, but the RDP initialization sequence isn't finished.
TSXConnectionConnected =
2, // Session has a full RDP connection established; though if the windows computer doesn't
// support NLA, a login screen might be shown in the session.
TSXConnectionDisconnected = 3 // Session is disconnected at the RDP layer. TSX RDC might still
// be disposing of resources, however.
} TSXConnectionState;
#pragma mark Session settings
// Represents the type of screen resolution the user has selected. Most are dynamic sizes, meaning
// that the actual session dimensions are calculated when connecting.
typedef enum
{
TSXScreenOptionFixed = 0, // A static resolution, like 1024x768
TSXScreenOptionFitScreen = 1, // Upon connection, fit the session to the entire screen size
TSXScreenOptionCustom = 2, // Like fixed just specified by the user
} TSXScreenOptions;
typedef enum
{
TSXAudioPlaybackLocal = 0,
TSXAudioPlaybackServer = 1,
TSXAudioPlaybackSilent = 2
} TSXAudioPlaybackOptions;
typedef enum
{
TSXProtocolSecurityAutomatic = 0,
TSXProtocolSecurityRDP = 1,
TSXProtocolSecurityTLS = 2,
TSXProtocolSecurityNLA = 3
} TSXProtocolSecurityOptions;
#endif

View File

@@ -0,0 +1,80 @@
/*
Utility functions
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import "TSXTypes.h"
// helper macro to encode a table path into a tag value (used to identify controls in their delegate
// handlers)
#define GET_TAG(section, row) ((((int)section) << 16) | ((int)(row)))
#define GET_TAG_FROM_PATH(path) ((((int)path.section) << 16) | ((int)(path.row)))
BOOL ScanHostNameAndPort(NSString *address, NSString **host, unsigned short *port);
#pragma mark -
#pragma mark Screen Resolutions
NSString *ScreenResolutionDescription(TSXScreenOptions type, int width, int height);
BOOL ScanScreenResolution(NSString *description, int *width, int *height, TSXScreenOptions *type);
NSDictionary *SelectionForColorSetting(void);
NSArray *ResolutionModes(void);
#pragma mark Security Protocol
NSString *ProtocolSecurityDescription(TSXProtocolSecurityOptions type);
BOOL ScanProtocolSecurity(NSString *description, TSXProtocolSecurityOptions *type);
NSDictionary *SelectionForSecuritySetting(void);
#pragma mark Bookmarks
@class BookmarkBase;
NSMutableArray *FilterBookmarks(NSArray *bookmarks, NSArray *filter_words);
NSMutableArray *FilterHistory(NSArray *history, NSString *filterStr);
#pragma mark iPad/iPhone detection
BOOL IsPad(void);
BOOL IsPhone(void);
#pragma mark Version Info
NSString *TSXAppFullVersion(void);
#pragma mark Touch/Mouse handling
// set mouse buttons swapped flag
void SetSwapMouseButtonsFlag(BOOL swapped);
// set invert scrolling flag
void SetInvertScrollingFlag(BOOL invert);
// return event value for left mouse button
int GetLeftMouseButtonClickEvent(BOOL down);
// return event value for right mouse button
int GetRightMouseButtonClickEvent(BOOL down);
// return event value for mouse move event
int GetMouseMoveEvent(void);
// return mouse wheel event
int GetMouseWheelEvent(BOOL down);
// scrolling gesture detection delta
CGFloat GetScrollGestureDelta(void);
#pragma mark Connectivity tools
// activates the iphone's WWAN interface in case it is offline
void WakeUpWWAN(void);
#pragma mark System Info functions
NSString *TSXGetPlatform(void);
BOOL TSXDeviceHasJailBreak(void);
NSString *TSXGetPrimaryMACAddress(NSString *sep);

View File

@@ -0,0 +1,397 @@
/*
Utility functions
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "Utils.h"
#import "OrderedDictionary.h"
#import "TSXAdditions.h"
#import <freerdp/input.h>
#import <freerdp/version.h>
#import <freerdp/config.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if_dl.h>
BOOL ScanHostNameAndPort(NSString *address, NSString **host, unsigned short *port)
{
*host = @"";
*port = 0;
if (![address length])
return NO;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"rdp://%@", address]];
if (!url || ![[url host] length])
return NO;
*host = [url host];
*port = [[url port] unsignedShortValue];
return YES;
}
#pragma mark -
#pragma mark Working with Screen Resolutions
NSString *LocalizedFitScreen()
{
return NSLocalizedString(@"Automatic", @"Screen resolution selector: Automatic resolution "
@"(Full Screen on iPad, reasonable size on iPhone)");
}
NSString *LocalizedCustom()
{
return NSLocalizedString(@"Custom", @"Screen resolution selector: Custom");
}
BOOL ScanScreenResolution(NSString *description, int *width, int *height, TSXScreenOptions *type)
{
*height = 0;
*width = 0;
*type = TSXScreenOptionFixed;
if ([description isEqualToString:LocalizedFitScreen()])
{
*type = TSXScreenOptionFitScreen;
return YES;
}
else if ([description isEqualToString:LocalizedCustom()])
{
*type = TSXScreenOptionCustom;
return YES;
}
NSArray *resolution_components = [description
componentsSeparatedByCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:@"x*×"]];
if ([resolution_components count] != 2)
return NO;
*width = [[resolution_components objectAtIndex:0] intValue];
*height = [[resolution_components objectAtIndex:1] intValue];
return YES;
}
NSString *ScreenResolutionDescription(TSXScreenOptions type, int width, int height)
{
if (type == TSXScreenOptionFitScreen)
return LocalizedFitScreen();
else if (type == TSXScreenOptionCustom)
return LocalizedCustom();
return [NSString stringWithFormat:@"%dx%d", width, height];
}
NSDictionary *SelectionForColorSetting()
{
OrderedDictionary *dict = [OrderedDictionary dictionaryWithCapacity:3];
[dict setValue:[NSNumber numberWithInt:8]
forKey:NSLocalizedString(@"Palette Color (8 Bit)", @"8 bit color selection")];
[dict setValue:[NSNumber numberWithInt:15]
forKey:NSLocalizedString(@"High Color (15 Bit)", @"15 bit color selection")];
[dict setValue:[NSNumber numberWithInt:16]
forKey:NSLocalizedString(@"High Color (16 Bit)", @"16 bit color selection")];
[dict setValue:[NSNumber numberWithInt:24]
forKey:NSLocalizedString(@"True Color (24 Bit)", @"24 bit color selection")];
[dict setValue:[NSNumber numberWithInt:32]
forKey:NSLocalizedString(@"Highest Quality (32 Bit)", @"32 bit color selection")];
return dict;
}
NSArray *ResolutionModes()
{
NSArray *array =
[NSArray arrayWithObjects:ScreenResolutionDescription(TSXScreenOptionFitScreen, 0, 0),
ScreenResolutionDescription(TSXScreenOptionFixed, 640, 480),
ScreenResolutionDescription(TSXScreenOptionFixed, 800, 600),
ScreenResolutionDescription(TSXScreenOptionFixed, 1024, 768),
ScreenResolutionDescription(TSXScreenOptionFixed, 1280, 1024),
ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 900),
ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 1050),
ScreenResolutionDescription(TSXScreenOptionFixed, 1600, 1200),
ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1080),
ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1200),
ScreenResolutionDescription(TSXScreenOptionCustom, 0, 0), nil];
return array;
}
#pragma mark Working with Security Protocols
NSString *LocalizedAutomaticSecurity()
{
return NSLocalizedString(@"Automatic", @"Automatic protocol security selection");
}
NSString *ProtocolSecurityDescription(TSXProtocolSecurityOptions type)
{
if (type == TSXProtocolSecurityNLA)
return @"NLA";
else if (type == TSXProtocolSecurityTLS)
return @"TLS";
else if (type == TSXProtocolSecurityRDP)
return @"RDP";
return LocalizedAutomaticSecurity();
}
BOOL ScanProtocolSecurity(NSString *description, TSXProtocolSecurityOptions *type)
{
*type = TSXProtocolSecurityRDP;
if ([description isEqualToString:@"NLA"])
{
*type = TSXProtocolSecurityNLA;
return YES;
}
else if ([description isEqualToString:@"TLS"])
{
*type = TSXProtocolSecurityTLS;
return YES;
}
else if ([description isEqualToString:@"RDP"])
{
*type = TSXProtocolSecurityRDP;
return YES;
}
else if ([description isEqualToString:LocalizedAutomaticSecurity()])
{
*type = TSXProtocolSecurityAutomatic;
return YES;
}
return NO;
}
NSDictionary *SelectionForSecuritySetting()
{
OrderedDictionary *dict = [OrderedDictionary dictionaryWithCapacity:4];
[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityAutomatic]
forKey:ProtocolSecurityDescription(TSXProtocolSecurityAutomatic)];
[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityRDP]
forKey:ProtocolSecurityDescription(TSXProtocolSecurityRDP)];
[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityTLS]
forKey:ProtocolSecurityDescription(TSXProtocolSecurityTLS)];
[dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityNLA]
forKey:ProtocolSecurityDescription(TSXProtocolSecurityNLA)];
return dict;
}
#pragma mark -
#pragma mark Bookmarks
#import "Bookmark.h"
NSMutableArray *FilterBookmarks(NSArray *bookmarks, NSArray *filter_words)
{
NSMutableArray *matching_items = [NSMutableArray array];
NSArray *searched_keys = [NSArray
arrayWithObjects:@"label", @"params.hostname", @"params.username", @"params.domain", nil];
for (ComputerBookmark *cur_bookmark in bookmarks)
{
double match_score = 0.0;
for (int i = 0; i < [searched_keys count]; i++)
{
NSString *val = [cur_bookmark valueForKeyPath:[searched_keys objectAtIndex:i]];
if (![val isKindOfClass:[NSString class]] || ![val length])
continue;
for (NSString *word in filter_words)
if ([val rangeOfString:word
options:(NSCaseInsensitiveSearch | NSWidthInsensitiveSearch)]
.location != NSNotFound)
match_score += (1.0 / [filter_words count]) * pow(2, [searched_keys count] - i);
}
if (match_score > 0.001)
[matching_items
addObject:[NSDictionary
dictionaryWithObjectsAndKeys:cur_bookmark, @"bookmark",
[NSNumber numberWithFloat:match_score],
@"score", nil]];
}
[matching_items
sortUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
return [[obj2 objectForKey:@"score"] compare:[obj1 objectForKey:@"score"]];
}];
return matching_items;
}
NSMutableArray *FilterHistory(NSArray *history, NSString *filterStr)
{
NSMutableArray *result = [NSMutableArray array];
for (NSString *item in history)
{
if ([item rangeOfString:filterStr].location != NSNotFound)
[result addObject:item];
}
return result;
}
#pragma mark Version Info
NSString *TSXAppFullVersion()
{
return [NSString stringWithUTF8String:FREERDP_GIT_REVISION];
}
#pragma mark iPad/iPhone detection
BOOL IsPad()
{
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
}
BOOL IsPhone()
{
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);
#else
return NO;
#endif
}
// set mouse buttons swapped flag
static BOOL g_swap_mouse_buttons = NO;
void SetSwapMouseButtonsFlag(BOOL swapped)
{
g_swap_mouse_buttons = swapped;
}
// set invert scrolling flag
static BOOL g_invert_scrolling = NO;
void SetInvertScrollingFlag(BOOL invert)
{
g_invert_scrolling = invert;
}
// return event value for left mouse button
int GetLeftMouseButtonClickEvent(BOOL down)
{
if (g_swap_mouse_buttons)
return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
else
return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
}
// return event value for right mouse button
int GetRightMouseButtonClickEvent(BOOL down)
{
if (g_swap_mouse_buttons)
return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
else
return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
}
// get mouse move event
int GetMouseMoveEvent()
{
return (PTR_FLAGS_MOVE);
}
// return mouse wheel event
int GetMouseWheelEvent(BOOL down)
{
if (g_invert_scrolling)
down = !down;
if (down)
return (PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | (0x0088));
else
return (PTR_FLAGS_WHEEL | (0x0078));
}
// scrolling gesture detection delta
CGFloat GetScrollGestureDelta()
{
return 10.0f;
}
// this hack activates the iphone's WWAN interface in case it is offline
void WakeUpWWAN()
{
NSURL *url = [[[NSURL alloc] initWithString:@"http://www.nonexistingdummyurl.com"] autorelease];
// NSData * data =
[NSData dataWithContentsOfURL:url]; // we don't need data but assigning one causes a "data not
// used" compiler warning
}
#pragma mark System Info functions
NSString *TSXGetPrimaryMACAddress(NSString *sep)
{
NSString *macaddress = @"";
struct ifaddrs *addrs;
if (getifaddrs(&addrs) < 0)
{
NSLog(@"getPrimaryMACAddress: getifaddrs failed.");
return macaddress;
}
for (struct ifaddrs *cursor = addrs; cursor != nullptr; cursor = cursor->ifa_next)
{
if (strcmp(cursor->ifa_name, "en0"))
continue;
if ((cursor->ifa_addr->sa_family == AF_LINK) &&
(((struct sockaddr_dl *)cursor->ifa_addr)->sdl_type == 0x6 /*IFT_ETHER*/))
{
struct sockaddr_dl *dlAddr = (struct sockaddr_dl *)cursor->ifa_addr;
if (dlAddr->sdl_alen != 6)
continue;
unsigned char *base = (unsigned char *)&dlAddr->sdl_data[dlAddr->sdl_nlen];
macaddress = [NSString hexStringFromData:base
ofSize:6
withSeparator:sep
afterNthChar:1];
break;
}
}
freeifaddrs(addrs);
return macaddress;
}
BOOL TSXDeviceHasJailBreak()
{
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app/"])
return YES;
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt/"])
return YES;
return NO;
}
NSString *TSXGetPlatform()
{
size_t size;
sysctlbyname("hw.machine", nullptr, &size, nullptr, 0);
char *machine = malloc(size);
sysctlbyname("hw.machine", machine, &size, nullptr, 0);
NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
free(machine);
return platform;
}

View File

@@ -0,0 +1,48 @@
/*
Bookmark model abstraction
Copyright 2013 Thincast Technologies GmbH, Authors: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "ConnectionParams.h"
@interface ComputerBookmark : NSObject <NSCoding>
{
@protected
ComputerBookmark *_parent;
NSString *_uuid, *_label;
UIImage *_image;
ConnectionParams *_connection_params;
BOOL _connected_via_wlan;
}
@property(nonatomic, assign) ComputerBookmark *parent;
@property(nonatomic, readonly) NSString *uuid;
@property(nonatomic, copy) NSString *label;
@property(nonatomic, retain) UIImage *image;
@property(readonly, nonatomic) ConnectionParams *params;
@property(nonatomic, assign) BOOL conntectedViaWLAN;
// Creates a copy of this object, with a new UUID
- (id)copy;
- (id)copyWithUUID;
// Whether user can delete, move, or rename this entry
- (BOOL)isDeletable;
- (BOOL)isMovable;
- (BOOL)isRenamable;
- (BOOL)hasImmutableHost;
- (id)initWithConnectionParameters:(ConnectionParams *)params;
- (id)initWithBaseDefaultParameters;
// A copy of @params, with _bookmark_uuid set.
- (ConnectionParams *)copyMarkedParams;
@end

View File

@@ -0,0 +1,312 @@
/*
Bookmark model abstraction
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "Bookmark.h"
#import "TSXAdditions.h"
#import "Utils.h"
#import "GlobalDefaults.h"
@interface ComputerBookmark (Private)
- (void)willChangeValueForKeyPath:(NSString *)keyPath;
- (void)didChangeValueForKeyPath:(NSString *)keyPath;
@end
@implementation ComputerBookmark
@synthesize parent = _parent, uuid = _uuid, label = _label, image = _image;
@synthesize params = _connection_params, conntectedViaWLAN = _connected_via_wlan;
- (id)init
{
if (!(self = [super init]))
return nil;
_uuid = [[NSString stringWithUUID] retain];
_label = @"";
_connected_via_wlan = NO;
return self;
}
// Designated initializer.
- (id)initWithConnectionParameters:(ConnectionParams *)params
{
if (!(self = [self init]))
return nil;
_connection_params = [params copy];
_connected_via_wlan = NO;
return self;
}
- (id)initWithCoder:(NSCoder *)decoder
{
if (!(self = [self init]))
return nil;
if (![decoder allowsKeyedCoding])
[NSException raise:NSInvalidArgumentException format:@"coder must support keyed archiving"];
if ([decoder containsValueForKey:@"uuid"])
{
[_uuid release];
_uuid = [[decoder decodeObjectForKey:@"uuid"] retain];
}
if ([decoder containsValueForKey:@"label"])
[self setLabel:[decoder decodeObjectForKey:@"label"]];
if ([decoder containsValueForKey:@"connectionParams"])
{
[_connection_params release];
_connection_params = [[decoder decodeObjectForKey:@"connectionParams"] retain];
}
return self;
}
- (id)initWithBaseDefaultParameters
{
return [self initWithConnectionParameters:[[[ConnectionParams alloc]
initWithBaseDefaultParameters] autorelease]];
}
- (id)copy
{
ComputerBookmark *copy = [[[self class] alloc] init];
[copy setLabel:[self label]];
copy->_connection_params = [_connection_params copy];
return copy;
}
- (id)copyWithUUID
{
ComputerBookmark *copy = [self copy];
copy->_uuid = [[self uuid] copy];
return copy;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
if (![coder allowsKeyedCoding])
[NSException raise:NSInvalidArgumentException format:@"coder must support keyed archiving"];
[coder encodeObject:_uuid forKey:@"uuid"];
[coder encodeObject:_label forKey:@"label"];
[coder encodeObject:_connection_params forKey:@"connectionParams"];
}
- (void)dealloc
{
_parent = nil;
[_label release];
_label = nil;
[_uuid release];
_uuid = nil;
[_connection_params release];
_connection_params = nil;
[super dealloc];
}
- (UIImage *)image
{
return nil;
}
- (BOOL)isEqual:(id)object
{
return [object respondsToSelector:@selector(uuid)] && [[object uuid] isEqual:_uuid];
}
- (NSString *)description
{
return ([self label] != nil) ? [self label] : _uuid;
}
- (BOOL)validateValue:(id *)val forKey:(NSString *)key error:(NSError **)error
{
NSString *string_value = *val;
if ([key isEqualToString:@"label"])
{
if (![[string_value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]
length])
{
if (error)
*error = [NSError
errorWithDomain:@""
code:NSKeyValueValidationError
userInfo:
[NSDictionary
dictionaryWithObjectsAndKeys:
NSLocalizedString(
@"Connection labels cannot be blank",
@"Bookmark data validation: label blank title."),
NSLocalizedDescriptionKey,
NSLocalizedString(
@"Please enter the short description of this Connection "
@"that will appear in the Connection list.",
@"Bookmark data validation: label blank message."),
NSLocalizedRecoverySuggestionErrorKey, nil]];
return NO;
}
}
return YES;
}
- (BOOL)validateValue:(id *)val forKeyPath:(NSString *)keyPath error:(NSError **)error
{
// Could be used to validate params.hostname, params.password, params.port, etc.
return [super validateValue:val forKeyPath:keyPath error:error];
}
- (BOOL)isDeletable
{
return YES;
}
- (BOOL)isMovable
{
return YES;
}
- (BOOL)isRenamable
{
return YES;
}
- (BOOL)hasImmutableHost
{
return NO;
}
#pragma mark Custom KVC
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath
{
if ([keyPath isEqualToString:@"params.resolution"])
{
int width, height;
TSXScreenOptions type;
if (ScanScreenResolution(value, &width, &height, &type))
{
[_connection_params willChangeValueForKey:@"resolution"];
[[self params] setInt:type forKey:@"screen_resolution_type"];
if (type == TSXScreenOptionFixed)
{
[[self params] setInt:width forKey:@"width"];
[[self params] setInt:height forKey:@"height"];
}
[_connection_params didChangeValueForKey:@"resolution"];
}
else
[NSException raise:NSInvalidArgumentException
format:@"%s got invalid screen resolution '%@'", __func__, value];
}
else
{
[self willChangeValueForKeyPath:keyPath];
[super setValue:value forKeyPath:keyPath];
[self didChangeValueForKeyPath:keyPath];
}
}
- (id)valueForKeyPath:(NSString *)keyPath
{
if ([keyPath isEqualToString:@"params.resolution"])
return ScreenResolutionDescription([[self params] intForKey:@"screen_resolution_type"],
[[self params] intForKey:@"width"],
[[self params] intForKey:@"height"]);
return [super valueForKeyPath:keyPath];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([[change objectForKey:NSKeyValueChangeNotificationIsPriorKey] boolValue])
[self willChangeValueForKeyPath:keyPath];
else
[self didChangeValueForKeyPath:keyPath];
}
- (NSDictionary *)targetForChangeNotificationForKeyPath:(NSString *)keyPath
{
NSString *changed_key = keyPath;
NSObject *changed_object = self;
if ([keyPath rangeOfString:@"params."].location == 0)
{
changed_key = [keyPath substringFromIndex:[@"params." length]];
changed_object = _connection_params;
}
return [NSDictionary
dictionaryWithObjectsAndKeys:changed_key, @"key", changed_object, @"object", nil];
}
- (void)willChangeValueForKeyPath:(NSString *)keyPath
{
NSDictionary *target = [self targetForChangeNotificationForKeyPath:keyPath];
[[target objectForKey:@"object"] willChangeValueForKey:[target objectForKey:@"key"]];
}
- (void)didChangeValueForKeyPath:(NSString *)keyPath
{
NSDictionary *target = [self targetForChangeNotificationForKeyPath:keyPath];
[[target objectForKey:@"object"] didChangeValueForKey:[target objectForKey:@"key"]];
}
- (ConnectionParams *)copyMarkedParams
{
ConnectionParams *param_copy = [[self params] copy];
[param_copy setValue:[self uuid] forKey:@"_bookmark_uuid"];
return param_copy;
}
#pragma mark No children
- (NSUInteger)numberOfChildren
{
return 0;
}
- (NSUInteger)numberOfDescendants
{
return 1;
}
- (BookmarkBase *)childAtIndex:(NSUInteger)index
{
return nil;
}
- (NSUInteger)indexOfChild:(BookmarkBase *)child
{
return 0;
}
- (void)removeChild:(BookmarkBase *)child
{
}
- (void)addChild:(BookmarkBase *)child
{
}
- (void)addChild:(BookmarkBase *)child afterExistingChild:(BookmarkBase *)existingChild
{
}
- (void)addChild:(BookmarkBase *)child atIndex:(NSInteger)index
{
}
- (BOOL)hasDescendant:(BookmarkBase *)needle
{
return NO;
}
- (BOOL)canContainChildren
{
return NO;
}
@end

View File

@@ -0,0 +1,46 @@
/*
Connection Parameters abstraction
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
@interface ConnectionParams : NSObject
{
@private
NSMutableDictionary *_connection_params;
}
// Designated initializer.
- (id)initWithDictionary:(NSDictionary *)dict;
- (id)initWithBaseDefaultParameters;
// Getting/setting values
- (NSArray *)allKeys;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKey:(NSString *)key;
- (BOOL)hasValueForKey:(NSString *)key;
- (void)setInt:(int)integer forKey:(NSString *)key;
- (int)intForKey:(NSString *)key;
- (void)setBool:(BOOL)v forKey:(NSString *)key;
- (BOOL)boolForKey:(NSString *)key;
- (const char *)UTF8StringForKey:(NSString *)key;
- (NSString *)StringForKey:(NSString *)key;
- (BOOL)hasValueForKeyPath:(NSString *)key;
- (void)setInt:(int)integer forKeyPath:(NSString *)key;
- (int)intForKeyPath:(NSString *)key;
- (void)setBool:(BOOL)v forKeyPath:(NSString *)key;
- (BOOL)boolForKeyPath:(NSString *)key;
- (const char *)UTF8StringForKeyPath:(NSString *)key;
- (NSString *)StringForKeyPath:(NSString *)key;
- (int)intForKey:(NSString *)key with3GEnabled:(BOOL)enabled;
- (BOOL)boolForKey:(NSString *)key with3GEnabled:(BOOL)enabled;
@end

View File

@@ -0,0 +1,258 @@
/*
Connection Parameters abstraction
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "ConnectionParams.h"
#import "GlobalDefaults.h"
#import "EncryptionController.h"
#import "Utils.h"
#import "TSXAdditions.h"
@interface ConnectionParams (Private)
- (id)initWithConnectionParams:(ConnectionParams *)params;
@end
@implementation ConnectionParams
// Designated initializer.
- (id)initWithDictionary:(NSDictionary *)dict
{
if (!(self = [super init]))
return nil;
_connection_params = [dict mutableDeepCopy];
[self decryptPasswordForKey:@"password"];
[self decryptPasswordForKey:@"tsg_password"];
return self;
}
- (void)decryptPasswordForKey:(NSString *)key
{
if ([[_connection_params objectForKey:key] isKindOfClass:[NSData class]])
{
NSString *plaintext_password = [[[EncryptionController sharedEncryptionController]
decryptor] decryptString:[_connection_params objectForKey:key]];
[self setValue:plaintext_password forKey:key];
}
}
- (id)initWithBaseDefaultParameters
{
return [self initWithDictionary:[[NSUserDefaults standardUserDefaults]
dictionaryForKey:@"TSXDefaultComputerBookmarkSettings"]];
}
- (id)init
{
return [self initWithDictionary:[NSDictionary dictionary]];
}
- (id)initWithConnectionParams:(ConnectionParams *)params
{
return [self initWithDictionary:params->_connection_params];
}
- (void)dealloc
{
[_connection_params release];
_connection_params = nil;
[super dealloc];
}
- (id)copyWithZone:(NSZone *)zone
{
return [[ConnectionParams alloc] initWithDictionary:_connection_params];
}
- (NSString *)description
{
return [NSString stringWithFormat:@"ConnectionParams: %@", [_connection_params description]];
}
#pragma mark -
#pragma mark NSCoder
- (id)initWithCoder:(NSCoder *)decoder
{
if ([decoder containsValueForKey:@"connectionParams"])
return [self initWithDictionary:[decoder decodeObjectForKey:@"connectionParams"]];
return [self init];
}
- (void)encodeWithCoder:(NSCoder *)coder
{
NSSet *unserializable_keys = [NSSet setWithObjects:@"view", nil];
NSMutableDictionary *serializable_params =
[[NSMutableDictionary alloc] initWithCapacity:[_connection_params count]];
for (NSString *k in _connection_params)
if (([k characterAtIndex:0] != '_') && ![unserializable_keys containsObject:k])
[serializable_params setObject:[_connection_params objectForKey:k] forKey:k];
if ([serializable_params objectForKey:@"password"] != nil)
[self serializeDecryptedForKey:@"password" forParams:serializable_params];
if ([serializable_params objectForKey:@"tsg_password"] != nil)
[self serializeDecryptedForKey:@"tsg_password" forParams:serializable_params];
[coder encodeObject:serializable_params forKey:@"connectionParams"];
[serializable_params release];
}
- (void)serializeDecryptedForKey:(NSString *)key forParams:(NSMutableDictionary *)params
{
NSData *encrypted_password = [[[EncryptionController sharedEncryptionController] encryptor]
encryptString:[params objectForKey:key]];
if (encrypted_password)
[params setObject:encrypted_password forKey:key];
else
[params removeObjectForKey:key];
}
#pragma mark -
#pragma mark NSKeyValueCoding
- (void)setValue:(id)value forKey:(NSString *)key
{
[self willChangeValueForKey:key];
if (value == nil)
[self setNilValueForKey:key];
else
[_connection_params setValue:value forKey:key];
[self didChangeValueForKey:key];
}
- (void)setValue:(id)value forKeyPath:(NSString *)key
{
[self willChangeValueForKey:key];
if (value == nil)
[self setNilValueForKey:key];
else
[_connection_params setValue:value forKeyPath:key];
[self didChangeValueForKey:key];
}
- (void)setNilValueForKey:(NSString *)key
{
[_connection_params removeObjectForKey:key];
}
- (id)valueForKey:(NSString *)key
{
return [_connection_params valueForKey:key];
}
- (NSArray *)allKeys
{
return [_connection_params allKeys];
}
#pragma mark -
#pragma mark KV convenience
- (BOOL)hasValueForKey:(NSString *)key
{
return [_connection_params objectForKey:key] != nil;
}
- (void)setInt:(int)integer forKey:(NSString *)key
{
[self setValue:[NSNumber numberWithInteger:integer] forKey:key];
}
- (int)intForKey:(NSString *)key
{
return [[self valueForKey:key] intValue];
}
- (void)setBool:(BOOL)v forKey:(NSString *)key
{
[self setValue:[NSNumber numberWithBool:v] forKey:key];
}
- (BOOL)boolForKey:(NSString *)key
{
return [[_connection_params objectForKey:key] boolValue];
}
- (const char *)UTF8StringForKey:(NSString *)key
{
id val = [self valueForKey:key];
const char *str;
if ([val respondsToSelector:@selector(UTF8String)] && (str = [val UTF8String]))
return str;
return "";
}
- (NSString *)StringForKey:(NSString *)key
{
return [self valueForKey:key];
}
- (BOOL)hasValueForKeyPath:(NSString *)key
{
return [_connection_params valueForKeyPath:key] != nil;
}
- (void)setInt:(int)integer forKeyPath:(NSString *)key
{
[self setValue:[NSNumber numberWithInteger:integer] forKeyPath:key];
}
- (int)intForKeyPath:(NSString *)key
{
return [[self valueForKeyPath:key] intValue];
}
- (void)setBool:(BOOL)v forKeyPath:(NSString *)key
{
[self setValue:[NSNumber numberWithBool:v] forKeyPath:key];
}
- (BOOL)boolForKeyPath:(NSString *)key
{
return [[self valueForKeyPath:key] boolValue];
}
- (const char *)UTF8StringForKeyPath:(NSString *)key
{
id val = [self valueForKeyPath:key];
const char *str;
if ([val respondsToSelector:@selector(UTF8String)] && (str = [val UTF8String]))
return str;
return "";
}
- (NSString *)StringForKeyPath:(NSString *)key
{
return [self valueForKeyPath:key];
}
- (int)intForKey:(NSString *)key with3GEnabled:(BOOL)enabled
{
if (enabled && [self boolForKey:@"enable_3g_settings"])
return [self intForKeyPath:[NSString stringWithFormat:@"settings_3g.%@", key]];
return [self intForKeyPath:key];
}
- (BOOL)boolForKey:(NSString *)key with3GEnabled:(BOOL)enabled
{
if (enabled && [self boolForKey:@"enable_3g_settings"])
return [self boolForKeyPath:[NSString stringWithFormat:@"settings_3g.%@", key]];
return [self boolForKeyPath:key];
}
@end

View File

@@ -0,0 +1,43 @@
/*
Password Encryptor
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
/* Encrypts data using AES 128 with a 256 bit key derived using PBKDF2-HMAC-SHA1 */
#import <Foundation/Foundation.h>
// Encryption block cipher config
#define TSXEncryptorBlockCipherAlgo kCCAlgorithmAES128
#define TSXEncryptorBlockCipherKeySize kCCKeySizeAES256
#define TSXEncryptorBlockCipherOptions kCCOptionPKCS7Padding
#define TSXEncryptorBlockCipherBlockSize 16
// Key generation: If any of these are changed, existing password stores will no longer work
#define TSXEncryptorPBKDF2Rounds 100
#define TSXEncryptorPBKDF2Salt "9D¶3L}S¿lA[e€3C«"
#define TSXEncryptorPBKDF2SaltLen TSXEncryptorBlockCipherOptions
#define TSXEncryptorPBKDF2KeySize TSXEncryptorBlockCipherKeySize
@interface Encryptor : NSObject
{
@private
NSData *_encryption_key;
NSString *_plaintext_password;
}
@property(readonly) NSString *plaintextPassword;
- (id)initWithPassword:(NSString *)plaintext_password;
- (NSData *)encryptData:(NSData *)plaintext_data;
- (NSData *)decryptData:(NSData *)encrypted_data;
- (NSData *)encryptString:(NSString *)plaintext_string;
- (NSString *)decryptString:(NSData *)encrypted_string;
@end

View File

@@ -0,0 +1,206 @@
/*
Password Encryptor
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
/* We try to use CommonCrypto as much as possible. PBKDF2 was added to CommonCrypto in iOS 5, so use
* OpenSSL only as a fallback to do PBKDF2 on pre iOS 5 systems. */
#import "Encryptor.h"
#import <CommonCrypto/CommonKeyDerivation.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>
#import <openssl/evp.h> // For PBKDF2 on < 5.0
#include <fcntl.h>
#pragma mark -
@interface Encryptor (Private)
- (NSData *)randomInitializationVector;
@end
@implementation Encryptor
@synthesize plaintextPassword = _plaintext_password;
- (id)initWithPassword:(NSString *)plaintext_password
{
if (plaintext_password == nil)
return nil;
if (!(self = [super init]))
return nil;
_plaintext_password = [plaintext_password retain];
const char *plaintext_password_data =
[plaintext_password length] ? [plaintext_password UTF8String] : " ";
if (!plaintext_password_data || !strlen(plaintext_password_data))
[NSException raise:NSInternalInconsistencyException
format:@"%s: plaintext password data is zero length!", __func__];
uint8_t *derived_key = calloc(1, TSXEncryptorPBKDF2KeySize);
if (CCKeyDerivationPBKDF != nullptr)
{
int ret = CCKeyDerivationPBKDF(
kCCPBKDF2, plaintext_password_data, strlen(plaintext_password_data) - 1,
(const uint8_t *)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen, kCCPRFHmacAlgSHA1,
TSXEncryptorPBKDF2Rounds, derived_key, TSXEncryptorPBKDF2KeySize);
// NSLog(@"CCKeyDerivationPBKDF ret = %d; key: %@", ret, [NSData
// dataWithBytesNoCopy:derived_key length:TWEncryptorPBKDF2KeySize freeWhenDone:NO]);
if (ret)
{
NSLog(@"%s: CCKeyDerivationPBKDF ret == %d, indicating some sort of failure.", __func__,
ret);
free(derived_key);
[self autorelease];
return nil;
}
}
else
{
// iOS 4.x or earlier -- use OpenSSL
unsigned long ret = PKCS5_PBKDF2_HMAC_SHA1(
plaintext_password_data, (int)strlen(plaintext_password_data) - 1,
(const unsigned char *)TSXEncryptorPBKDF2Salt, TSXEncryptorPBKDF2SaltLen,
TSXEncryptorPBKDF2Rounds, TSXEncryptorPBKDF2KeySize, derived_key);
// NSLog(@"PKCS5_PBKDF2_HMAC_SHA1 ret = %lu; key: %@", ret, [NSData
// dataWithBytesNoCopy:derived_key length:TWEncryptorPBKDF2KeySize freeWhenDone:NO]);
if (ret != 1)
{
NSLog(@"%s: PKCS5_PBKDF2_HMAC_SHA1 ret == %lu, indicating some sort of failure.",
__func__, ret);
free(derived_key);
[self release];
return nil;
}
}
_encryption_key = [[NSData alloc] initWithBytesNoCopy:derived_key
length:TSXEncryptorPBKDF2KeySize
freeWhenDone:YES];
return self;
}
#pragma mark -
#pragma mark Encrypting/Decrypting data
- (NSData *)encryptData:(NSData *)plaintext_data
{
if (![plaintext_data length])
return nil;
NSData *iv = [self randomInitializationVector];
NSMutableData *encrypted_data = [NSMutableData
dataWithLength:[iv length] + [plaintext_data length] + TSXEncryptorBlockCipherBlockSize];
[encrypted_data replaceBytesInRange:NSMakeRange(0, [iv length]) withBytes:[iv bytes]];
size_t data_out_moved = 0;
int ret = CCCrypt(kCCEncrypt, TSXEncryptorBlockCipherAlgo, TSXEncryptorBlockCipherOptions,
[_encryption_key bytes], TSXEncryptorBlockCipherKeySize, [iv bytes],
[plaintext_data bytes], [plaintext_data length],
[encrypted_data mutableBytes] + [iv length],
[encrypted_data length] - [iv length], &data_out_moved);
switch (ret)
{
case kCCSuccess:
[encrypted_data setLength:[iv length] + data_out_moved];
return encrypted_data;
default:
NSLog(
@"%s: uncaught error, ret CCCryptorStatus = %d (plaintext len = %lu; buffer size = "
@"%lu)",
__func__, ret, (unsigned long)[plaintext_data length],
(unsigned long)([encrypted_data length] - [iv length]));
return nil;
}
return nil;
}
- (NSData *)decryptData:(NSData *)encrypted_data
{
if ([encrypted_data length] <= TSXEncryptorBlockCipherBlockSize)
return nil;
NSMutableData *plaintext_data =
[NSMutableData dataWithLength:[encrypted_data length] + TSXEncryptorBlockCipherBlockSize];
size_t data_out_moved = 0;
int ret =
CCCrypt(kCCDecrypt, TSXEncryptorBlockCipherAlgo, TSXEncryptorBlockCipherOptions,
[_encryption_key bytes], TSXEncryptorBlockCipherKeySize, [encrypted_data bytes],
[encrypted_data bytes] + TSXEncryptorBlockCipherBlockSize,
[encrypted_data length] - TSXEncryptorBlockCipherBlockSize,
[plaintext_data mutableBytes], [plaintext_data length], &data_out_moved);
switch (ret)
{
case kCCSuccess:
[plaintext_data setLength:data_out_moved];
return plaintext_data;
case kCCBufferTooSmall: // Our output buffer is big enough to decrypt valid data. This
// return code indicates malformed data.
case kCCAlignmentError: // Shouldn't get this, since we're using padding.
case kCCDecodeError: // Wrong key.
return nil;
default:
NSLog(@"%s: uncaught error, ret CCCryptorStatus = %d (encrypted data len = %lu; buffer "
@"size = %lu; dom = %lu)",
__func__, ret, (unsigned long)[encrypted_data length],
(unsigned long)[plaintext_data length], data_out_moved);
return nil;
}
return nil;
}
- (NSData *)encryptString:(NSString *)plaintext_string
{
return [self encryptData:[plaintext_string dataUsingEncoding:NSUTF8StringEncoding]];
}
- (NSString *)decryptString:(NSData *)encrypted_string
{
return [[[NSString alloc] initWithData:[self decryptData:encrypted_string]
encoding:NSUTF8StringEncoding] autorelease];
}
- (NSData *)randomInitializationVector
{
NSMutableData *iv = [NSMutableData dataWithLength:TSXEncryptorBlockCipherBlockSize];
int fd;
if ((fd = open("/dev/urandom", O_RDONLY)) < 0)
return nil;
NSInteger bytes_needed = [iv length];
char *p = [iv mutableBytes];
while (bytes_needed)
{
long bytes_read = read(fd, p, bytes_needed);
if (bytes_read < 0)
continue;
p += bytes_read;
bytes_needed -= bytes_read;
}
close(fd);
return iv;
}
@end

View File

@@ -0,0 +1,30 @@
/*
Global default bookmark settings
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
@class ConnectionParams, ComputerBookmark;
@interface GlobalDefaults : NSObject
{
@private
ComputerBookmark *_default_bookmark;
}
+ (GlobalDefaults *)sharedGlobalDefaults;
// The same object is always returned from this method.
@property(readonly, nonatomic) ComputerBookmark *bookmark;
- (ConnectionParams *)newParams;
- (ComputerBookmark *)newBookmark;
- (ComputerBookmark *)newTestServerBookmark;
@end

View File

@@ -0,0 +1,88 @@
/*
Global default bookmark settings
Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "GlobalDefaults.h"
#import "Bookmark.h"
#import "ConnectionParams.h"
@implementation GlobalDefaults
+ (GlobalDefaults *)sharedGlobalDefaults
{
static GlobalDefaults *_shared_global_defaults = nil;
if (_shared_global_defaults == nil)
{
@synchronized(self)
{
if (_shared_global_defaults == nil)
_shared_global_defaults = [[GlobalDefaults alloc] init];
}
}
return _shared_global_defaults;
}
- (id)init
{
if (!(self = [super init]))
return nil;
ComputerBookmark *bookmark = nil;
NSData *bookmark_data =
[[NSUserDefaults standardUserDefaults] objectForKey:@"TSXSharedGlobalDefaultBookmark"];
if (bookmark_data && [bookmark_data length])
bookmark = [NSKeyedUnarchiver unarchiveObjectWithData:bookmark_data];
if (!bookmark)
bookmark = [[[ComputerBookmark alloc] initWithBaseDefaultParameters] autorelease];
_default_bookmark = [bookmark retain];
return self;
}
- (void)dealloc
{
[_default_bookmark release];
[super dealloc];
}
#pragma mark -
@synthesize bookmark = _default_bookmark;
- (ComputerBookmark *)newBookmark
{
return [[ComputerBookmark alloc] initWithConnectionParameters:[[self newParams] autorelease]];
}
- (ConnectionParams *)newParams
{
ConnectionParams *param_copy = [[[self bookmark] params] copy];
return param_copy;
}
- (ComputerBookmark *)newTestServerBookmark
{
ComputerBookmark *bm = [self newBookmark];
[bm setLabel:@"Test Server"];
[[bm params] setValue:@"testservice.ifreerdp.com" forKey:@"hostname"];
[[bm params] setInt:0 forKey:@"screen_resolution_type"];
[[bm params] setInt:1024 forKey:@"width"];
[[bm params] setInt:768 forKey:@"height"];
[[bm params] setInt:32 forKey:@"colors"];
[[bm params] setBool:YES forKey:@"perf_remotefx"];
[[bm params] setBool:YES forKey:@"perf_gfx"];
[[bm params] setBool:YES forKey:@"perf_h264"];
return bm;
}
@end

View File

@@ -0,0 +1,76 @@
/*
RDP Keyboard helper
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import "RDPSession.h"
@class RDPKeyboard;
@protocol RDPKeyboardDelegate <NSObject>
@optional
- (void)modifiersChangedForKeyboard:(RDPKeyboard *)keyboard;
@end
@interface RDPKeyboard : NSObject
{
RDPSession *_session;
int _virtual_key_map[256];
int _unicode_map[256];
NSDictionary *_special_keys;
NSObject<RDPKeyboardDelegate> *_delegate;
BOOL _ctrl_pressed;
BOOL _alt_pressed;
BOOL _shift_pressed;
BOOL _win_pressed;
}
@property(assign) id<RDPKeyboardDelegate> delegate;
@property(readonly) BOOL ctrlPressed;
@property(readonly) BOOL altPressed;
@property(readonly) BOOL shiftPressed;
@property(readonly) BOOL winPressed;
// returns a keyboard instance
+ (RDPKeyboard *)getSharedRDPKeyboard;
// init the keyboard and assign the given rdp session and delegate
- (void)initWithSession:(RDPSession *)session delegate:(NSObject<RDPKeyboardDelegate> *)delegate;
// called to reset any pending key states (i.e. pressed modifier keys)
- (void)reset;
// sends the given unicode character to the server
- (void)sendUnicode:(int)character;
// send a key stroke event using the given virtual key code
- (void)sendVirtualKeyCode:(int)keyCode;
// toggle ctrl key, returns true if pressed, otherwise false
- (void)toggleCtrlKey;
// toggle alt key, returns true if pressed, otherwise false
- (void)toggleAltKey;
// toggle shift key, returns true if pressed, otherwise false
- (void)toggleShiftKey;
// toggle windows key, returns true if pressed, otherwise false
- (void)toggleWinKey;
// send key strokes
- (void)sendEnterKeyStroke;
- (void)sendEscapeKeyStroke;
- (void)sendBackspaceKeyStroke;
@end

View File

@@ -0,0 +1,310 @@
/*
RDP Keyboard helper
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "RDPKeyboard.h"
#include <freerdp/locale/keyboard.h>
@interface RDPKeyboard (Private)
- (void)sendVirtualKey:(int)vKey up:(BOOL)up;
- (void)handleSpecialKey:(int)character;
- (void)handleAlphaNumChar:(int)character;
- (void)notifyDelegateModifiersChanged;
@end
@implementation RDPKeyboard
@synthesize delegate = _delegate, ctrlPressed = _ctrl_pressed, altPressed = _alt_pressed,
shiftPressed = _shift_pressed, winPressed = _win_pressed;
- (id)init
{
if ((self = [super init]) != nil)
{
[self initWithSession:nil delegate:nil];
memset(_virtual_key_map, 0, sizeof(_virtual_key_map));
memset(_unicode_map, 0, sizeof(_unicode_map));
// init vkey map - used for alpha-num characters
_virtual_key_map['0'] = VK_KEY_0;
_virtual_key_map['1'] = VK_KEY_1;
_virtual_key_map['2'] = VK_KEY_2;
_virtual_key_map['3'] = VK_KEY_3;
_virtual_key_map['4'] = VK_KEY_4;
_virtual_key_map['5'] = VK_KEY_5;
_virtual_key_map['6'] = VK_KEY_6;
_virtual_key_map['7'] = VK_KEY_7;
_virtual_key_map['8'] = VK_KEY_8;
_virtual_key_map['9'] = VK_KEY_9;
_virtual_key_map['a'] = VK_KEY_A;
_virtual_key_map['b'] = VK_KEY_B;
_virtual_key_map['c'] = VK_KEY_C;
_virtual_key_map['d'] = VK_KEY_D;
_virtual_key_map['e'] = VK_KEY_E;
_virtual_key_map['f'] = VK_KEY_F;
_virtual_key_map['g'] = VK_KEY_G;
_virtual_key_map['h'] = VK_KEY_H;
_virtual_key_map['i'] = VK_KEY_I;
_virtual_key_map['j'] = VK_KEY_J;
_virtual_key_map['k'] = VK_KEY_K;
_virtual_key_map['l'] = VK_KEY_L;
_virtual_key_map['m'] = VK_KEY_M;
_virtual_key_map['n'] = VK_KEY_N;
_virtual_key_map['o'] = VK_KEY_O;
_virtual_key_map['p'] = VK_KEY_P;
_virtual_key_map['q'] = VK_KEY_Q;
_virtual_key_map['r'] = VK_KEY_R;
_virtual_key_map['s'] = VK_KEY_S;
_virtual_key_map['t'] = VK_KEY_T;
_virtual_key_map['u'] = VK_KEY_U;
_virtual_key_map['v'] = VK_KEY_V;
_virtual_key_map['w'] = VK_KEY_W;
_virtual_key_map['x'] = VK_KEY_X;
_virtual_key_map['y'] = VK_KEY_Y;
_virtual_key_map['z'] = VK_KEY_Z;
// init scancode map - used for special characters
_unicode_map['-'] = 45;
_unicode_map['/'] = 47;
_unicode_map[':'] = 58;
_unicode_map[';'] = 59;
_unicode_map['('] = 40;
_unicode_map[')'] = 41;
_unicode_map['&'] = 38;
_unicode_map['@'] = 64;
_unicode_map['.'] = 46;
_unicode_map[','] = 44;
_unicode_map['?'] = 63;
_unicode_map['!'] = 33;
_unicode_map['\''] = 39;
_unicode_map['\"'] = 34;
_unicode_map['['] = 91;
_unicode_map[']'] = 93;
_unicode_map['{'] = 123;
_unicode_map['}'] = 125;
_unicode_map['#'] = 35;
_unicode_map['%'] = 37;
_unicode_map['^'] = 94;
_unicode_map['*'] = 42;
_unicode_map['+'] = 43;
_unicode_map['='] = 61;
_unicode_map['_'] = 95;
_unicode_map['\\'] = 92;
_unicode_map['|'] = 124;
_unicode_map['~'] = 126;
_unicode_map['<'] = 60;
_unicode_map['>'] = 62;
_unicode_map['$'] = 36;
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
#pragma mark -
#pragma mark class methods
// return a keyboard instance
+ (RDPKeyboard *)getSharedRDPKeyboard
{
static RDPKeyboard *_shared_keyboard = nil;
if (_shared_keyboard == nil)
{
@synchronized(self)
{
if (_shared_keyboard == nil)
_shared_keyboard = [[RDPKeyboard alloc] init];
}
}
return _shared_keyboard;
}
// reset the keyboard instance and assign the given rdp instance
- (void)initWithSession:(RDPSession *)session delegate:(NSObject<RDPKeyboardDelegate> *)delegate
{
_alt_pressed = NO;
_ctrl_pressed = NO;
_shift_pressed = NO;
_win_pressed = NO;
_session = session;
_delegate = delegate;
}
- (void)reset
{
// reset pressed ctrl, alt, shift or win key
if (_shift_pressed)
[self toggleShiftKey];
if (_alt_pressed)
[self toggleAltKey];
if (_ctrl_pressed)
[self toggleCtrlKey];
if (_win_pressed)
[self toggleWinKey];
}
// handles button pressed input event from the iOS keyboard
// performs all conversions etc.
- (void)sendUnicode:(int)character
{
if (isalnum(character))
[self handleAlphaNumChar:character];
else
[self handleSpecialKey:character];
[self reset];
}
// send a backspace key press
- (void)sendVirtualKeyCode:(int)keyCode
{
[self sendVirtualKey:keyCode up:NO];
[self sendVirtualKey:keyCode up:YES];
}
#pragma mark modifier key handling
// toggle ctrl key, returns true if pressed, otherwise false
- (void)toggleCtrlKey
{
[self sendVirtualKey:VK_LCONTROL up:_ctrl_pressed];
_ctrl_pressed = !_ctrl_pressed;
[self notifyDelegateModifiersChanged];
}
// toggle alt key, returns true if pressed, otherwise false
- (void)toggleAltKey
{
[self sendVirtualKey:VK_LMENU up:_alt_pressed];
_alt_pressed = !_alt_pressed;
[self notifyDelegateModifiersChanged];
}
// toggle shift key, returns true if pressed, otherwise false
- (void)toggleShiftKey
{
[self sendVirtualKey:VK_LSHIFT up:_shift_pressed];
_shift_pressed = !_shift_pressed;
[self notifyDelegateModifiersChanged];
}
// toggle windows key, returns true if pressed, otherwise false
- (void)toggleWinKey
{
[self sendVirtualKey:(VK_LWIN | KBDEXT) up:_win_pressed];
_win_pressed = !_win_pressed;
[self notifyDelegateModifiersChanged];
}
#pragma mark Sending special key strokes
- (void)sendEnterKeyStroke
{
[self sendVirtualKeyCode:(VK_RETURN | KBDEXT)];
}
- (void)sendEscapeKeyStroke
{
[self sendVirtualKeyCode:VK_ESCAPE];
}
- (void)sendBackspaceKeyStroke
{
[self sendVirtualKeyCode:VK_BACK];
}
@end
#pragma mark -
@implementation RDPKeyboard (Private)
- (void)handleAlphaNumChar:(int)character
{
// if we receive an uppercase letter - make it lower and send an shift down event to server
BOOL shift_was_sent = NO;
if (isupper(character) && _shift_pressed == NO)
{
character = tolower(character);
[self sendVirtualKey:VK_LSHIFT up:NO];
shift_was_sent = YES;
}
// convert the character to a VK
int vk = _virtual_key_map[character];
if (vk != 0)
{
// send key pressed
[self sendVirtualKey:vk up:NO];
[self sendVirtualKey:vk up:YES];
}
// send the missing shift up if we had a shift down
if (shift_was_sent)
[self sendVirtualKey:VK_LSHIFT up:YES];
}
- (void)handleSpecialKey:(int)character
{
NSDictionary *eventDescriptor = nil;
if (character < 256)
{
// convert the character to a unicode character
int code = _unicode_map[character];
if (code != 0)
eventDescriptor = [NSDictionary
dictionaryWithObjectsAndKeys:@"keyboard", @"type", @"unicode", @"subtype",
[NSNumber numberWithUnsignedShort:0], @"flags",
[NSNumber numberWithUnsignedShort:code],
@"unicode_char", nil];
}
if (eventDescriptor == nil)
eventDescriptor = [NSDictionary
dictionaryWithObjectsAndKeys:@"keyboard", @"type", @"unicode", @"subtype",
[NSNumber numberWithUnsignedShort:0], @"flags",
[NSNumber numberWithUnsignedShort:character],
@"unicode_char", nil];
[_session sendInputEvent:eventDescriptor];
}
// sends the vk code to the session
- (void)sendVirtualKey:(int)vKey up:(BOOL)up
{
DWORD scancode = GetVirtualScanCodeFromVirtualKeyCode(vKey, 4);
int flags = (up ? KBD_FLAGS_RELEASE : KBD_FLAGS_DOWN);
flags |= ((scancode & KBDEXT) ? KBD_FLAGS_EXTENDED : 0);
[_session
sendInputEvent:[NSDictionary
dictionaryWithObjectsAndKeys:@"keyboard", @"type", @"scancode",
@"subtype",
[NSNumber numberWithUnsignedShort:flags],
@"flags",
[NSNumber
numberWithUnsignedShort:(scancode &
0xFF)],
@"scancode", nil]];
}
- (void)notifyDelegateModifiersChanged
{
if ([[self delegate] respondsToSelector:@selector(modifiersChangedForKeyboard:)])
[[self delegate] modifiersChangedForKeyboard:self];
}
@end

View File

@@ -0,0 +1,109 @@
/*
RDP Session object
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#include <freerdp/freerdp.h>
// forward declaration
@class RDPSession;
@class ComputerBookmark;
@class ConnectionParams;
// notification handler for session disconnect
extern NSString *TSXSessionDidDisconnectNotification;
extern NSString *TSXSessionDidFailToConnectNotification;
// protocol for session notifications
@protocol RDPSessionDelegate <NSObject>
@optional
- (void)session:(RDPSession *)session didFailToConnect:(int)reason;
- (void)sessionWillConnect:(RDPSession *)session;
- (void)sessionDidConnect:(RDPSession *)session;
- (void)sessionWillDisconnect:(RDPSession *)session;
- (void)sessionDidDisconnect:(RDPSession *)session;
- (void)sessionBitmapContextWillChange:(RDPSession *)session;
- (void)sessionBitmapContextDidChange:(RDPSession *)session;
- (void)session:(RDPSession *)session needsRedrawInRect:(CGRect)rect;
- (CGSize)sizeForFitScreenForSession:(RDPSession *)session;
- (void)session:(RDPSession *)session
requestsAuthenticationWithParams:(NSMutableDictionary *)params;
- (void)session:(RDPSession *)session verifyCertificateWithParams:(NSMutableDictionary *)params;
@end
// rdp session
@interface RDPSession : NSObject
{
@private
freerdp *_freerdp;
ComputerBookmark *_bookmark;
ConnectionParams *_params;
NSObject<RDPSessionDelegate> *_delegate;
NSCondition *_ui_request_completed;
NSString *_name;
// flag if the session is suspended
BOOL _suspended;
// flag that specifies whether the RDP toolbar is visible
BOOL _toolbar_visible;
}
@property(readonly) ConnectionParams *params;
@property(readonly) ComputerBookmark *bookmark;
@property(assign) id<RDPSessionDelegate> delegate;
@property(assign) BOOL toolbarVisible;
@property(readonly) CGContextRef bitmapContext;
@property(readonly) NSCondition *uiRequestCompleted;
// initialize a new session with the given bookmark
- (id)initWithBookmark:(ComputerBookmark *)bookmark;
#pragma mark - session control functions
// connect the session
- (void)connect;
// disconnect session
- (void)disconnect;
// suspends the session
- (void)suspend;
// resumes a previously suspended session
- (void)resume;
// returns YES if the session is started
- (BOOL)isSuspended;
// send input event to the server
- (void)sendInputEvent:(NSDictionary *)event;
// session needs a refresh of its view
- (void)setNeedsDisplayInRectAsValue:(NSValue *)rect_value;
// get a small session screenshot
- (UIImage *)getScreenshotWithSize:(CGSize)size;
// returns the session's current parameters
- (rdpSettings *)getSessionParams;
// returns the session's name (usually the label of the bookmark the session was created with)
- (NSString *)sessionName;
@end

View File

@@ -0,0 +1,534 @@
/*
RDP Session object
Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at
http://mozilla.org/MPL/2.0/.
*/
#import "ios_freerdp.h"
#import "ios_freerdp_ui.h"
#import "ios_freerdp_events.h"
#import "RDPSession.h"
#import "TSXTypes.h"
#import "Bookmark.h"
#import "ConnectionParams.h"
NSString *TSXSessionDidDisconnectNotification = @"TSXSessionDidDisconnect";
NSString *TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect";
@interface RDPSession (Private)
- (void)runSession;
- (void)runSessionFinished:(NSNumber *)result;
- (mfInfo *)mfi;
// The connection thread calls these on the main thread.
- (void)sessionWillConnect;
- (void)sessionDidConnect;
- (void)sessionDidDisconnect;
- (void)sessionDidFailToConnect:(int)reason;
- (void)sessionBitmapContextWillChange;
- (void)sessionBitmapContextDidChange;
@end
@implementation RDPSession
@synthesize delegate = _delegate, params = _params, toolbarVisible = _toolbar_visible,
uiRequestCompleted = _ui_request_completed, bookmark = _bookmark;
+ (void)initialize
{
ios_init_freerdp();
}
static BOOL addArgument(int *argc, char ***argv, const char *fmt, ...)
{
va_list ap = WINPR_C_ARRAY_INIT;
char *arg = nullptr;
char **tmp = realloc(*argv, (*argc + 1) * sizeof(char *));
if (!tmp)
return FALSE;
*argv = tmp;
*argc = *argc + 1;
va_start(ap, fmt);
vasprintf(&arg, fmt, ap);
va_end(ap);
(*argv)[*argc - 1] = arg;
return TRUE;
}
static BOOL addFlag(int *argc, char ***argv, const char *str, BOOL flag)
{
return addArgument(argc, argv, "%s%s", flag ? "+" : "-", str);
}
static void freeArguments(int argc, char **argv)
{
for (int i = 0; i < argc; i++)
free(argv[i]);
free(argv);
}
// Designated initializer.
- (id)initWithBookmark:(ComputerBookmark *)bookmark
{
int status;
char **argv = nullptr;
int argc = 0;
if (!(self = [super init]))
return nil;
if (!bookmark)
[NSException raise:NSInvalidArgumentException
format:@"%s: params may not be nil.", __func__];
_bookmark = [bookmark retain];
_params = [[bookmark params] copy];
_name = [[bookmark label] retain];
_delegate = nil;
_toolbar_visible = YES;
_freerdp = ios_freerdp_new();
_ui_request_completed = [[NSCondition alloc] init];
BOOL connected_via_3g = ![bookmark conntectedViaWLAN];
if (!addArgument(&argc, &argv, "iFreeRDP"))
goto out_free;
if (!addArgument(&argc, &argv, "/gdi:sw"))
goto out_free;
// Screen Size is set on connect (we need a valid delegate in case the user choose an automatic
// screen size)
// Other simple numeric settings
if ([_params hasValueForKey:@"colors"])
if (!addArgument(&argc, &argv, "/bpp:%d",
[_params intForKey:@"colors" with3GEnabled:connected_via_3g]))
goto out_free;
if ([_params hasValueForKey:@"port"])
if (!addArgument(&argc, &argv, "/port:%d", [_params intForKey:@"port"]))
goto out_free;
if ([_params boolForKey:@"console"])
if (!addArgument(&argc, &argv, "/admin"))
goto out_free;
if (!addArgument(&argc, &argv, "/v:%s", [_params UTF8StringForKey:@"hostname"]))
goto out_free;
// String settings
if ([[_params StringForKey:@"username"] length])
{
if (!addArgument(&argc, &argv, "/u:%s", [_params UTF8StringForKey:@"username"]))
goto out_free;
}
if ([[_params StringForKey:@"password"] length])
{
if (!addArgument(&argc, &argv, "/p:%s", [_params UTF8StringForKey:@"password"]))
goto out_free;
}
if ([[_params StringForKey:@"domain"] length])
{
if (!addArgument(&argc, &argv, "/d:%s", [_params UTF8StringForKey:@"domain"]))
goto out_free;
}
if ([[_params StringForKey:@"working_directory"] length])
{
if (!addArgument(&argc, &argv, "/shell-dir:%s",
[_params UTF8StringForKey:@"working_directory"]))
goto out_free;
}
if ([[_params StringForKey:@"remote_program"] length])
{
if (!addArgument(&argc, &argv, "/shell:%s", [_params UTF8StringForKey:@"remote_program"]))
goto out_free;
}
// RemoteFX
if ([_params boolForKey:@"perf_remotefx" with3GEnabled:connected_via_3g])
if (!addArgument(&argc, &argv, "/rfx"))
goto out_free;
if ([_params boolForKey:@"perf_gfx" with3GEnabled:connected_via_3g])
if (!addArgument(&argc, &argv, "/gfx"))
goto out_free;
if ([_params boolForKey:@"perf_h264" with3GEnabled:connected_via_3g])
if (!addArgument(&argc, &argv, "/gfx-h264"))
goto out_free;
if (![_params boolForKey:@"perf_remotefx" with3GEnabled:connected_via_3g] &&
![_params boolForKey:@"perf_gfx" with3GEnabled:connected_via_3g] &&
![_params boolForKey:@"perf_h264" with3GEnabled:connected_via_3g])
if (!addArgument(&argc, &argv, "/nsc"))
goto out_free;
if (!addFlag(&argc, &argv, "bitmap-cache", TRUE))
goto out_free;
if (!addFlag(&argc, &argv, "wallpaper",
[_params boolForKey:@"perf_show_desktop" with3GEnabled:connected_via_3g]))
goto out_free;
if (!addFlag(&argc, &argv, "window-drag",
[_params boolForKey:@"perf_window_dragging" with3GEnabled:connected_via_3g]))
goto out_free;
if (!addFlag(&argc, &argv, "menu-anims",
[_params boolForKey:@"perf_menu_animation" with3GEnabled:connected_via_3g]))
goto out_free;
if (!addFlag(&argc, &argv, "themes",
[_params boolForKey:@"perf_windows_themes" with3GEnabled:connected_via_3g]))
goto out_free;
if (!addFlag(&argc, &argv, "fonts",
[_params boolForKey:@"perf_font_smoothing" with3GEnabled:connected_via_3g]))
goto out_free;
if (!addFlag(&argc, &argv, "aero",
[_params boolForKey:@"perf_desktop_composition" with3GEnabled:connected_via_3g]))
goto out_free;
if ([_params hasValueForKey:@"width"])
if (!addArgument(&argc, &argv, "/w:%d", [_params intForKey:@"width"]))
goto out_free;
if ([_params hasValueForKey:@"height"])
if (!addArgument(&argc, &argv, "/h:%d", [_params intForKey:@"height"]))
goto out_free;
// security
switch ([_params intForKey:@"security"])
{
case TSXProtocolSecurityNLA:
if (!addArgument(&argc, &argv, "/sec:NLA"))
goto out_free;
break;
case TSXProtocolSecurityTLS:
if (!addArgument(&argc, &argv, "/sec:TLS"))
goto out_free;
break;
case TSXProtocolSecurityRDP:
if (!addArgument(&argc, &argv, "/sec:RDP"))
goto out_free;
break;
default:
break;
}
// ts gateway settings
if ([_params boolForKey:@"enable_tsg_settings"])
{
if (!addArgument(&argc, &argv, "/g:%s", [_params UTF8StringForKey:@"tsg_hostname"]))
goto out_free;
if (!addArgument(&argc, &argv, "/gp:%d", [_params intForKey:@"tsg_port"]))
goto out_free;
if (!addArgument(&argc, &argv, "/gu:%s", [_params intForKey:@"tsg_username"]))
goto out_free;
if (!addArgument(&argc, &argv, "/gp:%s", [_params intForKey:@"tsg_password"]))
goto out_free;
if (!addArgument(&argc, &argv, "/gd:%s", [_params intForKey:@"tsg_domain"]))
goto out_free;
}
// Remote keyboard layout
if (!addArgument(&argc, &argv, "/kbd:%d", 0x409))
goto out_free;
status =
freerdp_client_settings_parse_command_line(_freerdp->context->settings, argc, argv, FALSE);
if (0 != status)
goto out_free;
freeArguments(argc, argv);
[self mfi]->session = self;
return self;
out_free:
freeArguments(argc, argv);
[self release];
return nil;
}
- (void)dealloc
{
[self setDelegate:nil];
[_bookmark release];
[_name release];
[_params release];
[_ui_request_completed release];
ios_freerdp_free(_freerdp);
[super dealloc];
}
- (CGContextRef)bitmapContext
{
return [self mfi]->bitmap_context;
}
#pragma mark -
#pragma mark Connecting and disconnecting
- (void)connect
{
// Set Screen Size to automatic if width or height are still 0
rdpSettings *settings = _freerdp->context->settings;
if (freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth) == 0 ||
freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight) == 0)
{
CGSize size = CGSizeZero;
if ([[self delegate] respondsToSelector:@selector(sizeForFitScreenForSession:)])
size = [[self delegate] sizeForFitScreenForSession:self];
if (!CGSizeEqualToSize(CGSizeZero, size))
{
[_params setInt:size.width forKey:@"width"];
[_params setInt:size.height forKey:@"height"];
(void)freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, size.width);
(void)freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, size.height);
}
}
// TODO: This is a hack to ensure connections to RDVH with 16bpp don't have an odd screen
// resolution width
// Otherwise this could result in screen corruption ..
if (freerdp_settings_get_uint32(settings, FreeRDP_ColorDepth) <= 16)
{
const UINT32 w = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth) & (~1);
(void)freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth, w);
}
[self performSelectorInBackground:@selector(runSession) withObject:nil];
}
- (void)disconnect
{
mfInfo *mfi = [self mfi];
ios_events_send(mfi, [NSDictionary dictionaryWithObject:@"disconnect" forKey:@"type"]);
if (mfi->connection_state == TSXConnectionConnecting)
{
mfi->unwanted = YES;
[self sessionDidDisconnect];
return;
}
}
- (TSXConnectionState)connectionState
{
return [self mfi]->connection_state;
}
// suspends the session
- (void)suspend
{
if (!_suspended)
{
_suspended = YES;
// instance->update->SuppressOutput(instance->context, 0, nullptr);
}
}
// resumes a previously suspended session
- (void)resume
{
if (_suspended)
{
/* RECTANGLE_16 rec;
rec.left = 0;
rec.top = 0;
rec.right = freerdp_settings_get_uint32(instance->settings, FreeRDP_DesktopWidth);
rec.bottom = freerdp_settings_get_uint32(instance->settings, FreeRDP_DesktopHeight);
*/
_suspended = NO;
// instance->update->SuppressOutput(instance->context, 1, &rec);
// [delegate sessionScreenSettingsChanged:self];
}
}
// returns YES if the session is started
- (BOOL)isSuspended
{
return _suspended;
}
#pragma mark -
#pragma mark Input events
- (void)sendInputEvent:(NSDictionary *)eventDescriptor
{
if ([self mfi]->connection_state == TSXConnectionConnected)
ios_events_send([self mfi], eventDescriptor);
}
#pragma mark -
#pragma mark Server events (main thread)
- (void)setNeedsDisplayInRectAsValue:(NSValue *)rect_value
{
if ([[self delegate] respondsToSelector:@selector(session:needsRedrawInRect:)])
[[self delegate] session:self needsRedrawInRect:[rect_value CGRectValue]];
}
#pragma mark -
#pragma mark interface functions
- (UIImage *)getScreenshotWithSize:(CGSize)size
{
NSAssert([self mfi]->bitmap_context != nil,
@"Screenshot requested while having no valid RDP drawing context");
CGImageRef cgImage = CGBitmapContextCreateImage([self mfi]->bitmap_context);
UIGraphicsBeginImageContext(size);
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, size.height);
CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height),
cgImage);
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(cgImage);
return viewImage;
}
- (rdpSettings *)getSessionParams
{
return _freerdp->context->settings;
}
- (NSString *)sessionName
{
return _name;
}
@end
#pragma mark -
@implementation RDPSession (Private)
- (mfInfo *)mfi
{
return MFI_FROM_INSTANCE(_freerdp);
}
// Blocks until rdp session finishes.
- (void)runSession
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Run the session
[self performSelectorOnMainThread:@selector(sessionWillConnect)
withObject:nil
waitUntilDone:YES];
int result_code = ios_run_freerdp(_freerdp);
[self mfi]->connection_state = TSXConnectionDisconnected;
[self performSelectorOnMainThread:@selector(runSessionFinished:)
withObject:[NSNumber numberWithInt:result_code]
waitUntilDone:YES];
[pool release];
}
// Main thread.
- (void)runSessionFinished:(NSNumber *)result
{
int result_code = [result intValue];
switch (result_code)
{
case MF_EXIT_CONN_CANCELED:
[self sessionDidDisconnect];
break;
case MF_EXIT_LOGON_TIMEOUT:
case MF_EXIT_CONN_FAILED:
[self sessionDidFailToConnect:result_code];
break;
case MF_EXIT_SUCCESS:
default:
[self sessionDidDisconnect];
break;
}
}
#pragma mark -
#pragma mark Session management (main thread)
- (void)sessionWillConnect
{
if ([[self delegate] respondsToSelector:@selector(sessionWillConnect:)])
[[self delegate] sessionWillConnect:self];
}
- (void)sessionDidConnect
{
if ([[self delegate] respondsToSelector:@selector(sessionDidConnect:)])
[[self delegate] sessionDidConnect:self];
}
- (void)sessionDidFailToConnect:(int)reason
{
[[NSNotificationCenter defaultCenter]
postNotificationName:TSXSessionDidFailToConnectNotification
object:self];
if ([[self delegate] respondsToSelector:@selector(session:didFailToConnect:)])
[[self delegate] session:self didFailToConnect:reason];
}
- (void)sessionDidDisconnect
{
[[NSNotificationCenter defaultCenter] postNotificationName:TSXSessionDidDisconnectNotification
object:self];
if ([[self delegate] respondsToSelector:@selector(sessionDidDisconnect:)])
[[self delegate] sessionDidDisconnect:self];
}
- (void)sessionBitmapContextWillChange
{
if ([[self delegate] respondsToSelector:@selector(sessionBitmapContextWillChange:)])
[[self delegate] sessionBitmapContextWillChange:self];
}
- (void)sessionBitmapContextDidChange
{
if ([[self delegate] respondsToSelector:@selector(sessionBitmapContextDidChange:)])
[[self delegate] sessionBitmapContextDidChange:self];
}
- (void)sessionRequestsAuthenticationWithParams:(NSMutableDictionary *)params
{
if ([[self delegate] respondsToSelector:@selector(session:requestsAuthenticationWithParams:)])
[[self delegate] session:self requestsAuthenticationWithParams:params];
}
- (void)sessionVerifyCertificateWithParams:(NSMutableDictionary *)params
{
if ([[self delegate] respondsToSelector:@selector(session:verifyCertificateWithParams:)])
[[self delegate] session:self verifyCertificateWithParams:params];
}
@end

View File

@@ -0,0 +1,3 @@
set(FREERDP_CLIENT_NAME "ifreerdp")
set(FREERDP_CLIENT_PLATFORM "iOS")
set(FREERDP_CLIENT_VENDOR "FreeRDP")

View File

@@ -0,0 +1,365 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITableView</string>
<string>IBUIView</string>
<string>IBUISearchBar</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUITableView" id="589060229">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{0, 44}, {320, 416}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="72664573"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">10</int>
<object class="NSImage" key="NSImage">
<int key="NSImageFlags">549453824</int>
<string key="NSSize">{512, 1}</string>
<array class="NSMutableArray" key="NSReps">
<array>
<integer value="0"/>
<object class="NSBitmapImageRep">
<object class="NSData" key="NSTIFFRepresentation">
<bytes key="NS.bytes">TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA
AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA
AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI
AAgACAAIAAEAAQABAAE</bytes>
</object>
</object>
</array>
</array>
<object class="NSColor" key="NSColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
</object>
<string key="IBUIColorCocoaTouchKeyPath">groupTableViewBackgroundColor</string>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIAlwaysBounceVertical">YES</bool>
<int key="IBUIStyle">1</int>
<int key="IBUISeparatorStyle">2</int>
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
<float key="IBUIRowHeight">44</float>
<float key="IBUISectionHeaderHeight">10</float>
<float key="IBUISectionFooterHeight">10</float>
</object>
<object class="IBUISearchBar" id="72664573">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">290</int>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<int key="IBUIContentMode">3</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="IBUITextInputTraits" key="IBTextInputTraits">
<int key="IBUIAutocorrectionType">1</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="589060229"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">tableView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="589060229"/>
</object>
<int key="connectionID">6</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">searchBar</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="72664573"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="589060229"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">8</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="589060229"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">9</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="72664573"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">10</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="589060229"/>
<reference ref="72664573"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="589060229"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="72664573"/>
<reference key="parent" ref="191373211"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">BookmarkListController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">10</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">BookmarkListController</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="bmTableCell">BookmarkTableCell</string>
<string key="searchBar">UISearchBar</string>
<string key="sessTableCell">SessionsTableCell</string>
<string key="tableView">UITableView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="bmTableCell">
<string key="name">bmTableCell</string>
<string key="candidateClassName">BookmarkTableCell</string>
</object>
<object class="IBToOneOutletInfo" key="searchBar">
<string key="name">searchBar</string>
<string key="candidateClassName">UISearchBar</string>
</object>
<object class="IBToOneOutletInfo" key="sessTableCell">
<string key="name">sessTableCell</string>
<string key="candidateClassName">SessionsTableCell</string>
</object>
<object class="IBToOneOutletInfo" key="tableView">
<string key="name">tableView</string>
<string key="candidateClassName">UITableView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/BookmarkListController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">BookmarkTableCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_connection_state_icon">UIImageView</string>
<string key="_sub_title">UILabel</string>
<string key="_title">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_connection_state_icon">
<string key="name">_connection_state_icon</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo" key="_sub_title">
<string key="name">_sub_title</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_title">
<string key="name">_title</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/BookmarkTableCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">SessionsTableCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_disconnect_button">UIButton</string>
<string key="_screenshot">UIImageView</string>
<string key="_server">UILabel</string>
<string key="_title">UILabel</string>
<string key="_username">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_disconnect_button">
<string key="name">_disconnect_button</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="_screenshot">
<string key="name">_screenshot</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo" key="_server">
<string key="name">_server</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_title">
<string key="name">_title</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_username">
<string key="name">_username</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/SessionsTableCell.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,428 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>IBProxyObject</string>
<string>IBUILabel</string>
<string>IBUITableViewCell</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBUITableViewCell" id="581303870">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIView" id="806623018">
<reference key="NSNextResponder" ref="581303870"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUILabel" id="915789886">
<reference key="NSNextResponder" ref="806623018"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{20, 2}, {267, 21}}</string>
<reference key="NSSuperview" ref="806623018"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="74446343"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor" id="782525937">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor" id="549211185">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">18</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">18</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUILabel" id="74446343">
<reference key="NSNextResponder" ref="806623018"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{20, 20}, {267, 21}}</string>
<reference key="NSSuperview" ref="806623018"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<string key="IBUIText">Label</string>
<reference key="IBUITextColor" ref="782525937"/>
<reference key="IBUIHighlightedColor" ref="549211185"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">14</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">14</double>
<int key="NSfFlags">16</int>
</object>
</object>
</object>
<string key="NSFrameSize">{287, 43}</string>
<reference key="NSSuperview" ref="581303870"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="915789886"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="806623018"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIAccessoryType">2</int>
<reference key="IBUIContentView" ref="806623018"/>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">bmTableCell</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="581303870"/>
</object>
<int key="connectionID">23</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_sub_title</string>
<reference key="source" ref="581303870"/>
<reference key="destination" ref="74446343"/>
</object>
<int key="connectionID">21</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_title</string>
<reference key="source" ref="581303870"/>
<reference key="destination" ref="915789886"/>
</object>
<int key="connectionID">22</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">18</int>
<reference key="object" ref="581303870"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="915789886"/>
<reference ref="74446343"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">19</int>
<reference key="object" ref="915789886"/>
<reference key="parent" ref="581303870"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="74446343"/>
<reference key="parent" ref="581303870"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-1.IBPluginDependency</string>
<string>-2.CustomClassName</string>
<string>-2.IBPluginDependency</string>
<string>18.CustomClassName</string>
<string>18.IBPluginDependency</string>
<string>19.IBPluginDependency</string>
<string>20.IBPluginDependency</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>BookmarkListController</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>UIResponder</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>BookmarkTableCell</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">23</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">BookmarkListController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>bmTableCell</string>
<string>searchBar</string>
<string>sessTableCell</string>
<string>tableView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>BookmarkTableCell</string>
<string>UISearchBar</string>
<string>SessionTableCell</string>
<string>UITableView</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>bmTableCell</string>
<string>searchBar</string>
<string>sessTableCell</string>
<string>tableView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">bmTableCell</string>
<string key="candidateClassName">BookmarkTableCell</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchBar</string>
<string key="candidateClassName">UISearchBar</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">sessTableCell</string>
<string key="candidateClassName">SessionTableCell</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">tableView</string>
<string key="candidateClassName">UITableView</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/BookmarkListController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">BookmarkTableCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_connection_state_icon</string>
<string>_sub_title</string>
<string>_title</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIImageView</string>
<string>UILabel</string>
<string>UILabel</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_connection_state_icon</string>
<string>_sub_title</string>
<string>_title</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">_connection_state_icon</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_sub_title</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_title</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/BookmarkTableCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">SessionTableCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_disconnect_button</string>
<string>_screenshot</string>
<string>_server</string>
<string>_title</string>
<string>_username</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIButton</string>
<string>UIImageView</string>
<string>UILabel</string>
<string>UILabel</string>
<string>UILabel</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_disconnect_button</string>
<string>_screenshot</string>
<string>_server</string>
<string>_title</string>
<string>_username</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">_disconnect_button</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_screenshot</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_server</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_title</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_username</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/SessionTableCell.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
<integer value="3100" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,481 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>IBUITextField</string>
<string>IBUILabel</string>
<string>IBUIButton</string>
<string>IBUIView</string>
<string>IBUIScrollView</string>
<string>IBProxyObject</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="234977634">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIScrollView" id="76355032">
<reference key="NSNextResponder" ref="234977634"/>
<int key="NSvFlags">279</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUITextField" id="502350293">
<reference key="NSNextResponder" ref="76355032"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{15, 112}, {210, 31}}</string>
<reference key="NSSuperview" ref="76355032"/>
<reference key="NSNextKeyView" ref="407758879"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText"/>
<int key="IBUIBorderStyle">3</int>
<string key="IBUIPlaceholder">Username</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace" id="1055564775">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<int key="IBUIClearButtonMode">3</int>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="72634085">
<int key="type">1</int>
<double key="pointSize">12</double>
</object>
<object class="NSFont" key="IBUIFont" id="168483421">
<string key="NSName">Helvetica</string>
<double key="NSSize">12</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUITextField" id="407758879">
<reference key="NSNextResponder" ref="76355032"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{15, 161}, {210, 31}}</string>
<reference key="NSSuperview" ref="76355032"/>
<reference key="NSNextKeyView" ref="316210701"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText"/>
<int key="IBUIBorderStyle">3</int>
<string key="IBUIPlaceholder">Password</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<reference key="NSCustomColorSpace" ref="1055564775"/>
</object>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<bool key="IBUISecureTextEntry">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<int key="IBUIClearButtonMode">3</int>
<reference key="IBUIFontDescription" ref="72634085"/>
<reference key="IBUIFont" ref="168483421"/>
</object>
<object class="IBUITextField" id="316210701">
<reference key="NSNextResponder" ref="76355032"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{15, 210}, {210, 31}}</string>
<reference key="NSSuperview" ref="76355032"/>
<reference key="NSNextKeyView" ref="266626143"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText"/>
<int key="IBUIBorderStyle">3</int>
<string key="IBUIPlaceholder">Domain</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<reference key="NSCustomColorSpace" ref="1055564775"/>
</object>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<int key="IBUIClearButtonMode">3</int>
<reference key="IBUIFontDescription" ref="72634085"/>
<reference key="IBUIFont" ref="168483421"/>
</object>
<object class="IBUIButton" id="67582393">
<reference key="NSNextResponder" ref="76355032"/>
<int key="NSvFlags">291</int>
<string key="NSFrame">{{130, 263}, {95, 37}}</string>
<reference key="NSSuperview" ref="76355032"/>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<string key="IBUINormalTitle">Cancel</string>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="484131582">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor" id="210891822">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="223796057">
<string key="name">Helvetica-Bold</string>
<string key="family">Helvetica</string>
<int key="traits">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont" id="1043513320">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="266626143">
<reference key="NSNextResponder" ref="76355032"/>
<int key="NSvFlags">294</int>
<string key="NSFrame">{{15, 263}, {95, 37}}</string>
<reference key="NSSuperview" ref="76355032"/>
<reference key="NSNextKeyView" ref="67582393"/>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<string key="IBUINormalTitle">Login</string>
<reference key="IBUIHighlightedTitleColor" ref="484131582"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="210891822"/>
<reference key="IBUIFontDescription" ref="223796057"/>
<reference key="IBUIFont" ref="1043513320"/>
</object>
<object class="IBUILabel" id="876100682">
<reference key="NSNextResponder" ref="76355032"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{15, 20}, {210, 71}}</string>
<reference key="NSSuperview" ref="76355032"/>
<reference key="NSNextKeyView" ref="502350293"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Please provide the missing user information in order to proceed and login.</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUINumberOfLines">3</int>
<int key="IBUILineBreakMode">0</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
</object>
<string key="NSFrameSize">{240, 320}</string>
<reference key="NSSuperview" ref="234977634"/>
<reference key="NSNextKeyView" ref="876100682"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIClipsSubviews">YES</bool>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
<string key="NSFrameSize">{240, 320}</string>
<reference key="NSSuperview"/>
<reference key="NSNextKeyView" ref="76355032"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<reference key="NSCustomColorSpace" ref="1055564775"/>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="234977634"/>
</object>
<int key="connectionID">41</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_scroll_view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="76355032"/>
</object>
<int key="connectionID">42</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_textfield_username</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="502350293"/>
</object>
<int key="connectionID">34</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_textfield_password</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="407758879"/>
</object>
<int key="connectionID">33</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_textfield_domain</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="316210701"/>
</object>
<int key="connectionID">32</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_btn_cancel</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="67582393"/>
</object>
<int key="connectionID">30</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_btn_login</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="266626143"/>
</object>
<int key="connectionID">31</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_lbl_message</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="876100682"/>
</object>
<int key="connectionID">43</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">cancelPressed:</string>
<reference key="source" ref="67582393"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">36</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">loginPressed:</string>
<reference key="source" ref="266626143"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">37</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">40</int>
<reference key="object" ref="234977634"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="76355032"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">38</int>
<reference key="object" ref="76355032"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="876100682"/>
<reference ref="266626143"/>
<reference ref="67582393"/>
<reference ref="502350293"/>
<reference ref="316210701"/>
<reference ref="407758879"/>
</object>
<reference key="parent" ref="234977634"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="502350293"/>
<reference key="parent" ref="76355032"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="407758879"/>
<reference key="parent" ref="76355032"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="316210701"/>
<reference key="parent" ref="76355032"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="67582393"/>
<reference key="parent" ref="76355032"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="266626143"/>
<reference key="parent" ref="76355032"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">11</int>
<reference key="object" ref="876100682"/>
<reference key="parent" ref="76355032"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-1.IBPluginDependency</string>
<string>-2.CustomClassName</string>
<string>-2.IBAttributePlaceholdersKey</string>
<string>-2.IBPluginDependency</string>
<string>10.IBPluginDependency</string>
<string>11.IBPluginDependency</string>
<string>20.IBPluginDependency</string>
<string>3.IBPluginDependency</string>
<string>38.IBPluginDependency</string>
<string>40.IBPluginDependency</string>
<string>5.IBPluginDependency</string>
<string>7.IBPluginDependency</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>CredentialsInputController</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>UIResponder</string>
<object class="NSMutableDictionary">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">43</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
<integer value="3100" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -0,0 +1,408 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITableViewCell</string>
<string>IBUIButton</string>
<string>IBUILabel</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableViewCell" id="899919877">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="209421689">
<reference key="NSNextResponder" ref="899919877"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUILabel" id="1032585218">
<reference key="NSNextResponder" ref="209421689"/>
<int key="NSvFlags">298</int>
<string key="NSFrame">{{12, 10}, {218, 25}}</string>
<reference key="NSSuperview" ref="209421689"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="866724112"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor" id="729087361">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUIButton" id="866724112">
<reference key="NSNextResponder" ref="209421689"/>
<int key="NSvFlags">297</int>
<string key="NSFrame">{{252, 6}, {58, 31}}</string>
<reference key="NSSuperview" ref="209421689"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<reference key="IBUIHighlightedTitleColor" ref="729087361"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrameSize">{320, 43}</string>
<reference key="NSSuperview" ref="899919877"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="1032585218"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="209421689"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<reference key="IBUIContentView" ref="209421689"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_buttonTableViewCell</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="899919877"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_button</string>
<reference key="source" ref="899919877"/>
<reference key="destination" ref="866724112"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label</string>
<reference key="source" ref="899919877"/>
<reference key="destination" ref="1032585218"/>
</object>
<int key="connectionID">6</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="899919877"/>
<array class="NSMutableArray" key="children">
<reference ref="1032585218"/>
<reference ref="866724112"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="1032585218"/>
<reference key="parent" ref="899919877"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="866724112"/>
<reference key="parent" ref="899919877"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">EditorBaseController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.CustomClassName">EditButtonTableViewCell</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">7</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">EditButtonTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_button">UIButton</string>
<string key="_label">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_button">
<string key="name">_button</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditButtonTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditFlagTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_toggle">UISwitch</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_toggle">
<string key="name">_toggle</string>
<string key="candidateClassName">UISwitch</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditFlagTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditSecretTextTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_textfield">UITextField</string>
<string key="_unhide_button">UIButton</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_textfield">
<string key="name">_textfield</string>
<string key="candidateClassName">UITextField</string>
</object>
<object class="IBToOneOutletInfo" key="_unhide_button">
<string key="name">_unhide_button</string>
<string key="candidateClassName">UIButton</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditSecretTextTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditSelectionTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_selection">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_selection">
<string key="name">_selection</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditSelectionTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditSubEditTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">_label</string>
<string key="NS.object.0">UILabel</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">_label</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditSubEditTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditTextTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_textfield">UITextField</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_textfield">
<string key="name">_textfield</string>
<string key="candidateClassName">UITextField</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditTextTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditorBaseController</string>
<string key="superclassName">UITableViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_buttonTableViewCell">EditButtonTableViewCell</string>
<string key="_flagTableViewCell">EditFlagTableViewCell</string>
<string key="_secretTextTableViewCell">EditSecretTextTableViewCell</string>
<string key="_selectionTableViewCell">EditSelectionTableViewCell</string>
<string key="_subEditTableViewCell">EditSubEditTableViewCell</string>
<string key="_textTableViewCell">EditTextTableViewCell</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_buttonTableViewCell">
<string key="name">_buttonTableViewCell</string>
<string key="candidateClassName">EditButtonTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_flagTableViewCell">
<string key="name">_flagTableViewCell</string>
<string key="candidateClassName">EditFlagTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_secretTextTableViewCell">
<string key="name">_secretTextTableViewCell</string>
<string key="candidateClassName">EditSecretTextTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_selectionTableViewCell">
<string key="name">_selectionTableViewCell</string>
<string key="candidateClassName">EditSelectionTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_subEditTableViewCell">
<string key="name">_subEditTableViewCell</string>
<string key="candidateClassName">EditSubEditTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_textTableViewCell">
<string key="name">_textTableViewCell</string>
<string key="candidateClassName">EditTextTableViewCell</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditorBaseController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITableViewCell</string>
<string>IBUISwitch</string>
<string>IBUILabel</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableViewCell" id="310994250">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="672481111">
<reference key="NSNextResponder" ref="310994250"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUILabel" id="165861018">
<reference key="NSNextResponder" ref="672481111"/>
<int key="NSvFlags">298</int>
<string key="NSFrame">{{10, 10}, {214, 25}}</string>
<reference key="NSSuperview" ref="672481111"/>
<reference key="NSNextKeyView" ref="801003579"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUISwitch" id="801003579">
<reference key="NSNextResponder" ref="672481111"/>
<int key="NSvFlags">297</int>
<string key="NSFrame">{{217, 8}, {94, 27}}</string>
<reference key="NSSuperview" ref="672481111"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<bool key="IBUIOn">YES</bool>
</object>
</array>
<string key="NSFrameSize">{320, 43}</string>
<reference key="NSSuperview" ref="310994250"/>
<reference key="NSNextKeyView" ref="165861018"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSNextKeyView" ref="672481111"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUISelectionStyle">0</int>
<reference key="IBUIContentView" ref="672481111"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_flagTableViewCell</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="310994250"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label</string>
<reference key="source" ref="310994250"/>
<reference key="destination" ref="165861018"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_toggle</string>
<reference key="source" ref="310994250"/>
<reference key="destination" ref="801003579"/>
</object>
<int key="connectionID">6</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="310994250"/>
<array class="NSMutableArray" key="children">
<reference ref="801003579"/>
<reference ref="165861018"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="165861018"/>
<reference key="parent" ref="310994250"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="801003579"/>
<reference key="parent" ref="310994250"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">EditorBaseController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.CustomClassName">EditFlagTableViewCell</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">7</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,288 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITableViewCell</string>
<string>IBUIButton</string>
<string>IBUILabel</string>
<string>IBUITextField</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableViewCell" id="955840644">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="667249610">
<reference key="NSNextResponder" ref="955840644"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUILabel" id="788635611">
<reference key="NSNextResponder" ref="667249610"/>
<int key="NSvFlags">300</int>
<string key="NSFrame">{{10, 10}, {100, 25}}</string>
<reference key="NSSuperview" ref="667249610"/>
<reference key="NSNextKeyView" ref="739180901"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor" id="507782670">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUITextField" id="739180901">
<reference key="NSNextResponder" ref="667249610"/>
<int key="NSvFlags">298</int>
<string key="NSFrame">{{120, 10}, {150, 25}}</string>
<reference key="NSSuperview" ref="667249610"/>
<reference key="NSNextKeyView" ref="932654538"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText">Test</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocorrectionType">1</int>
<bool key="IBUISecureTextEntry">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<int key="IBUIClearButtonMode">3</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="932654538">
<reference key="NSNextResponder" ref="667249610"/>
<int key="NSvFlags">297</int>
<string key="NSFrame">{{270, 10}, {50, 25}}</string>
<reference key="NSSuperview" ref="667249610"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUINormalTitle">Unhide</string>
<reference key="IBUIHighlightedTitleColor" ref="507782670"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzE0IDAuMzA5ODAzOTIxNiAwLjUyMTU2ODYyNzUAA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrameSize">{320, 43}</string>
<reference key="NSSuperview" ref="955840644"/>
<reference key="NSNextKeyView" ref="788635611"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSNextKeyView" ref="667249610"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUISelectionStyle">0</int>
<reference key="IBUIContentView" ref="667249610"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_secretTextTableViewCell</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="955840644"/>
</object>
<int key="connectionID">9</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label</string>
<reference key="source" ref="955840644"/>
<reference key="destination" ref="788635611"/>
</object>
<int key="connectionID">6</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_textfield</string>
<reference key="source" ref="955840644"/>
<reference key="destination" ref="739180901"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_unhide_button</string>
<reference key="source" ref="955840644"/>
<reference key="destination" ref="932654538"/>
</object>
<int key="connectionID">11</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="739180901"/>
<reference key="destination" ref="841351856"/>
</object>
<int key="connectionID">12</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="955840644"/>
<array class="NSMutableArray" key="children">
<reference ref="739180901"/>
<reference ref="788635611"/>
<reference ref="932654538"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="739180901"/>
<reference key="parent" ref="955840644"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="788635611"/>
<reference key="parent" ref="955840644"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="932654538"/>
<reference key="parent" ref="955840644"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">EditorBaseController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.CustomClassName">EditSecretTextTableViewCell</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">12</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,347 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUILabel</string>
<string>IBUITableViewCell</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableViewCell" id="1049047257">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="37971195">
<reference key="NSNextResponder" ref="1049047257"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUILabel" id="225091127">
<reference key="NSNextResponder" ref="37971195"/>
<int key="NSvFlags">302</int>
<string key="NSFrame">{{10, 10}, {140, 25}}</string>
<reference key="NSSuperview" ref="37971195"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="53086288"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor" id="487482859">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor" id="538435083">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUILabel" id="53086288">
<reference key="NSNextResponder" ref="37971195"/>
<int key="NSvFlags">299</int>
<string key="NSFrame">{{160, 10}, {120, 25}}</string>
<reference key="NSSuperview" ref="37971195"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Selection</string>
<reference key="IBUITextColor" ref="487482859"/>
<reference key="IBUIHighlightedColor" ref="538435083"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUITextAlignment">2</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
</array>
<string key="NSFrameSize">{300, 43}</string>
<reference key="NSSuperview" ref="1049047257"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="225091127"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="37971195"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIAccessoryType">1</int>
<reference key="IBUIContentView" ref="37971195"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_selectionTableViewCell</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="1049047257"/>
</object>
<int key="connectionID">9</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label</string>
<reference key="source" ref="1049047257"/>
<reference key="destination" ref="225091127"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_selection</string>
<reference key="source" ref="1049047257"/>
<reference key="destination" ref="53086288"/>
</object>
<int key="connectionID">8</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="1049047257"/>
<array class="NSMutableArray" key="children">
<reference ref="225091127"/>
<reference ref="53086288"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="225091127"/>
<reference key="parent" ref="1049047257"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="53086288"/>
<reference key="parent" ref="1049047257"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">EditorBaseController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.CustomClassName">EditSelectionTableViewCell</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">9</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">EditFlagTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_toggle">UISwitch</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_toggle">
<string key="name">_toggle</string>
<string key="candidateClassName">UISwitch</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditFlagTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditSelectionTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_selection">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_selection">
<string key="name">_selection</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditSelectionTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditSubEditTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">_label</string>
<string key="NS.object.0">UILabel</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">_label</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditSubEditTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditTextTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_textfield">UITextField</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_textfield">
<string key="name">_textfield</string>
<string key="candidateClassName">UITextField</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditTextTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditorBaseController</string>
<string key="superclassName">UITableViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_flagTableViewCell">EditFlagTableViewCell</string>
<string key="_selectionTableViewCell">EditSelectionTableViewCell</string>
<string key="_subEditTableViewCell">EditSubEditTableViewCell</string>
<string key="_textTableViewCell">EditTextTableViewCell</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_flagTableViewCell">
<string key="name">_flagTableViewCell</string>
<string key="candidateClassName">EditFlagTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_selectionTableViewCell">
<string key="name">_selectionTableViewCell</string>
<string key="candidateClassName">EditSelectionTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_subEditTableViewCell">
<string key="name">_subEditTableViewCell</string>
<string key="candidateClassName">EditSubEditTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_textTableViewCell">
<string key="name">_textTableViewCell</string>
<string key="candidateClassName">EditTextTableViewCell</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditorBaseController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUILabel</string>
<string>IBUITableViewCell</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableViewCell" id="330133912">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="747305151">
<reference key="NSNextResponder" ref="330133912"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUILabel" id="800335451">
<reference key="NSNextResponder" ref="747305151"/>
<int key="NSvFlags">298</int>
<string key="NSFrame">{{10, 10}, {270, 25}}</string>
<reference key="NSSuperview" ref="747305151"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
</array>
<string key="NSFrameSize">{300, 43}</string>
<reference key="NSSuperview" ref="330133912"/>
<reference key="NSNextKeyView" ref="800335451"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSNextKeyView" ref="747305151"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIAccessoryType">1</int>
<reference key="IBUIContentView" ref="747305151"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_subEditTableViewCell</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="330133912"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label</string>
<reference key="source" ref="330133912"/>
<reference key="destination" ref="800335451"/>
</object>
<int key="connectionID">4</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="330133912"/>
<array class="NSMutableArray" key="children">
<reference ref="800335451"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="800335451"/>
<reference key="parent" ref="330133912"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">EditorBaseController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.CustomClassName">EditSubEditTableViewCell</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">5</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,364 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITableViewCell</string>
<string>IBUILabel</string>
<string>IBUITextField</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableViewCell" id="873867585">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="571279607">
<reference key="NSNextResponder" ref="873867585"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUILabel" id="837238439">
<reference key="NSNextResponder" ref="571279607"/>
<int key="NSvFlags">300</int>
<string key="NSFrame">{{10, 10}, {100, 25}}</string>
<reference key="NSSuperview" ref="571279607"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="915318991"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUITextField" id="915318991">
<reference key="NSNextResponder" ref="571279607"/>
<int key="NSvFlags">298</int>
<string key="NSFrame">{{120, 10}, {200, 25}}</string>
<reference key="NSSuperview" ref="571279607"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText">Test</string>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocorrectionType">1</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<int key="IBUIClearButtonMode">3</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrameSize">{320, 43}</string>
<reference key="NSSuperview" ref="873867585"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="837238439"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 44}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="571279607"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUISelectionStyle">0</int>
<reference key="IBUIContentView" ref="571279607"/>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_textTableViewCell</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="873867585"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label</string>
<reference key="source" ref="873867585"/>
<reference key="destination" ref="837238439"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_textfield</string>
<reference key="source" ref="873867585"/>
<reference key="destination" ref="915318991"/>
</object>
<int key="connectionID">6</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="915318991"/>
<reference key="destination" ref="841351856"/>
</object>
<int key="connectionID">8</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="873867585"/>
<array class="NSMutableArray" key="children">
<reference ref="837238439"/>
<reference ref="915318991"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="837238439"/>
<reference key="parent" ref="873867585"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="915318991"/>
<reference key="parent" ref="873867585"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">EditorBaseController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.CustomClassName">EditTextTableViewCell</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">8</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">EditFlagTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_toggle">UISwitch</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_toggle">
<string key="name">_toggle</string>
<string key="candidateClassName">UISwitch</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditFlagTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditSelectionTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_selection">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_selection">
<string key="name">_selection</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditSelectionTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditSubEditTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">_label</string>
<string key="NS.object.0">UILabel</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">_label</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditSubEditTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditTextTableViewCell</string>
<string key="superclassName">UITableViewCell</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_label">UILabel</string>
<string key="_textfield">UITextField</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_label">
<string key="name">_label</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_textfield">
<string key="name">_textfield</string>
<string key="candidateClassName">UITextField</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditTextTableViewCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">EditorBaseController</string>
<string key="superclassName">UITableViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_flagTableViewCell">EditFlagTableViewCell</string>
<string key="_selectionTableViewCell">EditSelectionTableViewCell</string>
<string key="_subEditTableViewCell">EditSubEditTableViewCell</string>
<string key="_textTableViewCell">EditTextTableViewCell</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_flagTableViewCell">
<string key="name">_flagTableViewCell</string>
<string key="candidateClassName">EditFlagTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_selectionTableViewCell">
<string key="name">_selectionTableViewCell</string>
<string key="candidateClassName">EditSelectionTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_subEditTableViewCell">
<string key="name">_subEditTableViewCell</string>
<string key="candidateClassName">EditSubEditTableViewCell</string>
</object>
<object class="IBToOneOutletInfo" key="_textTableViewCell">
<string key="name">_textTableViewCell</string>
<string key="candidateClassName">EditTextTableViewCell</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/EditorBaseController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment version="2352" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIApplication">
<connections>
<outlet property="delegate" destination="11" id="12"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<customObject id="11" userLabel="AppDelegate" customClass="AppDelegate">
<connections>
<outlet property="tabBarController" destination="4" id="14"/>
<outlet property="window" destination="2" id="13"/>
</connections>
</customObject>
<window opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</window>
<tabBarController definesPresentationContext="YES" id="4" customClass="MainTabBarController">
<extendedEdge key="edgesForExtendedLayout"/>
<simulatedTabBarMetrics key="simulatedBottomBarMetrics"/>
<tabBar key="tabBar" contentMode="scaleToFill" id="5">
<rect key="frame" x="0.0" y="431" width="320" height="49"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</tabBar>
</tabBarController>
</objects>
</document>

View File

@@ -0,0 +1,342 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUIButton</string>
<string>IBUIActivityIndicatorView</string>
<string>IBUIView</string>
<string>IBUILabel</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">301</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIButton" id="971255490">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{45, 143}, {109, 37}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<string key="IBUINormalTitle">Cancel</string>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="107901828">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<reference key="IBUINormalTitleColor" ref="107901828"/>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="NSCustomResource" key="IBUINormalBackgroundImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">cancel_button_background.png</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIActivityIndicatorView" id="236881211">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">301</int>
<string key="NSFrame">{{82, 81}, {37, 37}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="971255490"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIHidesWhenStopped">NO</bool>
<int key="IBUIStyle">0</int>
</object>
<object class="IBUILabel" id="933286658">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{18, 20}, {165, 25}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="236881211"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Connecting</string>
<reference key="IBUITextColor" ref="107901828"/>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUITextAlignment">1</int>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
</array>
<string key="NSFrameSize">{200, 200}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="933286658"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
</object>
<object class="IBUISimulatedSizeMetrics" key="IBUISimulatedDestinationMetrics">
<string key="IBUISimulatedSizeMetricsClass">IBUISimulatedFreeformSizeMetricsSentinel</string>
<string key="IBUIDisplayName">Freeform</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_connecting_view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">6</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_cancel_connect_button</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="971255490"/>
</object>
<int key="connectionID">7</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_connecting_indicator_view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="236881211"/>
</object>
<int key="connectionID">8</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_lbl_connecting</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="933286658"/>
</object>
<int key="connectionID">10</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">cancelButtonPressed:</string>
<reference key="source" ref="971255490"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">9</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="971255490"/>
<reference ref="236881211"/>
<reference ref="933286658"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="971255490"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="236881211"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="933286658"/>
<reference key="parent" ref="191373211"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">RDPSessionViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">10</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">RDPSessionView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/RDPSessionView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">RDPSessionViewController</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_cancel_connect_button">UIButton</string>
<string key="_connecting_indicator_view">UIActivityIndicatorView</string>
<string key="_connecting_view">UIView</string>
<string key="_dummy_textfield">UITextField</string>
<string key="_lbl_connecting">UILabel</string>
<string key="_session_scrollview">UIScrollView</string>
<string key="_session_toolbar">UIToolbar</string>
<string key="_session_view">RDPSessionView</string>
<string key="_touchpointer_view">TouchPointerView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_cancel_connect_button">
<string key="name">_cancel_connect_button</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="_connecting_indicator_view">
<string key="name">_connecting_indicator_view</string>
<string key="candidateClassName">UIActivityIndicatorView</string>
</object>
<object class="IBToOneOutletInfo" key="_connecting_view">
<string key="name">_connecting_view</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="_dummy_textfield">
<string key="name">_dummy_textfield</string>
<string key="candidateClassName">UITextField</string>
</object>
<object class="IBToOneOutletInfo" key="_lbl_connecting">
<string key="name">_lbl_connecting</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_session_scrollview">
<string key="name">_session_scrollview</string>
<string key="candidateClassName">UIScrollView</string>
</object>
<object class="IBToOneOutletInfo" key="_session_toolbar">
<string key="name">_session_toolbar</string>
<string key="candidateClassName">UIToolbar</string>
</object>
<object class="IBToOneOutletInfo" key="_session_view">
<string key="name">_session_view</string>
<string key="candidateClassName">RDPSessionView</string>
</object>
<object class="IBToOneOutletInfo" key="_touchpointer_view">
<string key="name">_touchpointer_view</string>
<string key="candidateClassName">TouchPointerView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/RDPSessionViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">TouchPointerView</string>
<string key="superclassName">UIView</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">delegate</string>
<string key="NS.object.0">NSObject</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">delegate</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">delegate</string>
<string key="candidateClassName">NSObject</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/TouchPointerView.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NS.key.0">cancel_button_background.png</string>
<string key="NS.object.0">{63, 33}</string>
</object>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,553 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUITextField</string>
<string>IBUIBarButtonItem</string>
<string>IBUIToolbar</string>
<string>IBUIView</string>
<string>IBUIScrollView</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUITextField" id="774128306">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{0, 31}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="791392364"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentVerticalAlignment">0</int>
<string key="IBUIText">UserInput</string>
<int key="IBUIBorderStyle">3</int>
<object class="NSColor" key="IBUITextColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace" id="239224178">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIAdjustsFontSizeToFit">YES</bool>
<float key="IBUIMinimumFontSize">17</float>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocorrectionType">1</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">1</int>
<double key="pointSize">14</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica</string>
<double key="NSSize">14</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIScrollView" id="791392364">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIView" id="111719994">
<reference key="NSNextResponder" ref="791392364"/>
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="791392364"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="462653931"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<reference key="NSCustomColorSpace" ref="239224178"/>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="111719994"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor" id="916436089">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<array key="IBUIGestureRecognizers" id="0"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUICanCancelContentTouches">NO</bool>
<float key="IBUIMaximumZoomScale">2</float>
</object>
<object class="IBUIView" id="462653931">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">-2147483374</int>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MSAwAA</bytes>
<reference key="NSCustomColorSpace" ref="239224178"/>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIToolbar" id="902223647">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{0, -66}, {320, 44}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="774128306"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIBarStyle">2</int>
<array class="NSMutableArray" key="IBUIItems">
<object class="IBUIBarButtonItem" id="1053104">
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">toolbar_icon_keyboard.png</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<reference key="IBUIToolbar" ref="902223647"/>
</object>
<object class="IBUIBarButtonItem" id="610739936">
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<float key="IBUIWidth">20</float>
<reference key="IBUIToolbar" ref="902223647"/>
<int key="IBUISystemItemIdentifier">6</int>
</object>
<object class="IBUIBarButtonItem" id="619296838">
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">toolbar_icon_extkeyboad.png</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<reference key="IBUIToolbar" ref="902223647"/>
</object>
<object class="IBUIBarButtonItem" id="638922886">
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<float key="IBUIWidth">20</float>
<reference key="IBUIToolbar" ref="902223647"/>
<int key="IBUISystemItemIdentifier">6</int>
</object>
<object class="IBUIBarButtonItem" id="771290196">
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">toolbar_icon_touchpointer.png</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<reference key="IBUIToolbar" ref="902223647"/>
</object>
<object class="IBUIBarButtonItem" id="1053225403">
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<reference key="IBUIToolbar" ref="902223647"/>
<int key="IBUISystemItemIdentifier">5</int>
</object>
<object class="IBUIBarButtonItem" id="977115063">
<object class="NSCustomResource" key="IBUIImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">toolbar_icon_disconnect.png</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<reference key="IBUIToolbar" ref="902223647"/>
</object>
</array>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="902223647"/>
<reference key="IBUIBackgroundColor" ref="916436089"/>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">21</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_dummy_textfield</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="774128306"/>
</object>
<int key="connectionID">22</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_session_scrollview</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="791392364"/>
</object>
<int key="connectionID">23</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_touchpointer_view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="462653931"/>
</object>
<int key="connectionID">25</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_session_view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="111719994"/>
</object>
<int key="connectionID">26</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_session_toolbar</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="902223647"/>
</object>
<int key="connectionID">27</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">toggleKeyboard:</string>
<reference key="source" ref="1053104"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">33</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">toggleTouchPointer:</string>
<reference key="source" ref="771290196"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">34</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">disconnectSession:</string>
<reference key="source" ref="977115063"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">31</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="791392364"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">28</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="774128306"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">29</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="462653931"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">30</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">toggleShiftKey:</string>
<reference key="source" ref="638922886"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">38</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">toggleExtKeyboard:</string>
<reference key="source" ref="619296838"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">39</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<reference key="object" ref="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="902223647"/>
<reference ref="791392364"/>
<reference ref="774128306"/>
<reference ref="462653931"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="902223647"/>
<array class="NSMutableArray" key="children">
<reference ref="1053104"/>
<reference ref="610739936"/>
<reference ref="771290196"/>
<reference ref="1053225403"/>
<reference ref="977115063"/>
<reference ref="638922886"/>
<reference ref="619296838"/>
</array>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="1053104"/>
<reference key="parent" ref="902223647"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="610739936"/>
<reference key="parent" ref="902223647"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="771290196"/>
<reference key="parent" ref="902223647"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9</int>
<reference key="object" ref="1053225403"/>
<reference key="parent" ref="902223647"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="977115063"/>
<reference key="parent" ref="902223647"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">11</int>
<reference key="object" ref="791392364"/>
<array class="NSMutableArray" key="children">
<reference ref="111719994"/>
</array>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">12</int>
<reference key="object" ref="774128306"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">13</int>
<reference key="object" ref="111719994"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="791392364"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">14</int>
<reference key="object" ref="462653931"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">35</int>
<reference key="object" ref="638922886"/>
<reference key="parent" ref="902223647"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">36</int>
<reference key="object" ref="619296838"/>
<reference key="parent" ref="902223647"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">RDPSessionViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="12.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="13.CustomClassName">RDPSessionView</string>
<string key="13.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="14.CustomClassName">TouchPointerView</string>
<string key="14.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="35.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="36.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">39</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">RDPSessionView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/RDPSessionView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">RDPSessionViewController</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_cancel_connect_button">UIButton</string>
<string key="_connecting_indicator_view">UIActivityIndicatorView</string>
<string key="_connecting_view">UIView</string>
<string key="_dummy_textfield">UITextField</string>
<string key="_lbl_connecting">UILabel</string>
<string key="_session_scrollview">UIScrollView</string>
<string key="_session_toolbar">UIToolbar</string>
<string key="_session_view">RDPSessionView</string>
<string key="_touchpointer_view">TouchPointerView</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_cancel_connect_button">
<string key="name">_cancel_connect_button</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="_connecting_indicator_view">
<string key="name">_connecting_indicator_view</string>
<string key="candidateClassName">UIActivityIndicatorView</string>
</object>
<object class="IBToOneOutletInfo" key="_connecting_view">
<string key="name">_connecting_view</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo" key="_dummy_textfield">
<string key="name">_dummy_textfield</string>
<string key="candidateClassName">UITextField</string>
</object>
<object class="IBToOneOutletInfo" key="_lbl_connecting">
<string key="name">_lbl_connecting</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_session_scrollview">
<string key="name">_session_scrollview</string>
<string key="candidateClassName">UIScrollView</string>
</object>
<object class="IBToOneOutletInfo" key="_session_toolbar">
<string key="name">_session_toolbar</string>
<string key="candidateClassName">UIToolbar</string>
</object>
<object class="IBToOneOutletInfo" key="_session_view">
<string key="name">_session_view</string>
<string key="candidateClassName">RDPSessionView</string>
</object>
<object class="IBToOneOutletInfo" key="_touchpointer_view">
<string key="name">_touchpointer_view</string>
<string key="candidateClassName">TouchPointerView</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/RDPSessionViewController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">TouchPointerView</string>
<string key="superclassName">UIView</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">delegate</string>
<string key="NS.object.0">NSObject</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">delegate</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">delegate</string>
<string key="candidateClassName">NSObject</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/TouchPointerView.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="toolbar_icon_disconnect.png">{24, 24}</string>
<string key="toolbar_icon_extkeyboad.png">{24, 24}</string>
<string key="toolbar_icon_keyboard.png">{35, 24}</string>
<string key="toolbar_icon_touchpointer.png">{24, 24}</string>
</dictionary>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,574 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>IBUITableViewCell</string>
<string>IBUIImageView</string>
<string>IBUILabel</string>
<string>IBUIButton</string>
<string>IBProxyObject</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBUITableViewCell" id="660975430">
<reference key="NSNextResponder"/>
<int key="NSvFlags">292</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIView" id="64247618">
<reference key="NSNextResponder" ref="660975430"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIImageView" id="60336238">
<reference key="NSNextResponder" ref="64247618"/>
<int key="NSvFlags">300</int>
<string key="NSFrame">{{20, 12}, {63, 47}}</string>
<reference key="NSSuperview" ref="64247618"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="695281447"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
</object>
<object class="IBUILabel" id="695281447">
<reference key="NSNextResponder" ref="64247618"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{91, 12}, {168, 21}}</string>
<reference key="NSSuperview" ref="64247618"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="583414824"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<string key="IBUIText">Label</string>
<object class="NSColor" key="IBUITextColor" id="852118610">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<object class="NSColor" key="IBUIHighlightedColor" id="645846245">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">18</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">18</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUILabel" id="583414824">
<reference key="NSNextResponder" ref="64247618"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{91, 25}, {168, 21}}</string>
<reference key="NSSuperview" ref="64247618"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="597512619"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<string key="IBUIText">Label</string>
<reference key="IBUITextColor" ref="852118610"/>
<reference key="IBUIHighlightedColor" ref="645846245"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="263878792">
<int key="type">1</int>
<double key="pointSize">14</double>
</object>
<object class="NSFont" key="IBUIFont" id="649156643">
<string key="NSName">Helvetica</string>
<double key="NSSize">14</double>
<int key="NSfFlags">16</int>
</object>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUILabel" id="597512619">
<reference key="NSNextResponder" ref="64247618"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{91, 41}, {168, 21}}</string>
<reference key="NSSuperview" ref="64247618"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="30378675"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<string key="IBUIText">Label</string>
<reference key="IBUITextColor" ref="852118610"/>
<reference key="IBUIHighlightedColor" ref="645846245"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<reference key="IBUIFontDescription" ref="263878792"/>
<reference key="IBUIFont" ref="649156643"/>
<bool key="IBUIAdjustsFontSizeToFit">NO</bool>
</object>
<object class="IBUIButton" id="30378675">
<reference key="NSNextResponder" ref="64247618"/>
<int key="NSvFlags">297</int>
<string key="NSFrame">{{267, 19}, {33, 33}}</string>
<reference key="NSSuperview" ref="64247618"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<reference key="IBUIHighlightedTitleColor" ref="645846245"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="NSCustomResource" key="IBUINormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">toolbar_icon_disconnect.png</string>
</object>
<object class="NSCustomResource" key="IBUINormalBackgroundImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">cancel_button_background.png</string>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription">
<int key="type">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
</object>
<string key="NSFrameSize">{320, 71}</string>
<reference key="NSSuperview" ref="660975430"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="60336238"/>
<string key="NSReuseIdentifierKey">_NS:11</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">4</int>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
<string key="NSFrameSize">{320, 72}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="64247618"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<reference key="IBUIContentView" ref="64247618"/>
<real value="72" key="IBUIRowHeight"/>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">sessTableCell</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="660975430"/>
</object>
<int key="connectionID">34</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_disconnect_button</string>
<reference key="source" ref="660975430"/>
<reference key="destination" ref="30378675"/>
</object>
<int key="connectionID">29</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_screenshot</string>
<reference key="source" ref="660975430"/>
<reference key="destination" ref="60336238"/>
</object>
<int key="connectionID">30</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_server</string>
<reference key="source" ref="660975430"/>
<reference key="destination" ref="583414824"/>
</object>
<int key="connectionID">31</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_title</string>
<reference key="source" ref="660975430"/>
<reference key="destination" ref="695281447"/>
</object>
<int key="connectionID">32</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_username</string>
<reference key="source" ref="660975430"/>
<reference key="destination" ref="597512619"/>
</object>
<int key="connectionID">33</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">disconnectButtonPressed:</string>
<reference key="source" ref="30378675"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">35</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="0">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">23</int>
<reference key="object" ref="660975430"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="695281447"/>
<reference ref="597512619"/>
<reference ref="583414824"/>
<reference ref="60336238"/>
<reference ref="30378675"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">24</int>
<reference key="object" ref="695281447"/>
<reference key="parent" ref="660975430"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">25</int>
<reference key="object" ref="60336238"/>
<reference key="parent" ref="660975430"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">26</int>
<reference key="object" ref="583414824"/>
<reference key="parent" ref="660975430"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">27</int>
<reference key="object" ref="597512619"/>
<reference key="parent" ref="660975430"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">28</int>
<reference key="object" ref="30378675"/>
<reference key="parent" ref="660975430"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-1.IBPluginDependency</string>
<string>-2.CustomClassName</string>
<string>-2.IBPluginDependency</string>
<string>23.CustomClassName</string>
<string>23.IBPluginDependency</string>
<string>24.IBPluginDependency</string>
<string>25.IBPluginDependency</string>
<string>26.IBPluginDependency</string>
<string>27.IBPluginDependency</string>
<string>28.IBPluginDependency</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>BookmarkListController</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>UIResponder</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>SessionTableCell</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
</object>
<nil key="sourceID"/>
<int key="maxID">35</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">BookmarkListController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>bmTableCell</string>
<string>searchBar</string>
<string>sessTableCell</string>
<string>tableView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>BookmarkTableCell</string>
<string>UISearchBar</string>
<string>SessionTableCell</string>
<string>UITableView</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>bmTableCell</string>
<string>searchBar</string>
<string>sessTableCell</string>
<string>tableView</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">bmTableCell</string>
<string key="candidateClassName">BookmarkTableCell</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">searchBar</string>
<string key="candidateClassName">UISearchBar</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">sessTableCell</string>
<string key="candidateClassName">SessionTableCell</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">tableView</string>
<string key="candidateClassName">UITableView</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/BookmarkListController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">BookmarkTableCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_connection_state_icon</string>
<string>_sub_title</string>
<string>_title</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIImageView</string>
<string>UILabel</string>
<string>UILabel</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_connection_state_icon</string>
<string>_sub_title</string>
<string>_title</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">_connection_state_icon</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_sub_title</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_title</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/BookmarkTableCell.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">SessionTableCell</string>
<string key="superclassName">UITableViewCell</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_disconnect_button</string>
<string>_screenshot</string>
<string>_server</string>
<string>_title</string>
<string>_username</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIButton</string>
<string>UIImageView</string>
<string>UILabel</string>
<string>UILabel</string>
<string>UILabel</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>_disconnect_button</string>
<string>_screenshot</string>
<string>_server</string>
<string>_title</string>
<string>_username</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">_disconnect_button</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_screenshot</string>
<string key="candidateClassName">UIImageView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_server</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_title</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">_username</string>
<string key="candidateClassName">UILabel</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/SessionTableCell.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
<integer value="3100" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>cancel_button_background.png</string>
<string>toolbar_icon_disconnect.png</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>{63, 33}</string>
<string>{24, 24}</string>
</object>
</object>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

View File

@@ -0,0 +1,386 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1179</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBUIButton</string>
<string>IBUIView</string>
<string>IBUILabel</string>
<string>IBProxyObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">319</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIButton" id="683207246">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">291</int>
<string key="NSFrame">{{152, 237}, {95, 37}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<string key="IBUINormalTitle">No</string>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="1032157260">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<object class="NSColor" key="IBUINormalTitleShadowColor" id="417359316">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MC41AA</bytes>
</object>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="733176724">
<string key="name">Helvetica-Bold</string>
<string key="family">Helvetica</string>
<int key="traits">2</int>
<double key="pointSize">15</double>
</object>
<object class="NSFont" key="IBUIFont" id="197322835">
<string key="NSName">Helvetica-Bold</string>
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUIButton" id="985957052">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">294</int>
<string key="NSFrame">{{20, 237}, {95, 37}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="683207246"/>
<bool key="IBUIOpaque">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
<int key="IBUIButtonType">1</int>
<string key="IBUINormalTitle">Yes</string>
<reference key="IBUIHighlightedTitleColor" ref="1032157260"/>
<object class="NSColor" key="IBUINormalTitleColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
</object>
<reference key="IBUINormalTitleShadowColor" ref="417359316"/>
<reference key="IBUIFontDescription" ref="733176724"/>
<reference key="IBUIFont" ref="197322835"/>
</object>
<object class="IBUILabel" id="830896437">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">290</int>
<string key="NSFrame">{{20, 20}, {227, 94}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="485908522"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">The identity of the remote computer cannot be verified. Do you want to connect anyway?</string>
<object class="NSColor" key="IBUITextColor" id="232026869">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MCAwIDAAA</bytes>
</object>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUINumberOfLines">4</int>
<int key="IBUILineBreakMode">0</int>
<object class="IBUIFontDescription" key="IBUIFontDescription" id="820193683">
<int key="type">1</int>
<double key="pointSize">17</double>
</object>
<object class="NSFont" key="IBUIFont" id="784496446">
<string key="NSName">Helvetica</string>
<double key="NSSize">17</double>
<int key="NSfFlags">16</int>
</object>
</object>
<object class="IBUILabel" id="485908522">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">294</int>
<string key="NSFrame">{{20, 136}, {59, 21}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="23899749"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Issuer:</string>
<reference key="IBUITextColor" ref="232026869"/>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<reference key="IBUIFontDescription" ref="820193683"/>
<reference key="IBUIFont" ref="784496446"/>
</object>
<object class="IBUILabel" id="23899749">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">291</int>
<string key="NSFrame">{{87, 136}, {160, 21}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="985957052"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<string key="IBUIText">Label</string>
<reference key="IBUITextColor" ref="232026869"/>
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">0</int>
<float key="IBUIMinimumFontSize">10</float>
<reference key="IBUIFontDescription" ref="820193683"/>
<reference key="IBUIFont" ref="784496446"/>
</object>
</array>
<string key="NSFrameSize">{267, 294}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="830896437"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<object class="IBUISimulatedSizeMetrics" key="IBUISimulatedDestinationMetrics">
<string key="IBUISimulatedSizeMetricsClass">IBUISimulatedFreeformSizeMetricsSentinel</string>
<string key="IBUIDisplayName">Freeform</string>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">8</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_btn_accept</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="985957052"/>
</object>
<int key="connectionID">9</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_btn_decline</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="683207246"/>
</object>
<int key="connectionID">10</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label_issuer</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="23899749"/>
</object>
<int key="connectionID">11</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label_message</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="830896437"/>
</object>
<int key="connectionID">14</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">_label_for_issuer</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="485908522"/>
</object>
<int key="connectionID">16</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">declinePressed:</string>
<reference key="source" ref="683207246"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">13</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">acceptPressed:</string>
<reference key="source" ref="985957052"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">12</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="830896437"/>
<reference ref="485908522"/>
<reference ref="23899749"/>
<reference ref="985957052"/>
<reference ref="683207246"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="683207246"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="985957052"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="830896437"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">6</int>
<reference key="object" ref="485908522"/>
<reference key="parent" ref="191373211"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="23899749"/>
<reference key="parent" ref="191373211"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">VerifyCertificateController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="3.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="6.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">16</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">VerifyCertificateController</string>
<string key="superclassName">UIViewController</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="_btn_accept">UIButton</string>
<string key="_btn_decline">UIButton</string>
<string key="_label_for_issuer">UILabel</string>
<string key="_label_issuer">UILabel</string>
<string key="_label_message">UILabel</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="_btn_accept">
<string key="name">_btn_accept</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="_btn_decline">
<string key="name">_btn_decline</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo" key="_label_for_issuer">
<string key="name">_label_for_issuer</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_label_issuer">
<string key="name">_label_issuer</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo" key="_label_message">
<string key="name">_label_message</string>
<string key="candidateClassName">UILabel</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/VerifyCertificateController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1179</string>
</data>
</archive>

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,203 @@
<html>
<head>
<meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;' />
<script language="javascript">
function toggle() {
var ele = document.getElementById("toggleText");
var text = document.getElementById("displayText");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "show";
}
else {
ele.style.display = "block";
text.innerHTML = "<b>hide</b>";
}
}
</script>
<style type="text/css">
@charset "utf-8";
body {
font: 100%%/1.4 Helvetica;
background-color:#E9EBF8;
height: 100%%; width: 100%%; margin: 0;
background-image:url(back.jpg);
background-position:center;
text-align:center;
}
.centered-table {
margin-left: auto;
margin-right: auto;
}
#headline{
background-color:#353639;
opacity:0.9;
color:FFF;
text-align:center;
}
#footer{
padding-top:10px;
}
#footer img{
padding top:10 px;
}
#article{
background-color:#FFFFFF;
opacity: 0.8;
z-index:0;
margin-bottom:3%%;
padding-bottom:0.1%%;
border-radius: 15px;
border-top-left-radius:0px;
border-top-right-radius:0px;
color:#000;
margin: 10px auto;
position:relative;
}
#introduction_headline{
width:inherit;
background-color:#353639;
opacity:0.9;
color:FFF;
text-align:center;
border-bottom-left-radius:15px;
border-bottom-right-radius:15px;
}
#introduction{
background-color:#FFFFFF;
opacity: 0.8;
z-index:0;
margin-bottom:3%%;
padding-bottom:0.1%%;
border-radius: 10px;
color:#000;
}
#container
{
margin-left: auto;
margin-right: auto;
width: 50em;
width:420px;
}
/* ~~ Element/tag selectors ~~ */
ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */
padding: 0;
margin: 0;
}
h1, h2, h3, h4, h5, h6, p {
margin-top: 0; /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */
padding-right: 1px;
padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method. */
}
a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */
border: none;
alignment: right;}
}
/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */
/*a:link {
color:#414958;
text-decoration: underline; unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */
a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */
text-decoration: none;}
a:link { color:#0000FF; }
* {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
</style>
</head>
<body>
<div id="container">
<div id="introduction_headline">
<h2>iFreeRDP </br>Remote Desktop Client</h2>
</div>
<p>
<img src="FreeRDP_Logo.png" width="30%%"></p>
<div id="introduction">
iFreeRDP is an open source client
capable of natively using Remote Desktop Protocol (RDP) in order to remotely access your Windows desktop.</div>
<div id="article">
<div id="headline"><h3>Version Information</h3></div>
<p>
<table class="centered-table" border=0 cellspacing=1 cellpadding=3 >
<tr>
<td>iFreeRDP Version</td> <td>%@</td> </tr>
<tr> <td>System Name</td> <td>%@</td> </tr>
<tr> <td>System Version</td> <td>%@</td> </tr>
<tr> <td>Model</td> <td>%@</td> </tr>
</table>
</p>
</div>
<div id="article">
<div id="headline">
<h3>Credits</h3>
</div>
iFreeRDP is a part of <a href="http://www.freerdp.com/">FreeRDP</a>
</div>
<div id="article">
<div id="headline">
<h3>License</h3>
</div>
This program is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License, v. 2.0.
You can obtain an online version of the License from <a href="http://mozilla.org/MPL/2.0/">http://mozilla.org/MPL/2.0/</a>.
</p>
<p>
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</p>
<p>
A copy of the product's source code can be obtained from the FreeRDP GitHub repository at <a
href="https://github.com/FreeRDP/FreeRDP">https://github.com/FreeRDP/FreeRDP</a>.<br />
</p>
<br></div>
</body>
</html>

View File

@@ -0,0 +1,201 @@
<html>
<head>
<meta name='viewport' content='width=device-width; initial-scale=1.0; maximum-scale=1.0;' />
<script language="javascript">
function toggle() {
var ele = document.getElementById("toggleText");
var text = document.getElementById("displayText");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "show";
}
else {
ele.style.display = "block";
text.innerHTML = "<b>hide</b>";
}
}
</script>
<style type="text/css">
@charset "utf-8";
body {
font: 100%%/1 Helvetica;
background-color:#E9EBF8;
height: 100%%; width: 100%%; margin: 0;
background-image:url(back.jpg);
background-position:center;
text-align:center;
}
.centered-table {
margin-left: auto;
margin-right: auto;
}
#headline{
background-color:#353639;
opacity:0.9;
color:FFF;
text-align:center;
}
#footer{
padding-top:10px;
}
#footer img{
padding top:10 px;
}
#article{
background-color:#FFFFFF;
opacity: 0.8;
z-index:0;
margin-bottom:3%%;
padding-bottom:0.1%%;
border-radius: 15px;
border-top-left-radius:0px;
border-top-right-radius:0px;
color:#000;
margin: 10px auto;
position:relative;
}
#introduction_headline{
width:inherit;
background-color:#353639;
opacity:0.9;
color:FFF;
text-align:center;
border-bottom-left-radius:15px;
border-bottom-right-radius:15px;
}
#introduction{
background-color:#FFFFFF;
opacity: 0.8;
z-index:0;
margin-bottom:3%%;
padding-bottom:0.1%%;
border-radius: 10px;
color:#000;
}
#container
{
margin-left: auto;
margin-right: auto;
width:300px;
}
/* ~~ Element/tag selectors ~~ */
ul, ol, dl { /* Due to variations between browsers, it's best practices to zero padding and margin on lists. For consistency, you can either specify the amounts you want here, or on the list items (LI, DT, DD) they contain. Remember that what you do here will cascade to the .nav list unless you write a more specific selector. */
padding: 0;
margin: 0;
}
h1, h2, h3, h4, h5, h6, p {
margin-top: 0; /* removing the top margin gets around an issue where margins can escape from their containing div. The remaining bottom margin will hold it away from any elements that follow. */
padding-right: 1px;
padding-left: 1px; /* adding the padding to the sides of the elements within the divs, instead of the divs themselves, gets rid of any box model math. A nested div with side padding can also be used as an alternate method. */
}
a img { /* this selector removes the default blue border displayed in some browsers around an image when it is surrounded by a link */
border: none;
alignment: right;}
}
/* ~~ Styling for your site's links must remain in this order - including the group of selectors that create the hover effect. ~~ */
/*a:link {
color:#414958;
text-decoration: underline; unless you style your links to look extremely unique, it's best to provide underlines for quick visual identification */
a:hover, a:active, a:focus { /* this group of selectors will give a keyboard navigator the same hover experience as the person using a mouse. */
text-decoration: none;}
a:link { color:#0000FF; }
* {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
}
</style>
</head>
<body>
<div id="container">
<div id="introduction_headline">
<h2>iFreeRDP</br>Remote Desktop Client</h2>
</div>
<p>
<img src="FreeRDP_Logo.png" width="25%%"></p>
<div id="introduction">
<b>iFreeRDP</b> is an open source client for Windows Remote Services using Remote Desktop Protocol (RDP) in order to remotely access your Windows desktop.</div>
<div id="article">
<div id="headline"><h3>Version Information</h3></div>
<p>
<table class="centered-table" border=0 cellspacing=1 cellpadding=3 >
<tr>
<td>iFreerdp Version</td> <td>%@</td> </tr>
<tr> <td>System Name</td> <td>%@</td> </tr>
<tr> <td>System Version</td> <td>%@</td> </tr>
<tr> <td>Model</td> <td>%@</td> </tr>
</table>
</p>
</div>
<div id="article">
<div id="headline">
<h3>Credits</h3>
</div>
iFreeRDP is part of <a href="http://www.freerdp.com/">FreeRDP</a>
</div>
<div id="article">
<div id="headline">
<h3>License</h3>
</div>
This program is free software; you can redistribute it and/or modify it under the terms of the Mozilla Public License, v. 2.0.
You can obtain an online version of the License from <a href="http://mozilla.org/MPL/2.0/">http://mozilla.org/MPL/2.0/</a>.
</p>
<p>
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</p>
<p>
A copy of the product's source code can be obtained from the FreeRDP GitHub repository at <a
href="https://github.com/FreeRDP/FreeRDP">https://github.com/FreeRDP/FreeRDP</a>.<br />
</p> </div>
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More