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

Last change on this file since 19 was 19, checked in by Nicholas Riley, 18 years ago

F-Script Anywhere 1.1.6d1

File size: 8.2 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        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            [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"Associate With Interface", @"FSA", bundle, @"Title of Associate with Interface menu item") action: @selector(FSA_associateWithInterface:) keyEquivalent: @""];
107            [fsaMenu addItem: [NSMenuItem separatorItem]];
108            item = [fsaMenu addItemWithTitle: NSLocalizedStringFromTableInBundle(@"About F-Script AnywhereÉ", @"FSA", bundle, @"Title of Info Panel menu item") action:@selector(showInfo:) keyEquivalent: @""];
109            [item setTarget: self];
110            [[FSAWindowManager sharedManager] setWindowMenu: fsaMenu];
111        }
112    }
113
114}
115
116+ (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
117{
118    SEL sel;
119    NSAssert([menuItem target] == self, @"menu item does not target FSAController!");
120    sel = [menuItem action];
121    if (sel == @selector(showInfo:) || sel == @selector(createInterpreterWindow:)) return YES;
122    FSALog(@"+[FSAController validateMenuItem:] unknown menu item for validation: %@", menuItem);
123    return NO;
124}
125
126+ (void)createInterpreterWindow:(id)sender;
127{
128    [[self alloc] init];
129}
130
131+ (void)showInfo:(id)sender;
132{
133    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);
134    if (result == NSAlertAlternateReturn) {
135        [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: FSA_FScriptURL]];
136    }
137}
138
139+ (void)load;
140{
141    [self installMenu];
142}
143
144- (id)init {
145    self = [super initWithWindowNibName: @"FSAInterpreterPanel"];
146
147    if (self != nil) {
148        NSWindow *window = [self window];
149        NSString *label;
150        static unsigned numInterpWindows = 0;
151
152        NSAssert(window != nil, @"CanÕt get interpreter window!");
153        if (interpreterNum == 0) interpreterNum = ++numInterpWindows;
154        if ( (label = [self interpreterLabel]) != nil) {
155            [window setTitle: [NSString stringWithFormat: @"%@: %@", [window title], label]];
156        }
157
158        [window setLevel: NSNormalWindowLevel]; // XXX if set floating, it is globally floating!
159        [self showWindow: self];
160        [window makeKeyAndOrderFront: self];
161#warning this should go away when F-Script properly accepts firstResponder on the InterpreterView
162        [window makeFirstResponder: (NSView *)[[[self interpreterView] cliView] shellView]];
163        [[FSAWindowManager sharedManager] registerWindow: window];
164        system = [[[self interpreterView] interpreter] objectForIdentifier: @"sys" found: NULL];
165        [system retain];
166        NSAssert1([system isKindOfClass: [System class]], @"Initial value bound to identifier 'sys' is not a System object, but %@", system);
167    }
168   
169    return self;
170}
171
172- (void)dealloc;
173{
174    [system release];
175    [super dealloc];
176}
177
178- (NSString *)interpreterLabel;
179{
180    static NSString *appName = nil;
181    static BOOL retrievedAppName = NO;
182   
183    if (appName == nil) {
184        if (retrievedAppName) return nil;
185        NS_DURING
186            appName = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleName"];
187        NS_HANDLER
188            FSALog(@"Exception occurred while trying to obtain application name: %@", localException);
189        NS_ENDHANDLER
190        retrievedAppName = YES;
191    }
192    if (interpreterNum == 1) return appName;
193    return [NSString stringWithFormat: @"%@ [%u]", appName, interpreterNum];
194}
195
196- (FSInterpreterView *)interpreterView;
197{
198    return interpreterView;
199}
200
201- (System *)system;
202{
203    return system;
204}
205
206- (IBAction)setFloating:(id)sender;
207{
208    [[self window] setLevel: [sender state] == NSOnState ? NSFloatingWindowLevel : NSNormalWindowLevel];
209}
210
211- (IBAction)FSA_associateWithInterface:(id)sender;
212{
213    NS_DURING
214        FSAWindowManager *wm = [FSAWindowManager sharedManager];
215        if (viewAssociationController == nil) {
216            viewAssociationController = [[FSAViewAssociationController alloc] initWithFSAController: self];
217        }
218        [viewAssociationController showWindow: self];
219        if (![wm windowIsRegistered: [viewAssociationController window]]) {
220            [wm registerSubordinateWindow: [viewAssociationController window]
221                                forWindow: [self window]];
222        }
223    NS_HANDLER
224        FSALog(@"%@", localException);
225    NS_ENDHANDLER
226}
227
228@end
Note: See TracBrowser for help on using the repository browser.