-
Notifications
You must be signed in to change notification settings - Fork 0
/
Menulet.m
140 lines (114 loc) · 3.65 KB
/
Menulet.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//
// Menulet.m
// HostfileManager
//
// Created by ezarko on 11/23/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "Menulet.h"
@implementation Menulet
-(void)dealloc
{
[theMenu release];
[statusItem release];
[super dealloc];
}
-(void)awakeFromNib
{
statusItem = [[[NSStatusBar systemStatusBar]
statusItemWithLength:NSVariableStatusItemLength]
retain];
[statusItem setImage:[NSImage imageNamed:@"gh"]];
[statusItem setHighlightMode:YES];
[statusItem setTitle:[NSString
stringWithString:@""]];
[statusItem setEnabled:YES];
[statusItem setToolTip:@"Hostfile Manager"];
theMenu = [[NSMenu alloc] initWithTitle:@""];
[self refresh:self];
[theMenu addItem:[NSMenuItem separatorItem]];
NSMenuItem *theMenuItem = [[NSMenuItem alloc] initWithTitle:@"Refresh" action:@selector(refresh:) keyEquivalent:@"R"];
[theMenuItem setTarget:self];
[theMenu addItem:theMenuItem];
[theMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"Q"];
[statusItem setMenu:theMenu];
OSStatus err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagInteractionAllowed, &auth);
if (err != errAuthorizationSuccess)
NSLog(@"AuthorizationCreate returned %@\n", err);
}
NSInteger substringSort(id string1, id string2, void *context)
{
NSString* v1 = [string1 substringFromIndex:2];
NSString* v2 = [string2 substringFromIndex:2];
return [v1 localizedCompare:v2];
}
-(NSArray *)status
{
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/local/bin/hostfiles"];
NSArray *arguments = [NSArray arrayWithObjects:@"--status", nil];
[task setArguments: arguments];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file = [pipe fileHandleForReading];
[task launch];
NSData *data = [file readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSArray *lines = [string componentsSeparatedByString:@"\n"];
NSRange theRange;
theRange.location = 0;
theRange.length = [lines count] - 1;
return [[lines subarrayWithRange:theRange] sortedArrayUsingFunction:substringSort context:NULL];
}
-(IBAction)refresh:(id)sender
{
// remove items up to sepaerator
for (int i = [theMenu numberOfItems] - 4; i >= 0; --i) {
[theMenu removeItemAtIndex:i];
}
// insert items before separator
NSArray *fragments = [self status];
for (int i = 0; i < [fragments count]; ++i) {
NSString *text = [fragments objectAtIndex:i];
NSMenuItem *theMenuItem = [[NSMenuItem alloc] initWithTitle:[text substringFromIndex:2] action:@selector(toggleFragment:) keyEquivalent:@""];
[theMenuItem setTarget:self];
switch ([text characterAtIndex:0]) {
case '+':
[theMenuItem setState:NSOnState];
break;
case '*':
[theMenuItem setState:NSMixedState];
break;
case ' ':
[theMenuItem setState:NSOffState];
break;
default:
NSLog(@"Unknown state:%@\n", [text characterAtIndex:0]);
}
[theMenu insertItem:theMenuItem atIndex:i];
}
}
-(IBAction)toggleFragment:(id)sender
{
const char *command = "/usr/local/bin/hostfiles";
char *args[] = {NULL, [[sender title] cStringUsingEncoding:NSUTF8StringEncoding], NULL};
NSInteger state;
switch ([sender state]) {
case NSOnState:
case NSMixedState:
args[0] = "--disable";
state = NSOffState;
break;
case NSOffState:
args[0] = "--enable";
state = NSOnState;
}
OSStatus err = AuthorizationExecuteWithPrivileges(auth, command, kAuthorizationFlagDefaults, args, NULL);
if (err != errAuthorizationSuccess) {
NSLog(@"AuthorizationExecuteWithPrivileges returned %@\n", err);
return;
}
[sender setState:state];
}
@end