gscheme/Document.m

246 lines
7.1 KiB
Objective-C

/* Document.m Subclass of NSDocument for GScheme application
Copyright (C) 2000 Free Software Foundation, Inc.
Author: Fred Kiefer <fredkiefer@gmx.de>
Date: 2000.
Adapted by: Marko Riedel <mriedel@neuearbeit.de>.
Date: 2002.
This file is part of GNUstep.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <AppKit/AppKit.h>
#include <AppKit/NSWindowController.h>
#include "Document.h"
#include "SCMTextView.h"
@interface Document (Private)
- (NSWindow*)makeWindow;
@end
@implementation Document
- init
{
progstr = @"\n";
return [super init];
}
- (void)textDidChange:(NSNotification *)textObject
{
[self updateChangeCount: NSChangeDone];
}
- (NSData *)dataRepresentationOfType:(NSString *)aType
{
if(aType==nil || [aType isEqualToString:@"scm"]){
return [[tview string] dataUsingEncoding:NSASCIIStringEncoding];
}
else{
NSString *msg = [NSString stringWithFormat: @"Unknown type: %@",
[aType uppercaseString]];
NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
return nil;
}
}
- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
if([aType isEqualToString:@"scm"]){
progstr = [NSString stringWithCString:[data bytes]
length:[data length]];
}
else{
NSString *msg = [NSString stringWithFormat: @"Unknown type: %@",
[aType uppercaseString]];
NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
return NO;
}
return YES;
}
- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString *)docType
{
NSFileManager *manager = [NSFileManager defaultManager];
if([manager isWritableFileAtPath:fileName]==NO){
NSString *msg = [NSString stringWithFormat: @"File is read only: %@",
fileName];
readOnly = YES;
NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
}
return [super readFromFile:fileName ofType:docType];
}
- (BOOL)writeToFile:(NSString *)fullDocumentPath ofType:(NSString *)docType
originalFile:(NSString *)fullOriginalDocumentPath
saveOperation:(NSSaveOperationType)saveOperationType;
{
BOOL result =
[super writeToFile:fullDocumentPath ofType:docType
originalFile:fullOriginalDocumentPath
saveOperation:saveOperationType];
if(result==YES && readOnly==YES && saveOperationType==NSSaveAsOperation){
NSString *msg = [NSString stringWithFormat: @"File now writable: %@",
fullDocumentPath];
NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
readOnly = NO;
[tview setEditable:YES];
}
else if(result==NO){
NSString *msg = [NSString stringWithFormat: @"Write failed: %@",
fullDocumentPath];
NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
}
return result;
}
extern VScheme *vm;
extern NSWindow *interpreterWindow;
- evaluate:(id)sender
{
BOOL res;
SCMInteractive *intView =
[[interpreterWindow contentView] documentView];
NSString *suffix = [intView getSuffix];
if([suffix length]>0){
[intView appendString:@"\n> "];
}
progstr = [tview string];
res = [vm processString:progstr mode:MODE_EVALUATE];
if(res==NO){
int errpos = [vm errpos];
if(errpos!=-1){
[tview selectLineAtPos:errpos];
}
NSRunAlertPanel(@"Error", [vm errmsg],
@"Ok", nil, nil);
}
else{
[interpreterWindow makeKeyAndOrderFront:self];
}
return self;
}
- (void) makeWindowControllers
{
NSWindowController *controller;
NSWindow *win = [self makeWindow];
controller = [[NSWindowController alloc] initWithWindow: win];
RELEASE (win);
[self addWindowController:controller];
RELEASE(controller);
// We have to do this ourself, as there is currently no nib file
[self windowControllerDidLoadNib:controller];
}
@end
int shiftPos = 0;
#define WREP 7
@implementation Document (Private)
- (NSWindow*)makeWindow
{
NSWindow *window;
NSScrollView *scrollView;
SCMTextView *textView;
NSRect scrollViewRect = {{0, 0}, {470, 400}};
NSRect winRect = {{100+25*(shiftPos%WREP), 100+25*(shiftPos%WREP)},
{470, 400}};
NSRect textRect;
unsigned int style = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask;
shiftPos++;
// This is expected to be retained, as it would normaly come from a
// nib file, where the owner would retain it.
window = [[NSWindow alloc] initWithContentRect: winRect
styleMask: style
backing: NSBackingStoreRetained
defer: NO];
[window setMinSize:NSMakeSize(300, 300)];
[window setReleasedWhenClosed:YES];
scrollView = [[NSScrollView alloc] initWithFrame: scrollViewRect];
[scrollView setHasHorizontalScroller: NO];
[scrollView setHasVerticalScroller: YES];
[scrollView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
[[scrollView contentView] setAutoresizingMask: NSViewHeightSizable
| NSViewWidthSizable];
[[scrollView contentView] setAutoresizesSubviews:YES];
sview = scrollView;
// Build up the text network
textRect = [[scrollView contentView] frame];
textView = [[SCMTextView alloc] initWithFrame: textRect];
[textView setBackgroundColor: [NSColor whiteColor]];
[textView setString:progstr];
[textView setFont:[NSFont userFixedPitchFontOfSize:12]];
[textView setEditable:(readOnly==NO ? YES : NO)];
[textView setDelegate: self];
[textView setHorizontallyResizable: NO];
[textView setVerticallyResizable: YES];
[textView setMinSize: NSMakeSize (0, 0)];
[textView setMaxSize: NSMakeSize (1E7, 1E7)];
[textView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
[[textView textContainer] setContainerSize: NSMakeSize (textRect.size.width,
1e7)];
[[textView textContainer] setWidthTracksTextView: YES];
// Store the text view in an ivar
tview = textView;
[scrollView setDocumentView: textView];
RELEASE(textView);
[window setContentView: scrollView];
RELEASE(scrollView);
// Make the Document the delegate of the window
[window setDelegate: self];
[window setTitle:[self displayName]];
// Make the text view the first responder
[window makeFirstResponder:textView];
[window display];
[window orderFront: nil];
return window;
}
@end