This is Controller.m in view mode; [Download] [Up]
/* Generated by Interface Builder */
#import "Controller.h"
#import "NewWindow.h"
#import <streams/streams.h>
#import <objc/typedstream.h>
#import <objc/NXStringTable.h>
#import <strings.h>
#define SAVE NX_ALERTDEFAULT
#define CLOSE NX_ALERTALTERNATE
#define CANCEL NX_ALERTOTHER
@implementation Controller
/*=================
* load InfoPanel
*=================*/
- infoPanel:sender
{
if (infoPanel == nil) {
[NXApp loadNibSection:"InfoPanel.nib" owner:self];
}
[infoPanel orderFront:sender];
return self;
}
/*==================================================
* create a newWindow, or better said a new insert
*==================================================*/
- newWindow:sender
{
id win;
if ([NXApp loadNibSection:"NewWindow.nib" owner:self] == nil) {
return nil;
}
if ([newInsert setUp]) {
win = [newInsert window];
if (win) {
NXRect frame;
char buf[256];
[win getFrame: &frame];
NX_X(&frame) += offset;
NX_Y(&frame) -= offset;
if ((offset += 24.0) > 100.0) {
offset = 0.0;
}
sprintf(buf, [win title], ++calcNum);
[win setTitle: buf];
[win placeWindowAndDisplay: &frame];
[win makeKeyAndOrderFront:nil];
return newInsert;
}
}
return nil;
}
/*============================
* manages the service stuff
*============================*/
// This probably should be broken up into two funcs. One for an RTF message
// and one for an ASCII message. Oh well, it works...
- servicesMessage:(id)pasteboard
userData:(const char *)sortArgs
error:(char **)errorMessage
{
int length, currentType;
const char *data;
const char *const *ptypes;
NXStream *stream;
id contf = [newInsert contentfield];
ptypes=[pasteboard types];
//Look for RTF first...
for (currentType=0; ptypes[currentType] ; currentType++ ){
if (!strcmp(ptypes[currentType],NXRTFPboardType)){
[pasteboard readType:ptypes[currentType] data:&data length:&length];
stream = NXOpenMemory(data, length, NX_READONLY);
[[contf docView] readRichText:stream];
NXCloseMemory(stream, NX_FREEBUFFER);
return self;
}
}
for (currentType=0; ptypes[currentType] ; currentType++ ){
if (!strcmp(ptypes[currentType],NXAsciiPboardType)) {
[pasteboard readType:ptypes[currentType] data:&data length:&length];
stream = NXOpenMemory(data, length, NX_READONLY);
[[contf docView] readText:stream];
NXCloseMemory(stream, NX_FREEBUFFER);
return self;
}
}
return self; //should never be reached....
}
/*==============================
* printing and fieldtext copy
*==============================*/
- doPrint:sender
{
id insert = [[NXApp mainWindow] delegate];
id gr = [insert group];
[gr printPSCode:self];
return self;
}
- copyText:sender
{
NXStream *stream;
char *buffer;
int buttontag, length, maxlength;
id outp; // var to hold the main windows outputtitlefield
// The next statement "id insert = [[NXApp mainWindow] delegate];"
// is needed so we can access the actual (main) window's outlets,
// otherwise if we would use "newInsert" the last created insert window
// (which might not be the actual (main) window would receive the copied
// string. Why? - The reason is that the "newInsert" instance var will be
// overwritten each time we create a new insert window and so doesn't
// remember the earlier created ones. Thus if we would use it, we were
// only able to copy to the latest created window in the window list, even
// if some earlier one's were on top of it.
id insert = [[NXApp mainWindow] delegate];
outp = [insert outputtitlefield];
buttontag = [[sender selectedCell] tag];
stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
if (buttontag == 0)
[[inputTitleField docView] writeRichText:stream];
else
[[outp docView] writeRichText:stream];
NXGetMemoryBuffer(stream, &buffer, &length, &maxlength);
NXCloseMemory(stream, NX_SAVEBUFFER);
stream = NXOpenMemory(buffer, length, NX_READONLY);
// access the main windows outputtitlefield, see the above comments
if (buttontag == 0)
[[outp docView] readRichText:stream];
else
[[inputTitleField docView] readRichText:stream];
NXCloseMemory(stream, NX_FREEBUFFER);
return self;
}
/*========================
* load/save panel stuff
*========================*/
- showError: (const char *)errorMessage
{
NXRunAlertPanel(NULL, errorMessage,
[stringSet valueForStringKey:"OK"], NULL, NULL);
return self;
}
- openRequest:sender
{
const char *const types[2] = {[stringSet valueForStringKey:"extension"],
NULL};
if ([ [OpenPanel new] runModalForTypes:types]) {
if ([self newWindow:self]) {
[newInsert loadFile:[ [OpenPanel new]
filename] ];
}
}
return self;
}
- (int) countEditedWindows
{
id winList;
int i;
int count = 0;
winList = [NXApp windowList];
for (i=0; i<[winList count]; i++) {
if ([ [winList objectAt: i] isDocEdited])
count++;
}
return count;
}
- saveAll:sender
{
id winList;
int i;
winList = [NXApp windowList];
for (i=0; i<[winList count]; i++) {
id win = [winList objectAt: i];
id delegate = [win delegate];
if ([delegate isKindOf:[NewWindow class]]) {
[win makeKeyAndOrderFront:nil];
[delegate save:win];
}
}
return self;
}
- (BOOL)menuActive:menuCell
{
BOOL shouldBeEnabled;
shouldBeEnabled = [[[NXApp mainWindow] delegate]
isKindOf:[NewWindow class]];
if([menuCell isEnabled] != shouldBeEnabled) {
// Menu cell is either enabled and shouldn't be,
// or it is not enabled and should be.
// In any event, set the correct state.
[menuCell setEnabled:shouldBeEnabled];
return YES; /* redisplay */
}
return NO; /* no change */
}
@end
@implementation Controller(ApplicationDelegate)
/*=============================
* Application delegate stuff
*=============================*/
- appDidInit:sender
{
id docMenu = [insertSubmenuCell target];
[saveMenuCell setUpdateAction: @selector(menuActive:) forMenu: docMenu];
[saveAsMenuCell setUpdateAction: @selector(menuActive:) forMenu: docMenu];
[saveAllMenuCell setUpdateAction: @selector(menuActive:) forMenu: docMenu];
[[NXApp appListener] setServicesDelegate:self];
opanel = [OpenPanel new];
[opanel allowMultipleFiles:YES];
/* if you always want an empty insertwindow at startup,
un-comment the following line */
// [self newWindow:self];
[NXApp setAutoupdate: YES];
return self;
}
// appAcceptsAnotherFile: is an application delegate method which
// returns whether it is OK for the application to try to open more files
// with the "app:openFile:type:" method.
- (BOOL) appAcceptsAnotherFile:sender
{
return (YES);
}
// app:openFile:type: is called to open the specified file. It is called
// by the Application object in response to open requests from the Workspace.
- (int) app:sender openFile:(const char *)filename
type:(const char *)aType
{
if ([self newWindow:self]) {
if ([newInsert loadFile:filename]) {
return YES;
}
}
return NO;
}
// appWillTerminate: is called by the Application object when the 'quit'
// button is pressed. It checks for edited Windows which haven't be saved.
- appWillTerminate:sender
{
if ([self countEditedWindows]>0) {
int q = NXRunAlertPanel("Quit",
"There are edited windows.",
"Review Unsaved",
"Quit Anyway", "Cancel");
if (q==1) { /* Review */
int i;
id winList;
winList = [NXApp windowList];
for(i=0; i<[winList count]; i++){
id win = [winList objectAt: i];
if([ [win delegate]
isKindOf:[NewWindow class] ]){
[win performClose:nil];
}
}
return self;
}
if (q==-1) { /* cancel */
return nil;
}
}
return self; /* quit */
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.