source: trunk/macosx/GroupsWindowController.m @ 4202

Last change on this file since 4202 was 4202, checked in by livings124, 15 years ago

adjust group coloring

File size: 14.7 KB
Line 
1/******************************************************************************
2 * $Id$
3 *
4 * Copyright (c) 2007 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 "GroupsWindowController.h"
26#import "GradientCell.h"
27#import "CTGradient.h"
28#import "NSBezierPathAdditions.h"
29#import "NSApplicationAdditions.h"
30
31#define GROUP_TABLE_VIEW_DATA_TYPE @"GroupTableViewDataType"
32
33typedef enum
34{
35    ADD_TAG = 0,
36    REMOVE_TAG = 1
37} controlTag;
38
39@interface GroupsWindowController (Private)
40
41- (void) saveGroups;
42
43- (CTGradient *) gradientForColor: (NSColor *) color;
44- (void) changeColor: (id) sender;
45
46@end
47
48@implementation GroupsWindowController
49
50GroupsWindowController * fGroupsWindowInstance = nil;
51+ (GroupsWindowController *) groupsController
52{
53    if (!fGroupsWindowInstance)
54        fGroupsWindowInstance = [[GroupsWindowController alloc] init];
55    return fGroupsWindowInstance;
56}
57
58- (id) init
59{
60    if ((self = [super initWithWindowNibName: @"GroupsWindow"]))
61    {
62        NSData * data;
63        if ((data = [[NSUserDefaults standardUserDefaults] dataForKey: @"Groups"]))
64            fGroups = [[NSUnarchiver unarchiveObjectWithData: data] retain];
65        else
66        {
67            //default groups
68            NSMutableDictionary * red = [NSMutableDictionary dictionaryWithObjectsAndKeys:
69                                            [NSColor redColor], @"Color",
70                                            NSLocalizedString(@"Red", "Groups -> Name"), @"Name",
71                                            [NSNumber numberWithInt: 0], @"Index", nil];
72           
73            NSMutableDictionary * orange = [NSMutableDictionary dictionaryWithObjectsAndKeys:
74                                            [NSColor orangeColor], @"Color",
75                                            NSLocalizedString(@"Orange", "Groups -> Name"), @"Name",
76                                            [NSNumber numberWithInt: 1], @"Index", nil];
77           
78            NSMutableDictionary * yellow = [NSMutableDictionary dictionaryWithObjectsAndKeys:
79                                            [NSColor yellowColor], @"Color",
80                                            NSLocalizedString(@"Yellow", "Groups -> Name"), @"Name",
81                                            [NSNumber numberWithInt: 2], @"Index", nil];
82           
83            NSMutableDictionary * green = [NSMutableDictionary dictionaryWithObjectsAndKeys:
84                                            [NSColor greenColor], @"Color",
85                                            NSLocalizedString(@"Green", "Groups -> Name"), @"Name",
86                                            [NSNumber numberWithInt: 3], @"Index", nil];
87           
88            NSMutableDictionary * blue = [NSMutableDictionary dictionaryWithObjectsAndKeys:
89                                            [NSColor blueColor], @"Color",
90                                            NSLocalizedString(@"Blue", "Groups -> Name"), @"Name",
91                                            [NSNumber numberWithInt: 4], @"Index", nil];
92           
93            NSMutableDictionary * purple = [NSMutableDictionary dictionaryWithObjectsAndKeys:
94                                            [NSColor purpleColor], @"Color",
95                                            NSLocalizedString(@"Purple", "Groups -> Name"), @"Name",
96                                            [NSNumber numberWithInt: 5], @"Index", nil];
97           
98            NSMutableDictionary * gray = [NSMutableDictionary dictionaryWithObjectsAndKeys:
99                                            [NSColor grayColor], @"Color",
100                                            NSLocalizedString(@"Gray", "Groups -> Name"), @"Name",
101                                            [NSNumber numberWithInt: 6], @"Index", nil];
102           
103            fGroups = [[NSMutableArray alloc] initWithObjects: red, orange, yellow, green, blue, purple, gray, nil];
104            [self saveGroups]; //make sure this is saved right away
105        }
106    }
107   
108    return self;
109}
110
111- (void) awakeFromNib
112{
113    GradientCell * cell = [[GradientCell alloc] init];
114    [[fTableView tableColumnWithIdentifier: @"Color"] setDataCell: cell];
115    [cell release];
116   
117    [fTableView registerForDraggedTypes: [NSArray arrayWithObject: GROUP_TABLE_VIEW_DATA_TYPE]];
118   
119    if ([NSApp isOnLeopardOrBetter])
120        [[self window] setContentBorderThickness: [[fTableView enclosingScrollView] frame].origin.y forEdge: NSMinYEdge];
121    else
122    {
123        [fAddRemoveControl setLabel: @"+" forSegment: 0];
124        [fAddRemoveControl setLabel: @"-" forSegment: 1];
125    }
126   
127    [fAddRemoveControl setEnabled: NO forSegment: REMOVE_TAG];
128}
129
130- (void) dealloc
131{
132    [fGroups release];
133    [super dealloc];
134}
135
136- (CTGradient *) gradientForIndex: (int) index
137{
138    if (index < 0)
139        return nil;
140   
141    NSEnumerator * enumerator = [fGroups objectEnumerator];
142    NSDictionary * dict;
143    while ((dict = [enumerator nextObject]))
144        if ([[dict objectForKey: @"Index"] intValue] == index)
145            return [self gradientForColor: [dict objectForKey: @"Color"]];
146   
147    return nil;
148}
149
150- (int) orderValueForIndex: (int) index
151{
152    if (index != -1)
153    {
154        int i;
155        for (i = 0; i < [fGroups count]; i++)
156            if (index == [[[fGroups objectAtIndex: i] objectForKey: @"Index"] intValue])
157                return i;
158    }
159    return -1;
160}
161
162- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableview
163{
164    return [fGroups count];
165}
166
167- (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row
168{
169    NSString * identifier = [tableColumn identifier];
170    if ([identifier isEqualToString: @"Color"])
171        return [self gradientForColor: [[fGroups objectAtIndex: row] objectForKey: @"Color"]];
172    else
173        return [[fGroups objectAtIndex: row] objectForKey: @"Name"];
174}
175
176- (void) tableView: (NSTableView *) tableView setObjectValue: (id) object forTableColumn: (NSTableColumn *) tableColumn
177    row: (NSInteger) row
178{
179    NSString * identifier = [tableColumn identifier];
180    if ([identifier isEqualToString: @"Name"])
181    {
182        [[fGroups objectAtIndex: row] setObject: object forKey: @"Name"];
183        [self saveGroups];
184    }
185    else if ([identifier isEqualToString: @"Button"])
186    {
187        fCurrentColorDict = [fGroups objectAtIndex: row];
188       
189        NSColorPanel * colorPanel = [NSColorPanel sharedColorPanel];
190        [colorPanel setContinuous: YES];
191        [colorPanel setColor: [[fGroups objectAtIndex: row] objectForKey: @"Color"]];
192       
193        [colorPanel setTarget: self];
194        [colorPanel setAction: @selector(changeColor:)];
195       
196        [colorPanel orderFront: self];
197    }
198    else;
199}
200
201- (void) tableViewSelectionDidChange: (NSNotification *) notification
202{
203    [fAddRemoveControl setEnabled: [fTableView numberOfSelectedRows] > 0 forSegment: REMOVE_TAG];
204}
205
206- (BOOL) tableView: (NSTableView *) tableView writeRowsWithIndexes: (NSIndexSet *) rowIndexes toPasteboard: (NSPasteboard *) pboard
207{
208    [pboard declareTypes: [NSArray arrayWithObject: GROUP_TABLE_VIEW_DATA_TYPE] owner: self];
209    [pboard setData: [NSKeyedArchiver archivedDataWithRootObject: rowIndexes] forType: GROUP_TABLE_VIEW_DATA_TYPE];
210    return YES;
211}
212
213- (NSDragOperation) tableView: (NSTableView *) tableView validateDrop: (id <NSDraggingInfo>) info
214    proposedRow: (int) row proposedDropOperation: (NSTableViewDropOperation) operation
215{
216    NSPasteboard * pasteboard = [info draggingPasteboard];
217    if ([[pasteboard types] containsObject: GROUP_TABLE_VIEW_DATA_TYPE])
218    {
219        [fTableView setDropRow: row dropOperation: NSTableViewDropAbove];
220        return NSDragOperationGeneric;
221    }
222   
223    return NSDragOperationNone;
224}
225
226- (BOOL) tableView: (NSTableView *) t acceptDrop: (id <NSDraggingInfo>) info
227    row: (int) newRow dropOperation: (NSTableViewDropOperation) operation
228{
229    NSPasteboard * pasteboard = [info draggingPasteboard];
230    if ([[pasteboard types] containsObject: GROUP_TABLE_VIEW_DATA_TYPE])
231    {
232        NSIndexSet * indexes = [NSKeyedUnarchiver unarchiveObjectWithData: [pasteboard dataForType: GROUP_TABLE_VIEW_DATA_TYPE]];
233       
234        NSArray * selectedGroups = [fGroups objectsAtIndexes: [fTableView selectedRowIndexes]];
235       
236        //determine where to move them
237        int i;
238        for (i = [indexes firstIndex]; i < newRow && i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
239            newRow--;
240       
241        //remove objects to reinsert
242        NSArray * movingGroups = [[fGroups objectsAtIndexes: indexes] retain];
243        [fGroups removeObjectsAtIndexes: indexes];
244       
245        //insert objects at new location
246        for (i = 0; i < [movingGroups count]; i++)
247            [fGroups insertObject: [movingGroups objectAtIndex: i] atIndex: newRow + i];
248       
249        [movingGroups release];
250       
251        if ([selectedGroups count] > 0)
252        {
253            NSEnumerator * enumerator = [selectedGroups objectEnumerator];
254            NSMutableIndexSet * indexSet = [[NSMutableIndexSet alloc] init];
255            NSDictionary * dict;
256            while ((dict = [enumerator nextObject]))
257                [indexSet addIndex: [fGroups indexOfObject: dict]];
258           
259            [fTableView selectRowIndexes: indexSet byExtendingSelection: NO];
260            [indexSet release];
261        }
262       
263        [fTableView reloadData];
264       
265        [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: self];
266    }
267   
268    return YES;
269}
270
271- (void) addRemoveGroup: (id) sender
272{
273    NSEnumerator * enumerator;
274    NSDictionary * dict;
275    int index;
276    BOOL found;
277    NSIndexSet * rowIndexes;
278    NSMutableIndexSet * indexes;
279   
280    switch ([[sender cell] tagForSegment: [sender selectedSegment]])
281    {
282        case ADD_TAG:
283           
284            //find the lowest index
285            for (index = 0; index < [fGroups count]; index++)
286            {
287                found = NO;
288                enumerator = [fGroups objectEnumerator];
289                while ((dict = [enumerator nextObject]))
290                    if ([[dict objectForKey: @"Index"] intValue] == index)
291                    {
292                        found = YES;
293                        break;
294                    }
295               
296                if (!found)
297                    break;
298            }
299           
300            [fGroups addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: index], @"Index",
301                                    [NSColor cyanColor], @"Color", @"", @"Name", nil]];
302            [fTableView reloadData];
303            [fTableView deselectAll: self];
304           
305            [fTableView editColumn: [fTableView columnWithIdentifier: @"Name"] row: [fTableView numberOfRows]-1 withEvent: nil
306                        select: NO];
307            break;
308       
309        case REMOVE_TAG:
310           
311            rowIndexes = [fTableView selectedRowIndexes];
312            indexes = [NSMutableIndexSet indexSet];
313            for (index = [rowIndexes firstIndex]; index != NSNotFound; index = [rowIndexes indexGreaterThanIndex: index])
314                [indexes addIndex: [[[fGroups objectAtIndex: index] objectForKey: @"Index"] intValue]];
315           
316            [fGroups removeObjectsAtIndexes: rowIndexes];
317            [fTableView deselectAll: self];
318            [fTableView reloadData];
319           
320            [[NSNotificationCenter defaultCenter] postNotificationName: @"GroupValueRemoved" object: self userInfo:
321                [NSDictionary dictionaryWithObject: indexes forKey: @"Indexes"]];
322            break;
323       
324        default:
325            return;
326    }
327   
328    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: self];
329    [self saveGroups];
330}
331
332- (NSMenu *) groupMenuWithTarget: (id) target action: (SEL) action
333{
334    NSMenu * menu = [[NSMenu alloc] initWithTitle: @"Groups"];
335   
336    NSMenuItem * item = [[NSMenuItem alloc] initWithTitle: @"None" action: action keyEquivalent: @""];
337    [item setTarget: target];
338    [item setRepresentedObject: [NSNumber numberWithInt: -1]];
339    [menu addItem: item];
340    [item release];
341   
342    NSBezierPath * bp = [NSBezierPath bezierPathWithRoundedRect: NSMakeRect(0.0, 0.0, 16.0, 16.0) radius: 4.0];
343   
344    NSEnumerator * enumerator = [fGroups objectEnumerator];
345    NSDictionary * dict;
346    while ((dict = [enumerator nextObject]))
347    {
348        item = [[NSMenuItem alloc] initWithTitle: [dict objectForKey: @"Name"] action: action keyEquivalent: @""];
349        [item setTarget: target];
350       
351        NSImage * icon = [[NSImage alloc] initWithSize: [bp bounds].size];
352       
353        [icon lockFocus];
354        [[self gradientForColor: [dict objectForKey: @"Color"]] fillBezierPath: bp angle: 270.0];
355        [icon unlockFocus];
356       
357        [item setImage: icon];
358        [icon release];
359       
360        [item setRepresentedObject: [dict objectForKey: @"Index"]];
361       
362        [menu addItem: item];
363        [item release];
364    }
365   
366    return [menu autorelease];
367}
368
369@end
370
371@implementation GroupsWindowController (Private)
372
373- (void) saveGroups
374{
375    [[NSUserDefaults standardUserDefaults] setObject: [NSArchiver archivedDataWithRootObject: fGroups] forKey: @"Groups"];
376}
377
378- (CTGradient *) gradientForColor: (NSColor *) color
379{
380    return [CTGradient gradientWithBeginningColor: [color blendedColorWithFraction: 0.65 ofColor: [NSColor whiteColor]]
381            endingColor: [color blendedColorWithFraction: 0.2 ofColor: [NSColor whiteColor]]];
382}
383
384- (void) changeColor: (id) sender
385{
386    [fCurrentColorDict setObject: [sender color] forKey: @"Color"];
387    [fTableView reloadData];
388   
389    [self saveGroups];
390    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: self];
391}
392
393@end
Note: See TracBrowser for help on using the repository browser.