source: trunk/macosx/InfoPeersViewController.m @ 11409

Last change on this file since 11409 was 11409, checked in by livings124, 11 years ago

a couple of float -> double changes

  • Property svn:keywords set to Date Rev Author Id
File size: 24.0 KB
Line 
1/******************************************************************************
2 * $Id: InfoPeersViewController.m 11409 2010-11-14 15:16:39Z livings124 $
3 *
4 * Copyright (c) 2010 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "InfoPeersViewController.h"
26#import "NSApplicationAdditions.h"
27#import "NSStringAdditions.h"
28#import "PeerProgressIndicatorCell.h"
29#import "Torrent.h"
30
31#import "transmission.h" // required by utils.h
32#import "utils.h"
33
34@interface InfoPeersViewController (Private)
35
36- (void) setupInfo;
37
38- (void) setWebSeedTableHidden: (BOOL) hide animate: (BOOL) animate;
39- (NSArray *) peerSortDescriptors;
40
41@end
42
43@implementation InfoPeersViewController
44
45- (id) init
46{
47    if ((self = [super initWithNibName: @"InfoPeersView" bundle: nil]))
48    {
49        [self setTitle: NSLocalizedString(@"Peers", "Inspector view -> title")];
50    }
51   
52    return self;
53}
54
55- (void) awakeFromNib
56{
57    const CGFloat height = [[NSUserDefaults standardUserDefaults] floatForKey: @"InspectorContentHeightPeers"];
58    if (height != 0.0)
59    {
60        NSRect viewRect = [[self view] frame];
61        viewRect.size.height = height;
62        [[self view] setFrame: viewRect];
63    }
64   
65    //set table header text
66    [[[fPeerTable tableColumnWithIdentifier: @"IP"] headerCell] setStringValue: NSLocalizedString(@"IP Address",
67                                                                        "inspector -> peer table -> header")];
68    [[[fPeerTable tableColumnWithIdentifier: @"Client"] headerCell] setStringValue: NSLocalizedString(@"Client",
69                                                                        "inspector -> peer table -> header")];
70    [[[fPeerTable tableColumnWithIdentifier: @"DL From"] headerCell] setStringValue: NSLocalizedString(@"DL",
71                                                                        "inspector -> peer table -> header")];
72    [[[fPeerTable tableColumnWithIdentifier: @"UL To"] headerCell] setStringValue: NSLocalizedString(@"UL",
73                                                                        "inspector -> peer table -> header")];
74   
75    [[[fWebSeedTable tableColumnWithIdentifier: @"Address"] headerCell] setStringValue: NSLocalizedString(@"Web Seeds",
76                                                                        "inspector -> web seed table -> header")];
77    [[[fWebSeedTable tableColumnWithIdentifier: @"DL From"] headerCell] setStringValue: NSLocalizedString(@"DL",
78                                                                        "inspector -> web seed table -> header")];
79   
80    //set table header tool tips
81    [[fPeerTable tableColumnWithIdentifier: @"Encryption"] setHeaderToolTip: NSLocalizedString(@"Encrypted Connection",
82                                                                        "inspector -> peer table -> header tool tip")];
83    [[fPeerTable tableColumnWithIdentifier: @"Progress"] setHeaderToolTip: NSLocalizedString(@"Available",
84                                                                        "inspector -> peer table -> header tool tip")];
85    [[fPeerTable tableColumnWithIdentifier: @"DL From"] setHeaderToolTip: NSLocalizedString(@"Downloading From Peer",
86                                                                        "inspector -> peer table -> header tool tip")];
87    [[fPeerTable tableColumnWithIdentifier: @"UL To"] setHeaderToolTip: NSLocalizedString(@"Uploading To Peer",
88                                                                        "inspector -> peer table -> header tool tip")];
89   
90    [[fWebSeedTable tableColumnWithIdentifier: @"DL From"] setHeaderToolTip: NSLocalizedString(@"Downloading From Web Seed",
91                                                                        "inspector -> web seed table -> header tool tip")];
92   
93    //prepare for animating peer table and web seed table
94    NSRect webSeedTableFrame = [[fWebSeedTable enclosingScrollView] frame];
95    fWebSeedTableHeight = webSeedTableFrame.size.height;
96    fSpaceBetweenWebSeedAndPeer = webSeedTableFrame.origin.y - NSMaxY([[fPeerTable enclosingScrollView] frame]);
97   
98    [self setWebSeedTableHidden: YES animate: NO];
99}
100
101- (void) dealloc
102{
103    [fTorrents release];
104   
105    [fPeers release];
106    [fWebSeeds release];
107   
108    [fWebSeedTableAnimation release];
109   
110    [super dealloc];
111}
112
113#warning subclass?
114- (void) setInfoForTorrents: (NSArray *) torrents
115{
116    //don't check if it's the same in case the metadata changed
117    [fTorrents release];
118    fTorrents = [torrents retain];
119   
120    fSet = NO;
121}
122
123- (void) updateInfo
124{
125    if (!fSet)
126        [self setupInfo];
127   
128    if ([fTorrents count] == 0)
129        return;
130   
131    if (!fPeers)
132        fPeers = [[NSMutableArray alloc] init];
133    else
134        [fPeers removeAllObjects];
135   
136    if (!fWebSeeds)
137        fWebSeeds = [[NSMutableArray alloc] init];
138    else
139        [fWebSeeds removeAllObjects];
140   
141    NSUInteger known = 0, connected = 0, tracker = 0, incoming = 0, cache = 0, lpd = 0, pex = 0, dht = 0, ltep = 0,
142                toUs = 0, fromUs = 0;
143    BOOL anyActive = false;
144    for (Torrent * torrent in fTorrents)
145    {
146        if ([torrent webSeedCount] > 0)
147            [fWebSeeds addObjectsFromArray: [torrent webSeeds]];
148       
149        known += [torrent totalPeersKnown];
150       
151        if ([torrent isActive])
152        {
153            anyActive = YES;
154            [fPeers addObjectsFromArray: [torrent peers]];
155           
156            const NSUInteger connectedThis = [torrent totalPeersConnected];
157            if (connectedThis > 0)
158            {
159                connected += [torrent totalPeersConnected];
160                tracker += [torrent totalPeersTracker];
161                incoming += [torrent totalPeersIncoming];
162                cache += [torrent totalPeersCache];
163                lpd += [torrent totalPeersLocal];
164                pex += [torrent totalPeersPex];
165                dht += [torrent totalPeersDHT];
166                ltep += [torrent totalPeersLTEP];
167               
168                toUs += [torrent peersSendingToUs];
169                fromUs += [torrent peersGettingFromUs];
170            }
171        }
172    }
173   
174    [fPeers sortUsingDescriptors: [self peerSortDescriptors]];
175    [fPeerTable reloadData];
176   
177    [fWebSeeds sortUsingDescriptors: [fWebSeedTable sortDescriptors]];
178    [fWebSeedTable reloadData];
179   
180    NSString * knownString = [NSString stringWithFormat: NSLocalizedString(@"%d known", "Inspector -> Peers tab -> peers"), known];
181    if (anyActive)
182    {
183        NSString * connectedText = [NSString stringWithFormat: NSLocalizedString(@"%d Connected", "Inspector -> Peers tab -> peers"),
184                                    connected];
185       
186        if (connected > 0)
187        {
188            NSMutableArray * fromComponents = [NSMutableArray arrayWithCapacity: 6];
189            if (tracker > 0)
190                [fromComponents addObject: [NSString stringWithFormat:
191                                        NSLocalizedString(@"%d tracker", "Inspector -> Peers tab -> peers"), tracker]];
192            if (incoming > 0)
193                [fromComponents addObject: [NSString stringWithFormat:
194                                        NSLocalizedString(@"%d incoming", "Inspector -> Peers tab -> peers"), incoming]];
195            if (cache > 0)
196                [fromComponents addObject: [NSString stringWithFormat:
197                                        NSLocalizedString(@"%d cache", "Inspector -> Peers tab -> peers"), cache]];
198            if (lpd > 0)
199                [fromComponents addObject: [NSString stringWithFormat:
200                                        NSLocalizedString(@"%d local discovery", "Inspector -> Peers tab -> peers"), lpd]];
201            if (pex > 0)
202                [fromComponents addObject: [NSString stringWithFormat:
203                                        NSLocalizedString(@"%d PEX", "Inspector -> Peers tab -> peers"), pex]];
204            if (dht > 0)
205                [fromComponents addObject: [NSString stringWithFormat:
206                                        NSLocalizedString(@"%d DHT", "Inspector -> Peers tab -> peers"), dht]];
207            if (ltep > 0)
208                [fromComponents addObject: [NSString stringWithFormat:
209                                        NSLocalizedString(@"%d LTEP", "Inspector -> Peers tab -> peers"), ltep]];
210           
211            NSMutableArray * upDownComponents = [NSMutableArray arrayWithCapacity: 3];
212            if (toUs > 0)
213                [upDownComponents addObject: [NSString stringWithFormat:
214                                        NSLocalizedString(@"DL from %d", "Inspector -> Peers tab -> peers"), toUs]];
215            if (fromUs > 0)
216                [upDownComponents addObject: [NSString stringWithFormat:
217                                        NSLocalizedString(@"UL to %d", "Inspector -> Peers tab -> peers"), fromUs]];
218            [upDownComponents addObject: knownString];
219           
220            connectedText = [connectedText stringByAppendingFormat: @": %@\n%@", [fromComponents componentsJoinedByString: @", "],
221                                [upDownComponents componentsJoinedByString: @", "]];
222        }
223        else
224            connectedText = [connectedText stringByAppendingFormat: @"\n%@", knownString];
225       
226        [fConnectedPeersField setStringValue: connectedText];
227    }
228    else
229    {
230        NSString * activeString;
231        if ([fTorrents count] == 1)
232            activeString = NSLocalizedString(@"Transfer Not Active", "Inspector -> Peers tab -> peers");
233        else
234            activeString = NSLocalizedString(@"Transfers Not Active", "Inspector -> Peers tab -> peers");
235       
236        NSString * connectedText = [activeString stringByAppendingFormat: @"\n%@", knownString];
237        [fConnectedPeersField setStringValue: connectedText];
238    }
239}
240
241- (void) saveViewSize
242{
243    [[NSUserDefaults standardUserDefaults] setFloat: NSHeight([[self view] frame]) forKey: @"InspectorContentHeightPeers"];
244}
245
246- (void) clearView
247{
248    //if in the middle of animating, just stop and resize immediately
249    if (fWebSeedTableAnimation)
250        [self setWebSeedTableHidden: !fWebSeeds animate: NO];
251   
252    [fPeers release];
253    fPeers = nil;
254    [fWebSeeds release];
255    fWebSeeds = nil;
256}
257
258- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableView
259{
260    if (tableView == fWebSeedTable)
261        return fWebSeeds ? [fWebSeeds count] : 0;
262    else
263        return fPeers ? [fPeers count] : 0;
264}
265
266- (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) column row: (NSInteger) row
267{
268    if (tableView == fWebSeedTable)
269    {
270        NSString * ident = [column identifier];
271        NSDictionary * webSeed = [fWebSeeds objectAtIndex: row];
272       
273        if ([ident isEqualToString: @"DL From"])
274        {
275            NSNumber * rate;
276            return (rate = [webSeed objectForKey: @"DL From Rate"]) ? [NSString stringForSpeedAbbrev: [rate doubleValue]] : @"";
277        }
278        else
279            return [webSeed objectForKey: @"Address"];
280    }
281    else
282    {
283        NSString * ident = [column identifier];
284        NSDictionary * peer = [fPeers objectAtIndex: row];
285       
286        if ([ident isEqualToString: @"Encryption"])
287            return [[peer objectForKey: @"Encryption"] boolValue] ? [NSImage imageNamed: @"Lock.png"] : nil;
288        else if ([ident isEqualToString: @"Client"])
289            return [peer objectForKey: @"Client"];
290        else if  ([ident isEqualToString: @"Progress"])
291            return [peer objectForKey: @"Progress"];
292        else if ([ident isEqualToString: @"UL To"])
293        {
294            NSNumber * rate;
295            return (rate = [peer objectForKey: @"UL To Rate"]) ? [NSString stringForSpeedAbbrev: [rate doubleValue]] : @"";
296        }
297        else if ([ident isEqualToString: @"DL From"])
298        {
299            NSNumber * rate;
300            return (rate = [peer objectForKey: @"DL From Rate"]) ? [NSString stringForSpeedAbbrev: [rate doubleValue]] : @"";
301        }
302        else
303            return [peer objectForKey: @"IP"];
304    }
305}
306
307- (void) tableView: (NSTableView *) tableView willDisplayCell: (id) cell forTableColumn: (NSTableColumn *) tableColumn
308    row: (NSInteger) row
309{
310    if (tableView == fPeerTable)
311    {
312        NSString * ident = [tableColumn identifier];
313       
314        if  ([ident isEqualToString: @"Progress"])
315        {
316            NSDictionary * peer = [fPeers objectAtIndex: row];
317            [(PeerProgressIndicatorCell *)cell setSeed: [[peer objectForKey: @"Seed"] boolValue]];
318        }
319    }
320}
321
322- (void) tableView: (NSTableView *) tableView didClickTableColumn: (NSTableColumn *) tableColumn
323{
324    if (tableView == fWebSeedTable)
325    {
326        if (fWebSeeds)
327        {
328            [fWebSeeds sortUsingDescriptors: [fWebSeedTable sortDescriptors]];
329            [tableView reloadData];
330        }
331    }
332    else
333    {
334        if (fPeers)
335        {
336            [fPeers sortUsingDescriptors: [self peerSortDescriptors]];
337            [tableView reloadData];
338        }
339    }
340}
341
342- (BOOL) tableView: (NSTableView *) tableView shouldSelectRow: (NSInteger) row
343{
344    return NO;
345}
346
347- (NSString *) tableView: (NSTableView *) tableView toolTipForCell: (NSCell *) cell rect: (NSRectPointer) rect
348                tableColumn: (NSTableColumn *) column row: (NSInteger) row mouseLocation: (NSPoint) mouseLocation
349{
350    if (tableView == fPeerTable)
351    {
352        const BOOL multiple = [fTorrents count] > 1;
353       
354        NSDictionary * peer = [fPeers objectAtIndex: row];
355        NSMutableArray * components = [NSMutableArray arrayWithCapacity: multiple ? 6 : 5];
356       
357        if (multiple)
358            [components addObject: [peer objectForKey: @"Name"]];
359       
360        const CGFloat progress = [[peer objectForKey: @"Progress"] floatValue];
361        NSString * progressString = [NSString stringWithFormat: NSLocalizedString(@"Progress: %@",
362                                        "Inspector -> Peers tab -> table row tooltip"),
363                                        [NSString percentString: progress longDecimals: NO]];
364        if (progress < 1.0 && [[peer objectForKey: @"Seed"] boolValue])
365            progressString = [progressString stringByAppendingFormat: @" (%@)", NSLocalizedString(@"Partial Seed",
366                                "Inspector -> Peers tab -> table row tooltip")];
367        [components addObject: progressString];
368       
369        if ([[peer objectForKey: @"Encryption"] boolValue])
370            [components addObject: NSLocalizedString(@"Encrypted Connection", "Inspector -> Peers tab -> table row tooltip")];
371       
372        NSString * portString;
373        NSInteger port;
374        if ((port = [[peer objectForKey: @"Port"] intValue]) > 0)
375            portString = [NSString stringWithFormat: @"%d", port];
376        else
377            portString = NSLocalizedString(@"N/A", "Inspector -> Peers tab -> table row tooltip");
378        [components addObject: [NSString stringWithFormat: @"%@: %@", NSLocalizedString(@"Port",
379            "Inspector -> Peers tab -> table row tooltip"), portString]];
380       
381        const NSInteger peerFrom = [[peer objectForKey: @"From"] integerValue];
382        switch (peerFrom)
383        {
384            case TR_PEER_FROM_TRACKER:
385                [components addObject: NSLocalizedString(@"From: tracker", "Inspector -> Peers tab -> table row tooltip")];
386                break;
387            case TR_PEER_FROM_INCOMING:
388                [components addObject: NSLocalizedString(@"From: incoming connection", "Inspector -> Peers tab -> table row tooltip")];
389                break;
390            case TR_PEER_FROM_RESUME:
391                [components addObject: NSLocalizedString(@"From: cache", "Inspector -> Peers tab -> table row tooltip")];
392                break;
393            case TR_PEER_FROM_LPD:
394                [components addObject: NSLocalizedString(@"From: local peer discovery", "Inspector -> Peers tab -> table row tooltip")];
395                break;
396            case TR_PEER_FROM_PEX:
397                [components addObject: NSLocalizedString(@"From: peer exchange", "Inspector -> Peers tab -> table row tooltip")];
398                break;
399            case TR_PEER_FROM_DHT:
400                [components addObject: NSLocalizedString(@"From: distributed hash table", "Inspector -> Peers tab -> table row tooltip")];
401                break;
402            case TR_PEER_FROM_LTEP:
403                [components addObject: NSLocalizedString(@"From: libtorrent extension protocol handshake",
404                                        "Inspector -> Peers tab -> table row tooltip")];
405                break;
406            default:
407                NSAssert1(NO, @"Peer from unknown source: %d", peerFrom);
408        }
409       
410        //determing status strings from flags
411        NSMutableArray * statusArray = [NSMutableArray arrayWithCapacity: 6];
412        NSString * flags = [peer objectForKey: @"Flags"];
413       
414        if ([flags rangeOfString: @"D"].location != NSNotFound)
415            [statusArray addObject: NSLocalizedString(@"Currently downloading (interested and not choked)",
416                "Inspector -> peer -> status")];
417        if ([flags rangeOfString: @"d"].location != NSNotFound)
418            [statusArray addObject: NSLocalizedString(@"You want to download, but peer does not want to send (interested and choked)",
419                "Inspector -> peer -> status")];
420        if ([flags rangeOfString: @"U"].location != NSNotFound)
421            [statusArray addObject: NSLocalizedString(@"Currently uploading (interested and not choked)",
422                "Inspector -> peer -> status")];
423        if ([flags rangeOfString: @"u"].location != NSNotFound)
424            [statusArray addObject: NSLocalizedString(@"Peer wants you to upload, but you do not want to (interested and choked)",
425                "Inspector -> peer -> status")];
426        if ([flags rangeOfString: @"K"].location != NSNotFound)
427            [statusArray addObject: NSLocalizedString(@"Peer is unchoking you, but you are not interested",
428                "Inspector -> peer -> status")];
429        if ([flags rangeOfString: @"?"].location != NSNotFound)
430            [statusArray addObject: NSLocalizedString(@"You unchoked the peer, but the peer is not interested",
431                "Inspector -> peer -> status")];
432       
433        if ([statusArray count] > 0)
434        {
435            NSString * statusStrings = [statusArray componentsJoinedByString: @"\n\n"];
436            [components addObject: [@"\n" stringByAppendingString: statusStrings]];
437        }
438       
439        return [components componentsJoinedByString: @"\n"];
440    }
441    else
442    {
443        if ([fTorrents count] > 1)
444            return [[fWebSeeds objectAtIndex: row] objectForKey: @"Name"];
445    }
446   
447    return nil;
448}
449
450- (void) animationDidEnd: (NSAnimation *) animation
451{
452    if (animation == fWebSeedTableAnimation)
453    {
454        [fWebSeedTableAnimation release];
455        fWebSeedTableAnimation = nil;
456    }
457}
458
459- (void) stopWebSeedAnimation
460{
461    if (fWebSeedTableAnimation)
462    {
463        [fWebSeedTableAnimation stopAnimation]; // jumps to end frame
464        [fWebSeedTableAnimation release];
465        fWebSeedTableAnimation = nil;
466    }
467}
468
469@end
470
471@implementation InfoPeersViewController (Private)
472
473- (void) setupInfo
474{
475    BOOL hasWebSeeds = NO;
476   
477    if ([fTorrents count] == 0)
478    {
479        [fPeers release];
480        fPeers = nil;
481        [fPeerTable reloadData];
482       
483        [fConnectedPeersField setStringValue: @""];
484    }
485    else
486    {
487        for (Torrent * torrent in fTorrents)
488            if ([torrent webSeedCount] > 0)
489            {
490                hasWebSeeds = YES;
491                break;
492            }
493    }
494   
495    if (!hasWebSeeds)
496    {
497        [fWebSeeds release];
498        fWebSeeds = nil;
499        [fWebSeedTable reloadData];
500    }
501    [self setWebSeedTableHidden: !hasWebSeeds animate: YES];
502   
503    fSet = YES;
504}
505
506- (void) setWebSeedTableHidden: (BOOL) hide animate: (BOOL) animate
507{
508    if (animate && (![[self view] window] || ![[[self view] window] isVisible]))
509        animate = NO;
510   
511    if (fWebSeedTableAnimation)
512    {
513        [fWebSeedTableAnimation stopAnimation];
514        [fWebSeedTableAnimation release];
515        fWebSeedTableAnimation = nil;
516    }
517   
518    NSRect webSeedFrame = [[fWebSeedTable enclosingScrollView] frame];
519    NSRect peerFrame = [[fPeerTable enclosingScrollView] frame];
520   
521    if (hide)
522    {
523        CGFloat webSeedFrameMaxY = NSMaxY(webSeedFrame);
524        webSeedFrame.size.height = 0;
525        webSeedFrame.origin.y = webSeedFrameMaxY;
526       
527        peerFrame.size.height = webSeedFrameMaxY - peerFrame.origin.y;
528    }
529    else
530    {
531        webSeedFrame.origin.y -= fWebSeedTableHeight - webSeedFrame.size.height;
532        webSeedFrame.size.height = fWebSeedTableHeight;
533       
534        peerFrame.size.height = (webSeedFrame.origin.y - fSpaceBetweenWebSeedAndPeer) - peerFrame.origin.y;
535    }
536   
537    [[fWebSeedTable enclosingScrollView] setHidden: NO]; //this is needed for some reason
538   
539    //actually resize tables
540    if (animate)
541    {
542        NSDictionary * webSeedDict = [NSDictionary dictionaryWithObjectsAndKeys:
543                                    [fWebSeedTable enclosingScrollView], NSViewAnimationTargetKey,
544                                    [NSValue valueWithRect: [[fWebSeedTable enclosingScrollView] frame]], NSViewAnimationStartFrameKey,
545                                    [NSValue valueWithRect: webSeedFrame], NSViewAnimationEndFrameKey, nil],
546                    * peerDict = [NSDictionary dictionaryWithObjectsAndKeys:
547                                    [fPeerTable enclosingScrollView], NSViewAnimationTargetKey,
548                                    [NSValue valueWithRect: [[fPeerTable enclosingScrollView] frame]], NSViewAnimationStartFrameKey,
549                                    [NSValue valueWithRect: peerFrame], NSViewAnimationEndFrameKey, nil];
550       
551        fWebSeedTableAnimation = [[NSViewAnimation alloc] initWithViewAnimations:
552                                        [NSArray arrayWithObjects: webSeedDict, peerDict, nil]];
553        [fWebSeedTableAnimation setDuration: 0.125];
554        [fWebSeedTableAnimation setAnimationBlockingMode: NSAnimationNonblocking];
555        [fWebSeedTableAnimation setDelegate: self];
556       
557        [fWebSeedTableAnimation startAnimation];
558    }
559    else
560    {
561        [[fWebSeedTable enclosingScrollView] setFrame: webSeedFrame];
562        [[fPeerTable enclosingScrollView] setFrame: peerFrame];
563    }
564}
565
566- (NSArray *) peerSortDescriptors
567{
568    NSMutableArray * descriptors = [NSMutableArray arrayWithCapacity: 2];
569   
570    NSArray * oldDescriptors = [fPeerTable sortDescriptors];
571    BOOL useSecond = YES, asc = YES;
572    if ([oldDescriptors count] > 0)
573    {
574        NSSortDescriptor * descriptor = [oldDescriptors objectAtIndex: 0];
575        [descriptors addObject: descriptor];
576       
577        if ((useSecond = ![[descriptor key] isEqualToString: @"IP"]))
578            asc = [descriptor ascending];
579    }
580   
581    //sort by IP after primary sort
582    if (useSecond)
583    {
584        #warning when 10.6-only, replace with sortDescriptorWithKey:ascending:selector:
585        NSSortDescriptor * secondDescriptor = [[NSSortDescriptor alloc] initWithKey: @"IP" ascending: asc
586                                                                        selector: @selector(compareNumeric:)];
587        [descriptors addObject: secondDescriptor];
588        [secondDescriptor release];
589    }
590   
591    return descriptors;
592}
593
594@end
Note: See TracBrowser for help on using the repository browser.