osx: Initial import of the Objective-C App graphical user interface

This commit is contained in:
Martin Willi
2014-12-17 16:53:45 +01:00
parent 04337fed02
commit dacd667c84
27 changed files with 4681 additions and 9 deletions
+358
View File
@@ -0,0 +1,358 @@
/*
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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. See the GNU General Public License
* for more details.
*/
#import "AppDelegate.h"
#import "Control.h"
#import "LogController.h"
#import "ConnController.h"
#import "PasswordController.h"
@implementation AppDelegate {
NSStatusItem *statusItem;
NSImage *active;
NSImage *inactive;
NSInteger nonConnectionItemCount;
NSMutableArray *connections;
Control *control;
ConnController *editor;
PasswordController *password;
}
- (void)change:(connectionState)state withConnection:(NSDictionary*)conn
{
NSInteger idx;
NSMenuItem *item;
idx = [statusMenu indexOfItemWithRepresentedObject:conn];
if (idx != -1)
{
item = [statusMenu itemAtIndex:idx];
switch (state) {
case STATE_DOWN:
[item setState:NSOffState];
[item setAction:@selector(doConnection:)];
[[[item submenu] itemAtIndex:0] setAction:@selector(doConnection:)];
[[[item submenu] itemAtIndex:0] setTitle:@"Connect"];
[[[item submenu] itemAtIndex:1] setAction:@selector(editConnection:)];
[[[item submenu] itemAtIndex:2] setAction:@selector(removeConnection:)];
[self updateIcon];
break;
case STATE_WORKING:
[item setState:NSMixedState];
[item setAction:@selector(undoConnection:)];
[[[item submenu] itemAtIndex:0] setAction:@selector(undoConnection:)];
[[[item submenu] itemAtIndex:0] setTitle:@"Disconnect"];
[[[item submenu] itemAtIndex:1] setAction:nil];
[[[item submenu] itemAtIndex:2] setAction:nil];
[self updateIcon];
break;
case STATE_UP:
[item setState:NSOnState];
[self updateIcon];
break;
}
}
}
- (NSString*)createPasswordWithConnection:(NSDictionary*)conn
{
return [password query];
}
- (void)raise:(NSString*)alert withConnection:(NSDictionary*)conn
{
NSAlert *popup;
NSString *text;
text = [[NSString alloc]
initWithFormat:@"Establishing connection %@ failed:",
[conn objectForKey:@"name"]];
popup = [[NSAlert alloc] init];
[popup setMessageText:text];
[popup setInformativeText:alert];
[popup runModal];
[text release];
[popup release];
}
- (void)log:(NSString*)line withConnection:(NSDictionary*)conn
{
[[self findLog:conn] appendLine:line];
}
- (IBAction)undoConnection:(id)sender
{
NSDictionary *conn;
conn = [sender representedObject];
[control disconnect:conn];
}
- (IBAction)doConnection:(id)sender
{
NSDictionary *conn;
conn = [sender representedObject];
[[self findLog:conn] clear];
[control connect:conn];
}
- (IBAction)addConnection:(id)sender
{
NSMutableDictionary *conn;
conn = [editor createConnection];
if (conn)
{
[connections insertObject:conn atIndex:[connections count]];
[self saveConnections];
}
}
- (IBAction)editConnection:(id)sender
{
NSMutableDictionary *conn;
conn = [sender representedObject];
if ([editor editConnection:conn])
{
[self saveConnections];
}
}
- (IBAction)removeConnection:(id)sender
{
NSDictionary *conn;
conn = [sender representedObject];
[connections removeObject:conn];
[self saveConnections];
}
- (void)loadConnections
{
NSUserDefaults *defaults;
NSArray *array;
defaults = [NSUserDefaults standardUserDefaults];
array = [defaults arrayForKey:@"connections"];
if (array)
{
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *dict;
dict = [obj mutableCopy];
[connections insertObject:dict atIndex:[connections count]];
[dict release];
}
}];
}
[defaults addObserver:self
forKeyPath:@"connections"
options:NSKeyValueObservingOptionNew
context:NULL];
}
- (void)saveConnections
{
NSUserDefaults *defaults;
defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:connections forKey:@"connections"];
[defaults synchronize];
}
- (void)viewLog:(id)sender
{
[[sender representedObject] show];
}
- (LogController*)findLog:(NSDictionary *)connection
{
NSInteger idx;
NSMenuItem *item;
idx = [statusMenu indexOfItemWithRepresentedObject:connection];
if (idx != -1)
{
item = [statusMenu itemAtIndex:idx];
item = [[item submenu] itemAtIndex:3];
return [item representedObject];
}
return nil;
}
- (void)addMenuItem:(NSDictionary *)connection
{
NSString *name, *title;
NSMenuItem *item;
NSMenu *submenu;
LogController *ctl;
name = [connection objectForKey:@"name"];
if (name) {
/* create submenu first */
submenu = [[NSMenu alloc] initWithTitle:@"submenu"];
item = [[NSMenuItem alloc] initWithTitle:@"Connect"
action:@selector(doConnection:)
keyEquivalent:@""];
[item setTarget:self];
[item setRepresentedObject:connection];
[submenu insertItem:item atIndex:0];
[item release];
item = [[NSMenuItem alloc] initWithTitle:@"Edit..."
action:@selector(editConnection:)
keyEquivalent:@""];
[item setTarget:self];
[item setRepresentedObject:connection];
[submenu insertItem:item atIndex:1];
[item release];
item = [[NSMenuItem alloc] initWithTitle:@"Remove"
action:@selector(removeConnection:)
keyEquivalent:@""];
[item setTarget:self];
[item setRepresentedObject:connection];
[submenu insertItem:item atIndex:2];
[item release];
item = [[NSMenuItem alloc] initWithTitle:@"View Log..."
action:@selector(viewLog:)
keyEquivalent:@""];
[item setTarget:self];
ctl = [[LogController alloc] initWithWindowNibName:@"LogWindow"];
title = [NSString stringWithFormat: @"strongSwan Log: %@", name];
[[ctl window] setTitle:title];
[item setRepresentedObject:ctl];
[ctl release];
[submenu insertItem:item atIndex:3];
[item release];
item = [[NSMenuItem alloc] initWithTitle:name
action:@selector(doConnection:)
keyEquivalent:@""];
[item setTarget:self];
[item setRepresentedObject:connection];
[item setSubmenu:submenu];
[submenu release];
[statusMenu insertItem:item atIndex:
[statusMenu numberOfItems] - nonConnectionItemCount];
[item release];
}
}
- (void)repopulateMenu
{
while ([statusMenu numberOfItems] > nonConnectionItemCount)
{
[statusMenu removeItemAtIndex:0];
}
[connections enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
if ([obj isKindOfClass:[NSDictionary class]]) {
[self addMenuItem:obj];
}
}];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object change:(NSDictionary *)change
context:(void *)context
{
[self repopulateMenu];
}
- (void)updateIcon
{
NSMenuItem *item;
bool anyactive = FALSE;
int i;
for (i = 0; i < [statusMenu numberOfItems] - nonConnectionItemCount; i++)
{
item = [statusMenu itemAtIndex:i];
if ([item state] == NSOnState)
{
anyactive = TRUE;
break;
}
}
[statusItem setImage: anyactive ? active : inactive];
}
- (void)initializeMenu
{
NSImage *icon;
NSString *path;
statusItem = [[[NSStatusBar systemStatusBar]
statusItemWithLength:NSVariableStatusItemLength] retain];
[statusItem setMenu:statusMenu];
[statusItem setHighlightMode:YES];
path = [[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"];
icon = [[NSImage alloc] initWithContentsOfFile:path];
[statusItem setImage:icon];
inactive = icon;
path = [[NSBundle mainBundle] pathForResource:@"icon-active" ofType:@"png"];
icon = [[NSImage alloc] initWithContentsOfFile:path];
active = icon;
path = [[NSBundle mainBundle] pathForResource:@"icon-alt" ofType:@"png"];
icon = [[NSImage alloc] initWithContentsOfFile:path];
[statusItem setAlternateImage:icon];
[icon release];
nonConnectionItemCount = [statusMenu numberOfItems];
[self repopulateMenu];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self loadConnections];
[self initializeMenu];
}
- (id)init
{
self = [super init];
control = [[Control alloc] initWithDelegate:self];
connections = [[NSMutableArray alloc] init];
editor = [[ConnController alloc] initWithWindowNibName:@"ConnWindow"];
password = [[PasswordController alloc] initWithWindowNibName:@"PasswordWindow"];
return self;
}
- (void)dealloc
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObserver:self forKeyPath:@"connections"];
[statusItem release];
[active release];
[inactive release];
[connections release];
[control release];
[editor release];
[password release];
[super dealloc];
}
@end