Oolite 1.91.0.7644-241112-7f5034b
Loading...
Searching...
No Matches
OOJavaScriptConsoleController.m
Go to the documentation of this file.
1/*
2
3OOJavaScriptConsoleController.m
4
5
6Oolite Debug Bundle
7
8Copyright © 2007-2013 Jens Ayton
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the “Software”), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27
28*/
29
30
32#import "OOMacDebugger.h"
33#import "OODebugMonitor.h"
35
36#import "OOLogging.h"
37#import "OODebugUtilities.h"
40#import "RBSplitView.h"
41
42
43enum
44{
45 // Size limit for console scrollback
48
49 // Number of lines of console input to remember
50 kConsoleMemory = 100
51};
52
53
54@interface OOJavaScriptConsoleController (Private)
55
56/* Find a colour specified in the config plist, with the key
57 key-foreground-color or key-background-color. A key of nil will be treated
58 as "general", the fallback colour.
59*/
60- (NSColor *)foregroundColorForKey:(NSString *)key;
61- (NSColor *)backgroundColorForKey:(NSString *)key;
62
63// Load certain groups of config settings.
64- (void)reloadAllSettings;
65- (void)setUpFonts;
66
67- (void) saveHistory;
68
69@end
70
71
72@interface NSLayoutManager (Leopard)
73- (void)setAllowsNonContiguousLayout:(BOOL)flag;
74@end
75
76
78
79- (void)dealloc
80{
81 [consoleWindow release];
82 [inputHistoryManager release];
83
84 [_baseFont release];
85 [_boldFont release];
86
87 [_fgColors release];
88 [_bgColors release];
89
90 [super dealloc];
91}
92
93
94- (void)awakeFromNib
95{
97
98 // Build RBSplitView programmatically to avoid issues with IB plug-in.
99 NSView *contentView = [consoleWindow contentView];
100 RBSplitView *splitView = [[RBSplitView alloc] initWithFrame:[contentView frame]];
101
102 [contentView addSubview:splitView];
103 [splitView setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable];
104
105 [splitView setVertical:NO];
106 [splitView setDelegate:self];
107
108 [splitView addSubview:consoleLogHolderView atPosition:0];
110
111 CGFloat height = [consoleInputHolderView frame].size.height;
112 [splitView addSubview:consoleInputHolderView atPosition:1];
113 inputSplitSubview = [splitView subviewAtPosition:1];
114 [inputSplitSubview setMinDimension:30 andMaxDimension:0];
115
116 NSString *thumbPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"SplitViewThumb" ofType:@"png"];
117 [splitView setDivider:[[[NSImage alloc] initWithContentsOfFile:thumbPath] autorelease]];
118 [inputSplitSubview setDimension:height];
119
120 // Free performance boost in Leopard.
121 if ([[consoleTextView layoutManager] respondsToSelector:@selector(setAllowsNonContiguousLayout:)])
122 {
123 [[consoleTextView layoutManager] setAllowsNonContiguousLayout:YES];
124 }
125
126 // Ensure auto-scrolling will work.
127 [verticalScroller setFloatValue:1.0];
128
129 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
130 [inputHistoryManager setHistory:[defaults arrayForKey:@"debug-js-console-scrollback"]];
131
132 [self reloadAllSettings];
133
134 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:NSApplicationWillTerminateNotification object:nil];
135}
136
137
138- (void)applicationWillTerminate:(NSNotification *)notification
139{
140 [self saveHistory];
141}
142
143
144#pragma mark -
145
146- (IBAction) clearConsole:sender
147{
148 [self clearConsole];
149}
150
151
152- (IBAction)showConsole:sender
153{
155}
156
157
158- (IBAction)toggleShowOnWarning:sender
159{
160 [_debugger performConsoleCommand:@"console.settings[\"show-console-on-warning\"] = !console.settings[\"show-console-on-warning\"]"];
161}
162
163
164- (IBAction)toggleShowOnError:sender
165{
166 [_debugger performConsoleCommand:@"console.settings[\"show-console-on-error\"] = !console.settings[\"show-console-on-error\"]"];
167}
168
169
170- (IBAction)toggleShowOnLog:sender
171{
172 [_debugger performConsoleCommand:@"console.settings[\"show-console-on-log\"] = !console.settings[\"show-console-on-log\"]"];
173}
174
175
176- (IBAction)consolePerformCommand:sender
177{
178 NSString *command = nil;
179
180 // Use consoleInputField rather than sender so we can, e.g., add a button.
181 command = [consoleInputField stringValue];
182 [consoleInputField setStringValue:@""];
183 [consoleWindow makeFirstResponder:consoleInputField]; // Is unset if an empty string is entered otherwise.
184
185 [inputHistoryManager addToHistory:command];
186 [self saveHistory];
187
188 [_debugger performConsoleCommand:command];
189}
190
191
192- (void)appendMessage:(NSString *)string
193 colorKey:(NSString *)colorKey
194 emphasisRange:(NSRange)emphasisRange
195{
197
198 NSMutableAttributedString *mutableStr = nil;
199 NSColor *fgColor = nil,
200 *bgColor = nil;
201 volatile NSRange fullRange;
202 NSTextStorage *textStorage = nil;
203 BOOL doScroll;
204 NSUInteger length;
205
206 mutableStr = [NSMutableAttributedString stringWithString:[string stringByAppendingString:@"\n"]
207 font:_baseFont];
208
209 fullRange = (NSRange){ 0, [mutableStr length] };
210 fgColor = [self foregroundColorForKey:colorKey];
211 if (fgColor != nil)
212 {
213 if ([fgColor alphaComponent] == 0.0) return;
214 [mutableStr addAttribute:NSForegroundColorAttributeName
215 value:fgColor
216 range:fullRange];
217 }
218
219 bgColor = [self backgroundColorForKey:colorKey];
220 if (bgColor != nil)
221 {
222 [mutableStr addAttribute:NSBackgroundColorAttributeName
223 value:bgColor
224 range:fullRange];
225 }
226
227 if (emphasisRange.length != 0)
228 {
229 [mutableStr addAttribute:NSFontAttributeName
230 value:_boldFont
231 range:emphasisRange];
232 }
233
234 doScroll = [verticalScroller floatValue] > 0.980f;
235
236 textStorage = [consoleTextView textStorage];
237 [textStorage appendAttributedString:mutableStr];
238 length = [textStorage length];
239 if (fullRange.length > kConsoleMaxSize)
240 {
241 [textStorage deleteCharactersInRange:(NSRange){ length - kConsoleTrimToSize, kConsoleTrimToSize }];
242 length = kConsoleTrimToSize;
243 }
244
245 // Scroll to end of field
246 if (doScroll) [consoleTextView scrollRangeToVisible:(NSRange){ length, 0 }];
247
249}
250
251
252- (void)clearConsole
253{
254 NSTextStorage *textStorage = nil;
255
256 textStorage = [consoleTextView textStorage];
257 [textStorage deleteCharactersInRange:(NSRange){ 0, [textStorage length] }];
258}
259
260
261- (void) doShowConsole
262{
263 [consoleWindow makeKeyAndOrderFront:nil];
264 [consoleWindow makeFirstResponder:consoleInputField];
265}
266
267
268- (void)noteConfigurationChanged:(NSString *)key
269{
270 if ([key hasSuffix:@"-foreground-color"] || [key hasSuffix:@"-foreground-colour"])
271 {
272 // Flush foreground colour cache
273 [_fgColors removeAllObjects];
274 }
275 else if ([key hasSuffix:@"-background-color"] || [key hasSuffix:@"-background-colour"])
276 {
277 // Flush background colour cache
278 [_bgColors removeAllObjects];
279 [consoleTextView setBackgroundColor:[self backgroundColorForKey:nil]];
280 }
281 else if ([key hasPrefix:@"font-"])
282 {
283 [self setUpFonts];
284 }
285}
286
287
288- (void)setDebugger:(OOMacDebugger *)debugger
289{
290 _debugger = debugger;
291 [self reloadAllSettings];
292}
293
294
295#pragma mark -
296
297- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
298{
299 SEL action = NULL;
300 OODebugMonitor *monitor = nil;
301
302 action = [menuItem action];
304
305 if (action == @selector(toggleShowOnWarning:))
306 {
307 [menuItem setState:[_debugger configurationBoolValueForKey:@"show-console-on-warning"]];
308 return [monitor debuggerConnected];
309 }
310 if (action == @selector(toggleShowOnError:))
311 {
312 [menuItem setState:[_debugger configurationBoolValueForKey:@"show-console-on-error"]];
313 return [monitor debuggerConnected];
314 }
315 if (action == @selector(toggleShowOnLog:))
316 {
317 [menuItem setState:[_debugger configurationBoolValueForKey:@"show-console-on-log"]];
318 return [monitor debuggerConnected];
319 }
320 if (action == @selector(showConsole:))
321 {
322 return [monitor debuggerConnected];
323 }
324
325 return [self respondsToSelector:action];
326}
327
328
329// Split view delegate method to ensure only the console field is resized when resizing window.
330- (void)splitView:(RBSplitView*)sender wasResizedFrom:(float)oldDimension to:(float)newDimension
331{
332 [sender adjustSubviewsExcepting:inputSplitSubview];
333}
334
335@end
336
337
338@implementation OOJavaScriptConsoleController (Private)
339
340- (NSColor *)foregroundColorForKey:(NSString *)key
341{
342 NSColor *result = nil;
343 NSString *expandedKey = nil;
344
345 if (key == nil) key = @"general";
346
347 result = [_fgColors objectForKey:key];
348 if (result == nil)
349 {
350 // No cached colour; load colour description from config file
351 expandedKey = [key stringByAppendingString:@"-foreground-color"];
352 result = [NSColor colorWithOOColorDescription:[_debugger configurationValueForKey:expandedKey]];
353 if (result == nil)
354 {
355 expandedKey = [key stringByAppendingString:@"-foreground-colour"];
356 result = [NSColor colorWithOOColorDescription:[_debugger configurationValueForKey:expandedKey]];
357 }
358 if (result == nil && ![key isEqualToString:@"general"])
359 {
360 result = [self foregroundColorForKey:nil];
361 }
362 if (result == nil) result = [NSColor blackColor];
363
364 // Store loaded colour in cache
365 if (result != nil)
366 {
367 if (_fgColors == nil) _fgColors = [[NSMutableDictionary alloc] init];
368 [_fgColors setObject:result forKey:key];
369 }
370 }
371
372 return result;
373}
374
375
376- (NSColor *)backgroundColorForKey:(NSString *)key
377{
378 NSColor *result = nil;
379 NSString *expandedKey = nil;
380
381 if (key == nil) key = @"general";
382
383 result = [_bgColors objectForKey:key];
384 if (result == nil)
385 {
386 // No cached colour; load colour description from config file
387 expandedKey = [key stringByAppendingString:@"-background-color"];
388 result = [NSColor colorWithOOColorDescription:[_debugger configurationValueForKey:expandedKey]];
389 if (result == nil)
390 {
391 expandedKey = [key stringByAppendingString:@"-background-colour"];
392 result = [NSColor colorWithOOColorDescription:[_debugger configurationValueForKey:expandedKey]];
393 }
394 if (result == nil && ![key isEqualToString:@"general"])
395 {
396 result = [self backgroundColorForKey:nil];
397 }
398 if (result == nil) result = [NSColor whiteColor];
399
400 // Store loaded colour in cache
401 if (result != nil)
402 {
403 if (_bgColors == nil) _bgColors = [[NSMutableDictionary alloc] init];
404 [_bgColors setObject:result forKey:key];
405 }
406 }
407
408 return result;
409}
410
411
412- (void)reloadAllSettings
413{
414 [_fgColors removeAllObjects];
415 [_bgColors removeAllObjects];
416 [consoleTextView setBackgroundColor:[self backgroundColorForKey:nil]];
417 [self setUpFonts];
418}
419
420
421- (void)setUpFonts
422{
423 NSString *fontFace = nil;
424 NSInteger fontSize;
425
426 DESTROY(_baseFont);
427 DESTROY(_boldFont);
428
429 // Set font.
430 fontFace = [_debugger configurationValueForKey:@"font-face"
431 class:[NSString class]
432 defaultValue:@"Courier"];
433 fontSize = (NSInteger)[_debugger configurationIntValueForKey:@"font-size"
434 defaultValue:12];
435
436 _baseFont = [NSFont fontWithName:fontFace size:fontSize];
437 if (_baseFont == nil) _baseFont = [NSFont userFixedPitchFontOfSize:0];
438 [_baseFont retain];
439
440 // Get bold variant of font.
441 _boldFont = [[NSFontManager sharedFontManager] convertFont:_baseFont
442 toHaveTrait:NSBoldFontMask];
443 if (_boldFont == nil) _boldFont = _baseFont;
444 [_boldFont retain];
445}
446
447
448- (void) saveHistory
449{
450 NSArray *history = nil;
451
452 history = [inputHistoryManager history];
453 if (history != nil)
454 {
455 [[NSUserDefaults standardUserDefaults] setObject:history forKey:@"debug-js-console-scrollback"];
456 [[NSUserDefaults standardUserDefaults] synchronize];
457 }
458}
459
460@end
#define DESTROY(x)
Definition OOCocoa.h:77
#define OOJS_PROFILE_EXIT_VOID
#define OOJS_PROFILE_ENTER
return nil
OODebugMonitor * sharedDebugMonitor()
void setMinDimension:andMaxDimension:(CGFloat newMinDimension,[andMaxDimension] CGFloat newMaxDimension)
RBSplitSubview * subviewAtPosition:(NSUInteger position)
void adjustSubviewsExcepting:(RBSplitSubview *excepting)
void addSubview:atPosition:(NSView *aView,[atPosition] NSUInteger position)
void setDelegate:(id anObject)
void setDivider:(NSImage *image)
void setVertical:(BOOL flag)