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

Last change on this file since 415 was 404, checked in by Nicholas Riley, 17 years ago

Leopard-ize UI.

File size: 8.7 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@interface NSWindow (RoundedCorners)
45- (void)setBottomCornerRounded:(BOOL)yn;
46@end
47
48@implementation FSAController
49
50// derived from TETextWatcher.m in Mike Ferris's TextExtras
51+ (void)installMenu;
52{
53 static BOOL alreadyInstalled = NO;
54 NSMenu *mainMenu = nil;
55
56 if (!alreadyInstalled && ((mainMenu = [NSApp mainMenu]) != nil)) {
57 NSMenu *insertIntoMenu = nil;
58 NSMenuItem *item;
59 unsigned insertLoc = NSNotFound;
60 NSBundle *bundle = [NSBundle bundleForClass: self];
61 NSMenu * beforeSubmenu = [NSApp windowsMenu];
62 // Succeed or fail, we do not try again.
63 alreadyInstalled = YES;
64
65 // 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.)
66
67 if (!beforeSubmenu) {
68 beforeSubmenu = [NSApp servicesMenu];
69 }
70
71 insertIntoMenu = mainMenu;
72
73 if (beforeSubmenu) {
74 NSArray *itemArray = [insertIntoMenu itemArray];
75 unsigned i, c = [itemArray count];
76
77 // Default to end of menu
78 insertLoc = c;
79
80 for (i=0; i<c; i++) {
81 if ([[itemArray objectAtIndex:i] target] == beforeSubmenu) {
82 insertLoc = i;
83 break;
84 }
85 }
86 } else {
87 NSArray *itemArray = [insertIntoMenu itemArray];
88 unsigned i = [itemArray count];
89
90 // Default to end of menu
91 insertLoc = i;
92
93 while (i-- > 0) {
94 if ([[itemArray objectAtIndex:i] hasSubmenu]) {
95 insertLoc = i+1;
96 break;
97 }
98 }
99 }
100 if (insertIntoMenu) {
101 NSMenu *fsaMenu = [[NSMenu allocWithZone: [NSMenu menuZone]] initWithTitle:NSLocalizedStringFromTableInBundle(@"FSA", @"FSA", bundle, @"Title of F-Script Anywhere menu")];
102
103 item = [insertIntoMenu insertItemWithTitle: NSLocalizedStringFromTableInBundle(@"FSA", @"FSA", bundle, @"Title of F-Script Anywhere menu") action:NULL keyEquivalent:@"" atIndex:insertLoc];
104 [insertIntoMenu setSubmenu:fsaMenu forItem:item];
105 [fsaMenu release];
106
107 // Add the items for the commands.
108 item = [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"New F-Script Workspace", @"FSA", bundle, @"Title of F-Script Workspace menu item") action:@selector(createInterpreterWindow:) keyEquivalent: @""];
109 [item setTarget: self];
110 item = [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"Browser for Target...", @"FSA", bundle, @"Title of F-Script Workspace menu item") action:@selector(createBrowserForSelection:) keyEquivalent: @""];
111 [item setTarget: self];
112 [fsaMenu addItem: [NSMenuItem separatorItem]];
113 item = [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"About F-Script Anywhere", @"FSA", bundle, @"Title of Info Panel menu item") action:@selector(showInfo:) keyEquivalent: @""];
114 [item setTarget: self];
115 [[FSAWindowManager sharedManager] setWindowMenu: fsaMenu];
116 }
117 }
118
119}
120
121+ (BOOL)validateMenuItem:(NSMenuItem *)menuItem
122{
123 SEL sel;
124 NSAssert([menuItem target] == self, @"menu item does not target FSAController!");
125 sel = [menuItem action];
126 if (sel == @selector(showInfo:) || sel == @selector(createInterpreterWindow:) || sel == @selector(createBrowserForSelection:)) return YES;
127 FSALog(@"+[FSAController validateMenuItem:] unknown menu item for validation: %@", menuItem);
128 return NO;
129}
130
131+ (void)createInterpreterWindow:(id)sender;
132{
133 [[self alloc] initShowingInterpreter:YES];
134}
135
136+ (void)createBrowserForSelection:(id)sender;
137{
138 [[[self alloc] initShowingInterpreter:NO] FSA_associateAndOpenBrowser:sender];
139}
140
141+ (void)showInfo:(id)sender;
142{
143 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);
144 if (result == NSAlertAlternateReturn) {
145 [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: FSA_FScriptURL]];
146 }
147}
148
149- (id)initShowingInterpreter:(BOOL)showInterpreter {
150 self = [super initWithWindowNibName: @"FSAInterpreterPanel"];
151
152 if (self != nil) {
153 NSWindow *window = [self window];
154 NSString *label;
155 static unsigned numInterpWindows = 0;
156
157 if (showInterpreter) {
158 NSAssert(window != nil, @"Can't get interpreter window!");
159 if ([window respondsToSelector: @selector(setBottomCornerRounded:)])
160 [window setBottomCornerRounded: NO]; // XXX otherwise we get black areas because the window isn't rounded
161 [window setContentBorderThickness: 30 forEdge: NSMinYEdge];
162 // XXX why oh why is text not vertically centered in standard-sized buttons?
163 [openBrowserButton setFrameSize: NSMakeSize([openBrowserButton frame].size.width, 19)];
164 [associateWithInterfaceButton setFrameSize: NSMakeSize([associateWithInterfaceButton frame].size.width, 19)];
165 [floatButtonCell setBackgroundStyle: NSBackgroundStyleRaised];
166 if (interpreterNum == 0) interpreterNum = ++numInterpWindows;
167 if ( (label = [self interpreterLabel]) != nil) {
168 [window setTitle: [NSString stringWithFormat: @"%@: %@", [window title], label]];
169 }
170
171 [window setLevel: NSNormalWindowLevel]; // XXX if set floating, it is globally floating!
172 [self showWindow: self];
173 [window makeKeyAndOrderFront: self];
174#warning this should go away when F-Script properly accepts firstResponder on the InterpreterView
175 [window makeFirstResponder: (NSView *)[[[self interpreterView] cliView] shellView]];
176 [[FSAWindowManager sharedManager] registerWindow: window];
177 }
178 system = [[[self interpreterView] interpreter] objectForIdentifier: @"sys" found: NULL];
179 [system retain];
180 NSAssert1([system isKindOfClass: [System class]], @"Initial value bound to identifier 'sys' is not a System object, but %@", system);
181 }
182
183 return self;
184}
185
186- (void)dealloc;
187{
188 [system release];
189 [super dealloc];
190}
191
192- (NSString *)interpreterLabel;
193{
194 static NSString *appName = nil;
195 static BOOL retrievedAppName = NO;
196
197 if (appName == nil) {
198 if (retrievedAppName) return nil;
199 NS_DURING
200 appName = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleName"];
201 NS_HANDLER
202 FSALog(@"Exception occurred while trying to obtain application name: %@", localException);
203 NS_ENDHANDLER
204 retrievedAppName = YES;
205 }
206 if (interpreterNum == 1) return appName;
207 return [NSString stringWithFormat: @"%@ [%u]", appName, interpreterNum];
208}
209
210- (FSInterpreterView *)interpreterView;
211{
212 return interpreterView;
213}
214
215- (System *)system;
216{
217 return system;
218}
219
220- (IBAction)setFloating:(id)sender;
221{
222 [[self window] setLevel: [sender state] == NSOnState ? NSFloatingWindowLevel : NSNormalWindowLevel];
223}
224
225- (IBAction)FSA_associateAndOpenBrowser:(id)sender
226{
227 if (viewAssociationController == nil) {
228 viewAssociationController = [[FSAViewAssociationController alloc] initWithFSAController: self];
229 }
230 [viewAssociationController captureOneView];
231}
232
233@end
Note: See TracBrowser for help on using the repository browser.