forked from shadowsocks/shadowsocks-iOS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSWBConfigWindowController.m
243 lines (215 loc) · 7.86 KB
/
SWBConfigWindowController.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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
//
// Created by clowwindy on 14-2-26.
// Copyright (c) 2014 clowwindy. All rights reserved.
//
#import <openssl/evp.h>
#import <QuartzCore/QuartzCore.h>
#import "SWBConfigWindowController.h"
#import "ShadowsocksRunner.h"
#import "ProfileManager.h"
#import "encrypt.h"
@implementation SWBConfigWindowController {
Configuration *configuration;
}
- (void)windowWillLoad {
[super windowWillLoad];
}
- (void)addMethods {
for (int i = 0; i < kShadowsocksMethods; i++) {
const char* method_name = shadowsocks_encryption_names[i];
NSString *methodName = [[NSString alloc] initWithBytes:method_name length:strlen(method_name) encoding:NSUTF8StringEncoding];
[_methodBox addItemWithObjectValue:methodName];
}
}
- (void)loadSettings {
configuration = [ProfileManager configuration];
[self.tableView reloadData];
[self loadCurrentProfile];
}
- (void)saveSettings {
[ProfileManager saveConfiguration:configuration];
// if (_publicMatrix.selectedColumn == 0) {
// [ShadowsocksRunner setUsingPublicServer:YES];
// } else {
// [ShadowsocksRunner setUsingPublicServer:NO];
// [ShadowsocksRunner saveConfigForKey:kShadowsocksIPKey value:[_serverField stringValue]];
// [ShadowsocksRunner saveConfigForKey:kShadowsocksPortKey value:[_portField stringValue]];
// [ShadowsocksRunner saveConfigForKey:kShadowsocksPasswordKey value:[_passwordField stringValue]];
// [ShadowsocksRunner saveConfigForKey:kShadowsocksEncryptionKey value:[_methodBox stringValue]];
// }
// if (self.delegate != nil) {
// if ([self.delegate respondsToSelector:@selector(configurationDidChange)]) {
// [self.delegate configurationDidChange];
// }
// }
}
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row {
if (self.tableView.selectedRow < 0) {
// always allow no selection to selection
return YES;
}
if (row >= 0 && row < configuration.profiles.count) {
if ([self validateCurrentProfile]) {
[self saveCurrentProfile];
} else {
return NO;
}
}
// always allow selection to no selection
return YES;
}
- (void)tableViewSelectionDidChange:(NSNotification *)notification {
if (self.tableView.selectedRow >= 0) {
[self loadCurrentProfile];
}
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Profile *profile = configuration.profiles[row];
if ([profile.server isEqualToString:@""]) {
return @"New Server";
}
return profile.server;
}
- (IBAction)sectionClick:(id)sender {
NSInteger index = ((NSSegmentedControl *)sender).selectedSegment;
if (index == 0) {
[self add:sender];
} else if (index == 1) {
[self remove:sender];
}
}
- (IBAction)add:(id)sender {
if (configuration.profiles.count != 0 && ![self saveCurrentProfile]) {
[self shakeWindow];
return;
}
Profile *profile = [[Profile alloc] init];
profile.server = @"";
profile.serverPort = 8388;
profile.method = @"aes-256-cfb";
profile.password = @"";
[((NSMutableArray *) configuration.profiles) addObject:profile];
[self.tableView reloadData];
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:(configuration.profiles.count - 1)] byExtendingSelection:NO];
[self updateSettingsBoxVisible:self];
[self loadCurrentProfile];
}
- (IBAction)remove:(id)sender {
NSInteger selection = self.tableView.selectedRow;
if (selection >= 0 && selection < configuration.profiles.count) {
[((NSMutableArray *) configuration.profiles) removeObjectAtIndex:selection];
[self.tableView reloadData];
[self updateSettingsBoxVisible:self];
if (configuration.profiles.count > 0) {
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:(configuration.profiles.count - 1)] byExtendingSelection:NO];
}
[self loadCurrentProfile];
if (configuration.current > selection) {
// select the original profile
configuration.current = configuration.current - 1;
}
}
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return configuration.profiles.count;
}
- (void)windowDidLoad {
self.tableView.delegate = self;
self.tableView.dataSource = self;
[super windowDidLoad];
[self addMethods];
[self loadSettings];
[self updateSettingsBoxVisible:self];
}
- (IBAction)updateSettingsBoxVisible:(id)sender {
if (configuration.profiles.count == 0) {
[_settingsBox setHidden:YES];
[_placeholderLabel setHidden:NO];
} else {
[_settingsBox setHidden:NO];
[_placeholderLabel setHidden:YES];
}
}
- (void)loadCurrentProfile {
if (configuration.profiles.count > 0) {
if (self.tableView.selectedRow >= 0 && self.tableView.selectedRow < configuration.profiles.count) {
Profile *profile = configuration.profiles[self.tableView.selectedRow];
[_serverField setStringValue:profile.server];
[_portField setStringValue:[NSString stringWithFormat:@"%ld", (long)profile.serverPort]];
[_methodBox setStringValue:profile.method];
[_passwordField setStringValue:profile.password];
if (profile.remarks) {
[_remarksField setStringValue:profile.remarks];
} else {
[_remarksField setStringValue:@""];
}
}
}
}
- (BOOL)saveCurrentProfile {
if (![self validateCurrentProfile]) {
return NO;
}
if (self.tableView.selectedRow >= 0 && self.tableView.selectedRow < configuration.profiles.count) {
Profile *profile = configuration.profiles[self.tableView.selectedRow];
profile.server = [_serverField stringValue];
profile.serverPort = [_portField integerValue];
profile.method = [_methodBox stringValue];
profile.password = [_passwordField stringValue];
profile.remarks = [_remarksField stringValue];
}
return YES;
}
- (BOOL)validateCurrentProfile {
if ([[_serverField stringValue] isEqualToString:@""]) {
[_serverField becomeFirstResponder];
return NO;
}
if ([_portField integerValue] == 0) {
[_portField becomeFirstResponder];
return NO;
}
if ([[_methodBox stringValue] isEqualToString:@""]) {
[_methodBox becomeFirstResponder];
return NO;
}
if ([[_passwordField stringValue] isEqualToString:@""]) {
[_passwordField becomeFirstResponder];
return NO;
}
return YES;
}
- (IBAction)OK:(id)sender {
if ([self saveCurrentProfile]) {
[self saveSettings];
[ShadowsocksRunner reloadConfig];
[self.delegate configurationDidChange];
[self.window performClose:self];
} else {
[self shakeWindow];
}
}
- (IBAction)cancel:(id)sender {
[self.window performClose:self];
}
- (void)shakeWindow {
static int numberOfShakes = 3;
static float durationOfShake = 0.7f;
static float vigourOfShake = 0.03f;
CGRect frame=[self.window frame];
CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animation];
CGMutablePathRef shakePath = CGPathCreateMutable();
CGPathMoveToPoint(shakePath, NULL, NSMinX(frame), NSMinY(frame));
int index;
for (index = 0; index < numberOfShakes; ++index)
{
CGPathAddLineToPoint(shakePath, NULL, NSMinX(frame) - frame.size.width * vigourOfShake, NSMinY(frame));
CGPathAddLineToPoint(shakePath, NULL, NSMinX(frame) + frame.size.width * vigourOfShake, NSMinY(frame));
}
CGPathCloseSubpath(shakePath);
shakeAnimation.path = shakePath;
shakeAnimation.duration = durationOfShake;
[self.window setAnimations:[NSDictionary dictionaryWithObject: shakeAnimation forKey:@"frameOrigin"]];
[[self.window animator] setFrameOrigin:[self.window frame].origin];
}
@end