root/trunk/Inspectors/JVBuddyInspector.m

Revision 3497, 10.6 kB (checked in by timothy, 2 years ago)

Prevent deletion of the last buddy identifier.

Line 
1 #import "MVConnectionsController.h"
2 #import "MVBuddyListController.h"
3 #import "JVBuddyInspector.h"
4
5 @implementation JVBuddy (JVBuddyInspection)
6 - (id <JVInspector>) inspector {
7         return [[[JVBuddyInspector alloc] initWithBuddy:self] autorelease];
8 }
9 @end
10
11 #pragma mark -
12
13 @implementation JVBuddyInspector
14 - (id) initWithBuddy:(JVBuddy *) buddy {
15         if( ( self = [self init] ) )
16                 _buddy = [buddy retain];
17         return self;
18 }
19
20 - (void) dealloc {
21         [[NSNotificationCenter defaultCenter] removeObserver:self];
22
23         [identifiersTable setDataSource:nil];
24         [identifiersTable setDelegate:nil];
25
26         [_buddy release];
27         [_currentRule release];
28         [_editDomains release];
29
30         _buddy = nil;
31         _currentRule = nil;
32         _editDomains = nil;
33
34         [super dealloc];
35 }
36
37 #pragma mark -
38
39 - (NSView *) view {
40         if( ! _nibLoaded ) _nibLoaded = [NSBundle loadNibNamed:@"JVBuddyInspector" owner:self];
41         return view;
42 }
43
44 - (NSSize) minSize {
45         return NSMakeSize( 300., 350. );
46 }
47
48 - (NSString *) title {
49         return [_buddy compositeName];
50 }
51
52 - (NSString *) type {
53         return NSLocalizedString( @"Buddy", "buddy inspector type" );
54 }
55
56 - (void) willLoad {
57         while( [voices numberOfItems] > 2 )
58                 [voices removeItemAtIndex:2];
59
60         NSEnumerator *enumerator = [[NSSpeechSynthesizer availableVoices] objectEnumerator];
61         NSString *voiceIdentifier = nil;
62         while( ( voiceIdentifier = [enumerator nextObject] ) ) {
63                 [voices addItemWithTitle:[[NSSpeechSynthesizer attributesForVoice:voiceIdentifier] objectForKey:NSVoiceName]];
64                 [[voices lastItem] setRepresentedObject:voiceIdentifier];
65         }
66
67         [voices selectItemAtIndex:[[voices menu] indexOfItemWithRepresentedObject:[_buddy speechVoice]]];
68         if( ! [voices selectedItem] ) [voices selectItemAtIndex:0];
69
70         [removeIdentifier setEnabled:NO];
71         [editIdentifier setEnabled:NO];
72
73         [picture setImage:[_buddy picture]];
74         [firstName setObjectValue:[_buddy firstName]];
75         [lastName setObjectValue:[_buddy lastName]];
76         [nickname setObjectValue:[_buddy givenNickname]];
77         [email setObjectValue:[_buddy primaryEmail]];
78
79         [identifiersTable setTarget:self];
80         [identifiersTable setDoubleAction:@selector( editIdentifier: )];
81 }
82
83 - (BOOL) shouldUnload {
84         [[view window] makeFirstResponder:view];
85         [[MVBuddyListController sharedBuddyList] save];
86         return YES;
87 }
88
89 #pragma mark -
90
91 - (IBAction) addIdentifier:(id) sender {
92         [_currentRule release];
93         _currentRule = [[MVChatUserWatchRule allocWithZone:nil] init];
94
95         [_editDomains release];
96         _editDomains = [[NSMutableArray allocWithZone:nil] init];
97
98         [identifierDomainsTable reloadData];
99
100         [identifierNickname setStringValue:@""];
101         [identifierRealName setStringValue:@""];
102         [identifierUsername setStringValue:@""];
103         [identifierHostname setStringValue:@""];
104         [identifierDomainsTable setEnabled:NO];
105         [addDomain setEnabled:NO];
106         [identifierConnections selectCellWithTag:0];
107
108         [identifierOkay setEnabled:NO];
109
110         [identifierEditPanel makeFirstResponder:identifierNickname];
111
112         _identifierIsNew = YES;
113         [[NSApplication sharedApplication] beginSheet:identifierEditPanel modalForWindow:[view window] modalDelegate:self didEndSelector:@selector( identifierSheetDidEnd:returnCode:contextInfo: ) contextInfo:nil];
114 }
115
116 - (IBAction) editIdentifier:(id) sender {
117         int index = [identifiersTable selectedRow];
118         if( index == -1 ) return;
119
120         [_currentRule release];
121         _currentRule = [[[_buddy watchRules] objectAtIndex:index] retain];
122
123         [_editDomains release];
124         _editDomains = [[NSMutableArray allocWithZone:nil] init];
125         if( [[_currentRule applicableServerDomains] count] ) {
126                 [_editDomains setArray:[_currentRule applicableServerDomains]];
127                 [identifierDomainsTable setEnabled:YES];
128                 [addDomain setEnabled:YES];
129                 [identifierConnections selectCellWithTag:1];
130         } else {
131                 [identifierDomainsTable setEnabled:NO];
132                 [addDomain setEnabled:NO];
133                 [identifierConnections selectCellWithTag:0];
134         }
135
136         [identifierDomainsTable reloadData];
137
138         if( [_currentRule nickname] )
139                 [identifierNickname setStringValue:[_currentRule nickname]];
140         else [identifierNickname setStringValue:@""];
141
142         if( [_currentRule realName] )
143                 [identifierRealName setStringValue:[_currentRule realName]];
144         else [identifierRealName setStringValue:@""];
145
146         if( [_currentRule username] )
147                 [identifierUsername setStringValue:[_currentRule username]];
148         else [identifierUsername setStringValue:@""];
149
150         if( [_currentRule address] )
151                 [identifierHostname setStringValue:[_currentRule address]];
152         else [identifierHostname setStringValue:@""];
153
154         [identifierOkay setEnabled:YES];
155
156         [identifierEditPanel makeFirstResponder:identifierNickname];
157
158         _identifierIsNew = NO;
159         [[NSApplication sharedApplication] beginSheet:identifierEditPanel modalForWindow:[view window] modalDelegate:self didEndSelector:@selector( identifierSheetDidEnd:returnCode:contextInfo: ) contextInfo:nil];
160 }
161
162 - (IBAction) removeIdentifier:(id) sender {
163         int index = [identifiersTable selectedRow];
164         if( index == -1 ) return;
165
166         MVChatUserWatchRule *rule = [[_buddy watchRules] objectAtIndex:index];
167         [_buddy removeWatchRule:rule];
168
169         [_buddy unregisterWithConnections];
170         [_buddy registerWithApplicableConnections];
171
172         [identifiersTable noteNumberOfRowsChanged];
173 }
174
175 - (IBAction) discardIdentifierChanges:(id) sender {
176         [[NSApplication sharedApplication] endSheet:identifierEditPanel returnCode:NO];
177         [identifierEditPanel orderOut:sender];
178 }
179
180 - (IBAction) saveIdentifierChanges:(id) sender {
181         [[NSApplication sharedApplication] endSheet:identifierEditPanel returnCode:YES];
182         [identifierEditPanel orderOut:sender];
183 }
184
185 - (void) identifierSheetDidEnd:(NSWindow *) sheet returnCode:(int) returnCode contextInfo:(void *) contextInfo {
186         if( returnCode ) {
187                 NSString *string = [identifierNickname stringValue];
188                 [_currentRule setNickname:( [string length] ? string : nil )];
189
190                 string = [identifierRealName stringValue];
191                 [_currentRule setRealName:( [string length] ? string : nil )];
192
193                 string = [identifierUsername stringValue];
194                 [_currentRule setUsername:( [string length] ? string : nil )];
195
196                 string = [identifierHostname stringValue];
197                 [_currentRule setAddress:( [string length] ? string : nil )];
198
199                 [_currentRule setApplicableServerDomains:( [_editDomains count] && [identifierConnections selectedTag] ? _editDomains : nil )];
200
201                 if( _identifierIsNew )
202                         [_buddy addWatchRule:_currentRule];
203
204                 [_buddy unregisterWithConnections];
205                 [_buddy registerWithApplicableConnections];
206
207                 [identifiersTable reloadData];
208         }
209
210         [_currentRule release];
211         _currentRule = nil;
212
213         [_editDomains release];
214         _editDomains = nil;
215
216         [identifierDomainsTable reloadData];
217 }
218
219 - (IBAction) changeConnectionState:(id) sender {
220         BOOL enabled = [identifierConnections selectedTag];
221         [identifierDomainsTable setEnabled:enabled];
222         [addDomain setEnabled:enabled];
223 }
224
225 - (void) controlTextDidChange:(NSNotification *) notification {
226         if( [[identifierNickname stringValue] length] || [[identifierRealName stringValue] length] ||
227                 [[identifierUsername stringValue] length] || [[identifierHostname stringValue] length] )
228                 [identifierOkay setEnabled:YES];
229         else [identifierOkay setEnabled:NO];
230 }
231
232 #pragma mark -
233
234 - (IBAction) addDomain:(id) sender {
235         [_editDomains addObject:@""];
236         [identifierDomainsTable noteNumberOfRowsChanged];
237         [identifierDomainsTable selectRow:( [_editDomains count] - 1 ) byExtendingSelection:NO];
238         [identifierDomainsTable editColumn:0 row:( [_editDomains count] - 1 ) withEvent:nil select:NO];
239 }
240
241 - (IBAction) removeDomain:(id) sender {
242         if( [identifierDomainsTable selectedRow] == -1 || [identifierDomainsTable editedRow] != -1 ) return;
243         [_editDomains removeObjectAtIndex:[identifierDomainsTable selectedRow]];
244         [identifierDomainsTable noteNumberOfRowsChanged];
245 }
246
247 #pragma mark -
248
249 - (IBAction) changeCard:(id) sender {
250        
251 }
252
253 #pragma mark -
254
255 - (IBAction) changeBuddyIcon:(id) sender {
256         [_buddy setPicture:[sender image]];
257 }
258
259 - (IBAction) changeFirstName:(id) sender {
260         [_buddy setFirstName:[sender stringValue]];
261 }
262
263 - (IBAction) changeLastName:(id) sender {
264         [_buddy setLastName:[sender stringValue]];
265 }
266
267 - (IBAction) changeNickname:(id) sender {
268         [_buddy setGivenNickname:[sender stringValue]];
269 }
270
271 - (IBAction) changeEmail:(id) sender {
272         [_buddy setPrimaryEmail:[sender stringValue]];
273 }
274
275 - (IBAction) changeSpeechVoice:(id) sender {
276         NSString *voiceIdentifier = nil;
277
278         if( [sender indexOfSelectedItem] != 0 ) {
279                 voiceIdentifier = [[sender selectedItem] representedObject];
280                 NSSpeechSynthesizer *synth = [[NSSpeechSynthesizer alloc] initWithVoice:voiceIdentifier];
281                 [synth startSpeakingString:[[NSSpeechSynthesizer attributesForVoice:voiceIdentifier] objectForKey:NSVoiceDemoText]];
282                 [synth release];
283         }
284
285         [_buddy setSpeechVoice:voiceIdentifier];
286 }
287
288 #pragma mark -
289
290 - (int) numberOfRowsInTableView:(NSTableView *) tableView {
291         if( [tableView isEqual:identifiersTable] )
292                 return [[_buddy watchRules] count];
293         if( [tableView isEqual:identifierDomainsTable] )
294                 return [_editDomains count];
295         return 0;
296 }
297
298 - (id) tableView:(NSTableView *) tableView objectValueForTableColumn:(NSTableColumn *) column row:(int) row {
299         if( [tableView isEqual:identifiersTable] ) {
300                 NSMutableString *description = [NSMutableString string];
301                 MVChatUserWatchRule *rule = [[_buddy watchRules] objectAtIndex:row];
302                 unsigned count = 0;
303
304                 NSString *string = [rule nickname];
305                 if( [string length] ) {
306                         [description appendString:string];
307                         count++;
308                 }
309
310                 string = [rule realName];
311                 if( [string length] ) {
312                         if( ! count ) [description appendString:string];
313                         count++;
314                 }
315
316                 string = [rule username];
317                 if( [string length] ) {
318                         if( ! count ) [description appendString:string];
319                         count++;
320                 }
321
322                 string = [rule address];
323                 if( [string length] ) {
324                         if( ! count ) [description appendString:string];
325                         count++;
326                 }
327
328                 if( [[rule applicableServerDomains] count] )
329                         count++;
330
331                 count--; // exclude the first rule criterion in the count
332
333                 if( count == 1 )
334                         [description appendFormat:NSLocalizedString( @" (and 1 other criterion)", "one other buddy identifier criterion" ), count];
335                 else if( count > 1 )
336                         [description appendFormat:NSLocalizedString( @" (and %u other criteria)", "count of other buddy identifier criteria" ), count];
337
338                 return description;
339         }
340
341         if( [tableView isEqual:identifierDomainsTable] )
342                 return [_editDomains objectAtIndex:row];
343
344         return nil;
345 }
346
347 - (void) tableView:(NSTableView *) tableView setObjectValue:(id) object forTableColumn:(NSTableColumn *) column row:(int) row {
348         if( [tableView isEqual:identifierDomainsTable] )
349                 [_editDomains replaceObjectAtIndex:row withObject:object];
350 }
351
352 - (void) tableViewSelectionDidChange:(NSNotification *) notification {
353         NSTableView *tableView = [notification object];
354         if( [tableView isEqual:identifiersTable] ) {
355                 [removeIdentifier setEnabled:( [identifiersTable selectedRow] != -1 && [[_buddy watchRules] count] > 1 )];
356                 [editIdentifier setEnabled:( [identifiersTable selectedRow] != -1 )];
357         } else if( [tableView isEqual:identifierDomainsTable] ) {
358                 [removeDomain setEnabled:( [identifierDomainsTable selectedRow] != -1 )];
359         }
360 }
361 @end
Note: See TracBrowser for help on using the browser.