source: trunk/Cocoa/F-Script Anywhere/Source/FSAController.m@ 352

Last change on this file since 352 was 226, checked in by rchin, 18 years ago

Added a new "Browser for target..." at the top level FSA menu so that you can now open an object browser directly without opening a workspace (not everyone cares about smalltalk, unfortunantely).

File size: 8.0 KB
Line 
1//
2// FSAController.m
3// F-Script Anywhere
4//
5// Created by Nicholas Riley on Fri Feb 01 2002.
6// Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9/*
10
11 F-Script Anywhere is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 F-Script Anywhere is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with F-Script Anywhere; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
25*/
26
27#import "FSAController.h"
28#import "FSAViewAssociationController.h"
29#import "FSAnywhere.h"
30#import "FSAWindowManager.h"
31#import <FScript/FSInterpreter.h>
32
33@class ShellView;
34
35// XXX workaround for lack of focus on FSInterpreterView
36@interface CLIView : NSView
37- (ShellView *)shellView;
38@end
39
40@interface FSInterpreterView (FSAWorkaround)
41- (CLIView *)cliView;
42@end
43
44@implementation FSAController
45
46// derived from TETextWatcher.m in Mike Ferris's TextExtras
47+ (void)installMenu;
48{
49 static BOOL alreadyInstalled = NO;
50 NSMenu *mainMenu = nil;
51
52 if (!alreadyInstalled && ((mainMenu = [NSApp mainMenu]) != nil)) {
53 NSMenu *insertIntoMenu = nil;
54 id<NSMenuItem> item;
55 unsigned insertLoc = NSNotFound;
56 NSBundle *bundle = [NSBundle bundleForClass: self];
57 NSMenu * beforeSubmenu = [NSApp windowsMenu];
58 // Succeed or fail, we do not try again.
59 alreadyInstalled = YES;
60
61 // Add it to the main menu. We try to put it right before the Windows menu if there is one, or right before the Services menu if there is one, and if there's neither we put it right before the the last submenu item (ie above Quit and Hide on Mach, at the end on Windows.)
62
63 if (!beforeSubmenu) {
64 beforeSubmenu = [NSApp servicesMenu];
65 }
66
67 insertIntoMenu = mainMenu;
68
69 if (beforeSubmenu) {
70 NSArray *itemArray = [insertIntoMenu itemArray];
71 unsigned i, c = [itemArray count];
72
73 // Default to end of menu
74 insertLoc = c;
75
76 for (i=0; i<c; i++) {
77 if ([[itemArray objectAtIndex:i] target] == beforeSubmenu) {
78 insertLoc = i;
79 break;
80 }
81 }
82 } else {
83 NSArray *itemArray = [insertIntoMenu itemArray];
84 unsigned i = [itemArray count];
85
86 // Default to end of menu
87 insertLoc = i;
88
89 while (i-- > 0) {
90 if ([[itemArray objectAtIndex:i] hasSubmenu]) {
91 insertLoc = i+1;
92 break;
93 }
94 }
95 }
96 if (insertIntoMenu) {
97 NSMenu *fsaMenu = [[NSMenu allocWithZone: [NSMenu menuZone]] initWithTitle:NSLocalizedStringFromTableInBundle(@"FSA", @"FSA", bundle, @"Title of F-Script Anywhere menu")];
98
99 item = [insertIntoMenu insertItemWithTitle: NSLocalizedStringFromTableInBundle(@"FSA", @"FSA", bundle, @"Title of F-Script Anywhere menu") action:NULL keyEquivalent:@"" atIndex:insertLoc];
100 [insertIntoMenu setSubmenu:fsaMenu forItem:item];
101 [fsaMenu release];
102
103 // Add the items for the commands.
104 item = [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"New F-Script Workspace", @"FSA", bundle, @"Title of F-Script Workspace menu item") action:@selector(createInterpreterWindow:) keyEquivalent: @""];
105 [item setTarget: self];
106 item = [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"Browser for Target...", @"FSA", bundle, @"Title of F-Script Workspace menu item") action:@selector(createBrowserForSelection:) keyEquivalent: @""];
107 [item setTarget: self];
108 [fsaMenu addItem: [NSMenuItem separatorItem]];
109 item = [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"About F-Script Anywhere", @"FSA", bundle, @"Title of Info Panel menu item") action:@selector(showInfo:) keyEquivalent: @""];
110 [item setTarget: self];
111 [[FSAWindowManager sharedManager] setWindowMenu: fsaMenu];
112 }
113 }
114
115}
116
117+ (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
118{
119 SEL sel;
120 NSAssert([menuItem target] == self, @"menu item does not target FSAController!");
121 sel = [menuItem action];
122 if (sel == @selector(showInfo:) || sel == @selector(createInterpreterWindow:) || sel == @selector(createBrowserForSelection:)) return YES;
123 FSALog(@"+[FSAController validateMenuItem:] unknown menu item for validation: %@", menuItem);
124 return NO;
125}
126
127+ (void)createInterpreterWindow:(id)sender;
128{
129 [[self alloc] initShowingInterpreter:YES];
130}
131
132+ (void)createBrowserForSelection:(id)sender;
133{
134 [[[self alloc] initShowingInterpreter:NO] FSA_associateAndOpenBrowser:sender];
135}
136
137+ (void)showInfo:(id)sender;
138{
139 int result = NSRunInformationalAlertPanel([NSString stringWithFormat: @"About F-Script Anywhere (version %s)", FSA_VERSION], @"F-Script Anywhere lets you embed a F-Script interpreter in a Cocoa application while it is running.\n\nF-Script Anywhere is currently installed in this application. To remove it, quit this application.\n\nFor more information about F-Script, please visit its Web site %@.", @"OK", @"Visit Web Site", nil, FSA_FScriptURL);
140 if (result == NSAlertAlternateReturn) {
141 [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: FSA_FScriptURL]];
142 }
143}
144
145- (id)initShowingInterpreter:(BOOL)showInterpreter {
146 self = [super initWithWindowNibName: @"FSAInterpreterPanel"];
147
148 if (self != nil) {
149 NSWindow *window = [self window];
150 NSString *label;
151 static unsigned numInterpWindows = 0;
152
153 if(showInterpreter){
154 NSAssert(window != nil, @"Can't get interpreter window!");
155 if (interpreterNum == 0) interpreterNum = ++numInterpWindows;
156 if ( (label = [self interpreterLabel]) != nil) {
157 [window setTitle: [NSString stringWithFormat: @"%@: %@", [window title], label]];
158 }
159
160 [window setLevel: NSNormalWindowLevel]; // XXX if set floating, it is globally floating!
161 [self showWindow: self];
162 [window makeKeyAndOrderFront: self];
163#warning this should go away when F-Script properly accepts firstResponder on the InterpreterView
164 [window makeFirstResponder: (NSView *)[[[self interpreterView] cliView] shellView]];
165 [[FSAWindowManager sharedManager] registerWindow: window];
166 }
167 system = [[[self interpreterView] interpreter] objectForIdentifier: @"sys" found: NULL];
168 [system retain];
169 NSAssert1([system isKindOfClass: [System class]], @"Initial value bound to identifier 'sys' is not a System object, but %@", system);
170 }
171
172 return self;
173}
174
175- (void)dealloc;
176{
177 [system release];
178 [super dealloc];
179}
180
181- (NSString *)interpreterLabel;
182{
183 static NSString *appName = nil;
184 static BOOL retrievedAppName = NO;
185
186 if (appName == nil) {
187 if (retrievedAppName) return nil;
188 NS_DURING
189 appName = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleName"];
190 NS_HANDLER
191 FSALog(@"Exception occurred while trying to obtain application name: %@", localException);
192 NS_ENDHANDLER
193 retrievedAppName = YES;
194 }
195 if (interpreterNum == 1) return appName;
196 return [NSString stringWithFormat: @"%@ [%u]", appName, interpreterNum];
197}
198
199- (FSInterpreterView *)interpreterView;
200{
201 return interpreterView;
202}
203
204- (System *)system;
205{
206 return system;
207}
208
209- (IBAction)setFloating:(id)sender;
210{
211 [[self window] setLevel: [sender state] == NSOnState ? NSFloatingWindowLevel : NSNormalWindowLevel];
212}
213
214- (IBAction)FSA_associateAndOpenBrowser:(id)sender
215{
216 if (viewAssociationController == nil) {
217 viewAssociationController = [[FSAViewAssociationController alloc] initWithFSAController: self];
218 }
219 [viewAssociationController captureOneView];
220}
221
222@end
Note: See TracBrowser for help on using the repository browser.