source: trunk/PrefsPane/src/SuspectsController.m @ 1046

Revision 1018, 9.9 KB checked in by speck, 10 months ago (diff)

more indent and %ld

Line 
1/* Copyright (C) 2008-2009 Peter Speck
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#import "SuspectsController.h"
18#import "GBDebug.h"
19#import "XmlDoc.h"
20#import "Xml.h"
21#import "ServerCommunication.h"
22#import "AlertHelper.h"
23#import "Prefs.h"
24#import "FilterTabController.h"
25#import "FilterRuleEdit.h"
26
27@interface SuspectsController ()
28
29- (void)timerCallback:(NSTimer*)theTimer;
30- (void)updateTableLayout;
31
32- (void)tableViewSelectionDidChange:(NSNotification *)aNotification;
33@end
34
35@implementation SuspectsController
36
37- (id)initWithFilterTabController:(FilterTabController*)filterTabController
38                withContainerView:(NSView*)containerView
39                       withBundle:(NSBundle*)bundle
40{
41    if (!(self = [super init]))
42        return nil;
43    NSAssert([NSBundle loadNibNamed: @"Suspects" owner: self], @"Can't load nib 'Suspects'");
44    NSAssert(suspectTableView, @"suspectTableView is null");
45    _filterTabController = [filterTabController retain];
46    _comm = [[filterTabController comm] retain];
47    _prefs = [[_comm prefs] retain];
48    _alertHelper = [[_prefs alertHelper] retain];
49    _bundle = [[filterTabController bundle] retain];
50    _suspectList = [[NSMutableArray arrayWithCapacity:200] retain];
51    _showDetails = [_prefs boolForXPath:@"suspects/@show-details"];
52    _showJavascripts = [_prefs boolForXPath:@"suspects/@show-javascripts"];
53    _enabled = [_prefs boolForXPath:@"suspects/@enabled"];
54    [showDetailsCB setState:_showDetails];
55    [showJavascriptsCB setState:_showJavascripts];
56    [enableCB setState:_enabled];
57    [containerView addSubview:subView];
58    [suspectTableView setDataSource:self];
59    [suspectTableView setDelegate:self];
60    [self updateTableLayout];
61    [self tableViewSelectionDidChange:NULL];
62    [suspectTableView setTarget:self];
63    [suspectTableView setDoubleAction:@selector(doubleClickInTable:)];
64    [self notifyUpdatedAuthorizationState];
65    [suspectTableView registerForDraggedTypes:[NSArray arrayWithObjects:NSStringPboardType, NSURLPboardType, NULL]];
66    [suspectTableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:NO];
67    [suspectTableView setDraggingSourceOperationMask:NSDragOperationCopy forLocal:YES];
68    return self;
69}
70
71- (void)dealloc
72{
73    DebugNSLog(@"Suspects.dealloc");
74    [self notifyBecameHidden];
75    [subView removeFromSuperview];
76    [subView release];
77    [_alertHelper release];
78    [_prefs release];
79    [_comm release];
80    [_suspectList release];
81    [_bundle release];
82    [_filterTabController release];
83    [super dealloc];
84}
85
86- (void)startTimerWithImmediateExecute:(BOOL)immediate
87{
88    if (!_enabled)
89        return;
90    if (!immediate && [_timer isValid])
91        return;
92    [self stopTimer];
93    if (immediate)
94        [self timerCallback:NULL];
95    _timer = [[NSTimer scheduledTimerWithTimeInterval:2.0
96                                               target:self
97                                             selector:@selector(timerCallback:)
98                                             userInfo:NULL
99                                              repeats:NO] retain];
100}
101
102- (void)stopTimer
103{
104    if (!_timer)
105        return;
106    [_timer invalidate];
107    [_timer release];
108    _timer = NULL;
109}
110
111- (void)notifyBecameVisible
112{
113    _visible = YES;
114    [self startTimerWithImmediateExecute:YES];
115}
116
117- (void)notifyBecameHidden
118{
119    _visible = NO;
120    [self stopTimer];
121}
122
123- (void)notifyUpdatedAuthorizationState
124{
125    [enableCB setEnabled:[_prefs hasGlimmerAuth]];
126    [self tableViewSelectionDidChange:NULL];
127}
128
129- (void)timerCallback:(NSTimer*)theTimer
130{
131    [self stopTimer];
132    if (!_enabled) {
133        [_suspectList removeAllObjects];
134        [suspectTableView reloadData];
135        return;
136    }
137    if (!_visible) {
138        DebugNSLog(@"Suspects, Timer callback without being visible");
139        return;
140    }
141    NSString* pathArgs = [NSString stringWithFormat:@"/suspect/list?js=%@", _showJavascripts ? @"true" : @"false"];
142    NSError* error = NULL;
143    XmlDoc* doc = [_comm curlToXml:pathArgs
144             withActionDescription:@"get list of suspects"
145                      withErrorRef:&error];
146    [self startTimerWithImmediateExecute:NO];
147    if (!doc)
148        return;
149    NSArray* a = [[doc rootE] elementsForName:@"suspect"];
150    NSUInteger num = [a count];
151    if (!num) {
152        [_suspectList removeAllObjects];
153        [suspectTableView reloadData];
154        [self tableViewSelectionDidChange:NULL];
155        return;
156    }
157    NSString* selectedHost = NULL;
158    NSString* selectedPath = NULL;
159    NSInteger row = [suspectTableView selectedRow];
160    if (row >= 0) {
161        NSXMLElement* e = [_suspectList objectAtIndex:row];
162        selectedHost = [Xml getAttribute:e withName:@"host"];
163        selectedPath = [Xml getAttribute:e withName:@"path"];
164    }
165    [_suspectList setArray:a];
166    [suspectTableView reloadData];
167    if (selectedHost) {
168        BOOL found = NO;
169        for (NSUInteger i = 0; i < num; i++) {
170            NSXMLElement* e = [a objectAtIndex:i];
171            if ([selectedHost isEqual:[Xml getAttribute:e withName:@"host"]]
172                && [selectedPath isEqual:[Xml getAttribute:e withName:@"path"]]) {
173                NSIndexSet* set = [NSIndexSet indexSetWithIndex:i];
174                [suspectTableView selectRowIndexes:set byExtendingSelection:NO];
175                //DebugNSLog(@"Suspects.timer.selected-row: %d -> %d", row, i);
176                found = YES;
177                break;
178            }
179        }
180        if (!found) {
181            [suspectTableView deselectAll:self];
182        }
183    }
184}
185
186#pragma mark ------------------- IB
187
188- (void)updateTableLayout
189{
190    [suspectTableView setRowHeight:_showDetails ? 44 : 17];
191}
192
193- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
194{
195    [addBtn setEnabled:[_prefs hasGlimmerAuth] && [suspectTableView selectedRow] >= 0];
196}
197
198
199- (IBAction)showDetailsAction:(id)sender
200{
201    _showDetails = [showDetailsCB state];
202    [_prefs setBool:_showDetails forXPath:@"suspects/@show-details"];
203    [self updateTableLayout];
204    [suspectTableView reloadData];
205    if ([_prefs hasGlimmerAuth])
206        [_prefs markAsDirty];
207}
208
209- (IBAction)showJavascriptsAction:(id)sender;
210{
211    _showJavascripts = [showJavascriptsCB state];
212    [_prefs setBool:_showJavascripts forXPath:@"suspects/@show-javascripts"];
213    if ([_prefs hasGlimmerAuth])
214        [_prefs markAsDirty];
215    [self startTimerWithImmediateExecute:YES];
216}
217
218- (IBAction)enableAction:(id)sender
219{
220    _enabled = [enableCB state];
221    DebugNSLog(@"enableAction: %d", _enabled);
222    [_prefs setBool:_enabled forXPath:@"suspects/@enabled"];
223    [_prefs markAsDirty];
224    [_comm saveDirtyPrefsAndNotify];
225    if (_enabled) {
226        [self startTimerWithImmediateExecute:YES];
227    } else {
228        [self stopTimer];
229        [_suspectList removeAllObjects];
230        [suspectTableView reloadData];
231    }
232}
233
234- (void)openFilterSheet:(NSInteger)row
235{
236    if (row < 0 || row >= (int)[_suspectList count])
237        return;
238    NSXMLElement* suspectE = [_suspectList objectAtIndex:row];
239    [[[FilterRuleEdit alloc] initWithFilterTabController:_filterTabController
240                                         withOwnerFilter:NULL
241                                         withRuleElement:NULL
242                                      withSuspectElement:suspectE] autorelease];
243}
244
245- (IBAction)addAction:(id)sender
246{
247    [self openFilterSheet:[suspectTableView selectedRow]];
248}
249
250- (IBAction)doubleClickInTable:(id)sender
251{
252    [self openFilterSheet:[suspectTableView clickedRow]];
253}
254
255
256- (NSString *)tableView:(NSTableView *)aTableView
257         toolTipForCell:(NSCell *)aCell
258                   rect:(NSRectPointer)rect
259            tableColumn:(NSTableColumn *)aTableColumn
260                    row:(NSInteger)row
261          mouseLocation:(NSPoint)mouseLocation
262{
263    if (aTableView != suspectTableView || _showDetails)
264        return @"";
265    NSXMLElement* e = [_suspectList objectAtIndex:row];
266    return [NSString stringWithFormat:@"%@\nFrom: %@",
267            [Xml getAttribute:e withName:@"why"],
268            [Xml getAttribute:e withName:@"referer"]];
269}
270
271- (NSString*)urlForRow:(NSUInteger)row
272{
273    NSXMLElement* e = [_suspectList objectAtIndex:row];
274    NSString* host = [Xml getAttribute:e withName:@"host"];
275    NSString* path = [Xml getAttribute:e withName:@"path"];
276    NSString* query = [Xml getAttribute:e withName:@"query"];
277    NSString* url = [host stringByAppendingString:path];
278    if ([query length])
279        url = [[url stringByAppendingString:@"?"] stringByAppendingString:query];
280    return url;
281}
282
283- (BOOL)tableView:(NSTableView *)view writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard
284{
285    DebugNSLog(@"writeRows.%d: %@", (view == suspectTableView), rowIndexes);
286    if (view != suspectTableView || [rowIndexes count] != 1)
287        return NO;
288    NSString* u = [@"http://" stringByAppendingString:[self urlForRow:[rowIndexes firstIndex]]];
289    [pboard declareTypes:[NSArray arrayWithObjects:NSStringPboardType, NSURLPboardType, NULL] owner:nil];
290    [pboard setString:u forType:NSStringPboardType];
291    @try {
292        [[NSURL URLWithString:u] writeToPasteboard:pboard];
293    }
294    @catch (NSException* ex) {
295        NSLog(@"Couldn't copy URL to pasteboard: %@", u);
296    }
297    return YES;
298}
299
300- (void)copyFromSuspectsTable
301{
302    NSInteger row = [suspectTableView selectedRow];
303    if (row < 0 || row >= (NSInteger)[_suspectList count])
304        return;
305    NSIndexSet *set = [NSIndexSet indexSetWithIndex:row];
306    [self tableView:suspectTableView
307          writeRowsWithIndexes:set
308       toPasteboard:[NSPasteboard generalPasteboard]];
309}
310
311@end
312
313@implementation SuspectsController(NSTableDataSource)
314
315- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
316{
317    NSAssert(tableView == suspectTableView, @"tableView == suspectTableView");
318    return [_suspectList count];
319}
320
321- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)col row:(NSInteger)row
322{
323    NSAssert(tableView == suspectTableView, @"tableView == suspectTableView");
324    if (!_showDetails)
325        return [self urlForRow:row];
326    NSXMLElement* e = [_suspectList objectAtIndex:row];
327    return [NSString stringWithFormat:@"%@\n       from: %@\n       %@",
328            [self urlForRow:row],
329            [Xml getAttribute:e withName:@"referer"],
330            [Xml getAttribute:e withName:@"why"]];
331}
332
333@end
334
335@implementation SuspectsTableView
336
337- (IBAction)copy:(id)sender
338{
339    id del = [self delegate];
340    if ([del isKindOfClass:[SuspectsController class]]) {
341        SuspectsController* sc = (SuspectsController*)del;
342        [sc copyFromSuspectsTable];
343    }
344}
345
346@end
Note: See TracBrowser for help on using the repository browser.