diff --git a/NEWS b/NEWS index 45c875368..de9e81db7 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ NEWS file for Transmission http://trac.transmissionbt.com/query?group=component&milestone=1.30&order=severity - All Platforms + Ability to add and remove tracker addresses + + Ability to create torrent files with multiple tracker addresses + Creation of torrent files with no tracker address (for easier creation for upload to some tracker sites) - Mac + Quick Look integration in the main window and inspector's file tab diff --git a/macosx/CreatorWindowController.h b/macosx/CreatorWindowController.h index cead20782..9035e6e50 100644 --- a/macosx/CreatorWindowController.h +++ b/macosx/CreatorWindowController.h @@ -29,7 +29,9 @@ @interface CreatorWindowController : NSWindowController { IBOutlet NSImageView * fIconView; - IBOutlet NSTextField * fNameField, * fStatusField, * fPiecesField, * fTrackerField, * fLocationField; + IBOutlet NSTextField * fNameField, * fStatusField, * fPiecesField, * fLocationField; + IBOutlet NSTableView * fTrackerTable; + IBOutlet NSSegmentedControl * fTrackerAddRemoveControl; IBOutlet NSTextView * fCommentView; IBOutlet NSButton * fPrivateCheck, * fOpenCheck; @@ -37,7 +39,8 @@ IBOutlet NSProgressIndicator * fProgressIndicator; tr_metainfo_builder * fInfo; - NSString * fPath, * fLocation, * fTracker; + NSString * fPath, * fLocation; + NSMutableArray * fTrackers; BOOL fOpenTorrent; NSTimer * fTimer; @@ -58,4 +61,6 @@ - (void) cancelCreateWindow: (id) sender; - (void) cancelCreateProgress: (id) sender; +- (void) addRemoveTracker: (id) sender; + @end diff --git a/macosx/CreatorWindowController.m b/macosx/CreatorWindowController.m index b18f6a355..dfbc229ef 100644 --- a/macosx/CreatorWindowController.m +++ b/macosx/CreatorWindowController.m @@ -27,10 +27,13 @@ #import "NSStringAdditions.h" #include "utils.h" //tr_httpIsValidURL +#define TRACKER_ADD_TAG 0 +#define TRACKER_REMOVE_TAG 1 + @interface CreatorWindowController (Private) + (NSString *) chooseFile; -- (void) updateEnableOpenCheckForTrackerField; +- (void) updateEnableOpenCheckForTrackers; - (void) locationSheetClosed: (NSSavePanel *) openPanel returnCode: (int) code contextInfo: (void *) info; - (void) createBlankAddressAlertDidEnd: (NSAlert *) alert returnCode: (int) returnCode contextInfo: (void *) contextInfo; @@ -102,6 +105,21 @@ } fDefaults = [NSUserDefaults standardUserDefaults]; + + //get list of trackers + if (!(fTrackers = [[fDefaults arrayForKey: @"CreatorTrackers"] mutableCopy])) + { + fTrackers = [[NSMutableArray alloc] initWithCapacity: 1]; + + //check for tracker from versions before 1.3 + NSString * tracker; + if ((tracker = [fDefaults stringForKey: @"CreatorTracker"])) + { + [fTrackers addObject: tracker]; + [fDefaults removeObjectForKey: @"CreatorTracker"]; + [fDefaults setObject: fTrackers forKey: @"CreatorTrackers"]; + } + }NSLog([fTrackers description]); } return self; } @@ -151,15 +169,18 @@ [fLocationField setToolTip: fLocation]; //set previously saved values - NSString * tracker; - if ((tracker = [fDefaults stringForKey: @"CreatorTracker"])) - [fTrackerField setStringValue: tracker]; - if ([fDefaults objectForKey: @"CreatorPrivate"]) [fPrivateCheck setState: [fDefaults boolForKey: @"CreatorPrivate"] ? NSOnState : NSOffState]; fOpenTorrent = [fDefaults boolForKey: @"CreatorOpen"]; - [self updateEnableOpenCheckForTrackerField]; + [self updateEnableOpenCheckForTrackers]; + + if (![NSApp isOnLeopardOrBetter]) + { + [fTrackerAddRemoveControl sizeToFit]; + [fTrackerAddRemoveControl setLabel: @"+" forSegment: TRACKER_ADD_TAG]; + [fTrackerAddRemoveControl setLabel: @"-" forSegment: TRACKER_REMOVE_TAG]; + } } - (void) dealloc @@ -167,7 +188,7 @@ [fPath release]; [fLocation release]; - [fTracker release]; + [fTrackers release]; if (fInfo) tr_metaInfoBuilderFree(fInfo); @@ -183,12 +204,6 @@ fOpenTorrent = [fOpenCheck state] == NSOnState; } -- (void) controlTextDidChange: (NSNotification *) notification -{ - if ([notification object] == fTrackerField) - [self updateEnableOpenCheckForTrackerField]; -} - - (void) setLocation: (id) sender { NSSavePanel * panel = [NSSavePanel savePanel]; @@ -207,7 +222,7 @@ - (void) create: (id) sender { - if ([[fTrackerField stringValue] isEqualToString: @""] && [fDefaults boolForKey: @"WarningCreatorBlankAddress"]) + if ([fTrackers count] == 0 && [fDefaults boolForKey: @"WarningCreatorBlankAddress"]) { NSAlert * alert = [[NSAlert alloc] init]; [alert setMessageText: NSLocalizedString(@"The tracker address is blank.", "Create torrent -> blank address -> title")]; @@ -245,6 +260,70 @@ [fTimer fire]; } +- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableView +{ + return [fTrackers count]; +} + +- (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row +{ + return [fTrackers objectAtIndex: row]; +} + +- (void) addRemoveTracker: (id) sender +{ + //don't allow add/remove when currently adding - it leads to weird results + if ([fTrackerTable editedRow] != -1) + return; + + if ([[sender cell] tagForSegment: [sender selectedSegment]] == TRACKER_REMOVE_TAG) + { + [fTrackers removeObjectsAtIndexes: [fTrackerTable selectedRowIndexes]]; + + [fTrackerTable deselectAll: self]; + [fTrackerTable reloadData]; + + [self updateEnableOpenCheckForTrackers]; + } + else + { + [fTrackers addObject: @""]; + [fTrackerTable reloadData]; + + int row = [fTrackers count] - 1; + [fTrackerTable selectRow: row byExtendingSelection: NO]; + [fTrackerTable editColumn: 0 row: row withEvent: nil select: YES]; + } +} + +- (void) tableView: (NSTableView *) tableView setObjectValue: (id) object forTableColumn: (NSTableColumn *) tableColumn + row: (NSInteger) row +{ + NSString * tracker = (NSString *)object; + + if ([tracker rangeOfString: @"://"].location == NSNotFound) + tracker = [@"http://" stringByAppendingString: tracker]; + + if (!tr_httpIsValidURL([tracker UTF8String])) + { + NSBeep(); + [fTrackers removeObjectAtIndex: row]; + } + else + { + [fTrackers replaceObjectAtIndex: row withObject: tracker]; + [self updateEnableOpenCheckForTrackers]; + } + + [fTrackerTable deselectAll: self]; + [fTrackerTable reloadData]; +} + +- (void) tableViewSelectionDidChange: (NSNotification *) notification +{ + [fTrackerAddRemoveControl setEnabled: [fTrackerTable numberOfSelectedRows] > 0 forSegment: TRACKER_REMOVE_TAG]; +} + @end @implementation CreatorWindowController (Private) @@ -266,9 +345,9 @@ return success ? [[panel filenames] objectAtIndex: 0] : nil; } -- (void) updateEnableOpenCheckForTrackerField +- (void) updateEnableOpenCheckForTrackers { - BOOL hasTracker = ![[fTrackerField stringValue] isEqualToString: @""]; + BOOL hasTracker = [fTrackers count] > 0; [fOpenCheck setEnabled: hasTracker]; [fOpenCheck setState: (fOpenTorrent && hasTracker) ? NSOnState : NSOffState]; } @@ -319,15 +398,15 @@ return; } - [fTracker release]; //incase a previous create was aborted - fTracker = [[fTrackerField stringValue] retain]; - //parse non-empty tracker strings - tr_tracker_info trackerInfo; - BOOL isTracker = NO; - if (![fTracker isEqualToString: @""]) + tr_tracker_info * trackerInfo = tr_new0(tr_tracker_info, [fTrackers count]); + + NSUInteger i; + for (i = 0; i < [fTrackers count]; i++) + trackerInfo[i].announce = (char *)[[fTrackers objectAtIndex: i] UTF8String]; + + /*if ([fTrackers count] > 0) { - isTracker = YES; if ([fTracker rangeOfString: @"://"].location == NSNotFound) { NSString * fullTracker = [@"http://" stringByAppendingString: fTracker]; @@ -335,6 +414,10 @@ fTracker = [fullTracker retain]; } + #warning remove + NSString * fTracker = [fTrackers objectAtIndex: 0]; + + #warning move to adding if (!tr_httpIsValidURL([fTracker UTF8String])) { NSAlert * alert = [[[NSAlert alloc] init] autorelease]; @@ -357,17 +440,18 @@ trackerInfo.tier = 0; trackerInfo.announce = (char *)[fTracker UTF8String]; - } + }*/ //store values - [fDefaults setObject: fTracker forKey: @"CreatorTracker"]; + [fDefaults setObject: fTrackers forKey: @"CreatorTrackers"]; [fDefaults setBool: [fPrivateCheck state] == NSOnState forKey: @"CreatorPrivate"]; [fDefaults setBool: fOpenTorrent forKey: @"CreatorOpen"]; [fDefaults setObject: [fLocation stringByDeletingLastPathComponent] forKey: @"CreatorLocation"]; [[NSNotificationCenter defaultCenter] postNotificationName: @"BeginCreateTorrentFile" object: fLocation userInfo: nil]; - tr_makeMetaInfo(fInfo, [fLocation UTF8String], &trackerInfo, isTracker ? 1 : 0, [[fCommentView string] UTF8String], + tr_makeMetaInfo(fInfo, [fLocation UTF8String], trackerInfo, [fTrackers count], [[fCommentView string] UTF8String], [fPrivateCheck state] == NSOnState); + tr_free(trackerInfo); fTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(checkProgress) userInfo: nil repeats: YES]; @@ -384,7 +468,7 @@ switch (fInfo->result) { case TR_MAKEMETA_OK: - if (fOpenTorrent && ![fTracker isEqualToString: @""]) + if (fOpenTorrent && [fTrackers count] > 0) { NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys: fLocation, @"File", [fPath stringByDeletingLastPathComponent], @"Path", nil]; diff --git a/macosx/English.lproj/Creator.xib b/macosx/English.lproj/Creator.xib index 5a9d2a8ea..c9e357ddc 100644 --- a/macosx/English.lproj/Creator.xib +++ b/macosx/English.lproj/Creator.xib @@ -28,7 +28,7 @@ 15 2 - {{432, 603}, {480, 313}} + {{432, 524}, {488, 392}} 1886912512 Torrent Creator NSWindow @@ -36,7 +36,7 @@ View {3.40282e+38, 3.40282e+38} - {430, 285} + {430, 350} 256 @@ -57,7 +57,7 @@ NeXT TIFF v4.0 pasteboard type - {{20, 239}, {64, 64}} + {{20, 318}, {64, 64}} YES @@ -77,7 +77,7 @@ 266 - {{89, 272}, {371, 22}} + {{89, 351}, {379, 22}} YES @@ -113,7 +113,7 @@ 266 - {{89, 247}, {374, 17}} + {{89, 326}, {382, 17}} YES @@ -132,7 +132,7 @@ - 274 + 290 YES @@ -166,7 +166,7 @@ WebURLsWithTitlesPboardType - {340, 14} + {348, 14} @@ -184,7 +184,7 @@ - 3.400000e+02 + 3.480000e+02 1 @@ -237,12 +237,12 @@ 6 - {697, 1e+07} + {713, 1e+07} {83, 0} - {{1, 1}, {340, 82}} + {{1, 1}, {348, 73}} @@ -256,7 +256,7 @@ 256 - {{341, 1}, {15, 82}} + {{349, 1}, {15, 73}} _doScroller: @@ -274,7 +274,7 @@ 9.456522e-01 - {{103, 120}, {357, 84}} + {{103, 120}, {365, 75}} 18 @@ -284,8 +284,8 @@ - 268 - {{28, 187}, {70, 17}} + 292 + {{28, 178}, {70, 17}} YES @@ -301,50 +301,23 @@ 268 - {{42, 214}, {56, 17}} + {{35, 293}, {63, 17}} YES 67239424 272629760 - Tracker: + Trackers: - - - 266 - {{103, 212}, {357, 22}} - - YES - - -1804468671 - 272630784 - http:// - - - YES - - 6 - System - textBackgroundColor - - - - 6 - System - textColor - - - - 290 - {{12, 85}, {456, 5}} + {{12, 85}, {464, 5}} {0, 0} @@ -352,7 +325,12 @@ 0 Box - + + 6 + System + textBackgroundColor + + 3 MCAwLjgwMDAwMDAxAA @@ -366,7 +344,7 @@ 289 - {{388, 53}, {77, 28}} + {{396, 53}, {77, 28}} YES @@ -413,12 +391,12 @@ 290 - {{123, 45}, {265, 30}} + {{123, 45}, {273, 30}} YES 67239424 - 272761344 + 272761600 RmlsZQpGaWxlA @@ -461,7 +439,7 @@ 292 - {{103, 96}, {65, 18}} + {{101, 96}, {65, 18}} YES @@ -488,7 +466,7 @@ 289 - {{385, 12}, {81, 32}} + {{393, 12}, {81, 32}} YES @@ -509,7 +487,7 @@ 289 - {{303, 12}, {82, 32}} + {{311, 12}, {82, 32}} YES @@ -530,7 +508,7 @@ 290 - {{169, 98}, {294, 17}} + {{169, 98}, {302, 17}} YES @@ -546,7 +524,7 @@ 292 - {{102, 21}, {144, 18}} + {{101, 21}, {144, 18}} YES @@ -564,14 +542,195 @@ 25 + + + 274 + + YES + + + 2304 + + YES + + + 256 + {348, 79} + + YES + + + 256 + {{345, 1}, {16, 17}} + + + YES + + 3.450000e+02 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + + + + 3 + MC4zMzMzMzI5OQA + + + 6 + System + headerTextColor + + + + + 337772096 + 2048 + Text Cell + + + + 6 + System + controlBackgroundColor + + + + + 3 + YES + YES + + + + 3.000000e+00 + 2.000000e+00 + + + 6 + System + gridColor + + 3 + MC41AA + + + 1.700000e+01 + 448790528 + 4 + 15 + 0 + NO + + + {{1, 1}, {348, 79}} + + + + + 4 + + + + 256 + {{349, 1}, {15, 79}} + + + _doScroller: + 9.843750e-01 + + + + 256 + {{-100, -100}, {344, 15}} + + 1 + + _doScroller: + 9.971014e-01 + + + {{103, 229}, {365, 81}} + + + 18 + + + + QSAAAEEgAABBmAAAQZgAAA + + + + 292 + {{103, 202}, {67, 23}} + + YES + + -2080244224 + 0 + + + + YES + + 3.200000e+01 + + NSImage + NSAddTemplate + + + 0 + + + 3.200000e+01 + + NSImage + NSRemoveTemplate + + + 1 + YES + 0 + + + 2 + 6 + + + + + 256 + {{175, 206}, {296, 14}} + + YES + + 67239424 + 272760832 + Trackers will be randomized in the same tier + + + + + 6 + System + disabledControlTextColor + + 3 + MC4zMzMzMzMzNAA + + + + - {480, 313} + {488, 392} {{0, 0}, {1680, 1028}} - {430, 307} + {430, 372} {3.40282e+38, 3.40282e+38} - TorrentCreator + CreatorWindow @@ -685,14 +844,6 @@ 34 - - - fTrackerField - - - - 35 - window @@ -773,14 +924,6 @@ 65 - - - delegate - - - - 86 - toggleOpenCheck: @@ -789,6 +932,46 @@ 88 + + + fTrackerTable + + + + 99 + + + + dataSource + + + + 100 + + + + delegate + + + + 101 + + + + fTrackerAddRemoveControl + + + + 105 + + + + addRemoveTracker: + + + + 106 + @@ -831,10 +1014,7 @@ - - - @@ -845,6 +1025,11 @@ + + + + + @@ -875,31 +1060,6 @@ - - 11 - - - YES - - - - - - - - 12 - - - - - 13 - - - YES - - - - 14 @@ -909,15 +1069,6 @@ - - 15 - - - YES - - - - 16 @@ -1067,21 +1218,11 @@ - - 70 - - - 71 - - 72 - - - 73 @@ -1138,9 +1279,35 @@ - 84 - - + -3 + + + Application + + + 13 + + + YES + + + + + + 70 + + + + + 11 + + + YES + + + + + 85 @@ -1148,10 +1315,86 @@ - -3 - - - Application + 84 + + + + + 12 + + + + + 89 + + + YES + + + + + + + + 92 + + + YES + + + + + + 94 + + + YES + + + + + + 97 + + + + + 91 + + + + + 90 + + + + + 103 + + + YES + + + + + + 104 + + + + + 107 + + + YES + + + + + + 108 + + @@ -1163,6 +1406,12 @@ -2.IBPluginDependency 10.IBPluginDependency 10.ImportedFromIB2 + 103.IBPluginDependency + 103.IBSegmentedControlTracker.RoundRobinState + 103.IBSegmentedControlTracker.WasGrowing + 104.IBPluginDependency + 107.IBPluginDependency + 107.ImportedFromIB2 11.IBPluginDependency 11.ImportedFromIB2 12.IBPluginDependency @@ -1171,8 +1420,6 @@ 13.ImportedFromIB2 14.IBPluginDependency 14.ImportedFromIB2 - 15.IBPluginDependency - 15.ImportedFromIB2 16.IBPluginDependency 16.ImportedFromIB2 17.IBPluginDependency @@ -1219,8 +1466,14 @@ 8.ImportedFromIB2 84.IBShouldRemoveOnLegacySave 85.IBShouldRemoveOnLegacySave + 89.IBPluginDependency 9.IBPluginDependency 9.ImportedFromIB2 + 90.IBPluginDependency + 91.IBPluginDependency + 92.IBPluginDependency + 94.IBPluginDependency + 97.IBPluginDependency YES @@ -1229,7 +1482,11 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1258,16 +1515,16 @@ com.apple.InterfaceBuilder.CocoaPlugin - {{0, 682}, {480, 313}} + {{139, 514}, {488, 392}} com.apple.InterfaceBuilder.CocoaPlugin - {{0, 682}, {480, 313}} + {{139, 514}, {488, 392}} {{432, 603}, {480, 313}} {3.40282e+38, 3.40282e+38} - {430, 285} + {430, 350} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1285,7 +1542,13 @@ com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin @@ -1308,7 +1571,7 @@ - 88 + 108 @@ -1320,6 +1583,7 @@ YES YES + addRemoveTracker: cancelCreateProgress: cancelCreateWindow: create: @@ -1333,6 +1597,7 @@ id id id + id @@ -1349,7 +1614,8 @@ fProgressIndicator fProgressView fStatusField - fTrackerField + fTrackerAddRemoveControl + fTrackerTable YES @@ -1363,7 +1629,8 @@ NSProgressIndicator NSView NSTextField - NSTextField + NSSegmentedControl + NSTableView