From a9101bb1c2530e0b6e9a727b70ed17c795566f59 Mon Sep 17 00:00:00 2001 From: Mitchell Livingston Date: Mon, 28 Sep 2009 01:57:35 +0000 Subject: [PATCH] first go at redoing the tracker inspector tab (some functionality is still missing) --- Transmission.xcodeproj/project.pbxproj | 6 + macosx/Controller.m | 1 - macosx/InfoWindowController.h | 2 + macosx/InfoWindowController.m | 47 ++++-- macosx/TrackerCell.h | 32 +++++ macosx/TrackerCell.m | 192 +++++++++++++++++++++++++ macosx/TrackerNode.h | 5 + macosx/TrackerNode.m | 83 +++++++++++ macosx/en.lproj/InfoWindow.xib | 92 +++--------- 9 files changed, 377 insertions(+), 83 deletions(-) create mode 100644 macosx/TrackerCell.h create mode 100644 macosx/TrackerCell.m diff --git a/Transmission.xcodeproj/project.pbxproj b/Transmission.xcodeproj/project.pbxproj index 47ed28be4..449635888 100644 --- a/Transmission.xcodeproj/project.pbxproj +++ b/Transmission.xcodeproj/project.pbxproj @@ -80,6 +80,7 @@ A215BF5C0F02EBB800350CDB /* GroupRules.xib in Resources */ = {isa = PBXBuildFile; fileRef = A215BF5B0F02EBB800350CDB /* GroupRules.xib */; }; A219798B0D07B78400438EA7 /* GroupToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = A219798A0D07B78400438EA7 /* GroupToolbarItem.m */; }; A21A9BE2106D86A800F1C3C1 /* TrackerNode.m in Sources */ = {isa = PBXBuildFile; fileRef = A21A9BE1106D86A800F1C3C1 /* TrackerNode.m */; }; + A21A9D41106EC2E800F1C3C1 /* TrackerCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A21A9D40106EC2E800F1C3C1 /* TrackerCell.m */; }; A21DFF100A292B2B007C5F76 /* Transfers.png in Resources */ = {isa = PBXBuildFile; fileRef = A21DFF0F0A292B2B007C5F76 /* Transfers.png */; }; A21FBBAB0EDA78C300BC3C51 /* bandwidth.h in Headers */ = {isa = PBXBuildFile; fileRef = A21FBBA90EDA78C300BC3C51 /* bandwidth.h */; }; A21FBBAC0EDA78C300BC3C51 /* bandwidth.c in Sources */ = {isa = PBXBuildFile; fileRef = A21FBBAA0EDA78C300BC3C51 /* bandwidth.c */; }; @@ -489,6 +490,8 @@ A219798A0D07B78400438EA7 /* GroupToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GroupToolbarItem.m; path = macosx/GroupToolbarItem.m; sourceTree = ""; }; A21A9BE0106D86A800F1C3C1 /* TrackerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrackerNode.h; path = macosx/TrackerNode.h; sourceTree = ""; }; A21A9BE1106D86A800F1C3C1 /* TrackerNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TrackerNode.m; path = macosx/TrackerNode.m; sourceTree = ""; }; + A21A9D3F106EC2E800F1C3C1 /* TrackerCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrackerCell.h; path = macosx/TrackerCell.h; sourceTree = ""; }; + A21A9D40106EC2E800F1C3C1 /* TrackerCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TrackerCell.m; path = macosx/TrackerCell.m; sourceTree = ""; }; A21DFF0F0A292B2B007C5F76 /* Transfers.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Transfers.png; path = macosx/Images/Transfers.png; sourceTree = ""; }; A21FBBA90EDA78C300BC3C51 /* bandwidth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bandwidth.h; path = libtransmission/bandwidth.h; sourceTree = ""; }; A21FBBAA0EDA78C300BC3C51 /* bandwidth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bandwidth.c; path = libtransmission/bandwidth.c; sourceTree = ""; }; @@ -1381,6 +1384,8 @@ A2AA579B0ADFCAB400CA59F6 /* PiecesView.m */, A2725D5B0DE7507C003445E7 /* TrackerTableView.h */, A2725D5C0DE7507C003445E7 /* TrackerTableView.m */, + A21A9D3F106EC2E800F1C3C1 /* TrackerCell.h */, + A21A9D40106EC2E800F1C3C1 /* TrackerCell.m */, ); name = "Info Window"; sourceTree = ""; @@ -1996,6 +2001,7 @@ A23F526F0F14395900AA02E3 /* PredicateEditorRowTemplateAny.m in Sources */, A29D84041049C25600D1987A /* NSApplicationAdditions.m in Sources */, A21A9BE2106D86A800F1C3C1 /* TrackerNode.m in Sources */, + A21A9D41106EC2E800F1C3C1 /* TrackerCell.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/Controller.m b/macosx/Controller.m index b3ad52263..cd63db5c3 100644 --- a/macosx/Controller.m +++ b/macosx/Controller.m @@ -29,7 +29,6 @@ #import "Controller.h" #import "Torrent.h" #import "TorrentGroup.h" -#import "TorrentCell.h" #import "TorrentTableView.h" #import "CreatorWindowController.h" #import "StatsWindowController.h" diff --git a/macosx/InfoWindowController.h b/macosx/InfoWindowController.h index bdb0c68a3..0f12ee2da 100644 --- a/macosx/InfoWindowController.h +++ b/macosx/InfoWindowController.h @@ -28,6 +28,7 @@ @class Torrent; @class TrackerTableView; +@class TrackerCell; @class FileOutlineController; @class PiecesView; @@ -53,6 +54,7 @@ IBOutlet NSButton * fRevealDataButton; IBOutlet TrackerTableView * fTrackerTable; + TrackerCell * fTrackerCell; IBOutlet NSSegmentedControl * fTrackerAddRemoveControl; NSArray * fPeers, * fWebSeeds; diff --git a/macosx/InfoWindowController.m b/macosx/InfoWindowController.m index 711fd64a7..c18e9c7ad 100644 --- a/macosx/InfoWindowController.m +++ b/macosx/InfoWindowController.m @@ -32,6 +32,7 @@ #import "PeerProgressIndicatorCell.h" #import "PiecesView.h" #import "Torrent.h" +#import "TrackerCell.h" #import "TrackerNode.h" #import "TrackerTableView.h" #include "utils.h" //tr_getRatio() @@ -45,6 +46,8 @@ #define TAB_MIN_HEIGHT 250 +#define TRACKER_GROUP_SEPARATOR_HEIGHT 14.0 + #define PIECES_CONTROL_PROGRESS 0 #define PIECES_CONTROL_AVAILABLE 1 @@ -96,7 +99,12 @@ typedef enum - (id) init { - return [super initWithWindowNibName: @"InfoWindow"]; + if ((self = [super initWithWindowNibName: @"InfoWindow"])) + { + fTrackerCell = [[TrackerCell alloc] init]; + } + + return self; } - (void) awakeFromNib @@ -236,6 +244,8 @@ typedef enum [fWebSeedTableAnimation release]; + [fTrackerCell release]; + [fTrackerIconCache release]; [fTrackerIconCacheLeopard release]; [fTrackerIconLoading release]; @@ -890,10 +900,11 @@ typedef enum } else if (tableView == fTrackerTable) { - NSString * ident = [column identifier]; + //NSString * ident = [column identifier]; id item = [fTrackers objectAtIndex: row]; - if ([ident isEqualToString: @"Icon"]) + #warning isn't used + /*if ([ident isEqualToString: @"Icon"]) { NSAssert([item isKindOfClass: [TrackerNode class]], @"Value passed to tracker table's icon row is not a TrackerNode!"); @@ -917,11 +928,13 @@ typedef enum } return (icon && icon != [NSNull null]) ? icon : [NSImage imageNamed: @"FavIcon.png"]; - } - if ([ident isEqualToString: @"Address"]) - return [(TrackerNode *)item host]; - else + }*/ + + if ([item isKindOfClass: [NSNumber class]]) return [NSString stringWithFormat: NSLocalizedString(@"Tier %d", "Inspector -> tracker table"), [item integerValue]]; + else + return item; + } return nil; } @@ -954,18 +967,28 @@ typedef enum [pool drain]; } -- (NSCell *)tableView: (NSTableView *) tableView dataCellForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row +- (NSCell *) tableView: (NSTableView *) tableView dataCellForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row { if (tableView == fTrackerTable) { - //group row the full column width - if (!tableColumn && [[fTrackers objectAtIndex: row] isKindOfClass: [NSNumber class]]) - return [[tableView tableColumnWithIdentifier: @"Address"] dataCell]; + const BOOL group = [[fTrackers objectAtIndex: row] isKindOfClass: [NSNumber class]]; + return group ? [tableColumn dataCellForRow: row] : fTrackerCell; } return nil; } +- (CGFloat) tableView: (NSTableView *) tableView heightOfRow: (NSInteger) row +{ + if (tableView == fTrackerTable) + { + if ([[fTrackers objectAtIndex: row] isKindOfClass: [NSNumber class]]) + return TRACKER_GROUP_SEPARATOR_HEIGHT; + } + + return [tableView rowHeight]; +} + - (void) tableView: (NSTableView *) tableView willDisplayCell: (id) cell forTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row { @@ -1731,7 +1754,7 @@ typedef enum [fTrackerTable reloadData]; [fTrackerTable selectRowIndexes: [NSIndexSet indexSetWithIndex: [fTrackers count]-1] byExtendingSelection: NO]; - [fTrackerTable editColumn: [fTrackerTable columnWithIdentifier: @"Address"] row: [fTrackers count]-1 withEvent: nil select: YES]; + [fTrackerTable editColumn: [fTrackerTable columnWithIdentifier: @"Tracker"] row: [fTrackers count]-1 withEvent: nil select: YES]; } - (void) removeTrackers diff --git a/macosx/TrackerCell.h b/macosx/TrackerCell.h new file mode 100644 index 000000000..6e319a135 --- /dev/null +++ b/macosx/TrackerCell.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * $Id$ + * + * Copyright (c) 2009 Transmission authors and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + *****************************************************************************/ + +#import + +@interface TrackerCell : NSActionCell +{ + NSMutableDictionary * fNameAttributes, * fStatusAttributes; +} + +@end diff --git a/macosx/TrackerCell.m b/macosx/TrackerCell.m new file mode 100644 index 000000000..743685d9c --- /dev/null +++ b/macosx/TrackerCell.m @@ -0,0 +1,192 @@ +/****************************************************************************** + * $Id$ + * + * Copyright (c) 2009 Transmission authors and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + *****************************************************************************/ + +#import "TrackerCell.h" +#import "TrackerNode.h" + +#define PADDING_HORIZONAL 2.0 +#define PADDING_STATUS_HORIZONAL 4.0 +#define ICON_SIZE 14.0 +#define PADDING_BETWEEN_IMAGE_AND_NAME 4.0 +#define PADDING_ABOVE_NAME 2.0 +#define PADDING_BETWEEN_LINES 1.0 + +@interface TrackerCell (Private) + +- (NSImage *) favIcon; + +- (NSRect) imageRectForBounds: (NSRect) bounds; +- (NSRect) rectForNameWithString: (NSAttributedString *) string inBounds: (NSRect) bounds; +- (NSRect) rectForStatusWithString: (NSAttributedString *) string withAboveRect: (NSRect) nameRect inBounds: (NSRect) bounds; + +- (NSAttributedString *) attributedNameWithColor: (NSColor *) color; +- (NSAttributedString *) attributedStatusWithString: (NSString *) statusString color: (NSColor *) color; + +@end + +@implementation TrackerCell + +- (id) init +{ + if ((self = [super init])) + { + NSMutableParagraphStyle * paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; + [paragraphStyle setLineBreakMode: NSLineBreakByTruncatingTail]; + + fNameAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: + [NSFont messageFontOfSize: 11.0], NSFontAttributeName, + paragraphStyle, NSParagraphStyleAttributeName, nil]; + + fStatusAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys: + [NSFont messageFontOfSize: 9.0], NSFontAttributeName, + paragraphStyle, NSParagraphStyleAttributeName, nil]; + + [paragraphStyle release]; + } + return self; +} + +- (void) dealloc +{ + [fNameAttributes release]; + [fStatusAttributes release]; + + [super dealloc]; +} + +- (id) copyWithZone: (NSZone *) zone +{ + TrackerCell * copy = [super copyWithZone: zone]; + + copy->fNameAttributes = [fNameAttributes retain]; + copy->fStatusAttributes = [fStatusAttributes retain]; + + return copy; +} + +- (void) drawWithFrame: (NSRect) cellFrame inView: (NSView *) controlView +{ + //icon + [[self favIcon] drawInRect: [self imageRectForBounds: cellFrame] fromRect: NSZeroRect operation: NSCompositeSourceOver + fraction: 1.0]; + + NSColor * nameColor, * statusColor; + if ([self backgroundStyle] == NSBackgroundStyleDark) + nameColor = statusColor = [NSColor whiteColor]; + else + { + nameColor = [NSColor controlTextColor]; + statusColor = [NSColor darkGrayColor]; + } + + //name + NSAttributedString * nameString = [self attributedNameWithColor: nameColor]; + NSRect nameRect = [self rectForNameWithString: nameString inBounds: cellFrame]; + [nameString drawInRect: nameRect]; + + //status strings + TrackerNode * node = (TrackerNode *)[self objectValue]; + + NSAttributedString * lastAnnounceString = [self attributedStatusWithString: [node lastAnnounceStatusString] color: statusColor]; + NSRect lastAnnounceRect = [self rectForStatusWithString: lastAnnounceString withAboveRect: nameRect inBounds: cellFrame]; + [lastAnnounceString drawInRect: lastAnnounceRect]; + + NSAttributedString * nextAnnounceString = [self attributedStatusWithString: [node nextAnnounceStatusString] color: statusColor]; + NSRect nextAnnounceRect = [self rectForStatusWithString: nextAnnounceString withAboveRect: lastAnnounceRect inBounds: cellFrame]; + [nextAnnounceString drawInRect: nextAnnounceRect]; + + NSAttributedString * lastScrapeString = [self attributedStatusWithString: [node lastScrapeStatusString] color: statusColor]; + NSRect lastScrapeRect = [self rectForStatusWithString: lastScrapeString withAboveRect: nextAnnounceRect inBounds: cellFrame]; + [lastScrapeString drawInRect: lastScrapeRect]; + + NSLog(@"%f", NSMaxY(lastScrapeRect)-NSMinY(cellFrame)); +} + +@end + + +@implementation TrackerCell (Private) + +#warning needed? +- (NSImage *) favIcon +{ + return [NSImage imageNamed: @"FavIcon.png"]; +} + +- (NSRect) imageRectForBounds: (NSRect) bounds +{ + NSRect result = bounds; + result.origin.x += PADDING_HORIZONAL; + result.origin.y += PADDING_ABOVE_NAME; + result.size = NSMakeSize(ICON_SIZE, ICON_SIZE); + + return result; +} + +- (NSRect) rectForNameWithString: (NSAttributedString *) string inBounds: (NSRect) bounds +{ + const NSSize nameSize = [string size]; + + NSRect result = bounds; + result.origin.x += PADDING_HORIZONAL + ICON_SIZE + PADDING_BETWEEN_IMAGE_AND_NAME; + result.origin.y += PADDING_ABOVE_NAME; + + result.size = nameSize; + result.size.width = MIN(result.size.width, NSMaxX(bounds) - NSMinX(result)); + + return result; +} + +- (NSRect) rectForStatusWithString: (NSAttributedString *) string withAboveRect: (NSRect) nameRect inBounds: (NSRect) bounds; +{ + const NSSize statusSize = [string size]; + + NSRect result = bounds; + result.origin.x += PADDING_STATUS_HORIZONAL; + result.origin.y = NSMaxY(nameRect) + PADDING_BETWEEN_LINES; + + result.size = statusSize; + result.size.width = MIN(result.size.width, NSMaxX(bounds) - NSMinX(result)); + + return result; +} + +- (NSAttributedString *) attributedNameWithColor: (NSColor *) color +{ + if (color) + [fNameAttributes setObject: color forKey: NSForegroundColorAttributeName]; + + NSString * name = [(TrackerNode *)[self objectValue] host]; + return [[[NSAttributedString alloc] initWithString: name attributes: fNameAttributes] autorelease]; +} + +- (NSAttributedString *) attributedStatusWithString: (NSString *) statusString color: (NSColor *) color +{ + if (color) + [fStatusAttributes setObject: color forKey: NSForegroundColorAttributeName]; + + return [[[NSAttributedString alloc] initWithString: statusString attributes: fStatusAttributes] autorelease]; +} + +@end diff --git a/macosx/TrackerNode.h b/macosx/TrackerNode.h index f3b407652..be25a5c4d 100644 --- a/macosx/TrackerNode.h +++ b/macosx/TrackerNode.h @@ -34,6 +34,10 @@ - (NSString *) host; +- (NSString *) lastAnnounceStatusString; +- (NSString *) nextAnnounceStatusString; +- (NSString *) lastScrapeStatusString; + #if 0 - (BOOL) isActive; @@ -51,6 +55,7 @@ - (int) lastAnnouncePeerCount; - (NSString *) lastAnnounceResult; +- (NSDate *) lastAnnounceDate; - (NSDate *) lastAnnounceStartDate; - (BOOL) lastAnnounceSucceeded; - (NSDate *) lastAnnounceDate; diff --git a/macosx/TrackerNode.m b/macosx/TrackerNode.m index b44a56a93..943ef537a 100644 --- a/macosx/TrackerNode.m +++ b/macosx/TrackerNode.m @@ -23,6 +23,8 @@ *****************************************************************************/ #import "TrackerNode.h" +#import "NSApplicationAdditions.h" +#import "NSStringAdditions.h" @implementation TrackerNode @@ -36,9 +38,90 @@ return self; } +- (id) copyWithZone: (NSZone *) zone +{ + //this object is essentially immutable after initial setup + return [self retain]; +} + - (NSString *) host { return [NSString stringWithUTF8String: fStat.host]; } +#warning work in peer count? +#warning consider "isActive" +- (NSString *) lastAnnounceStatusString +{ + NSString * dateString; + if (fStat.hasAnnounced && fStat.lastAnnounceTime != 0) + { + NSDate * announceDate = [NSDate dateWithTimeIntervalSince1970: fStat.lastAnnounceTime]; + if ([NSApp isOnSnowLeopardOrBetter]) + dateString = [NSDateFormatter localizedStringFromDate: announceDate dateStyle: NSDateFormatterFullStyle + timeStyle: NSDateFormatterShortStyle]; + else + { + NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle: NSDateFormatterFullStyle]; + [dateFormatter setTimeStyle: NSDateFormatterShortStyle]; + + dateString = [dateFormatter stringFromDate: announceDate]; + [dateFormatter release]; + } + } + else + dateString = NSLocalizedString(@"N/A", "Tracker last announce"); + + if (fStat.hasAnnounced && !fStat.lastAnnounceSucceeded) + dateString = [NSString stringWithFormat: @"%@: %@ - %@", NSLocalizedString(@"Announce error", "Tracker last announce"), + [NSString stringWithUTF8String: fStat.lastAnnounceResult], dateString]; + else + dateString = [NSString stringWithFormat: NSLocalizedString(@"Last Announce: %@", "Tracker last announce"), dateString]; + + return dateString; +} + +- (NSString *) nextAnnounceStatusString +{ + if (fStat.isAnnouncing) + return [NSLocalizedString(@"Announce in progress", "Tracker next announce") stringByAppendingEllipsis]; + else if (fStat.willAnnounce) + return [NSString stringWithFormat: NSLocalizedString(@"Next announce in %@", "Tracker next announce"), + [NSString timeString: fStat.nextAnnounceTime - [[NSDate date] timeIntervalSince1970] showSeconds: YES]]; + else + return NSLocalizedString(@"Announce not scheduled", "Tracker next announce"); +} + +- (NSString *) lastScrapeStatusString +{ + NSString * dateString; + if (fStat.hasScraped && fStat.lastScrapeTime != 0) + { + NSDate * scrapeDate = [NSDate dateWithTimeIntervalSince1970: fStat.lastScrapeTime]; + if ([NSApp isOnSnowLeopardOrBetter]) + dateString = [NSDateFormatter localizedStringFromDate: scrapeDate dateStyle: NSDateFormatterFullStyle + timeStyle: NSDateFormatterShortStyle]; + else + { + NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateStyle: NSDateFormatterFullStyle]; + [dateFormatter setTimeStyle: NSDateFormatterShortStyle]; + + dateString = [dateFormatter stringFromDate: scrapeDate]; + [dateFormatter release]; + } + } + else + dateString = NSLocalizedString(@"N/A", "Tracker last announce"); + + if (fStat.hasScraped && !fStat.lastScrapeSucceeded) + dateString = [NSString stringWithFormat: @"%@: %@ - %@", NSLocalizedString(@"Scrape error", "Tracker last announce"), + [NSString stringWithUTF8String: fStat.lastScrapeResult], dateString]; + else + dateString = [NSString stringWithFormat: NSLocalizedString(@"Last Scrape: %@", "Tracker last announce"), dateString]; + + return dateString; +} + @end diff --git a/macosx/en.lproj/InfoWindow.xib b/macosx/en.lproj/InfoWindow.xib index 1b69126d3..735f79e17 100644 --- a/macosx/en.lproj/InfoWindow.xib +++ b/macosx/en.lproj/InfoWindow.xib @@ -12,8 +12,7 @@ YES - - + YES @@ -423,7 +422,7 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA {1.79769e+308, 1.79769e+308} - + 258 YES @@ -836,7 +835,7 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA 6 - {503, 1e+07} + {509, 1e+07} {87, 0} @@ -884,14 +883,13 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA {350, 210} - NSView NSResponder - + 258 YES @@ -1569,14 +1567,13 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA {360, 290} - NSView NSResponder - + 274 YES @@ -1603,46 +1600,9 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA YES - - Icon - 17 - 17 - 17 - - 75628096 - 2048 - - - - 6 - System - headerColor - - - - 6 - System - headerTextColor - - - - - 67239424 - 33554432 - - 8 - 3 - 0 - NO - - 3 - YES - YES - - - Address - 337 + Tracker + 357 40 1000 @@ -1654,7 +1614,12 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA 3 MC4zMzMzMzI5OQA - + + 6 + System + headerTextColor + + 337772096 @@ -1692,7 +1657,7 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA MC41AA - 14 + 57 440401920 @@ -1739,7 +1704,7 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA - QSAAAEEgAABBgAAAQYAAAA + QSAAAEEgAABCbAAAQmwAAA @@ -1780,6 +1745,7 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA {382, 352} + NSView @@ -1831,7 +1797,12 @@ AAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA 2048 IP Address - + + 6 + System + headerColor + + @@ -5960,7 +5931,6 @@ AAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSwgSW5jLiwgMjAwOQA YES - @@ -6211,20 +6181,6 @@ AAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSwgSW5jLiwgMjAwOQA - - 1823 - - - YES - - - - - - 1825 - - - @@ -6579,8 +6535,6 @@ AAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSwgSW5jLiwgMjAwOQA 1816.IBPluginDependency 1817.IBPluginDependency 1818.IBPluginDependency - 1823.IBPluginDependency - 1825.IBPluginDependency 28.IBPluginDependency 28.ImportedFromIB2 29.IBPluginDependency @@ -7020,8 +6974,6 @@ AAAAAAAAAAAAAAAAAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSwgSW5jLiwgMjAwOQA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin