Now translated. One minor crash to figure out.
This commit is contained in:
281
ZeroTier One/AppDelegate.m
Normal file
281
ZeroTier One/AppDelegate.m
Normal file
@@ -0,0 +1,281 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// ZeroTier One
|
||||
//
|
||||
// Created by Grant Limberg on 8/7/16.
|
||||
// Copyright © 2016 ZeroTier, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "NetworkMonitor.h"
|
||||
#import "Network.h"
|
||||
#import "NodeStatus.h"
|
||||
#import "JoinNetworkViewController.h"
|
||||
#import "ShowNetworksViewController.h"
|
||||
#import "PreferencesViewController.h"
|
||||
#import "AboutViewController.h"
|
||||
#import "ServiceCom.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:-2.0f];
|
||||
self.networkListPopover = [[NSPopover alloc] init];
|
||||
self.joinNetworkPopover = [[NSPopover alloc] init];
|
||||
self.preferencesPopover = [[NSPopover alloc] init];
|
||||
self.aboutPopover = [[NSPopover alloc] init];
|
||||
self.transientMonitor = nil;
|
||||
self.monitor = [[NetworkMonitor alloc] init];
|
||||
self.networks = [NSMutableArray<Network*> array];
|
||||
self.status = nil;
|
||||
self.pasteboard = [NSPasteboard generalPasteboard];
|
||||
|
||||
[self.pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSDictionary *defaultsDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"firstRun"];
|
||||
[defaults registerDefaults:defaultsDict];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[nc addObserver:self
|
||||
selector:@selector(onNetworkListUpdated:)
|
||||
name:NetworkUpdateKey
|
||||
object:nil];
|
||||
[nc addObserver:self
|
||||
selector:@selector(onNodeStatusUpdated:)
|
||||
name:StatusUpdateKey
|
||||
object:nil];
|
||||
|
||||
self.statusItem.image = [NSImage imageNamed:@"MenuBarIconMac"];
|
||||
|
||||
[self buildMenu];
|
||||
|
||||
self.joinNetworkPopover.contentViewController = [[JoinNetworkViewController alloc] initWithNibName:@"JoinNetworkViewController" bundle:nil];
|
||||
self.joinNetworkPopover.behavior = NSPopoverBehaviorTransient;
|
||||
|
||||
ShowNetworksViewController *showNetworksView = [[ShowNetworksViewController alloc] initWithNibName:@"ShowNetworksViewController" bundle:nil];
|
||||
showNetworksView.netMonitor = self.monitor;
|
||||
self.networkListPopover.contentViewController = showNetworksView;
|
||||
self.networkListPopover.behavior = NSPopoverBehaviorTransient;
|
||||
|
||||
PreferencesViewController *prefsView = [[PreferencesViewController alloc] initWithNibName:@"PreferencesViewController" bundle:nil];
|
||||
self.preferencesPopover.contentViewController = prefsView;
|
||||
self.preferencesPopover.behavior = NSPopoverBehaviorTransient;
|
||||
|
||||
self.aboutPopover.contentViewController = [[AboutViewController alloc] initWithNibName:@"AboutViewController" bundle:nil];
|
||||
self.aboutPopover.behavior = NSPopoverBehaviorTransient;
|
||||
|
||||
BOOL firstRun = [defaults boolForKey:@"firstRun"];
|
||||
|
||||
if(firstRun) {
|
||||
[defaults setBool:NO forKey:@"firstRun"];
|
||||
[defaults synchronize];
|
||||
|
||||
[prefsView setLaunchAtLoginEnabled:YES];
|
||||
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
[self showAbout];
|
||||
}];
|
||||
}
|
||||
|
||||
[self.monitor updateNetworkInfo];
|
||||
[self.monitor start];
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)showNetworks {
|
||||
if(self.statusItem.button != nil) {
|
||||
NSStatusBarButton *button = self.statusItem.button;
|
||||
[self.networkListPopover showRelativeToRect:button.bounds
|
||||
ofView:button
|
||||
preferredEdge:NSMinYEdge];
|
||||
|
||||
if(self.transientMonitor == nil) {
|
||||
self.transientMonitor =
|
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown)
|
||||
handler:^(NSEvent * _Nonnull e) {
|
||||
[NSEvent removeMonitor:self.transientMonitor];
|
||||
self.transientMonitor = nil;
|
||||
[self.networkListPopover close];
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)joinNetwork {
|
||||
if(self.statusItem.button != nil) {
|
||||
NSStatusBarButton *button = self.statusItem.button;
|
||||
[self.joinNetworkPopover showRelativeToRect:button.bounds
|
||||
ofView:button
|
||||
preferredEdge:NSMinYEdge];
|
||||
if(self.transientMonitor == nil) {
|
||||
self.transientMonitor =
|
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown)
|
||||
handler:^(NSEvent * _Nonnull e) {
|
||||
[NSEvent removeMonitor:self.transientMonitor];
|
||||
self.transientMonitor = nil;
|
||||
[self.joinNetworkPopover close];
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showPreferences {
|
||||
if(self.statusItem.button != nil) {
|
||||
NSStatusBarButton *button = self.statusItem.button;
|
||||
[self.preferencesPopover showRelativeToRect:button.bounds
|
||||
ofView:button
|
||||
preferredEdge:NSMinYEdge];
|
||||
if(self.transientMonitor == nil) {
|
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown)
|
||||
handler:^(NSEvent * _Nonnull e) {
|
||||
[NSEvent removeMonitor:self.transientMonitor];
|
||||
self.transientMonitor = nil;
|
||||
[self.preferencesPopover close];
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showAbout {
|
||||
if(self.statusItem.button != nil) {
|
||||
NSStatusBarButton *button = self.statusItem.button;
|
||||
[self.aboutPopover showRelativeToRect:button.bounds
|
||||
ofView:button
|
||||
preferredEdge:NSMinYEdge];
|
||||
if(self.transientMonitor == nil) {
|
||||
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDown|NSRightMouseDown|NSOtherMouseDown)
|
||||
handler:^(NSEvent * _Nonnull e) {
|
||||
[NSEvent removeMonitor:self.transientMonitor];
|
||||
self.transientMonitor = nil;
|
||||
[self.aboutPopover close];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)quit {
|
||||
[NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0];
|
||||
}
|
||||
|
||||
- (void)onNetworkListUpdated:(NSNotification*)note {
|
||||
NSArray<Network*> *netList = [note.userInfo objectForKey:@"networks"];
|
||||
[(ShowNetworksViewController*)self.networkListPopover.contentViewController setNetworks:netList];
|
||||
self.networks = [netList mutableCopy];
|
||||
|
||||
[self buildMenu];
|
||||
}
|
||||
|
||||
- (void)onNodeStatusUpdated:(NSNotification*)note {
|
||||
NodeStatus *status = [note.userInfo objectForKey:@"status"];
|
||||
self.status = status;
|
||||
|
||||
[self buildMenu];
|
||||
}
|
||||
|
||||
- (void)buildMenu {
|
||||
NSMenu *menu = [[NSMenu alloc] init];
|
||||
menu.delegate = self;
|
||||
|
||||
if(self.status != nil) {
|
||||
NSString *nodeId = @"Node ID: ";
|
||||
nodeId = [nodeId stringByAppendingString:self.status.address];
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:nodeId
|
||||
action:@selector(copyNodeID)
|
||||
keyEquivalent:@""]];
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
}
|
||||
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Network Details..."
|
||||
action:@selector(showNetworks)
|
||||
keyEquivalent:@"n"]];
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Join Network..."
|
||||
action:@selector(joinNetwork)
|
||||
keyEquivalent:@"j"]];
|
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
if([self.networks count] > 0) {
|
||||
for(Network *net in self.networks) {
|
||||
NSString *nwid = [NSString stringWithFormat:@"%10llx", net.nwid];
|
||||
NSString *networkName = @"";
|
||||
if([net.name lengthOfBytesUsingEncoding:NSUTF8StringEncoding] == 0) {
|
||||
networkName = nwid;
|
||||
}
|
||||
else {
|
||||
networkName = [NSString stringWithFormat:@"%@ (%@)", nwid, net.name];
|
||||
}
|
||||
|
||||
if(net.allowDefault && net.connected) {
|
||||
networkName = [networkName stringByAppendingString:@" [default]"];
|
||||
}
|
||||
|
||||
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:networkName
|
||||
action:@selector(toggleNetwork:)
|
||||
keyEquivalent:@""];
|
||||
if(net.connected) {
|
||||
item.state = NSOnState;
|
||||
}
|
||||
else {
|
||||
item.state = NSOffState;
|
||||
}
|
||||
|
||||
item.representedObject = net;
|
||||
|
||||
[menu addItem:item];
|
||||
}
|
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
}
|
||||
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"About ZeroTier One..."
|
||||
action:@selector(showAbout)
|
||||
keyEquivalent:@""]];
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Preferences..."
|
||||
action:@selector(showPreferences)
|
||||
keyEquivalent:@""]];
|
||||
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
[menu addItem:[[NSMenuItem alloc] initWithTitle:@"Quit"
|
||||
action:@selector(quit)
|
||||
keyEquivalent:@"q"]];
|
||||
|
||||
self.statusItem.menu = menu;
|
||||
}
|
||||
|
||||
- (void)toggleNetwork:(NSMenuItem*)sender {
|
||||
Network *network = sender.representedObject;
|
||||
NSString *nwid = [NSString stringWithFormat:@"%10llx", network.nwid];
|
||||
|
||||
if(network.connected) {
|
||||
[[ServiceCom sharedInstance] leaveNetwork:nwid];
|
||||
}
|
||||
else {
|
||||
[[ServiceCom sharedInstance] joinNetwork:nwid
|
||||
allowManaged:network.allowManaged
|
||||
allowGlobal:network.allowGlobal
|
||||
allowDefault:(network.allowDefault && ![Network defaultRouteExists:self.networks])];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)copyNodeID {
|
||||
if(self.status != nil) {
|
||||
[self.pasteboard setString:self.status.address forType:NSPasteboardTypeString];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)menuWillOpen:(NSMenu*)menu {
|
||||
|
||||
}
|
||||
|
||||
- (void)menuDidClose:(NSMenu*)menu {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user