source: trunk/macosx/GroupsWindowController.m @ 4219

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

use tag instead of represented object for group values in the menu items

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: NSLocalizedString(@"None", "Groups -> Menu") action: action
337                            keyEquivalent: @""];
338    [item setTarget: target];
339    [item setTag: -1];
340    [menu addItem: item];
341    [item release];
342   
343    NSBezierPath * bp = [NSBezierPath bezierPathWithRoundedRect: NSMakeRect(0.0, 0.0, 16.0, 16.0) radius: 4.0];
344   
345    NSEnumerator * enumerator = [fGroups objectEnumerator];
346    NSDictionary * dict;
347    while ((dict = [enumerator nextObject]))
348    {
349        item = [[NSMenuItem alloc] initWithTitle: [dict objectForKey: @"Name"] action: action keyEquivalent: @""];
350        [item setTarget: target];
351       
352        NSImage * icon = [[NSImage alloc] initWithSize: [bp bounds].size];
353       
354        [icon lockFocus];
355        [[self gradientForColor: [dict objectForKey: @"Color"]] fillBezierPath: bp angle: 270.0];
356        [icon unlockFocus];
357       
358        [item setImage: icon];
359        [icon release];
360       
361        [item setTag: [[dict objectForKey: @"Index"] intValue]];
362       
363        [menu addItem: item];
364        [item release];
365    }
366   
367    return [menu autorelease];
368}
369
370@end
371
372@implementation GroupsWindowController (Private)
373
374- (void) saveGroups
375{
376    [[NSUserDefaults standardUserDefaults] setObject: [NSArchiver archivedDataWithRootObject: fGroups] forKey: @"Groups"];
377}
378
379- (CTGradient *) gradientForColor: (NSColor *) color
380{
381    return [CTGradient gradientWithBeginningColor: [color blendedColorWithFraction: 0.65 ofColor: [NSColor whiteColor]]
382            endingColor: [color blendedColorWithFraction: 0.2 ofColor: [NSColor whiteColor]]];
383}
384
385- (void) changeColor: (id) sender
386{
387    [fCurrentColorDict setObject: [sender color] forKey: @"Color"];
388    [fTableView reloadData];
389   
390    [self saveGroups];
391    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: self];
392}
393
394@end
Note: See TracBrowser for help on using the repository browser.