source: trunk/macosx/GroupsController.m @ 7210

Last change on this file since 7210 was 7210, checked in by livings124, 12 years ago

patch from ciaran for #757 to add separate download locations for each group (when added)

  • Property svn:keywords set to Date Rev Author Id
File size: 14.3 KB
Line 
1/******************************************************************************
2 * $Id: GroupsController.m 7210 2008-11-30 19:23:15Z livings124 $
3 *
4 * Copyright (c) 2007-2008 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 "GroupsController.h"
26#import "CTGradient.h"
27#import "NSBezierPathAdditions.h"
28
29#define ICON_WIDTH 16.0
30#define ICON_WIDTH_SMALL 12.0
31
32@interface GroupsController (Private)
33
34- (void) saveGroups;
35
36- (NSImage *) imageForGroup: (NSMutableDictionary *) dict;
37
38@end
39
40@implementation GroupsController
41
42GroupsController * fGroupsInstance = nil;
43+ (GroupsController *) groups
44{
45    if (!fGroupsInstance)
46        fGroupsInstance = [[GroupsController alloc] init];
47    return fGroupsInstance;
48}
49
50- (id) init
51{
52    if ((self = [super init]))
53    {
54        NSData * data;
55        if ((data = [[NSUserDefaults standardUserDefaults] dataForKey: @"Groups"]))
56            fGroups = [[NSUnarchiver unarchiveObjectWithData: data] retain];
57        else
58        {
59            //default groups
60            NSMutableDictionary * red = [NSMutableDictionary dictionaryWithObjectsAndKeys:
61                                            [NSColor redColor], @"Color",
62                                            NSLocalizedString(@"Red", "Groups -> Name"), @"Name",
63                                            [NSNumber numberWithInt: 0], @"Index", nil];
64           
65            NSMutableDictionary * orange = [NSMutableDictionary dictionaryWithObjectsAndKeys:
66                                            [NSColor orangeColor], @"Color",
67                                            NSLocalizedString(@"Orange", "Groups -> Name"), @"Name",
68                                            [NSNumber numberWithInt: 1], @"Index", nil];
69           
70            NSMutableDictionary * yellow = [NSMutableDictionary dictionaryWithObjectsAndKeys:
71                                            [NSColor yellowColor], @"Color",
72                                            NSLocalizedString(@"Yellow", "Groups -> Name"), @"Name",
73                                            [NSNumber numberWithInt: 2], @"Index", nil];
74           
75            NSMutableDictionary * green = [NSMutableDictionary dictionaryWithObjectsAndKeys:
76                                            [NSColor greenColor], @"Color",
77                                            NSLocalizedString(@"Green", "Groups -> Name"), @"Name",
78                                            [NSNumber numberWithInt: 3], @"Index", nil];
79           
80            NSMutableDictionary * blue = [NSMutableDictionary dictionaryWithObjectsAndKeys:
81                                            [NSColor blueColor], @"Color",
82                                            NSLocalizedString(@"Blue", "Groups -> Name"), @"Name",
83                                            [NSNumber numberWithInt: 4], @"Index", nil];
84           
85            NSMutableDictionary * purple = [NSMutableDictionary dictionaryWithObjectsAndKeys:
86                                            [NSColor purpleColor], @"Color",
87                                            NSLocalizedString(@"Purple", "Groups -> Name"), @"Name",
88                                            [NSNumber numberWithInt: 5], @"Index", nil];
89           
90            NSMutableDictionary * gray = [NSMutableDictionary dictionaryWithObjectsAndKeys:
91                                            [NSColor grayColor], @"Color",
92                                            NSLocalizedString(@"Gray", "Groups -> Name"), @"Name",
93                                            [NSNumber numberWithInt: 6], @"Index", nil];
94           
95            fGroups = [[NSMutableArray alloc] initWithObjects: red, orange, yellow, green, blue, purple, gray, nil];
96            [self saveGroups]; //make sure this is saved right away
97        }
98    }
99   
100    return self;
101}
102
103- (void) dealloc
104{
105    [fGroups release];
106    [super dealloc];
107}
108
109- (NSInteger) numberOfGroups
110{
111    return [fGroups count];
112}
113
114- (NSInteger) rowValueForIndex: (NSInteger) index
115{
116    if (index != -1)
117    {
118        for (NSInteger i = 0; i < [fGroups count]; i++)
119            if (index == [[[fGroups objectAtIndex: i] objectForKey: @"Index"] intValue])
120                return i;
121    }
122    return -1;
123}
124
125- (NSInteger) indexForRow: (NSInteger) row
126{
127    return [[[fGroups objectAtIndex: row] objectForKey: @"Index"] intValue];
128}
129
130- (NSString *) nameForIndex: (NSInteger) index
131{
132    NSInteger orderIndex = [self rowValueForIndex: index];
133    return orderIndex != -1 ? [[fGroups objectAtIndex: orderIndex] objectForKey: @"Name"] : nil;
134}
135
136- (void) setName: (NSString *) name forIndex: (NSInteger) index
137{
138    NSInteger orderIndex = [self rowValueForIndex: index];
139    [[fGroups objectAtIndex: orderIndex] setObject: name forKey: @"Name"];
140    [self saveGroups];
141   
142    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self];
143}
144
145- (NSImage *) imageForIndex: (NSInteger) index
146{
147    NSInteger orderIndex = [self rowValueForIndex: index];
148    return orderIndex != -1 ? [self imageForGroup: [fGroups objectAtIndex: orderIndex]]
149                            : [NSImage imageNamed: @"GroupsNoneTemplate.png"];
150}
151
152- (NSColor *) colorForIndex: (NSInteger) index
153{
154    NSInteger orderIndex = [self rowValueForIndex: index];
155    return orderIndex != -1 ? [[fGroups objectAtIndex: orderIndex] objectForKey: @"Color"] : nil;
156}
157
158- (void) setColor: (NSColor *) color forIndex: (NSInteger) index
159{
160    NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]];
161    [dict removeObjectForKey: @"Icon"];
162   
163    [dict setObject: color forKey: @"Color"];
164   
165    [[GroupsController groups] saveGroups];
166    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self];
167}
168
169- (BOOL) usesCustomDownloadLocationForIndex: (NSInteger) index
170{
171    NSInteger orderIndex = [self rowValueForIndex: index];
172    return orderIndex != -1 ? [[[fGroups objectAtIndex: orderIndex] objectForKey: @"UsesCustomDownloadLocation"] boolValue] : NO;
173}
174
175- (void) setUsesCustomDownloadLocation: (BOOL) useCustomLocation forIndex: (NSInteger) index
176{
177    NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]];
178   
179    [dict setObject: [NSNumber numberWithBool:useCustomLocation] forKey: @"UsesCustomDownloadLocation"];
180   
181    [[GroupsController groups] saveGroups];
182    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self];
183}
184
185- (NSString *) customDownloadLocationForIndex: (NSInteger) index
186{
187    NSInteger orderIndex = [self rowValueForIndex: index];
188    return orderIndex != -1 ? [[fGroups objectAtIndex: orderIndex] objectForKey: @"CustomDownloadLocation"] : nil;
189}
190
191- (void) setCustomDownloadLocation: (NSString *) location forIndex: (NSInteger) index
192{
193    NSMutableDictionary * dict = [fGroups objectAtIndex: [self rowValueForIndex: index]];
194   
195    if (location)
196        [dict setObject: location forKey: @"CustomDownloadLocation"];
197    else
198        [dict removeObjectForKey: @"CustomDownloadLocation"];
199   
200    [[GroupsController groups] saveGroups];
201    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self];
202}
203
204- (void) addNewGroup
205{
206    //find the lowest index
207    NSInteger index;
208    for (index = 0; index < [fGroups count]; index++)
209    {
210        BOOL found = NO;
211        NSEnumerator * enumerator = [fGroups objectEnumerator];
212        NSDictionary * dict;
213        while ((dict = [enumerator nextObject]))
214            if ([[dict objectForKey: @"Index"] intValue] == index)
215            {
216                found = YES;
217                break;
218            }
219       
220        if (!found)
221            break;
222    }
223   
224    [fGroups addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: index], @"Index",
225                            [NSColor cyanColor], @"Color", @"", @"Name", nil]];
226   
227    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self];
228    [self saveGroups];
229}
230
231- (void) removeGroupWithRowIndex: (NSInteger) row
232{
233    NSInteger index = [[[fGroups objectAtIndex: row] objectForKey: @"Index"] intValue];
234    [fGroups removeObjectAtIndex: row];
235   
236    [[NSNotificationCenter defaultCenter] postNotificationName: @"GroupValueRemoved" object: self userInfo:
237        [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: index] forKey: @"Index"]];
238   
239    if (index == [[NSUserDefaults standardUserDefaults] integerForKey: @"FilterGroup"])
240        [[NSUserDefaults standardUserDefaults] setInteger: -2 forKey: @"FilterGroup"];
241   
242    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self];
243    [self saveGroups];
244}
245
246#warning rework for single row?
247- (NSIndexSet *) moveGroupsAtRowIndexes: (NSIndexSet *) indexes toRow: (NSInteger) newRow oldSelected: (NSIndexSet *) selectedIndexes
248{
249    NSArray * selectedGroups = [fGroups objectsAtIndexes: selectedIndexes];
250   
251    //determine where to move them
252    for (NSInteger i = [indexes firstIndex], startRow = newRow; i < startRow && i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
253        newRow--;
254   
255    //remove objects to reinsert
256    NSArray * movingGroups = [[fGroups objectsAtIndexes: indexes] retain];
257    [fGroups removeObjectsAtIndexes: indexes];
258   
259    //insert objects at new location
260    for (NSInteger i = 0; i < [movingGroups count]; i++)
261        [fGroups insertObject: [movingGroups objectAtIndex: i] atIndex: newRow + i];
262   
263    [movingGroups release];
264   
265    [self saveGroups];
266    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateGroups" object: self];
267   
268    NSMutableIndexSet * newSelectedIndexes = nil;
269    if ([selectedGroups count] > 0)
270    {
271        newSelectedIndexes = [NSMutableIndexSet indexSet];
272        NSEnumerator * enumerator = [selectedGroups objectEnumerator];
273        NSDictionary * dict;
274        while ((dict = [enumerator nextObject]))
275            [newSelectedIndexes addIndex: [fGroups indexOfObject: dict]];
276    }
277   
278    return newSelectedIndexes;
279}
280
281- (NSMenu *) groupMenuWithTarget: (id) target action: (SEL) action isSmall: (BOOL) small
282{
283    NSMenu * menu = [[NSMenu alloc] initWithTitle: @"Groups"];
284   
285    NSMenuItem * item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"None", "Groups -> Menu") action: action
286                            keyEquivalent: @""];
287    [item setTarget: target];
288    [item setTag: -1];
289   
290    NSImage * icon = [NSImage imageNamed: @"GroupsNoneTemplate.png"];
291    if (small)
292    {
293        icon = [icon copy];
294        [icon setScalesWhenResized: YES];
295        [icon setSize: NSMakeSize(ICON_WIDTH_SMALL, ICON_WIDTH_SMALL)];
296       
297        [item setImage: icon];
298        [icon release];
299    }
300    else
301        [item setImage: icon];
302   
303    [menu addItem: item];
304    [item release];
305   
306    NSEnumerator * enumerator = [fGroups objectEnumerator];
307    NSMutableDictionary * dict;
308    while ((dict = [enumerator nextObject]))
309    {
310        item = [[NSMenuItem alloc] initWithTitle: [dict objectForKey: @"Name"] action: action keyEquivalent: @""];
311        [item setTarget: target];
312       
313        [item setTag: [[dict objectForKey: @"Index"] intValue]];
314       
315        NSImage * icon = [self imageForGroup: dict];
316        if (small)
317        {
318            icon = [icon copy];
319            [icon setScalesWhenResized: YES];
320            [icon setSize: NSMakeSize(ICON_WIDTH_SMALL, ICON_WIDTH_SMALL)];
321           
322            [item setImage: icon];
323            [icon release];
324        }
325        else
326            [item setImage: icon];
327       
328        [menu addItem: item];
329        [item release];
330    }
331   
332    return [menu autorelease];
333}
334
335@end
336
337@implementation GroupsController (Private)
338
339- (void) saveGroups
340{
341    //don't archive the icon
342    NSMutableArray * groups = [NSMutableArray arrayWithCapacity: [fGroups count]];
343    NSEnumerator * enumerator = [fGroups objectEnumerator];
344    NSDictionary * dict;
345    while ((dict = [enumerator nextObject]))
346    {
347        NSMutableDictionary * tempDict = [dict mutableCopy];
348        [tempDict removeObjectForKey: @"Icon"];
349        [groups addObject: tempDict];
350        [tempDict release];
351    }
352   
353    [[NSUserDefaults standardUserDefaults] setObject: [NSArchiver archivedDataWithRootObject: groups] forKey: @"Groups"];
354}
355
356- (NSImage *) imageForGroup: (NSMutableDictionary *) dict
357{
358    NSImage * image;
359    if ((image = [dict objectForKey: @"Icon"]))
360        return image;
361   
362    NSRect rect = NSMakeRect(0.0, 0.0, ICON_WIDTH, ICON_WIDTH);
363   
364    NSBezierPath * bp = [NSBezierPath bezierPathWithRoundedRect: rect radius: 3.0];
365    NSImage * icon = [[NSImage alloc] initWithSize: rect.size];
366   
367    NSColor * color = [dict objectForKey: @"Color"];
368   
369    [icon lockFocus];
370   
371    //border
372    CTGradient * gradient = [CTGradient gradientWithBeginningColor: [color blendedColorWithFraction: 0.45 ofColor:
373                                [NSColor whiteColor]] endingColor: color];
374    [gradient fillBezierPath: bp angle: 270.0];
375   
376    //inside
377    bp = [NSBezierPath bezierPathWithRoundedRect: NSInsetRect(rect, 1.0, 1.0) radius: 3.0];
378    gradient = [CTGradient gradientWithBeginningColor: [color blendedColorWithFraction: 0.75 ofColor: [NSColor whiteColor]]
379                endingColor: [color blendedColorWithFraction: 0.2 ofColor: [NSColor whiteColor]]];
380    [gradient fillBezierPath: bp angle: 270.0];
381   
382    [icon unlockFocus];
383   
384    [dict setObject: icon forKey: @"Icon"];
385    [icon release];
386   
387    return icon;
388}
389
390@end
Note: See TracBrowser for help on using the repository browser.