move the filter bar into its own xib
This commit is contained in:
parent
a41e93c506
commit
6d10cd2c9c
|
@ -280,6 +280,8 @@
|
|||
A2E38540130DFECD001F501B /* libminiupnp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE1183480CE160960002D0F3 /* libminiupnp.a */; };
|
||||
A2E57ABB1310822C00A7DAB1 /* StatusBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = A2E57ABA1310822C00A7DAB1 /* StatusBarController.m */; };
|
||||
A2E57AC61310831400A7DAB1 /* StatusBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2E57AC51310831400A7DAB1 /* StatusBar.xib */; };
|
||||
A2E57B9C13109DC200A7DAB1 /* FilterBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2E57B9B13109DC200A7DAB1 /* FilterBar.xib */; };
|
||||
A2E57BA713109E6B00A7DAB1 /* FilterBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = A2E57BA613109E6B00A7DAB1 /* FilterBarController.m */; };
|
||||
A2E669790F5B8E5A00B4251A /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A2E669780F5B8E5A00B4251A /* Security.framework */; };
|
||||
A2E9AA760C249AF400085DCF /* ToolbarCreateTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = A2E9AA750C249AF400085DCF /* ToolbarCreateTemplate.png */; };
|
||||
A2ED7D8F0CEF431B00970975 /* FilterButton.m in Sources */ = {isa = PBXBuildFile; fileRef = A2ED7D8E0CEF431B00970975 /* FilterButton.m */; };
|
||||
|
@ -863,6 +865,9 @@
|
|||
A2E57AB91310822C00A7DAB1 /* StatusBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StatusBarController.h; path = macosx/StatusBarController.h; sourceTree = "<group>"; };
|
||||
A2E57ABA1310822C00A7DAB1 /* StatusBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = StatusBarController.m; path = macosx/StatusBarController.m; sourceTree = "<group>"; };
|
||||
A2E57AC51310831400A7DAB1 /* StatusBar.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = StatusBar.xib; path = macosx/StatusBar.xib; sourceTree = "<group>"; };
|
||||
A2E57B9B13109DC200A7DAB1 /* FilterBar.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = FilterBar.xib; path = macosx/FilterBar.xib; sourceTree = "<group>"; };
|
||||
A2E57BA513109E6B00A7DAB1 /* FilterBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FilterBarController.h; path = macosx/FilterBarController.h; sourceTree = "<group>"; };
|
||||
A2E57BA613109E6B00A7DAB1 /* FilterBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FilterBarController.m; path = macosx/FilterBarController.m; sourceTree = "<group>"; };
|
||||
A2E669780F5B8E5A00B4251A /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
|
||||
A2E9AA750C249AF400085DCF /* ToolbarCreateTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ToolbarCreateTemplate.png; path = macosx/Images/ToolbarCreateTemplate.png; sourceTree = "<group>"; };
|
||||
A2EA8E3C0CC3C9830081201C /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = macosx/fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
|
@ -1110,6 +1115,8 @@
|
|||
A2E57ABA1310822C00A7DAB1 /* StatusBarController.m */,
|
||||
A21282A50CA6C66800EAEE0F /* StatusBarView.h */,
|
||||
A21282A60CA6C66800EAEE0F /* StatusBarView.m */,
|
||||
A2E57BA513109E6B00A7DAB1 /* FilterBarController.h */,
|
||||
A2E57BA613109E6B00A7DAB1 /* FilterBarController.m */,
|
||||
A2661D3A12D0E51A004F69D5 /* FilterBarView.h */,
|
||||
A2661D3B12D0E51B004F69D5 /* FilterBarView.m */,
|
||||
A2ED7D8D0CEF431B00970975 /* FilterButton.h */,
|
||||
|
@ -1193,6 +1200,7 @@
|
|||
A233BD680D8CF2C7007EE7B4 /* StatsWindow.xib */,
|
||||
A231274B0D11D0B7003F9AFF /* AboutWindow.xib */,
|
||||
A2E57AC51310831400A7DAB1 /* StatusBar.xib */,
|
||||
A2E57B9B13109DC200A7DAB1 /* FilterBar.xib */,
|
||||
A2F7CF5413035F7B0016FF10 /* URLSheetWindow.xib */,
|
||||
A2D307B00D9EC9F50051FD27 /* BlocklistStatusWindow.xib */,
|
||||
A209ECA1114319C3002B02D1 /* InfoWindow.xib */,
|
||||
|
@ -2084,6 +2092,7 @@
|
|||
A21F15AD11729A9F00CF5A9C /* AddMagnetWindow.xib in Resources */,
|
||||
A2F7CF5513035F7B0016FF10 /* URLSheetWindow.xib in Resources */,
|
||||
A2E57AC61310831400A7DAB1 /* StatusBar.xib in Resources */,
|
||||
A2E57B9C13109DC200A7DAB1 /* FilterBar.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -2276,6 +2285,7 @@
|
|||
A25BB02A12F4F517004B724E /* InfoTabButtonBack.m in Sources */,
|
||||
A2F7CF5F13035FFD0016FF10 /* URLSheetWindowController.m in Sources */,
|
||||
A2E57ABB1310822C00A7DAB1 /* StatusBarController.m in Sources */,
|
||||
A2E57BA713109E6B00A7DAB1 /* FilterBarController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -31,8 +31,7 @@
|
|||
@class AddWindowController;
|
||||
@class Badger;
|
||||
@class DragOverlayWindow;
|
||||
@class FilterBarView;
|
||||
@class FilterButton;
|
||||
@class FilterBarController;
|
||||
@class InfoWindowController;
|
||||
@class MessageWindowController;
|
||||
@class PrefsController;
|
||||
|
@ -74,13 +73,10 @@ typedef enum
|
|||
IBOutlet NSButton * fActionButton, * fSpeedLimitButton;
|
||||
IBOutlet NSTextField * fTotalTorrentsField;
|
||||
|
||||
IBOutlet StatusBarController * fStatusBar;
|
||||
StatusBarController * fStatusBar;
|
||||
|
||||
IBOutlet FilterBarView * fFilterBar;
|
||||
IBOutlet FilterButton * fNoFilterButton, * fActiveFilterButton, * fDownloadFilterButton,
|
||||
* fSeedFilterButton, * fPauseFilterButton;
|
||||
IBOutlet NSSearchField * fSearchFilterField;
|
||||
IBOutlet NSMenuItem * fNextFilterItem, * fPrevFilterItem;
|
||||
FilterBarController * fFilterBar;
|
||||
IBOutlet NSMenuItem * fNextFilterItem;
|
||||
|
||||
IBOutlet NSMenuItem * fNextInfoTabItem, * fPrevInfoTabItem;
|
||||
|
||||
|
@ -91,8 +87,7 @@ typedef enum
|
|||
IBOutlet NSMenu * fRatioStopMenu;
|
||||
IBOutlet NSMenuItem * fCheckRatioItem, * fNoCheckRatioItem;
|
||||
|
||||
IBOutlet NSMenu * fGroupsSetMenu, * fGroupsSetContextMenu, * fGroupFilterMenu;
|
||||
IBOutlet NSPopUpButton * fGroupsButton;
|
||||
IBOutlet NSMenu * fGroupsSetMenu, * fGroupsSetContextMenu;
|
||||
|
||||
#warning change to QLPreviewPanel
|
||||
id fPreviewPanel;
|
||||
|
@ -195,7 +190,7 @@ typedef enum
|
|||
|
||||
- (void) updateTorrentHistory;
|
||||
|
||||
- (void) applyFilter: (id) sender;
|
||||
- (void) applyFilter;
|
||||
|
||||
- (void) sortTorrents;
|
||||
- (void) sortTorrentsIgnoreSelected;
|
||||
|
@ -203,14 +198,9 @@ typedef enum
|
|||
- (void) setSortByGroup: (id) sender;
|
||||
- (void) setSortReverse: (id) sender;
|
||||
|
||||
- (void) setFilter: (id) sender;
|
||||
- (void) setFilterSearchType: (id) sender;
|
||||
- (void) switchFilter: (id) sender;
|
||||
|
||||
- (void) setGroup: (id) sender; //used by delegate-generated menu items
|
||||
- (void) setGroupFilter: (id) sender;
|
||||
- (void) updateGroupsFilterButton;
|
||||
- (void) updateGroupsFilters: (NSNotification *) notification;
|
||||
|
||||
- (void) toggleSpeedLimit: (id) sender;
|
||||
- (void) speedLimitChanged: (id) sender;
|
||||
|
@ -248,8 +238,6 @@ typedef enum
|
|||
- (void) setWindowSizeToFit;
|
||||
- (NSRect) sizedWindowFrame;
|
||||
|
||||
- (void) resizeFilterBar;
|
||||
|
||||
- (void) updateForExpandCollape;
|
||||
|
||||
- (void) showMainWindow: (id) sender;
|
||||
|
|
|
@ -45,8 +45,7 @@
|
|||
#import "ToolbarSegmentedCell.h"
|
||||
#import "BlocklistDownloader.h"
|
||||
#import "StatusBarController.h"
|
||||
#import "FilterBarView.h"
|
||||
#import "FilterButton.h"
|
||||
#import "FilterBarController.h"
|
||||
#import "BonjourController.h"
|
||||
#import "Badger.h"
|
||||
#import "DragOverlayWindow.h"
|
||||
|
@ -107,20 +106,6 @@ typedef enum
|
|||
SORT_DESC_TAG = 1
|
||||
} sortOrderTag;
|
||||
|
||||
#define FILTER_NONE @"None"
|
||||
#define FILTER_ACTIVE @"Active"
|
||||
#define FILTER_DOWNLOAD @"Download"
|
||||
#define FILTER_SEED @"Seed"
|
||||
#define FILTER_PAUSE @"Pause"
|
||||
|
||||
#define FILTER_TYPE_NAME @"Name"
|
||||
#define FILTER_TYPE_TRACKER @"Tracker"
|
||||
|
||||
#define FILTER_TYPE_TAG_NAME 401
|
||||
#define FILTER_TYPE_TAG_TRACKER 402
|
||||
|
||||
#define GROUP_FILTER_ALL_TAG -2
|
||||
|
||||
#define GROWL_DOWNLOAD_COMPLETE @"Download Complete"
|
||||
#define GROWL_SEEDING_COMPLETE @"Seeding Complete"
|
||||
#define GROWL_AUTO_ADD @"Torrent Auto Added"
|
||||
|
@ -132,9 +117,6 @@ typedef enum
|
|||
#define ROW_HEIGHT_SMALL 22.0
|
||||
#define WINDOW_REGULAR_WIDTH 468.0
|
||||
|
||||
#define SEARCH_FILTER_MIN_WIDTH 48.0
|
||||
#define SEARCH_FILTER_MAX_WIDTH 95.0
|
||||
|
||||
#define UPDATE_UI_SECONDS 1.0
|
||||
|
||||
#define DOCK_SEEDING_TAG 101
|
||||
|
@ -414,20 +396,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
|
||||
[[fTotalTorrentsField cell] setBackgroundStyle: NSBackgroundStyleRaised];
|
||||
|
||||
[self updateGroupsFilterButton];
|
||||
|
||||
//set up filter bar
|
||||
NSView * contentView = [fWindow contentView];
|
||||
NSSize windowSize = [contentView convertSize: [fWindow frame].size fromView: nil];
|
||||
[fFilterBar setHidden: YES];
|
||||
|
||||
NSRect filterBarFrame = [fFilterBar frame];
|
||||
filterBarFrame.size.width = windowSize.width;
|
||||
[fFilterBar setFrame: filterBarFrame];
|
||||
|
||||
[contentView addSubview: fFilterBar];
|
||||
[fFilterBar setFrameOrigin: NSMakePoint(0, NSMaxY([contentView frame]))];
|
||||
|
||||
[self showFilterBar: [fDefaults boolForKey: @"FilterBar"] animate: NO];
|
||||
|
||||
//set up status bar
|
||||
|
@ -472,43 +441,6 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
}
|
||||
}
|
||||
|
||||
//set filter
|
||||
NSString * filterType = [fDefaults stringForKey: @"Filter"];
|
||||
|
||||
NSButton * currentFilterButton;
|
||||
if ([filterType isEqualToString: FILTER_ACTIVE])
|
||||
currentFilterButton = fActiveFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_PAUSE])
|
||||
currentFilterButton = fPauseFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_SEED])
|
||||
currentFilterButton = fSeedFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_DOWNLOAD])
|
||||
currentFilterButton = fDownloadFilterButton;
|
||||
else
|
||||
{
|
||||
//safety
|
||||
if (![filterType isEqualToString: FILTER_NONE])
|
||||
[fDefaults setObject: FILTER_NONE forKey: @"Filter"];
|
||||
currentFilterButton = fNoFilterButton;
|
||||
}
|
||||
[currentFilterButton setState: NSOnState];
|
||||
|
||||
//set filter search type
|
||||
NSString * filterSearchType = [fDefaults stringForKey: @"FilterSearchType"];
|
||||
|
||||
NSMenu * filterSearchMenu = [[fSearchFilterField cell] searchMenuTemplate];
|
||||
NSString * filterSearchTypeTitle;
|
||||
if ([filterSearchType isEqualToString: FILTER_TYPE_TRACKER])
|
||||
filterSearchTypeTitle = [[filterSearchMenu itemWithTag: FILTER_TYPE_TAG_TRACKER] title];
|
||||
else
|
||||
{
|
||||
//safety
|
||||
if (![filterType isEqualToString: FILTER_TYPE_NAME])
|
||||
[fDefaults setObject: FILTER_TYPE_NAME forKey: @"FilterSearchType"];
|
||||
filterSearchTypeTitle = [[filterSearchMenu itemWithTag: FILTER_TYPE_TAG_NAME] title];
|
||||
}
|
||||
[[fSearchFilterField cell] setPlaceholderString: filterSearchTypeTitle];
|
||||
|
||||
fBadger = [[Badger alloc] initWithLib: fLib];
|
||||
|
||||
//observe notifications
|
||||
|
@ -545,6 +477,9 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[nc addObserver: self selector: @selector(updateTorrentsInQueue)
|
||||
name: @"UpdateQueue" object: nil];
|
||||
|
||||
[nc addObserver: self selector: @selector(applyFilter)
|
||||
name: @"ApplyFilter" object: nil];
|
||||
|
||||
//open newly created torrent file
|
||||
[nc addObserver: self selector: @selector(beginCreateFile:)
|
||||
name: @"BeginCreateTorrentFile" object: nil];
|
||||
|
@ -552,10 +487,6 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
//open newly created torrent file
|
||||
[nc addObserver: self selector: @selector(openCreatedFile:)
|
||||
name: @"OpenCreatedTorrentFile" object: nil];
|
||||
|
||||
//update when groups change
|
||||
[nc addObserver: self selector: @selector(updateGroupsFilters:)
|
||||
name: @"UpdateGroups" object: nil];
|
||||
|
||||
//timer to update the interface every second
|
||||
[self updateUI];
|
||||
|
@ -564,13 +495,14 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSModalPanelRunLoopMode];
|
||||
[[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSEventTrackingRunLoopMode];
|
||||
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
|
||||
[fWindow makeKeyAndOrderFront: nil];
|
||||
|
||||
#warning still needed?
|
||||
//can't be done earlier
|
||||
if (![fFilterBar isHidden])
|
||||
[self resizeFilterBar];
|
||||
/*if (![fFilterBar isHidden])
|
||||
[self resizeFilterBar];*/
|
||||
|
||||
if ([fDefaults boolForKey: @"InfoVisible"])
|
||||
[self showInfo: nil];
|
||||
|
@ -1266,7 +1198,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
}
|
||||
|
||||
[self updateUI];
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
[[fWindow toolbar] validateVisibleItems];
|
||||
[self updateTorrentHistory];
|
||||
}
|
||||
|
@ -1290,7 +1222,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[torrents makeObjectsPerformSelector: @selector(stopTransfer)];
|
||||
|
||||
[self updateUI];
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
[[fWindow toolbar] validateVisibleItems];
|
||||
[self updateTorrentHistory];
|
||||
}
|
||||
|
@ -1605,7 +1537,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
for (Torrent * torrent in torrents)
|
||||
[torrent resetCache];
|
||||
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
}
|
||||
|
||||
- (void) showPreferenceWindow: (id) sender
|
||||
|
@ -1760,7 +1692,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
}
|
||||
|
||||
[self updateUI];
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
[[fWindow toolbar] validateVisibleItems];
|
||||
[self updateTorrentHistory];
|
||||
}
|
||||
|
@ -1923,7 +1855,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
}
|
||||
|
||||
[fDefaults setObject: sortType forKey: @"Sort"];
|
||||
[self applyFilter: nil]; //better than calling sortTorrents because it will even apply to queue order
|
||||
[self applyFilter]; //better than calling sortTorrents because it will even apply to queue order
|
||||
}
|
||||
|
||||
- (void) setSortByGroup: (id) sender
|
||||
|
@ -1935,7 +1867,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
if (sortByGroup)
|
||||
[fTableView removeAllCollapsedGroups];
|
||||
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
}
|
||||
|
||||
- (void) setSortReverse: (id) sender
|
||||
|
@ -2027,7 +1959,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[fTableView reloadData];
|
||||
}
|
||||
|
||||
- (void) applyFilter: (id) sender
|
||||
- (void) applyFilter
|
||||
{
|
||||
//get all the torrents in the table
|
||||
NSMutableArray * previousTorrents;
|
||||
|
@ -2060,8 +1992,8 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
const NSInteger groupFilterValue = [fDefaults integerForKey: @"FilterGroup"];
|
||||
const BOOL filterGroup = groupFilterValue != GROUP_FILTER_ALL_TAG;
|
||||
|
||||
NSString * searchString = [fSearchFilterField stringValue];
|
||||
const BOOL filterText = [searchString length] > 0,
|
||||
NSString * searchString = fFilterBar ? [fFilterBar searchString] : @"";
|
||||
const BOOL filterText = ![searchString isEqualToString: @""],
|
||||
filterTracker = filterText && [[fDefaults stringForKey: @"FilterSearchType"] isEqualToString: FILTER_TYPE_TRACKER];
|
||||
|
||||
NSMutableArray * allTorrents = [NSMutableArray arrayWithCapacity: [fTorrents count]];
|
||||
|
@ -2132,11 +2064,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
}
|
||||
|
||||
//set button tooltips
|
||||
[fNoFilterButton setCount: [fTorrents count]];
|
||||
[fActiveFilterButton setCount: active];
|
||||
[fDownloadFilterButton setCount: downloading];
|
||||
[fSeedFilterButton setCount: seeding];
|
||||
[fPauseFilterButton setCount: paused];
|
||||
[fFilterBar setCountAll: [fTorrents count] active: active downloading: downloading seeding: seeding paused: paused];
|
||||
|
||||
//clear display cache for not-shown torrents
|
||||
[previousTorrents removeObjectsInArray: allTorrents];
|
||||
|
@ -2219,110 +2147,19 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[self setWindowSizeToFit];
|
||||
}
|
||||
|
||||
//resets filter and sorts torrents
|
||||
- (void) setFilter: (id) sender
|
||||
{
|
||||
NSString * oldFilterType = [fDefaults stringForKey: @"Filter"];
|
||||
|
||||
NSButton * prevFilterButton;
|
||||
if ([oldFilterType isEqualToString: FILTER_PAUSE])
|
||||
prevFilterButton = fPauseFilterButton;
|
||||
else if ([oldFilterType isEqualToString: FILTER_ACTIVE])
|
||||
prevFilterButton = fActiveFilterButton;
|
||||
else if ([oldFilterType isEqualToString: FILTER_SEED])
|
||||
prevFilterButton = fSeedFilterButton;
|
||||
else if ([oldFilterType isEqualToString: FILTER_DOWNLOAD])
|
||||
prevFilterButton = fDownloadFilterButton;
|
||||
else
|
||||
prevFilterButton = fNoFilterButton;
|
||||
|
||||
if (sender != prevFilterButton)
|
||||
{
|
||||
[prevFilterButton setState: NSOffState];
|
||||
[sender setState: NSOnState];
|
||||
|
||||
NSString * filterType;
|
||||
if (sender == fActiveFilterButton)
|
||||
filterType = FILTER_ACTIVE;
|
||||
else if (sender == fDownloadFilterButton)
|
||||
filterType = FILTER_DOWNLOAD;
|
||||
else if (sender == fPauseFilterButton)
|
||||
filterType = FILTER_PAUSE;
|
||||
else if (sender == fSeedFilterButton)
|
||||
filterType = FILTER_SEED;
|
||||
else
|
||||
filterType = FILTER_NONE;
|
||||
|
||||
[fDefaults setObject: filterType forKey: @"Filter"];
|
||||
}
|
||||
else
|
||||
[sender setState: NSOnState];
|
||||
|
||||
[self applyFilter: nil];
|
||||
}
|
||||
|
||||
- (void) setFilterSearchType: (id) sender
|
||||
{
|
||||
NSString * oldFilterType = [fDefaults stringForKey: @"FilterSearchType"];
|
||||
|
||||
NSInteger prevTag, currentTag = [sender tag];
|
||||
if ([oldFilterType isEqualToString: FILTER_TYPE_TRACKER])
|
||||
prevTag = FILTER_TYPE_TAG_TRACKER;
|
||||
else
|
||||
prevTag = FILTER_TYPE_TAG_NAME;
|
||||
|
||||
if (currentTag != prevTag)
|
||||
{
|
||||
NSString * filterType;
|
||||
if (currentTag == FILTER_TYPE_TAG_TRACKER)
|
||||
filterType = FILTER_TYPE_TRACKER;
|
||||
else
|
||||
filterType = FILTER_TYPE_NAME;
|
||||
|
||||
[fDefaults setObject: filterType forKey: @"FilterSearchType"];
|
||||
|
||||
[[fSearchFilterField cell] setPlaceholderString: [sender title]];
|
||||
}
|
||||
|
||||
[self applyFilter: nil];
|
||||
}
|
||||
|
||||
- (void) switchFilter: (id) sender
|
||||
{
|
||||
NSString * filterType = [fDefaults stringForKey: @"Filter"];
|
||||
|
||||
NSButton * button;
|
||||
if ([filterType isEqualToString: FILTER_NONE])
|
||||
button = sender == fNextFilterItem ? fActiveFilterButton : fPauseFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_ACTIVE])
|
||||
button = sender == fNextFilterItem ? fDownloadFilterButton : fNoFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_DOWNLOAD])
|
||||
button = sender == fNextFilterItem ? fSeedFilterButton : fActiveFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_SEED])
|
||||
button = sender == fNextFilterItem ? fPauseFilterButton : fDownloadFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_PAUSE])
|
||||
button = sender == fNextFilterItem ? fNoFilterButton : fSeedFilterButton;
|
||||
else
|
||||
button = fNoFilterButton;
|
||||
|
||||
[self setFilter: button];
|
||||
[fFilterBar switchFilter: sender == fNextFilterItem];
|
||||
}
|
||||
|
||||
- (void) menuNeedsUpdate: (NSMenu *) menu
|
||||
{
|
||||
if (menu == fGroupsSetMenu || menu == fGroupsSetContextMenu || menu == fGroupFilterMenu)
|
||||
if (menu == fGroupsSetMenu || menu == fGroupsSetContextMenu)
|
||||
{
|
||||
const BOOL filter = menu == fGroupFilterMenu;
|
||||
|
||||
const NSInteger remaining = filter ? 3 : 0;
|
||||
for (NSInteger i = [menu numberOfItems]-1; i >= remaining; i--)
|
||||
for (NSInteger i = [menu numberOfItems]-1; i >= 0; i--)
|
||||
[menu removeItemAtIndex: i];
|
||||
|
||||
NSMenu * groupMenu;
|
||||
if (!filter)
|
||||
groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(setGroup:) isSmall: NO];
|
||||
else
|
||||
groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(setGroupFilter:) isSmall: YES];
|
||||
NSMenu * groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(setGroup:) isSmall: NO];
|
||||
|
||||
const NSInteger groupMenuCount = [groupMenu numberOfItems];
|
||||
for (NSInteger i = 0; i < groupMenuCount; i++)
|
||||
|
@ -2382,47 +2219,11 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[torrent setGroupValue: [sender tag]];
|
||||
}
|
||||
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
[self updateUI];
|
||||
[self updateTorrentHistory];
|
||||
}
|
||||
|
||||
- (void) setGroupFilter: (id) sender
|
||||
{
|
||||
[fDefaults setInteger: [sender tag] forKey: @"FilterGroup"];
|
||||
[self updateGroupsFilterButton];
|
||||
[self applyFilter: nil];
|
||||
}
|
||||
|
||||
- (void) updateGroupsFilterButton
|
||||
{
|
||||
NSInteger groupIndex = [fDefaults integerForKey: @"FilterGroup"];
|
||||
|
||||
NSImage * icon;
|
||||
NSString * toolTip;
|
||||
if (groupIndex == GROUP_FILTER_ALL_TAG)
|
||||
{
|
||||
icon = [NSImage imageNamed: @"PinTemplate.png"];
|
||||
toolTip = NSLocalizedString(@"All Groups", "Groups -> Button");
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = [[GroupsController groups] imageForIndex: groupIndex];
|
||||
NSString * groupName = groupIndex != -1 ? [[GroupsController groups] nameForIndex: groupIndex]
|
||||
: NSLocalizedString(@"None", "Groups -> Button");
|
||||
toolTip = [NSLocalizedString(@"Group", "Groups -> Button") stringByAppendingFormat: @": %@", groupName];
|
||||
}
|
||||
|
||||
[[fGroupFilterMenu itemAtIndex: 0] setImage: icon];
|
||||
[fGroupsButton setToolTip: toolTip];
|
||||
}
|
||||
|
||||
- (void) updateGroupsFilters: (NSNotification *) notification
|
||||
{
|
||||
[self updateGroupsFilterButton];
|
||||
[self applyFilter: nil];
|
||||
}
|
||||
|
||||
- (void) toggleSpeedLimit: (id) sender
|
||||
{
|
||||
[fDefaults setBool: ![fDefaults boolForKey: @"SpeedLimit"] forKey: @"SpeedLimit"];
|
||||
|
@ -2786,7 +2587,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[fTorrents insertObjects: movingTorrents atIndexes: insertIndexes];
|
||||
}
|
||||
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
[fTableView selectValues: selectedValues];
|
||||
}
|
||||
|
||||
|
@ -2984,8 +2785,8 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
NSSize maxSize = [scrollView convertSize: [[fWindow screen] visibleFrame].size fromView: nil];
|
||||
if (!fStatusBar)
|
||||
maxSize.height -= [[fStatusBar view] frame].size.height;
|
||||
if ([fFilterBar isHidden])
|
||||
maxSize.height -= [fFilterBar frame].size.height;
|
||||
if (!fFilterBar)
|
||||
maxSize.height -= [[fFilterBar view] frame].size.height;
|
||||
if (windowSize.height > maxSize.height)
|
||||
windowSize.height = maxSize.height;
|
||||
}
|
||||
|
@ -3025,7 +2826,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[[fStatusBar view] setFrame: statusBarFrame];
|
||||
|
||||
[contentView addSubview: [fStatusBar view]];
|
||||
[[fStatusBar view] setFrameOrigin: NSMakePoint(0, NSMaxY([contentView frame]))];
|
||||
[[fStatusBar view] setFrameOrigin: NSMakePoint(0.0, NSMaxY([contentView frame]))];
|
||||
}
|
||||
|
||||
NSRect frame;
|
||||
|
@ -3054,8 +2855,12 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
//set views to not autoresize
|
||||
const NSUInteger statsMask = [[fStatusBar view] autoresizingMask];
|
||||
[[fStatusBar view] setAutoresizingMask: NSViewNotSizable];
|
||||
const NSUInteger filterMask = [fFilterBar autoresizingMask];
|
||||
[fFilterBar setAutoresizingMask: NSViewNotSizable];
|
||||
NSUInteger filterMask;
|
||||
if (fFilterBar)
|
||||
{
|
||||
filterMask = [[fFilterBar view] autoresizingMask];
|
||||
[[fFilterBar view] setAutoresizingMask: NSViewNotSizable];
|
||||
}
|
||||
const NSUInteger scrollMask = [scrollView autoresizingMask];
|
||||
[scrollView setAutoresizingMask: NSViewNotSizable];
|
||||
|
||||
|
@ -3064,7 +2869,8 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
|
||||
//re-enable autoresize
|
||||
[[fStatusBar view] setAutoresizingMask: statsMask];
|
||||
[fFilterBar setAutoresizingMask: filterMask];
|
||||
if (fFilterBar)
|
||||
[[fFilterBar view] setAutoresizingMask: filterMask];
|
||||
[scrollView setAutoresizingMask: scrollMask];
|
||||
|
||||
//change min size
|
||||
|
@ -3074,6 +2880,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
|
||||
if (!show)
|
||||
{
|
||||
[[fStatusBar view] removeFromSuperview];
|
||||
[fStatusBar release];
|
||||
fStatusBar = nil;
|
||||
}
|
||||
|
@ -3081,38 +2888,56 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
|
||||
- (void) toggleFilterBar: (id) sender
|
||||
{
|
||||
//disable filtering when hiding
|
||||
if (![fFilterBar isHidden])
|
||||
{
|
||||
[fSearchFilterField setStringValue: @""];
|
||||
[self setFilter: fNoFilterButton];
|
||||
[self setGroupFilter: [fGroupFilterMenu itemWithTag: GROUP_FILTER_ALL_TAG]];
|
||||
}
|
||||
|
||||
[self showFilterBar: [fFilterBar isHidden] animate: YES];
|
||||
[fDefaults setBool: ![fFilterBar isHidden] forKey: @"FilterBar"];
|
||||
const BOOL show = fFilterBar == nil;
|
||||
|
||||
[self showFilterBar: show animate: YES];
|
||||
[fDefaults setBool: show forKey: @"FilterBar"];
|
||||
[[fWindow toolbar] validateVisibleItems];
|
||||
|
||||
//disable filtering when hiding
|
||||
if (!show)
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setObject: FILTER_NONE forKey: @"Filter"];
|
||||
[[NSUserDefaults standardUserDefaults] setInteger: GROUP_FILTER_ALL_TAG forKey: @"FilterGroup"];
|
||||
[self applyFilter];
|
||||
}
|
||||
}
|
||||
|
||||
//doesn't save shown state
|
||||
- (void) showFilterBar: (BOOL) show animate: (BOOL) animate
|
||||
{
|
||||
if (show != [fFilterBar isHidden])
|
||||
const BOOL prevShown = fFilterBar != nil;
|
||||
if (show == prevShown)
|
||||
return;
|
||||
|
||||
|
||||
if (show)
|
||||
[fFilterBar setHidden: NO];
|
||||
|
||||
NSRect frame;
|
||||
CGFloat heightChange = [fFilterBar frame].size.height;
|
||||
{
|
||||
fFilterBar = [[FilterBarController alloc] init];
|
||||
|
||||
NSView * contentView = [fWindow contentView];
|
||||
const NSSize windowSize = [contentView convertSize: [fWindow frame].size fromView: nil];
|
||||
|
||||
NSRect filterBarFrame = [[fFilterBar view] frame];
|
||||
filterBarFrame.size.width = windowSize.width;
|
||||
[[fFilterBar view] setFrame: filterBarFrame];
|
||||
|
||||
if (fStatusBar)
|
||||
[contentView addSubview: [fFilterBar view] positioned: NSWindowBelow relativeTo: [fStatusBar view]];
|
||||
else
|
||||
[contentView addSubview: [fFilterBar view]];
|
||||
const CGFloat originY = fStatusBar ? NSMinY([[fStatusBar view] frame]) : NSMaxY([contentView frame]);
|
||||
[[fFilterBar view] setFrameOrigin: NSMakePoint(0.0, originY)];
|
||||
}
|
||||
|
||||
CGFloat heightChange = NSHeight([[fFilterBar view] frame]);
|
||||
if (!show)
|
||||
heightChange *= -1;
|
||||
|
||||
//allow bar to show even if not enough room
|
||||
if (show && ![fDefaults boolForKey: @"AutoSize"])
|
||||
{
|
||||
frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO];
|
||||
CGFloat change = [[fWindow screen] visibleFrame].size.height - frame.size.height;
|
||||
NSRect frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO];
|
||||
const CGFloat change = NSHeight([[fWindow screen] visibleFrame]) - NSHeight(frame);
|
||||
if (change < 0.0)
|
||||
{
|
||||
frame = [fWindow frame];
|
||||
|
@ -3125,16 +2950,16 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
NSScrollView * scrollView = [fTableView enclosingScrollView];
|
||||
|
||||
//set views to not autoresize
|
||||
NSUInteger filterMask = [fFilterBar autoresizingMask];
|
||||
NSUInteger scrollMask = [scrollView autoresizingMask];
|
||||
[fFilterBar setAutoresizingMask: NSViewNotSizable];
|
||||
const NSUInteger filterMask = [[fFilterBar view] autoresizingMask];
|
||||
const NSUInteger scrollMask = [scrollView autoresizingMask];
|
||||
[[fFilterBar view] setAutoresizingMask: NSViewNotSizable];
|
||||
[scrollView setAutoresizingMask: NSViewNotSizable];
|
||||
|
||||
frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO];
|
||||
const NSRect frame = [self windowFrameByAddingHeight: heightChange checkLimits: NO];
|
||||
[fWindow setFrame: frame display: YES animate: animate];
|
||||
|
||||
//re-enable autoresize
|
||||
[fFilterBar setAutoresizingMask: filterMask];
|
||||
[[fFilterBar view] setAutoresizingMask: filterMask];
|
||||
[scrollView setAutoresizingMask: scrollMask];
|
||||
|
||||
//change min size
|
||||
|
@ -3144,16 +2969,19 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
|
||||
if (!show)
|
||||
{
|
||||
[fFilterBar setHidden: YES];
|
||||
[[fFilterBar view] removeFromSuperview];
|
||||
[fFilterBar release];
|
||||
fFilterBar = nil;
|
||||
[fWindow makeFirstResponder: fTableView];
|
||||
}
|
||||
}
|
||||
|
||||
#warning fix?
|
||||
- (void) focusFilterField
|
||||
{
|
||||
[fWindow makeFirstResponder: fSearchFilterField];
|
||||
/*[fWindow makeFirstResponder: fSearchFilterField];
|
||||
if ([fFilterBar isHidden])
|
||||
[self toggleFilterBar: self];
|
||||
[self toggleFilterBar: self];*/
|
||||
}
|
||||
|
||||
#warning change from id to QLPreviewPanel
|
||||
|
@ -3550,7 +3378,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
//set filter image
|
||||
if ([ident isEqualToString: TOOLBAR_FILTER])
|
||||
{
|
||||
[(NSButton *)[toolbarItem view] setState: ![fFilterBar isHidden]];
|
||||
[(NSButton *)[toolbarItem view] setState: fFilterBar != nil];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -3633,12 +3461,6 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
return canUseTable && [fTableView numberOfSelectedRows] > 0;
|
||||
}
|
||||
|
||||
if (action == @selector(setGroupFilter:))
|
||||
{
|
||||
[menuItem setState: [menuItem tag] == [fDefaults integerForKey: @"FilterGroup"] ? NSOnState : NSOffState];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (action == @selector(toggleSmallView:))
|
||||
{
|
||||
[menuItem setState: [fDefaults boolForKey: @"SmallView"] ? NSOnState : NSOffState];
|
||||
|
@ -3724,7 +3546,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
//enable toggle filter bar
|
||||
if (action == @selector(toggleFilterBar:))
|
||||
{
|
||||
NSString * title = [fFilterBar isHidden] ? NSLocalizedString(@"Show Filter Bar", "View menu -> Filter Bar")
|
||||
NSString * title = !fFilterBar ? NSLocalizedString(@"Show Filter Bar", "View menu -> Filter Bar")
|
||||
: NSLocalizedString(@"Hide Filter Bar", "View menu -> Filter Bar");
|
||||
[menuItem setTitle: title];
|
||||
|
||||
|
@ -3733,7 +3555,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
|
||||
//enable prev/next filter button
|
||||
if (action == @selector(switchFilter:))
|
||||
return [fWindow isVisible] && ![fFilterBar isHidden];
|
||||
return [fWindow isVisible] && fFilterBar;
|
||||
|
||||
//enable reveal in finder
|
||||
if (action == @selector(revealFile:))
|
||||
|
@ -3906,21 +3728,6 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
return YES;
|
||||
}
|
||||
|
||||
//check proper filter search item
|
||||
if (action == @selector(setFilterSearchType:))
|
||||
{
|
||||
NSString * filterType = [fDefaults stringForKey: @"FilterSearchType"];
|
||||
|
||||
BOOL state;
|
||||
if ([menuItem tag] == FILTER_TYPE_TAG_TRACKER)
|
||||
state = [filterType isEqualToString: FILTER_TYPE_TRACKER];
|
||||
else
|
||||
state = [filterType isEqualToString: FILTER_TYPE_NAME];
|
||||
|
||||
[menuItem setState: state ? NSOnState : NSOffState];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (action == @selector(toggleQuickLook:))
|
||||
{
|
||||
const BOOL visible = [NSApp isOnSnowLeopardOrBetter] && [QLPreviewPanelSL sharedPreviewPanelExists]
|
||||
|
@ -4085,66 +3892,6 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
return [self windowFrameByAddingHeight: heightChange checkLimits: YES];
|
||||
}
|
||||
|
||||
- (void) resizeFilterBar
|
||||
{
|
||||
//replace all buttons
|
||||
[fNoFilterButton sizeToFit];
|
||||
[fActiveFilterButton sizeToFit];
|
||||
[fDownloadFilterButton sizeToFit];
|
||||
[fSeedFilterButton sizeToFit];
|
||||
[fPauseFilterButton sizeToFit];
|
||||
|
||||
NSRect allRect = [fNoFilterButton frame];
|
||||
NSRect activeRect = [fActiveFilterButton frame];
|
||||
NSRect downloadRect = [fDownloadFilterButton frame];
|
||||
NSRect seedRect = [fSeedFilterButton frame];
|
||||
NSRect pauseRect = [fPauseFilterButton frame];
|
||||
|
||||
//size search filter to not overlap buttons
|
||||
NSRect searchFrame = [fSearchFilterField frame];
|
||||
searchFrame.origin.x = NSMaxX(pauseRect) + 5.0;
|
||||
searchFrame.size.width = [fFilterBar frame].size.width - searchFrame.origin.x - 5.0;
|
||||
|
||||
//make sure it is not too long
|
||||
if (searchFrame.size.width > SEARCH_FILTER_MAX_WIDTH)
|
||||
{
|
||||
searchFrame.origin.x += searchFrame.size.width - SEARCH_FILTER_MAX_WIDTH;
|
||||
searchFrame.size.width = SEARCH_FILTER_MAX_WIDTH;
|
||||
}
|
||||
else if (searchFrame.size.width < SEARCH_FILTER_MIN_WIDTH)
|
||||
{
|
||||
searchFrame.origin.x += searchFrame.size.width - SEARCH_FILTER_MIN_WIDTH;
|
||||
searchFrame.size.width = SEARCH_FILTER_MIN_WIDTH;
|
||||
|
||||
//calculate width the buttons can take up
|
||||
const CGFloat allowedWidth = (searchFrame.origin.x - 5.0) - allRect.origin.x;
|
||||
const CGFloat currentWidth = NSWidth(allRect) + NSWidth(activeRect) + NSWidth(downloadRect) + NSWidth(seedRect)
|
||||
+ NSWidth(pauseRect) + 4.0; //add 4 for space between buttons
|
||||
const CGFloat ratio = allowedWidth / currentWidth;
|
||||
|
||||
//decrease button widths proportionally
|
||||
allRect.size.width = NSWidth(allRect) * ratio;
|
||||
activeRect.size.width = NSWidth(activeRect) * ratio;
|
||||
downloadRect.size.width = NSWidth(downloadRect) * ratio;
|
||||
seedRect.size.width = NSWidth(seedRect) * ratio;
|
||||
pauseRect.size.width = NSWidth(pauseRect) * ratio;
|
||||
}
|
||||
else;
|
||||
|
||||
activeRect.origin.x = NSMaxX(allRect) + 1.0;
|
||||
downloadRect.origin.x = NSMaxX(activeRect) + 1.0;
|
||||
seedRect.origin.x = NSMaxX(downloadRect) + 1.0;
|
||||
pauseRect.origin.x = NSMaxX(seedRect) + 1.0;
|
||||
|
||||
[fNoFilterButton setFrame: allRect];
|
||||
[fActiveFilterButton setFrame: activeRect];
|
||||
[fDownloadFilterButton setFrame: downloadRect];
|
||||
[fSeedFilterButton setFrame: seedRect];
|
||||
[fPauseFilterButton setFrame: pauseRect];
|
||||
|
||||
[fSearchFilterField setFrame: searchFrame];
|
||||
}
|
||||
|
||||
- (void) updateForExpandCollape
|
||||
{
|
||||
[self setWindowSizeToFit];
|
||||
|
@ -4170,12 +3917,6 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
return proposedFrameSize;
|
||||
}
|
||||
|
||||
- (void) windowDidResize: (NSNotification *) notification
|
||||
{
|
||||
if (![fFilterBar isHidden])
|
||||
[self resizeFilterBar];
|
||||
}
|
||||
|
||||
- (void) applicationWillUnhide: (NSNotification *) notification
|
||||
{
|
||||
[self updateUI];
|
||||
|
@ -4349,7 +4090,7 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy
|
|||
[torrent release];
|
||||
|
||||
[self updateUI];
|
||||
[self applyFilter: nil];
|
||||
[self applyFilter];
|
||||
[self updateTorrentHistory];
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,63 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2011 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 <Cocoa/Cocoa.h>
|
||||
|
||||
@class FilterButton;
|
||||
|
||||
#define FILTER_NONE @"None"
|
||||
#define FILTER_ACTIVE @"Active"
|
||||
#define FILTER_DOWNLOAD @"Download"
|
||||
#define FILTER_SEED @"Seed"
|
||||
#define FILTER_PAUSE @"Pause"
|
||||
|
||||
#define FILTER_TYPE_NAME @"Name"
|
||||
#define FILTER_TYPE_TRACKER @"Tracker"
|
||||
|
||||
#define GROUP_FILTER_ALL_TAG -2
|
||||
|
||||
@interface FilterBarController : NSViewController
|
||||
{
|
||||
IBOutlet FilterButton * fNoFilterButton, * fActiveFilterButton, * fDownloadFilterButton,
|
||||
* fSeedFilterButton, * fPauseFilterButton;
|
||||
|
||||
IBOutlet NSSearchField * fSearchField;
|
||||
|
||||
IBOutlet NSPopUpButton * fGroupsButton;
|
||||
}
|
||||
|
||||
- (id) init;
|
||||
|
||||
- (void) setFilter: (id) sender;
|
||||
- (void) switchFilter: (BOOL) right;
|
||||
- (void) setSearchText: (id) sender;
|
||||
- (void) setSearchType: (id) sender;
|
||||
- (void) setGroupFilter: (id) sender;
|
||||
|
||||
- (NSString *) searchString;
|
||||
|
||||
- (void) setCountAll: (NSUInteger) all active: (NSUInteger) active downloading: (NSUInteger) downloading
|
||||
seeding: (NSUInteger) seeding paused: (NSUInteger) paused;
|
||||
|
||||
@end
|
|
@ -0,0 +1,370 @@
|
|||
/******************************************************************************
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2011 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 "FilterBarController.h"
|
||||
#import "FilterButton.h"
|
||||
#include "GroupsController.h"
|
||||
|
||||
#define FILTER_TYPE_TAG_NAME 401
|
||||
#define FILTER_TYPE_TAG_TRACKER 402
|
||||
|
||||
#define SEARCH_MIN_WIDTH 48.0
|
||||
#define SEARCH_MAX_WIDTH 95.0
|
||||
|
||||
@interface FilterBarController (Private)
|
||||
|
||||
- (void) resizeBar;
|
||||
- (void) updateGroupsButton;
|
||||
- (void) updateGroups: (NSNotification *) notification;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FilterBarController
|
||||
|
||||
- (id) init
|
||||
{
|
||||
return (self = [super initWithNibName: @"FilterBar" bundle: nil]);
|
||||
}
|
||||
|
||||
- (void) awakeFromNib
|
||||
{
|
||||
#warning localize every thing
|
||||
|
||||
[self resizeBar];
|
||||
|
||||
//set current filter
|
||||
NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"];
|
||||
|
||||
NSButton * currentFilterButton;
|
||||
if ([filterType isEqualToString: FILTER_ACTIVE])
|
||||
currentFilterButton = fActiveFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_PAUSE])
|
||||
currentFilterButton = fPauseFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_SEED])
|
||||
currentFilterButton = fSeedFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_DOWNLOAD])
|
||||
currentFilterButton = fDownloadFilterButton;
|
||||
else
|
||||
{
|
||||
//safety
|
||||
if (![filterType isEqualToString: FILTER_NONE])
|
||||
[[NSUserDefaults standardUserDefaults] setObject: FILTER_NONE forKey: @"Filter"];
|
||||
currentFilterButton = fNoFilterButton;
|
||||
}
|
||||
[currentFilterButton setState: NSOnState];
|
||||
|
||||
|
||||
//set filter search type
|
||||
NSString * filterSearchType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"];
|
||||
|
||||
NSMenu * filterSearchMenu = [[fSearchField cell] searchMenuTemplate];
|
||||
NSString * filterSearchTypeTitle;
|
||||
if ([filterSearchType isEqualToString: FILTER_TYPE_TRACKER])
|
||||
filterSearchTypeTitle = [[filterSearchMenu itemWithTag: FILTER_TYPE_TAG_TRACKER] title];
|
||||
else
|
||||
{
|
||||
//safety
|
||||
if (![filterType isEqualToString: FILTER_TYPE_NAME])
|
||||
[[NSUserDefaults standardUserDefaults] setObject: FILTER_TYPE_NAME forKey: @"FilterSearchType"];
|
||||
filterSearchTypeTitle = [[filterSearchMenu itemWithTag: FILTER_TYPE_TAG_NAME] title];
|
||||
}
|
||||
[[fSearchField cell] setPlaceholderString: filterSearchTypeTitle];
|
||||
|
||||
[self updateGroupsButton];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resizeBar)
|
||||
name: NSWindowDidResizeNotification object: [[self view] window]];
|
||||
|
||||
//update when groups change
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateGroups:)
|
||||
name: @"UpdateGroups" object: nil];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setFilter: (id) sender
|
||||
{
|
||||
NSString * oldFilterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"];
|
||||
|
||||
NSButton * prevFilterButton;
|
||||
if ([oldFilterType isEqualToString: FILTER_PAUSE])
|
||||
prevFilterButton = fPauseFilterButton;
|
||||
else if ([oldFilterType isEqualToString: FILTER_ACTIVE])
|
||||
prevFilterButton = fActiveFilterButton;
|
||||
else if ([oldFilterType isEqualToString: FILTER_SEED])
|
||||
prevFilterButton = fSeedFilterButton;
|
||||
else if ([oldFilterType isEqualToString: FILTER_DOWNLOAD])
|
||||
prevFilterButton = fDownloadFilterButton;
|
||||
else
|
||||
prevFilterButton = fNoFilterButton;
|
||||
|
||||
if (sender != prevFilterButton)
|
||||
{
|
||||
[prevFilterButton setState: NSOffState];
|
||||
[sender setState: NSOnState];
|
||||
|
||||
NSString * filterType;
|
||||
if (sender == fActiveFilterButton)
|
||||
filterType = FILTER_ACTIVE;
|
||||
else if (sender == fDownloadFilterButton)
|
||||
filterType = FILTER_DOWNLOAD;
|
||||
else if (sender == fPauseFilterButton)
|
||||
filterType = FILTER_PAUSE;
|
||||
else if (sender == fSeedFilterButton)
|
||||
filterType = FILTER_SEED;
|
||||
else
|
||||
filterType = FILTER_NONE;
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject: filterType forKey: @"Filter"];
|
||||
}
|
||||
else
|
||||
[sender setState: NSOnState];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
|
||||
}
|
||||
|
||||
- (void) switchFilter: (BOOL) right
|
||||
{
|
||||
NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"];
|
||||
|
||||
NSButton * button;
|
||||
if ([filterType isEqualToString: FILTER_NONE])
|
||||
button = right ? fActiveFilterButton : fPauseFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_ACTIVE])
|
||||
button = right ? fDownloadFilterButton : fNoFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_DOWNLOAD])
|
||||
button = right ? fSeedFilterButton : fActiveFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_SEED])
|
||||
button = right ? fPauseFilterButton : fDownloadFilterButton;
|
||||
else if ([filterType isEqualToString: FILTER_PAUSE])
|
||||
button = right ? fNoFilterButton : fSeedFilterButton;
|
||||
else
|
||||
button = fNoFilterButton;
|
||||
|
||||
[self setFilter: button];
|
||||
}
|
||||
|
||||
- (void) setSearchText: (id) sender
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
|
||||
}
|
||||
|
||||
- (void) setSearchType: (id) sender
|
||||
{
|
||||
NSString * oldFilterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"];
|
||||
|
||||
NSInteger prevTag, currentTag = [sender tag];
|
||||
if ([oldFilterType isEqualToString: FILTER_TYPE_TRACKER])
|
||||
prevTag = FILTER_TYPE_TAG_TRACKER;
|
||||
else
|
||||
prevTag = FILTER_TYPE_TAG_NAME;
|
||||
|
||||
if (currentTag != prevTag)
|
||||
{
|
||||
NSString * filterType;
|
||||
if (currentTag == FILTER_TYPE_TAG_TRACKER)
|
||||
filterType = FILTER_TYPE_TRACKER;
|
||||
else
|
||||
filterType = FILTER_TYPE_NAME;
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setObject: filterType forKey: @"FilterSearchType"];
|
||||
|
||||
[[fSearchField cell] setPlaceholderString: [sender title]];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
|
||||
}
|
||||
|
||||
- (void) setGroupFilter: (id) sender
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setInteger: [sender tag] forKey: @"FilterGroup"];
|
||||
[self updateGroupsButton];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
|
||||
}
|
||||
|
||||
- (NSString *) searchString
|
||||
{
|
||||
return [fSearchField stringValue];
|
||||
}
|
||||
|
||||
- (void) setCountAll: (NSUInteger) all active: (NSUInteger) active downloading: (NSUInteger) downloading
|
||||
seeding: (NSUInteger) seeding paused: (NSUInteger) paused
|
||||
{
|
||||
[fNoFilterButton setCount: all];
|
||||
[fActiveFilterButton setCount: active];
|
||||
[fDownloadFilterButton setCount: downloading];
|
||||
[fSeedFilterButton setCount: seeding];
|
||||
[fPauseFilterButton setCount: paused];
|
||||
}
|
||||
|
||||
- (void) menuNeedsUpdate: (NSMenu *) menu
|
||||
{
|
||||
if (menu == [fGroupsButton menu])
|
||||
{
|
||||
for (NSInteger i = [menu numberOfItems]-1; i >= 3; i--)
|
||||
[menu removeItemAtIndex: i];
|
||||
|
||||
NSMenu * groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(setGroupFilter:) isSmall: YES];
|
||||
|
||||
const NSInteger groupMenuCount = [groupMenu numberOfItems];
|
||||
for (NSInteger i = 0; i < groupMenuCount; i++)
|
||||
{
|
||||
NSMenuItem * item = [[groupMenu itemAtIndex: 0] retain];
|
||||
[groupMenu removeItemAtIndex: 0];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
|
||||
{
|
||||
const SEL action = [menuItem action];
|
||||
|
||||
//check proper filter search item
|
||||
if (action == @selector(setSearchType:))
|
||||
{
|
||||
NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"];
|
||||
|
||||
BOOL state;
|
||||
if ([menuItem tag] == FILTER_TYPE_TAG_TRACKER)
|
||||
state = [filterType isEqualToString: FILTER_TYPE_TRACKER];
|
||||
else
|
||||
state = [filterType isEqualToString: FILTER_TYPE_NAME];
|
||||
|
||||
[menuItem setState: state ? NSOnState : NSOffState];
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (action == @selector(setGroupFilter:))
|
||||
{
|
||||
[menuItem setState: [menuItem tag] == [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"]
|
||||
? NSOnState : NSOffState];
|
||||
return YES;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation FilterBarController (Private)
|
||||
|
||||
- (void) resizeBar
|
||||
{
|
||||
//replace all buttons
|
||||
[fNoFilterButton sizeToFit];
|
||||
[fActiveFilterButton sizeToFit];
|
||||
[fDownloadFilterButton sizeToFit];
|
||||
[fSeedFilterButton sizeToFit];
|
||||
[fPauseFilterButton sizeToFit];
|
||||
|
||||
NSRect allRect = [fNoFilterButton frame];
|
||||
NSRect activeRect = [fActiveFilterButton frame];
|
||||
NSRect downloadRect = [fDownloadFilterButton frame];
|
||||
NSRect seedRect = [fSeedFilterButton frame];
|
||||
NSRect pauseRect = [fPauseFilterButton frame];
|
||||
|
||||
//size search filter to not overlap buttons
|
||||
NSRect searchFrame = [fSearchField frame];
|
||||
searchFrame.origin.x = NSMaxX(pauseRect) + 5.0;
|
||||
searchFrame.size.width = NSWidth([[self view] frame]) - searchFrame.origin.x - 5.0;
|
||||
|
||||
//make sure it is not too long
|
||||
if (NSWidth(searchFrame) > SEARCH_MAX_WIDTH)
|
||||
{
|
||||
searchFrame.origin.x += NSWidth(searchFrame) - SEARCH_MAX_WIDTH;
|
||||
searchFrame.size.width = SEARCH_MAX_WIDTH;
|
||||
}
|
||||
else if (NSWidth(searchFrame) < SEARCH_MIN_WIDTH)
|
||||
{
|
||||
searchFrame.origin.x += NSWidth(searchFrame) - SEARCH_MIN_WIDTH;
|
||||
searchFrame.size.width = SEARCH_MIN_WIDTH;
|
||||
|
||||
//calculate width the buttons can take up
|
||||
const CGFloat allowedWidth = (searchFrame.origin.x - 5.0) - allRect.origin.x;
|
||||
const CGFloat currentWidth = NSWidth(allRect) + NSWidth(activeRect) + NSWidth(downloadRect) + NSWidth(seedRect)
|
||||
+ NSWidth(pauseRect) + 4.0; //add 4 for space between buttons
|
||||
const CGFloat ratio = allowedWidth / currentWidth;
|
||||
|
||||
//decrease button widths proportionally
|
||||
allRect.size.width = NSWidth(allRect) * ratio;
|
||||
activeRect.size.width = NSWidth(activeRect) * ratio;
|
||||
downloadRect.size.width = NSWidth(downloadRect) * ratio;
|
||||
seedRect.size.width = NSWidth(seedRect) * ratio;
|
||||
pauseRect.size.width = NSWidth(pauseRect) * ratio;
|
||||
}
|
||||
else;
|
||||
|
||||
activeRect.origin.x = NSMaxX(allRect) + 1.0;
|
||||
downloadRect.origin.x = NSMaxX(activeRect) + 1.0;
|
||||
seedRect.origin.x = NSMaxX(downloadRect) + 1.0;
|
||||
pauseRect.origin.x = NSMaxX(seedRect) + 1.0;
|
||||
|
||||
[fNoFilterButton setFrame: allRect];
|
||||
[fActiveFilterButton setFrame: activeRect];
|
||||
[fDownloadFilterButton setFrame: downloadRect];
|
||||
[fSeedFilterButton setFrame: seedRect];
|
||||
[fPauseFilterButton setFrame: pauseRect];
|
||||
|
||||
[fSearchField setFrame: searchFrame];
|
||||
}
|
||||
|
||||
- (void) updateGroupsButton
|
||||
{
|
||||
const NSInteger groupIndex = [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"];
|
||||
|
||||
NSImage * icon;
|
||||
NSString * toolTip;
|
||||
if (groupIndex == GROUP_FILTER_ALL_TAG)
|
||||
{
|
||||
icon = [NSImage imageNamed: @"PinTemplate.png"];
|
||||
toolTip = NSLocalizedString(@"All Groups", "Groups -> Button");
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = [[GroupsController groups] imageForIndex: groupIndex];
|
||||
NSString * groupName = groupIndex != -1 ? [[GroupsController groups] nameForIndex: groupIndex]
|
||||
: NSLocalizedString(@"None", "Groups -> Button");
|
||||
toolTip = [NSLocalizedString(@"Group", "Groups -> Button") stringByAppendingFormat: @": %@", groupName];
|
||||
}
|
||||
|
||||
[[[fGroupsButton menu] itemAtIndex: 0] setImage: icon];
|
||||
[fGroupsButton setToolTip: toolTip];
|
||||
}
|
||||
|
||||
- (void) updateGroups: (NSNotification *) notification
|
||||
{
|
||||
[self updateGroupsButton];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
|
||||
}
|
||||
|
||||
@end
|
|
@ -72,6 +72,8 @@ EXTRA_DIST = \
|
|||
FileOutlineView.m \
|
||||
FilePriorityCell.h \
|
||||
FilePriorityCell.m \
|
||||
FilterBarController.h \
|
||||
FilterBarController.m \
|
||||
FilterBarView.h \
|
||||
FilterBarView.m \
|
||||
FilterButton.h \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue