source: trunk/macosx/GroupsPrefsController.m @ 10461

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

when removing the bottom group, select the group above it instead of the first group

  • Property svn:keywords set to Date Rev Author Id
File size: 14.0 KB
Line 
1/******************************************************************************
2 * $Id: GroupsPrefsController.m 10461 2010-04-10 15:48:09Z livings124 $
3 *
4 * Copyright (c) 2007-2010 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 "GroupsPrefsController.h"
26#import "GroupsController.h"
27#import "ExpandedPathToPathTransformer.h"
28#import "ExpandedPathToIconTransformer.h"
29
30#define GROUP_TABLE_VIEW_DATA_TYPE @"GroupTableViewDataType"
31
32#define ADD_TAG 0
33#define REMOVE_TAG 1
34
35@interface GroupsPrefsController (Private)
36
37- (void) updateSelectedGroup;
38- (void) refreshCustomLocationWithSingleGroup;
39
40@end
41
42@implementation GroupsPrefsController
43
44- (void) awakeFromNib
45{
46    [fTableView registerForDraggedTypes: [NSArray arrayWithObject: GROUP_TABLE_VIEW_DATA_TYPE]];
47   
48    [fSelectedColorView addObserver: self forKeyPath: @"color" options: 0 context: NULL];
49   
50    [self updateSelectedGroup];
51}
52
53- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableview
54{
55    return [[GroupsController groups] numberOfGroups];
56}
57
58- (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row
59{
60    GroupsController * groupsController = [GroupsController groups];
61    NSInteger groupsIndex = [groupsController indexForRow: row];
62   
63    NSString * identifier = [tableColumn identifier];
64    if ([identifier isEqualToString: @"Color"])
65        return [groupsController imageForIndex: groupsIndex];
66    else
67        return [groupsController nameForIndex: groupsIndex];
68}
69
70- (void) tableViewSelectionDidChange: (NSNotification *) notification
71{
72    [self updateSelectedGroup];
73}
74
75- (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object change: (NSDictionary *) change context: (void *) context
76{
77    if (object == fSelectedColorView && [fTableView numberOfSelectedRows] == 1)
78    {
79       NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
80       [[GroupsController groups] setColor: [fSelectedColorView color] forIndex: index];
81       [fTableView setNeedsDisplay: YES];
82    }
83}
84
85- (void) controlTextDidEndEditing: (NSNotification *) notification
86{
87    if ([notification object] == fSelectedColorNameField)
88    {
89       NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
90       [[GroupsController groups] setName: [fSelectedColorNameField stringValue] forIndex: index];
91       [fTableView setNeedsDisplay: YES];
92    }
93}
94
95- (BOOL) tableView: (NSTableView *) tableView writeRowsWithIndexes: (NSIndexSet *) rowIndexes toPasteboard: (NSPasteboard *) pboard
96{
97    [pboard declareTypes: [NSArray arrayWithObject: GROUP_TABLE_VIEW_DATA_TYPE] owner: self];
98    [pboard setData: [NSKeyedArchiver archivedDataWithRootObject: rowIndexes] forType: GROUP_TABLE_VIEW_DATA_TYPE];
99    return YES;
100}
101
102- (NSDragOperation) tableView: (NSTableView *) tableView validateDrop: (id <NSDraggingInfo>) info
103    proposedRow: (NSInteger) row proposedDropOperation: (NSTableViewDropOperation) operation
104{
105    NSPasteboard * pasteboard = [info draggingPasteboard];
106    if ([[pasteboard types] containsObject: GROUP_TABLE_VIEW_DATA_TYPE])
107    {
108        [fTableView setDropRow: row dropOperation: NSTableViewDropAbove];
109        return NSDragOperationGeneric;
110    }
111   
112    return NSDragOperationNone;
113}
114
115- (BOOL) tableView: (NSTableView *) tableView acceptDrop: (id <NSDraggingInfo>) info row: (NSInteger) newRow
116    dropOperation: (NSTableViewDropOperation) operation
117{
118    NSPasteboard * pasteboard = [info draggingPasteboard];
119    if ([[pasteboard types] containsObject: GROUP_TABLE_VIEW_DATA_TYPE])
120    {
121        NSIndexSet * indexes = [NSKeyedUnarchiver unarchiveObjectWithData: [pasteboard dataForType: GROUP_TABLE_VIEW_DATA_TYPE]];
122        NSInteger oldRow = [indexes firstIndex], selectedRow = [fTableView selectedRow];
123       
124        [[GroupsController groups] moveGroupAtRow: oldRow toRow: newRow];
125       
126        if (oldRow < newRow)
127            newRow--;
128       
129        if (selectedRow == oldRow)
130            selectedRow = newRow;
131        else if (selectedRow > oldRow && selectedRow <= newRow)
132            selectedRow--;
133        else if (selectedRow < oldRow && selectedRow >= newRow)
134            selectedRow++;
135        else;
136       
137        [fTableView selectRowIndexes: [NSIndexSet indexSetWithIndex: selectedRow] byExtendingSelection: NO];
138        [fTableView reloadData];
139    }
140   
141    return YES;
142}
143
144- (void) addRemoveGroup: (id) sender
145{
146    [[NSColorPanel sharedColorPanel] close];
147
148    NSInteger row;
149   
150    switch ([[sender cell] tagForSegment: [sender selectedSegment]])
151    {
152        case ADD_TAG:
153            [[GroupsController groups] addNewGroup];
154           
155            [fTableView reloadData];
156           
157            row = [fTableView numberOfRows]-1;
158            [fTableView selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO];
159            [fTableView scrollRowToVisible: row];
160           
161            [[fSelectedColorNameField window] makeFirstResponder: fSelectedColorNameField];
162           
163            break;
164       
165        case REMOVE_TAG:
166            row = [fTableView selectedRow];
167            [[GroupsController groups] removeGroupWithRowIndex: row];           
168                       
169            [fTableView reloadData];
170           
171            if ([fTableView numberOfRows] > 0)
172            {
173                if (row == [fTableView numberOfRows])
174                {
175                    --row;
176                    [fTableView selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO];
177                }
178               
179                [fTableView scrollRowToVisible: row];
180            }
181           
182            break;
183    }
184   
185    [self updateSelectedGroup];
186}
187
188- (void) customDownloadLocationSheetShow: (id) sender
189{
190    NSOpenPanel * panel = [NSOpenPanel openPanel];
191
192    [panel setPrompt: NSLocalizedString(@"Select", "Preferences -> Open panel prompt")];
193    [panel setAllowsMultipleSelection: NO];
194    [panel setCanChooseFiles: NO];
195    [panel setCanChooseDirectories: YES];
196    [panel setCanCreateDirectories: YES];
197
198    [panel beginSheetForDirectory: nil file: nil types: nil
199        modalForWindow: [fCustomLocationPopUp window] modalDelegate: self didEndSelector:
200        @selector(customDownloadLocationSheetClosed:returnCode:contextInfo:) contextInfo: nil];
201}
202
203- (IBAction) toggleUseCustomDownloadLocation: (id) sender
204{
205    NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
206    if ([fCustomLocationEnableCheck state] == NSOnState)
207    {
208        if ([[GroupsController groups] customDownloadLocationForIndex: index])
209            [[GroupsController groups] setUsesCustomDownloadLocation: YES forIndex: index];
210        else
211            [self customDownloadLocationSheetShow: nil];
212    }
213    else
214        [[GroupsController groups] setUsesCustomDownloadLocation: NO forIndex: index];
215
216    [fCustomLocationPopUp setEnabled: ([fCustomLocationEnableCheck state] == NSOnState)];
217}
218
219- (void) customDownloadLocationSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
220{
221    NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
222    if (code == NSOKButton)
223    {
224        NSString * path = [[openPanel filenames] objectAtIndex: 0];
225        [[GroupsController groups] setCustomDownloadLocation: path forIndex: index];
226        [[GroupsController groups] setUsesCustomDownloadLocation: YES forIndex: index];
227    }
228    else
229    {
230        if (![[GroupsController groups] customDownloadLocationForIndex: index])
231            [[GroupsController groups] setUsesCustomDownloadLocation: NO forIndex: index];
232    }
233   
234    [self refreshCustomLocationWithSingleGroup];
235   
236    [fCustomLocationPopUp selectItemAtIndex: 0];
237}
238
239#pragma mark -
240#pragma mark Rule editor
241
242- (IBAction) toggleUseAutoAssignRules: (id) sender;
243{
244    NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
245    if ([fAutoAssignRulesEnableCheck state] == NSOnState)
246    {
247        if ([[GroupsController groups] autoAssignRulesForIndex: index])
248            [[GroupsController groups] setUsesAutoAssignRules: YES forIndex: index];
249        else
250            [self orderFrontRulesSheet: nil];
251    }
252    else
253        [[GroupsController groups] setUsesAutoAssignRules: NO forIndex: index];
254
255    [fAutoAssignRulesEditButton setEnabled: [fAutoAssignRulesEnableCheck state] == NSOnState];
256}
257
258- (IBAction) orderFrontRulesSheet: (id) sender;
259{
260    if (!fGroupRulesSheetWindow)
261        [NSBundle loadNibNamed: @"GroupRules" owner: self];
262
263    NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
264        NSPredicate *predicate = [[GroupsController groups] autoAssignRulesForIndex: index];
265        [fRuleEditor setObjectValue: predicate];
266       
267    if ([fRuleEditor numberOfRows] == 0)
268        [fRuleEditor addRow: nil];
269       
270    [NSApp beginSheet: fGroupRulesSheetWindow modalForWindow: [fTableView window] modalDelegate: nil didEndSelector: NULL
271        contextInfo: NULL];
272}
273
274- (IBAction) cancelRules: (id) sender;
275{
276    [fGroupRulesSheetWindow orderOut: nil];
277    [NSApp endSheet: fGroupRulesSheetWindow];
278   
279    NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
280    if (![[GroupsController groups] autoAssignRulesForIndex: index])
281    {
282        [[GroupsController groups] setUsesAutoAssignRules: NO forIndex: index];
283        [fAutoAssignRulesEnableCheck setState: NO];
284        [fAutoAssignRulesEditButton setEnabled: NO];
285    }
286}
287
288- (IBAction) saveRules: (id) sender;
289{
290    [fGroupRulesSheetWindow orderOut: nil];
291    [NSApp endSheet: fGroupRulesSheetWindow];
292   
293    NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
294    [[GroupsController groups] setUsesAutoAssignRules: YES forIndex: index];
295   
296    NSPredicate * predicate = [fRuleEditor objectValue];
297    [[GroupsController groups] setAutoAssignRules: predicate forIndex: index];
298       
299    [fAutoAssignRulesEnableCheck setState: [[GroupsController groups] usesAutoAssignRulesForIndex: index]];
300    [fAutoAssignRulesEditButton setEnabled: [fAutoAssignRulesEnableCheck state] == NSOnState];
301}
302
303- (void) ruleEditorRowsDidChange: (NSNotification *) notification
304{
305    const CGFloat heightDifference = [fRuleEditor numberOfRows] * [fRuleEditor rowHeight] - [fRuleEditor frame].size.height;
306    NSRect windowFrame = [fRuleEditor window].frame;
307    windowFrame.size.height += heightDifference;
308    windowFrame.origin.y -= heightDifference;
309   
310    [fRuleEditor.window setFrame: windowFrame display: YES animate: YES];
311}
312
313@end
314
315@implementation GroupsPrefsController (Private)
316
317- (void) updateSelectedGroup
318{
319    [fAddRemoveControl setEnabled: [fTableView numberOfSelectedRows] > 0 forSegment: REMOVE_TAG];
320    if ([fTableView numberOfSelectedRows] == 1)
321    {
322        const NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
323        [fSelectedColorView setColor: [[GroupsController groups] colorForIndex: index]];
324        [fSelectedColorView setEnabled: YES];
325        [fSelectedColorNameField setStringValue: [[GroupsController groups] nameForIndex: index]];
326        [fSelectedColorNameField setEnabled: YES];
327       
328        [self refreshCustomLocationWithSingleGroup];
329
330        [fAutoAssignRulesEnableCheck setState: [[GroupsController groups] usesAutoAssignRulesForIndex: index]];
331        [fAutoAssignRulesEnableCheck setEnabled: YES];
332        [fAutoAssignRulesEditButton setEnabled: ([fAutoAssignRulesEnableCheck state] == NSOnState)];
333    }
334    else
335    {
336        [fSelectedColorView setColor: [NSColor whiteColor]];
337        [fSelectedColorView setEnabled: NO];
338        [fSelectedColorNameField setStringValue: @""];
339        [fSelectedColorNameField setEnabled: NO];
340        [fCustomLocationEnableCheck setEnabled: NO];
341        [fCustomLocationPopUp setEnabled: NO];
342        [fAutoAssignRulesEnableCheck setEnabled: NO];
343        [fAutoAssignRulesEditButton setEnabled: NO];
344    }
345}
346
347- (void) refreshCustomLocationWithSingleGroup
348{
349    const NSInteger index = [[GroupsController groups] indexForRow: [fTableView selectedRow]];
350   
351    const BOOL hasCustomLocation = [[GroupsController groups] usesCustomDownloadLocationForIndex: index];
352    [fCustomLocationEnableCheck setState: hasCustomLocation];
353    [fCustomLocationEnableCheck setEnabled: YES];
354    [fCustomLocationPopUp setEnabled: hasCustomLocation];
355   
356    NSString * location = [[GroupsController groups] customDownloadLocationForIndex: index];
357    if (location)
358    {
359        ExpandedPathToPathTransformer * pathTransformer = [[[ExpandedPathToPathTransformer alloc] init] autorelease];
360        [[fCustomLocationPopUp itemAtIndex: 0] setTitle: [pathTransformer transformedValue: location]];
361        ExpandedPathToIconTransformer * iconTransformer = [[[ExpandedPathToIconTransformer alloc] init] autorelease];
362        [[fCustomLocationPopUp itemAtIndex: 0] setImage: [iconTransformer transformedValue: location]];
363    }
364    else
365    {
366        [[fCustomLocationPopUp itemAtIndex: 0] setTitle: @""];
367        [[fCustomLocationPopUp itemAtIndex: 0] setImage: nil];
368    }
369}
370
371@end
Note: See TracBrowser for help on using the repository browser.