mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-06 08:55:34 +00:00
450 lines
19 KiB
Objective-C
450 lines
19 KiB
Objective-C
//
|
|
// LanguageViewController.m
|
|
// Keyman Engine
|
|
//
|
|
// Created by Serkan Kurt on 26/07/13.
|
|
// Copyright (c) 2017 SIL International. All rights reserved.
|
|
//
|
|
|
|
#import "LanguageViewController.h"
|
|
#import "LanguageDetailViewController.h"
|
|
#import "KeyboardPickerViewController.h"
|
|
#import "KeyboardNameTableViewCell.h"
|
|
#import "KMManager+Internal.h"
|
|
#import "QuartzCore/QuartzCore.h"
|
|
#import <UIKit/UIKit.h>
|
|
|
|
static const NSInteger kmErrorAlertTag = -1;
|
|
static const NSInteger kmActivityViewTag = -2;
|
|
static const NSInteger kmToolbarButtonTag = 100;
|
|
static const NSInteger kmToolbarLabelTag = 101;
|
|
static const NSInteger kmToolbarActivityIndicatorTag = 102;
|
|
|
|
@interface LanguageViewController ()
|
|
@property (nonatomic, strong) NSMutableDictionary *userKeyboards;
|
|
@property (nonatomic, strong) NSMutableArray *sectionIndexTitles;
|
|
@property (nonatomic, strong) NSMutableArray *indices;
|
|
@property (nonatomic, assign) NSInteger selectedSection;
|
|
@property (assign) BOOL isUpdate;
|
|
@end
|
|
|
|
@implementation LanguageViewController
|
|
|
|
@synthesize userKeyboards, sectionIndexTitles, indices, selectedSection;
|
|
|
|
- (id)initWithStyle:(UITableViewStyle)style
|
|
{
|
|
self = [super initWithStyle:style];
|
|
if (self) {
|
|
// Custom initialization
|
|
}
|
|
return self;
|
|
}
|
|
|
|
#pragma mark - View lifecycle
|
|
|
|
- (void)loadView {
|
|
[super loadView];
|
|
self.sectionIndexTitles = nil;
|
|
self.indices = nil;
|
|
if ([KMManager sharedInstance].currentRequest == nil && [KMManager sharedInstance].languages == nil) {
|
|
[KMManager fetchKeyboardsWithCompletionBlock:nil];
|
|
}
|
|
[self loadUserKeyboards];
|
|
}
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
|
|
self.title = @"Add New Keyboard";
|
|
self.selectedSection = NSNotFound;
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageFetchFinished) name:kKeymanLanguagesUpdatedNotification object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageFetchFailed) name:kKeymanLanguagesDownloadFailedNotification object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDownloadStarted:) name:kKeymanKeyboardDownloadStartedNotification object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDownloadFailed:) name:kKeymanKeyboardDownloadFailedNotification object:nil];
|
|
|
|
// Uncomment the following line to preserve selection between presentations.
|
|
// self.clearsSelectionOnViewWillAppear = NO;
|
|
|
|
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
|
|
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated {
|
|
[super viewDidAppear:animated];
|
|
[self.navigationController setToolbarHidden:YES animated:YES];
|
|
// if no rows to show yet, show a loading indicator
|
|
if ([self numberOfSectionsInTableView:self.tableView] == 0) {
|
|
[self showActivityView];
|
|
}
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
}
|
|
|
|
- (void)didReceiveMemoryWarning
|
|
{
|
|
[super didReceiveMemoryWarning];
|
|
// Dispose of any resources that can be recreated.
|
|
}
|
|
|
|
#pragma mark - Table view data source
|
|
|
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
|
{
|
|
return [[[KMManager sharedInstance] languages] count];
|
|
}
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
static NSString *cellIdentifierType1 = @"CellType1";
|
|
static NSString *cellIdentifierType2 = @"CellType2";
|
|
|
|
NSArray *keyboards = [[KMManager sharedInstance] keyboardsForIndex:indexPath.section];
|
|
NSString *cellIdentifier = ([keyboards count] < 2) ? cellIdentifierType1 : cellIdentifierType2;
|
|
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
|
|
if (!cell) {
|
|
if ([keyboards count] < 2) {
|
|
cell = [[KeyboardNameTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
|
|
UIView *selectionColor = [[UIView alloc] init];
|
|
[selectionColor setBackgroundColor:[UIColor colorWithRed:204.0/255.0 green:136.0/255.0 blue:34.0/255.0 alpha:1.0]];
|
|
[cell setSelectedBackgroundView:selectionColor];
|
|
}
|
|
else {
|
|
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
|
|
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
|
|
UIView *selectionColor = [[UIView alloc] init];
|
|
[selectionColor setBackgroundColor:[UIColor colorWithRed:204.0/255.0 green:136.0/255.0 blue:34.0/255.0 alpha:1.0]];
|
|
[cell setSelectedBackgroundView:selectionColor];
|
|
}
|
|
}
|
|
|
|
cell.detailTextLabel.text = ([keyboards count] < 2) ? [[keyboards objectAtIndex:0] objectForKey:kKeymanNameKey] : @"";
|
|
|
|
return cell;
|
|
}
|
|
|
|
/*
|
|
// Override to support conditional editing of the table view.
|
|
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
// Return NO if you do not want the specified item to be editable.
|
|
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
|
|
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
|
}
|
|
else if (editingStyle == UITableViewCellEditingStyleInsert) {
|
|
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
// Override to support rearranging the table view.
|
|
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
|
|
{
|
|
}
|
|
*/
|
|
|
|
/*
|
|
// Override to support conditional rearranging of the table view.
|
|
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
// Return NO if you do not want the item to be re-orderable.
|
|
return YES;
|
|
}
|
|
*/
|
|
|
|
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
|
|
{
|
|
NSString *iosVersionStr = [[UIDevice currentDevice] systemVersion];
|
|
if ([iosVersionStr rangeOfString:@"7.0"].location != NSNotFound)
|
|
return nil; // return nil to prevent crash on iOS 7.0.x
|
|
|
|
if (self.sectionIndexTitles == nil || ![self.sectionIndexTitles count]) {
|
|
NSArray *languages = [KMManager sharedInstance].languages;
|
|
self.sectionIndexTitles = [[NSMutableArray alloc] initWithCapacity:1];
|
|
self.indices = [[NSMutableArray alloc] initWithCapacity:1];
|
|
|
|
NSInteger langIndex = 0;
|
|
for (NSDictionary *item in languages) {
|
|
if(![self.sectionIndexTitles containsObject:[[item objectForKey:kKeymanNameKey] substringToIndex:1]]) {
|
|
[self.sectionIndexTitles addObject:[[item objectForKey:kKeymanNameKey] substringToIndex:1]];
|
|
[self.indices addObject:[NSNumber numberWithLong:langIndex]];
|
|
}
|
|
langIndex++;
|
|
}
|
|
}
|
|
return self.sectionIndexTitles;
|
|
}
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
|
|
return [[self.indices objectAtIndex:index] integerValue];
|
|
}
|
|
|
|
#pragma mark - Table view delegate
|
|
|
|
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
NSArray *languages = [[KMManager sharedInstance] languages];
|
|
if (cell.accessoryType == UITableViewCellAccessoryDisclosureIndicator) {
|
|
if (indexPath.section < [languages count]) {
|
|
cell.textLabel.text = [[languages objectAtIndex:indexPath.section] objectForKey:kKeymanNameKey];
|
|
}
|
|
}
|
|
else {
|
|
if (indexPath.section < [languages count]) {
|
|
[(KeyboardNameTableViewCell *)cell setIndexPath:indexPath];
|
|
|
|
cell.textLabel.text = [[languages objectAtIndex:indexPath.section] objectForKey:kKeymanNameKey];
|
|
NSString *languageID = [[languages objectAtIndex:indexPath.section] objectForKey:kKeymanIdKey];
|
|
NSString *keyboardID = [[[[languages objectAtIndex:indexPath.section] objectForKey:kKeymanLanguageKeyboardsKey] objectAtIndex:0] objectForKey:kKeymanIdKey];
|
|
if ([self isAdded:languageID keyboardID:keyboardID]) {
|
|
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
|
|
cell.userInteractionEnabled = NO;
|
|
cell.textLabel.enabled = NO;
|
|
cell.detailTextLabel.enabled = NO;
|
|
}
|
|
else {
|
|
[cell setAccessoryType:UITableViewCellAccessoryNone];
|
|
cell.userInteractionEnabled = YES;
|
|
cell.textLabel.enabled = YES;
|
|
cell.detailTextLabel.enabled = YES;
|
|
}
|
|
|
|
eKMKeyboardState kbState = [[KMManager sharedInstance] stateForKeyboardWithID:keyboardID];
|
|
[(KeyboardNameTableViewCell *)cell setKeyboardState:kbState selected:NO defaultAccessoryType:cell.accessoryType];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
selectedSection = indexPath.section;
|
|
[tableView cellForRowAtIndexPath:indexPath].selected = NO;
|
|
if ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryDisclosureIndicator) {
|
|
[self showLanguageDetailViewWithTitle:[tableView cellForRowAtIndexPath:indexPath].textLabel.text languageIndex:indexPath.section];
|
|
}
|
|
else {
|
|
NSArray *languages = [[KMManager sharedInstance] languages];
|
|
//NSString *langID = [[languages objectAtIndex:indexPath.section] objectForKey:kKeymanIdKey];
|
|
NSString *langName = [[languages objectAtIndex:indexPath.section] objectForKey:kKeymanNameKey];
|
|
NSArray *keyboards = [[KMManager sharedInstance] keyboardsForIndex:indexPath.section];
|
|
NSString *kbID = [[keyboards objectAtIndex:0] objectForKey:kKeymanIdKey];
|
|
NSString *kbName = [[keyboards objectAtIndex:0] objectForKey:kKeymanNameKey];
|
|
//NSString *isRTL = [[keyboards objectAtIndex:0] objectForKey:kKeymanKeyboardRTLKey];
|
|
//isRTL = (isRTL == nil)?@"N":@"Y";
|
|
//NSString *font = [[KMManager sharedInstance] jsFontFromFontDictionary:[[keyboards objectAtIndex:0] objectForKey:kKeymanFontKey]];
|
|
//NSString *oskFont = [[KMManager sharedInstance] jsFontFromFontDictionary:[[keyboards objectAtIndex:0] objectForKey:kKeymanOskFontKey]];
|
|
eKMKeyboardState state = [[KMManager sharedInstance] stateForKeyboardWithID:kbID];
|
|
if (state != kKMKeyboardStateDownloading) {
|
|
if (state == kKMKeyboardStateNeedsDownload)
|
|
self.isUpdate = NO;
|
|
else
|
|
self.isUpdate = YES;
|
|
|
|
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%@: %@", langName, kbName]
|
|
message:@"Would you like to download this keyboard?"
|
|
delegate:self
|
|
cancelButtonTitle:@"Cancel"
|
|
otherButtonTitles:@"Download", nil];
|
|
alert.tag = 0;
|
|
[alert show];
|
|
}
|
|
|
|
/*
|
|
if (state == kKMKeyboardStateNeedsDownload) {
|
|
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%@: %@", langName, kbName]
|
|
message:@"Would you like to download this keyboard?"
|
|
delegate:self
|
|
cancelButtonTitle:@"Cancel"
|
|
otherButtonTitles:@"Download", nil];
|
|
alert.tag = 0;
|
|
[alert show];
|
|
}
|
|
else if (state == kKMKeyboardStateDownloading || state == kKMKeyboardStateNone) {
|
|
// Do nothing
|
|
}
|
|
else {
|
|
// Add keyboard.
|
|
[[KMManager sharedInstance] addKeyboardWithID:kbID languageID:langID keyboardName:kbName languageName:langName isRTL:[isRTL isEqualToString:@"Y"]?YES:NO isCustom:NO font:font oskFont:oskFont];
|
|
[[KMManager sharedInstance] setKeyboardWithID:kbID languageID:langID keyboardName:kbName languageName:langName font:font oskFont:oskFont];
|
|
[self.navigationController popToRootViewControllerAnimated:YES];
|
|
}*/
|
|
}
|
|
}
|
|
|
|
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
|
|
[self showLanguageDetailViewWithTitle:[tableView cellForRowAtIndexPath:indexPath].textLabel.text languageIndex:indexPath.section];
|
|
}
|
|
|
|
- (void)showLanguageDetailViewWithTitle:(NSString *)title languageIndex:(NSInteger)langIndex {
|
|
LanguageDetailViewController *langDetailView = [[LanguageDetailViewController alloc] init];
|
|
NSArray *languages = [[KMManager sharedInstance] languages];
|
|
langDetailView.title = title;
|
|
langDetailView.languageIndex = langIndex;
|
|
langDetailView.languageName = [[languages objectAtIndex:langIndex] objectForKey:kKeymanNameKey];
|
|
langDetailView.languageID = [[languages objectAtIndex:langIndex] objectForKey:kKeymanIdKey];
|
|
langDetailView.keyboards = [[NSArray alloc] initWithArray:[[KMManager sharedInstance] keyboardsForIndex:langIndex]];
|
|
|
|
[self.navigationController pushViewController:langDetailView animated:YES];
|
|
}
|
|
|
|
#pragma mark - Alert view delegate
|
|
|
|
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
|
|
if (alertView.tag == kmErrorAlertTag) {
|
|
if ([KMManager sharedInstance].languages == nil) {
|
|
[self.navigationController popToRootViewControllerAnimated:YES];
|
|
}
|
|
}
|
|
else {
|
|
// Keyboard download confirmation alert (tag is used for keyboard index).
|
|
if (buttonIndex != alertView.cancelButtonIndex) {
|
|
[[KMManager sharedInstance] downloadKeyboardForLanguageIndex:selectedSection keyboardIndex:alertView.tag isUpdate:self.isUpdate];
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark - Keyman notifications
|
|
|
|
- (void)languageFetchFinished {
|
|
[self dismissActivityView];
|
|
[self.tableView reloadData];
|
|
if ([self numberOfSectionsInTableView:self.tableView] == 0) {
|
|
[self showConnectionErrorAlert];
|
|
}
|
|
}
|
|
|
|
- (void)languageFetchFailed {
|
|
[self dismissActivityView];
|
|
[self showConnectionErrorAlert];
|
|
}
|
|
|
|
- (void)keyboardDownloadStarted:(NSNotification *)notification {
|
|
[self.view setUserInteractionEnabled:NO];
|
|
[self.navigationItem setHidesBackButton:YES animated:YES];
|
|
|
|
CGRect frame = [self.navigationController.toolbar frame];
|
|
CGFloat width = frame.size.width;
|
|
CGFloat height = frame.size.height;
|
|
frame.size.width = width*0.95;
|
|
frame.size.height = height*0.7;
|
|
UILabel *label = [[UILabel alloc] initWithFrame:frame];
|
|
[label setBackgroundColor:[UIColor clearColor]];
|
|
[label setTextColor:[UIColor whiteColor]];
|
|
[label setTextAlignment:NSTextAlignmentCenter];
|
|
[label setCenter:CGPointMake(width*0.5, height*0.5)];
|
|
[label setText:@"Downloading\u2026"];
|
|
[label setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
|
|
[label setTag:kmToolbarLabelTag];
|
|
|
|
UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
|
frame = [indicatorView frame];
|
|
[indicatorView setCenter:CGPointMake(width - frame.size.width, height*0.5)];
|
|
[indicatorView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin];
|
|
[indicatorView setTag:kmToolbarActivityIndicatorTag];
|
|
[indicatorView startAnimating];
|
|
|
|
[[self.navigationController.toolbar viewWithTag:kmToolbarButtonTag] removeFromSuperview];
|
|
[[self.navigationController.toolbar viewWithTag:kmToolbarLabelTag] removeFromSuperview];
|
|
[[self.navigationController.toolbar viewWithTag:kmToolbarActivityIndicatorTag] removeFromSuperview];
|
|
[self.navigationController.toolbar addSubview:label];
|
|
[self.navigationController.toolbar addSubview:indicatorView];
|
|
[self.navigationController setToolbarHidden:NO animated:YES];
|
|
}
|
|
|
|
- (void)keyboardDownloadFailed:(NSNotification *)notification {
|
|
[self.view setUserInteractionEnabled:YES];
|
|
[self.navigationItem setHidesBackButton:NO animated:YES];
|
|
}
|
|
|
|
#pragma mark - Private methods
|
|
|
|
- (void)showActivityView {
|
|
[self.view setUserInteractionEnabled:NO];
|
|
|
|
UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
|
|
UIView *activityView = [[UIView alloc] initWithFrame:CGRectInset(indicatorView.bounds, -10.0f, -10.0f)];
|
|
activityView.backgroundColor = [UIColor colorWithWhite:0.5f alpha:0.8f];
|
|
activityView.layer.cornerRadius = 6.0f;
|
|
activityView.center = self.view.center;
|
|
activityView.tag = kmActivityViewTag;
|
|
activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
|
|
|
|
indicatorView.center = CGPointMake(activityView.bounds.size.width*0.5f, activityView.bounds.size.height*0.5f);
|
|
[indicatorView startAnimating];
|
|
[activityView addSubview:indicatorView];
|
|
|
|
[self.view addSubview:activityView];
|
|
}
|
|
|
|
- (void)dismissActivityView {
|
|
UIView *activityView = [self.view viewWithTag:kmActivityViewTag];
|
|
[activityView removeFromSuperview];
|
|
[self.view setUserInteractionEnabled:YES];
|
|
}
|
|
|
|
- (void)loadUserKeyboards {
|
|
NSUserDefaults *userData = [[KMManager sharedInstance] activeUserDefaults];
|
|
NSArray *userKbList = [[NSArray alloc] initWithArray:[userData arrayForKey:kKeymanUserKeyboardsListKey]];
|
|
NSUInteger len = [userKbList count];
|
|
|
|
if (len == 0) {
|
|
userKeyboards = nil;
|
|
return;
|
|
}
|
|
|
|
NSString *langID = nil;
|
|
NSString *kbID = nil;
|
|
NSString *dictKey = nil;
|
|
userKeyboards = [[NSMutableDictionary alloc] initWithCapacity:len];
|
|
for (NSDictionary *kb in userKbList) {
|
|
langID = [kb objectForKey:kKeymanLanguageIdKey];
|
|
kbID = [kb objectForKey:kKeymanKeyboardIdKey];
|
|
dictKey = [NSString stringWithFormat:@"%@_%@", langID, kbID];
|
|
[userKeyboards setObject:kb forKey:dictKey];
|
|
}
|
|
}
|
|
|
|
- (BOOL)isAdded:(NSString *)langID keyboardID:(NSString *)kbID {
|
|
if (userKeyboards != nil) {
|
|
if([userKeyboards objectForKey:[NSString stringWithFormat:@"%@_%@", langID, kbID]]) {
|
|
return YES;
|
|
}
|
|
else {
|
|
return NO;
|
|
}
|
|
}
|
|
else {
|
|
return NO;
|
|
}
|
|
}
|
|
|
|
- (void)showConnectionErrorAlert {
|
|
[self dismissActivityView];
|
|
|
|
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Connection Error"
|
|
message:@"Could not reach Keyman server. Please try again later."
|
|
delegate:self
|
|
cancelButtonTitle:@"OK"
|
|
otherButtonTitles:nil];
|
|
alert.tag = kmErrorAlertTag;
|
|
[alert show];
|
|
}
|
|
|
|
@end
|