source: trunk/macosx/FilterBarController.m @ 11995

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

localize the filter bar

File size: 13.9 KB
Line 
1/******************************************************************************
2 * $Id$
3 *
4 * Copyright (c) 2011 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "FilterBarController.h"
26#import "FilterButton.h"
27#include "GroupsController.h"
28
29#define FILTER_TYPE_TAG_NAME    401
30#define FILTER_TYPE_TAG_TRACKER 402
31
32#define SEARCH_MIN_WIDTH 48.0
33#define SEARCH_MAX_WIDTH 95.0
34
35@interface FilterBarController (Private)
36
37- (void) resizeBar;
38- (void) updateGroupsButton;
39- (void) updateGroups: (NSNotification *) notification;
40
41@end
42
43@implementation FilterBarController
44
45- (id) init
46{
47    return (self = [super initWithNibName: @"FilterBar" bundle: nil]);
48}
49
50- (void) awakeFromNib
51{
52    //localizations
53    [fNoFilterButton setTitle: NSLocalizedString(@"All", "Filter Bar -> filter button")];
54    [fActiveFilterButton setTitle: NSLocalizedString(@"Active", "Filter Bar -> filter button")];
55    [fDownloadFilterButton setTitle: NSLocalizedString(@"Downloading", "Filter Bar -> filter button")];
56    [fSeedFilterButton setTitle: NSLocalizedString(@"Seeding", "Filter Bar -> filter button")];
57    [fPauseFilterButton setTitle: NSLocalizedString(@"Paused", "Filter Bar -> filter button")];
58   
59    [[[[fSearchField cell] searchMenuTemplate] itemWithTag: FILTER_TYPE_TAG_NAME] setTitle:
60        NSLocalizedString(@"Name", "Filter Bar -> filter menu")];
61    [[[[fSearchField cell] searchMenuTemplate] itemWithTag: FILTER_TYPE_TAG_TRACKER] setTitle:
62        NSLocalizedString(@"Tracker", "Filter Bar -> filter menu")];
63   
64    [[[fGroupsButton menu] itemWithTag: GROUP_FILTER_ALL_TAG] setTitle:
65        NSLocalizedString(@"All Groups", "Filter Bar -> group filter menu")];
66   
67    [self resizeBar];
68   
69    //set current filter
70    NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"];
71   
72    NSButton * currentFilterButton;
73    if ([filterType isEqualToString: FILTER_ACTIVE])
74        currentFilterButton = fActiveFilterButton;
75    else if ([filterType isEqualToString: FILTER_PAUSE])
76        currentFilterButton = fPauseFilterButton;
77    else if ([filterType isEqualToString: FILTER_SEED])
78        currentFilterButton = fSeedFilterButton;
79    else if ([filterType isEqualToString: FILTER_DOWNLOAD])
80        currentFilterButton = fDownloadFilterButton;
81    else
82    {
83        //safety
84        if (![filterType isEqualToString: FILTER_NONE])
85            [[NSUserDefaults standardUserDefaults] setObject: FILTER_NONE forKey: @"Filter"];
86        currentFilterButton = fNoFilterButton;
87    }
88    [currentFilterButton setState: NSOnState];
89   
90    //set filter search type
91    NSString * filterSearchType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"];
92   
93    NSMenu * filterSearchMenu = [[fSearchField cell] searchMenuTemplate];
94    NSString * filterSearchTypeTitle;
95    if ([filterSearchType isEqualToString: FILTER_TYPE_TRACKER])
96        filterSearchTypeTitle = [[filterSearchMenu itemWithTag: FILTER_TYPE_TAG_TRACKER] title];
97    else
98    {
99        //safety
100        if (![filterType isEqualToString: FILTER_TYPE_NAME])
101            [[NSUserDefaults standardUserDefaults] setObject: FILTER_TYPE_NAME forKey: @"FilterSearchType"];
102        filterSearchTypeTitle = [[filterSearchMenu itemWithTag: FILTER_TYPE_TAG_NAME] title];
103    }
104    [[fSearchField cell] setPlaceholderString: filterSearchTypeTitle];
105   
106    [self updateGroupsButton];
107   
108    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resizeBar)
109        name: NSWindowDidResizeNotification object: [[self view] window]];
110   
111    //update when groups change
112    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateGroups:)
113        name: @"UpdateGroups" object: nil];
114}
115
116- (void) dealloc
117{
118    [[NSNotificationCenter defaultCenter] removeObserver: self];
119   
120    [super dealloc];
121}
122
123- (void) setFilter: (id) sender
124{
125    NSString * oldFilterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"];
126   
127    NSButton * prevFilterButton;
128    if ([oldFilterType isEqualToString: FILTER_PAUSE])
129        prevFilterButton = fPauseFilterButton;
130    else if ([oldFilterType isEqualToString: FILTER_ACTIVE])
131        prevFilterButton = fActiveFilterButton;
132    else if ([oldFilterType isEqualToString: FILTER_SEED])
133        prevFilterButton = fSeedFilterButton;
134    else if ([oldFilterType isEqualToString: FILTER_DOWNLOAD])
135        prevFilterButton = fDownloadFilterButton;
136    else
137        prevFilterButton = fNoFilterButton;
138   
139    if (sender != prevFilterButton)
140    {
141        [prevFilterButton setState: NSOffState];
142        [sender setState: NSOnState];
143
144        NSString * filterType;
145        if (sender == fActiveFilterButton)
146            filterType = FILTER_ACTIVE;
147        else if (sender == fDownloadFilterButton)
148            filterType = FILTER_DOWNLOAD;
149        else if (sender == fPauseFilterButton)
150            filterType = FILTER_PAUSE;
151        else if (sender == fSeedFilterButton)
152            filterType = FILTER_SEED;
153        else
154            filterType = FILTER_NONE;
155
156        [[NSUserDefaults standardUserDefaults] setObject: filterType forKey: @"Filter"];
157    }
158    else
159        [sender setState: NSOnState];
160   
161    [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
162}
163
164- (void) switchFilter: (BOOL) right
165{
166    NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"Filter"];
167   
168    NSButton * button;
169    if ([filterType isEqualToString: FILTER_NONE])
170        button = right ? fActiveFilterButton : fPauseFilterButton;
171    else if ([filterType isEqualToString: FILTER_ACTIVE])
172        button = right ? fDownloadFilterButton : fNoFilterButton;
173    else if ([filterType isEqualToString: FILTER_DOWNLOAD])
174        button = right ? fSeedFilterButton : fActiveFilterButton;
175    else if ([filterType isEqualToString: FILTER_SEED])
176        button = right ? fPauseFilterButton : fDownloadFilterButton;
177    else if ([filterType isEqualToString: FILTER_PAUSE])
178        button = right ? fNoFilterButton : fSeedFilterButton;
179    else
180        button = fNoFilterButton;
181   
182    [self setFilter: button];
183}
184
185- (void) setSearchText: (id) sender
186{
187    [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
188}
189
190- (void) setSearchType: (id) sender
191{
192    NSString * oldFilterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"];
193   
194    NSInteger prevTag, currentTag = [sender tag];
195    if ([oldFilterType isEqualToString: FILTER_TYPE_TRACKER])
196        prevTag = FILTER_TYPE_TAG_TRACKER;
197    else
198        prevTag = FILTER_TYPE_TAG_NAME;
199   
200    if (currentTag != prevTag)
201    {
202        NSString * filterType;
203        if (currentTag == FILTER_TYPE_TAG_TRACKER)
204            filterType = FILTER_TYPE_TRACKER;
205        else
206            filterType = FILTER_TYPE_NAME;
207       
208        [[NSUserDefaults standardUserDefaults] setObject: filterType forKey: @"FilterSearchType"];
209       
210        [[fSearchField cell] setPlaceholderString: [sender title]];
211    }
212   
213    [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
214}
215
216- (void) setGroupFilter: (id) sender
217{
218    [[NSUserDefaults standardUserDefaults] setInteger: [sender tag] forKey: @"FilterGroup"];
219    [self updateGroupsButton];
220   
221    [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
222}
223
224- (NSString *) searchString
225{
226    return [fSearchField stringValue];
227}
228
229- (void) setCountAll: (NSUInteger) all active: (NSUInteger) active downloading: (NSUInteger) downloading
230        seeding: (NSUInteger) seeding paused: (NSUInteger) paused
231{
232    [fNoFilterButton setCount: all];
233    [fActiveFilterButton setCount: active];
234    [fDownloadFilterButton setCount: downloading];
235    [fSeedFilterButton setCount: seeding];
236    [fPauseFilterButton setCount: paused];
237}
238
239- (void) menuNeedsUpdate: (NSMenu *) menu
240{
241    if (menu == [fGroupsButton menu])
242    {
243        for (NSInteger i = [menu numberOfItems]-1; i >= 3; i--)
244            [menu removeItemAtIndex: i];
245       
246        NSMenu * groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(setGroupFilter:) isSmall: YES];
247       
248        const NSInteger groupMenuCount = [groupMenu numberOfItems];
249        for (NSInteger i = 0; i < groupMenuCount; i++)
250        {
251            NSMenuItem * item = [[groupMenu itemAtIndex: 0] retain];
252            [groupMenu removeItemAtIndex: 0];
253            [menu addItem: item];
254            [item release];
255        }
256    }
257}
258
259- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
260{
261    const SEL action = [menuItem action];
262   
263    //check proper filter search item
264    if (action == @selector(setSearchType:))
265    {
266        NSString * filterType = [[NSUserDefaults standardUserDefaults] stringForKey: @"FilterSearchType"];
267       
268        BOOL state;
269        if ([menuItem tag] == FILTER_TYPE_TAG_TRACKER)
270            state = [filterType isEqualToString: FILTER_TYPE_TRACKER];
271        else
272            state = [filterType isEqualToString: FILTER_TYPE_NAME];
273       
274        [menuItem setState: state ? NSOnState : NSOffState];
275        return YES;
276    }
277   
278    if (action == @selector(setGroupFilter:))
279    {
280        [menuItem setState: [menuItem tag] == [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"]
281                                                ? NSOnState : NSOffState];
282        return YES;
283    }
284   
285    return YES;
286}
287
288@end
289
290@implementation FilterBarController (Private)
291
292- (void) resizeBar
293{
294    //replace all buttons
295    [fNoFilterButton sizeToFit];
296    [fActiveFilterButton sizeToFit];
297    [fDownloadFilterButton sizeToFit];
298    [fSeedFilterButton sizeToFit];
299    [fPauseFilterButton sizeToFit];
300   
301    NSRect allRect = [fNoFilterButton frame];
302    NSRect activeRect = [fActiveFilterButton frame];
303    NSRect downloadRect = [fDownloadFilterButton frame];
304    NSRect seedRect = [fSeedFilterButton frame];
305    NSRect pauseRect = [fPauseFilterButton frame];
306   
307    //size search filter to not overlap buttons
308    NSRect searchFrame = [fSearchField frame];
309    searchFrame.origin.x = NSMaxX(pauseRect) + 5.0;
310    searchFrame.size.width = NSWidth([[self view] frame]) - searchFrame.origin.x - 5.0;
311   
312    //make sure it is not too long
313    if (NSWidth(searchFrame) > SEARCH_MAX_WIDTH)
314    {
315        searchFrame.origin.x += NSWidth(searchFrame) - SEARCH_MAX_WIDTH;
316        searchFrame.size.width = SEARCH_MAX_WIDTH;
317    }
318    else if (NSWidth(searchFrame) < SEARCH_MIN_WIDTH)
319    {
320        searchFrame.origin.x += NSWidth(searchFrame) - SEARCH_MIN_WIDTH;
321        searchFrame.size.width = SEARCH_MIN_WIDTH;
322       
323        //calculate width the buttons can take up
324        const CGFloat allowedWidth = (searchFrame.origin.x - 5.0) - allRect.origin.x;
325        const CGFloat currentWidth = NSWidth(allRect) + NSWidth(activeRect) + NSWidth(downloadRect) + NSWidth(seedRect)
326                                        + NSWidth(pauseRect) + 4.0; //add 4 for space between buttons
327        const CGFloat ratio = allowedWidth / currentWidth;
328       
329        //decrease button widths proportionally
330        allRect.size.width  = NSWidth(allRect) * ratio;
331        activeRect.size.width = NSWidth(activeRect) * ratio;
332        downloadRect.size.width = NSWidth(downloadRect) * ratio;
333        seedRect.size.width = NSWidth(seedRect) * ratio;
334        pauseRect.size.width = NSWidth(pauseRect) * ratio;
335    }
336    else;
337   
338    activeRect.origin.x = NSMaxX(allRect) + 1.0;
339    downloadRect.origin.x = NSMaxX(activeRect) + 1.0;
340    seedRect.origin.x = NSMaxX(downloadRect) + 1.0;
341    pauseRect.origin.x = NSMaxX(seedRect) + 1.0;
342   
343    [fNoFilterButton setFrame: allRect];
344    [fActiveFilterButton setFrame: activeRect];
345    [fDownloadFilterButton setFrame: downloadRect];
346    [fSeedFilterButton setFrame: seedRect];
347    [fPauseFilterButton setFrame: pauseRect];
348   
349    [fSearchField setFrame: searchFrame];
350}
351
352- (void) updateGroupsButton
353{
354    const NSInteger groupIndex = [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"];
355   
356    NSImage * icon;
357    NSString * toolTip;
358    if (groupIndex == GROUP_FILTER_ALL_TAG)
359    {
360        icon = [NSImage imageNamed: @"PinTemplate.png"];
361        toolTip = NSLocalizedString(@"All Groups", "Groups -> Button");
362    }
363    else
364    {
365        icon = [[GroupsController groups] imageForIndex: groupIndex];
366        NSString * groupName = groupIndex != -1 ? [[GroupsController groups] nameForIndex: groupIndex]
367                                                : NSLocalizedString(@"None", "Groups -> Button");
368        toolTip = [NSLocalizedString(@"Group", "Groups -> Button") stringByAppendingFormat: @": %@", groupName];
369    }
370   
371    [[[fGroupsButton menu] itemAtIndex: 0] setImage: icon];
372    [fGroupsButton setToolTip: toolTip];
373}
374
375- (void) updateGroups: (NSNotification *) notification
376{
377    [self updateGroupsButton];
378   
379    [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplyFilter" object: nil];
380}
381
382@end
Note: See TracBrowser for help on using the repository browser.