Add support for function return breakpoints.
[macgdbp.git] / Source / BreakpointController.m
1 /*
2 * MacGDBp
3 * Copyright (c) 2007 - 2011, Blue Static <http://www.bluestatic.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17 #import "BreakpointController.h"
18
19 #import "AppDelegate.h"
20 #import "PreferenceNames.h"
21
22 @implementation BreakpointController {
23 BreakpointManager* _manager;
24
25 BSSourceView* _sourceView;
26
27 NSArrayController* _arrayController;
28 }
29
30 /**
31 * Constructor
32 */
33 - (instancetype)initWithBreakpointManager:(BreakpointManager*)breakpointManager
34 sourceView:(BSSourceView*)sourceView
35 {
36 if ((self = [super initWithNibName:@"Breakpoints" bundle:nil])) {
37 _manager = breakpointManager;
38 _sourceView = sourceView;
39 }
40 return self;
41 }
42
43 - (void)awakeFromNib
44 {
45 [[self.addBreakpointButton cell] setUsesItemFromMenu:NO];
46 [self.addBreakpointButton.cell setMenuItem:[self.addBreakpointButton.menu itemAtIndex:0]];
47 }
48
49 /**
50 * Adds a breakpoint by calling up a file chooser and selecting a file for
51 * breaking in
52 */
53 - (IBAction)addBreakpoint:(id)sender
54 {
55 NSOpenPanel* panel = [NSOpenPanel openPanel];
56
57 if ([panel runModal] != NSOKButton)
58 {
59 return;
60 }
61
62 [_sourceView setFile:[[panel URL] path]];
63 }
64
65 - (IBAction)addFunctionBreakpoint:(id)sender
66 {
67 NSUInteger tag = [sender tag];
68 NSString* type;
69 if (tag == 'e') {
70 type = kBreakpointTypeFunctionEntry;
71 } else if (tag == 'r') {
72 type = kBreakpointTypeFunctionReturn;
73 } else {
74 [NSException raise:NSInvalidArgumentException
75 format:@"Unexpected breakpoint type from tag %ld sender %@", tag, sender];
76 }
77 [self.view.window beginSheet:self.addFunctionBreakpointWindow completionHandler:^(NSModalResponse returnCode) {
78 if (returnCode == NSModalResponseOK) {
79 [_manager addBreakpoint:[Breakpoint breakpointOnFunctionNamed:self.functionNameField.stringValue type:type]];
80 }
81 }];
82 }
83
84 - (IBAction)cancelFunctionBreakpoint:(id)sender
85 {
86 [self.view.window endSheet:self.addFunctionBreakpointWindow returnCode:NSModalResponseCancel];
87 }
88
89 - (IBAction)saveFunctionBreakpoint:(id)sender
90 {
91 [self.view.window endSheet:self.addFunctionBreakpointWindow returnCode:NSModalResponseOK];
92 }
93
94 /**
95 * Removes a breakpoint
96 */
97 - (IBAction)removeBreakpoint:(id)sender
98 {
99 NSArray* selection = [_arrayController selectedObjects];
100 if ([selection count] < 1)
101 {
102 return;
103 }
104
105 for (Breakpoint* bp in selection) {
106 [_manager removeBreakpoint:bp];
107 }
108 }
109
110 #pragma mark NSTableView Delegate
111
112 /**
113 * NSTableView delegate method that informs the controller that the stack selection did change and that
114 * we should update the source viewer
115 */
116 - (void)tableViewSelectionDidChange:(NSNotification*)notif
117 {
118 NSArray* selection = [_arrayController selectedObjects];
119 if ([selection count] < 1) {
120 return;
121 }
122
123 Breakpoint* bp = [selection objectAtIndex:0];
124 if (bp.type != kBreakpointTypeFile) {
125 return;
126 }
127
128 [_sourceView setFile:[bp file]];
129 [_sourceView scrollToLine:[bp line]];
130 [_sourceView setMarkers:[_manager breakpointsForFile:bp.file]];
131 }
132
133 @end