This is IAppDelegate.m in view mode; [Download] [Up]
/*$Copyright: * Copyright (C) 1992.5.22. Recruit Co.,Ltd. * Institute for Supercomputing Research * All rights reserved. * NewsBase by ISR, Kazuto MIYAI, Gary ARAKAKI, Katsunori SUZUKI, Kok-meng Lue * * You may freely copy, distribute and reuse the code in this program under * following conditions. * - to include this notice in the source code, if it is to be distributed * with source code. * - to add the file named "COPYING" within the code, which shall include * GNU GENERAL PUBLIC LICENSE(*). * - to display an acknowledgement in binary code as follows: "This product * includes software developed by Recruit Co.,Ltd., ISR." * - to display a notice which shall state that the users may freely copy, * distribute and reuse the code in this program under GNU GENERAL PUBLIC * LICENSE(*) * - to indicate the way to access the copy of GNU GENERAL PUBLIC LICENSE(*) * * (*)GNU GENERAL PUBLIC LICENSE is stored in the file named COPYING * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. $*/ /* IAppDelegate.m connects the user interface and WorkSpace Manager to/from the editor/viewer. */ #import "IAppDelegate.h" #import "IMediaTable.h" #import <appkit/Application.h> #import <appkit/Window.h> #import <appkit/Panel.h> #import <appkit/PopUpList.h> #import <mach_init.h> #import <objc/List.h> #import <appkit/MenuCell.h> #import <appkit/publicWraps.h> #import <sys/dir.h> #import <defaults.h> #import <mach.h> #import <libc.h> #import <ctype.h> #import "ILocalFileD.h" #import "INewsD.h" #import "IMMEditor.h" #import "IBinaryD.h" #import "ITextD.h" #import "IOrderedListD.h" #import "IReceiveListener.h" #import "IReceiveSpeaker.h" #import "data_types.h" #import "errdebug.h" #import "Localization.h" #import "IConvertMIME.h" #import "IArticleD.h" #import "IHelp.h" #import "InfoPanel.h" #define LoStr(key) doLocalString(NULL,key,NULL) struct windowDef { @defs(Window) }; extern char *ioBaseClassNameTable[]; static BOOL launchedFromDoubleClickOnFile = NO; // ## REWRITE! ## Really shouldn't use an extern for this better to send message HashTable *listOfTempFiles = nil; // these tags must match the tags of the menu cell (really not a good way!) // but IB doesn't gives us better! #define MENU_TAG_SAVE 701 #define MENU_TAG_POST 703 #define MENU_TAG_RECURSIVE_SAVE 702 #define MENU_TAG_RECURSIVE_POST 704 #define MENU_TAG_SAVE_AS_MIME 705 #define FIND_NEXT_TAG 110 #define FIND_PREVIOUS_TAG 111 #define FIND_ENTER_SELECTION 113 @implementation IAppDelegate - init { [super init]; iHelpPanel = nil; iInfoPanel = nil; listOfTempFiles = [[HashTable alloc] initKeyDesc:"*"]; return(self); } -(int)receiveArticle:(char *)data length:(int)length { const char *articleBuffer; articleBuffer = NXCopyInputData(0); DBG(10,fprintf(stderr, "***** start of article *****\n")); DBG(10,fputs(articleBuffer, stderr)); DBG(10,fprintf(stderr, "***** end of article *****\n")); [INewsD openArticle:articleBuffer length:length]; return(0); } - sendArticle:sender { IMMEditor *sendEditor; IArticleD *article; sendEditor = [[NXApp keyWindow] delegate]; if ([sendEditor class] == [IMMEditor class]) { if ((article = [sendEditor sendArticle]) != nil) { if ([[article dataForKey:HEADER_INFO] infoForKey:GROUPNAME] == NULL) { NXRunAlertPanel(LoStr("NewsBase"), LoStr("Newsgroups field is missing, Please enter."), NULL,NULL,NULL); return (self); } // post article [INewsD save:article]; } } else { NXRunAlertPanel(LoStr("NewsBase"), LoStr("key window is not an Editor window"),NULL,NULL,NULL); } return(self); } - openArticle:sender { [ILocalFileD open]; return(self); } - saveArticle:sender { IMMEditor *theEditor; IArticleD *article; theEditor = [[NXApp keyWindow] delegate]; if ([theEditor class] == [IMMEditor class]) { if ((article = [theEditor sendArticle]) != nil) { if ([[article dataForKey:HEADER_INFO] infoForKey:GROUPNAME] == NULL) { NXRunAlertPanel(LoStr("NewsBase"), LoStr("Newsgroups field is missing, Please enter."), NULL,NULL,NULL); return (self); } [ILocalFileD save:article]; } } else { NXRunAlertPanel(LoStr("NewsBase"),LoStr("key window is not an Editor" " window"), NULL, NULL, NULL); } return(self); } - postArticle:(const char *)articleBuffer length:(int)length { port_t port; int returnCode; port = NXPortFromName("NewsBase", NULL); [[NXApp appSpeaker] setSendPort:port]; if ((returnCode = [[NXApp appSpeaker] receiveArticle:articleBuffer length:length]) != 0) { NXRunAlertPanel([self name],LoStr("cannot contact NewsBase"), LoStr("OK"),NULL,NULL); } return(self); } - sendArticleFrom:sender toIOClass:(Class)ioClass { IMMEditor *sendEditor; IOrderedListD *article; sendEditor = [[NXApp keyWindow] delegate]; if ([sendEditor class] != [IMMEditor class]) { NXRunAlertPanel(LoStr("NewsBase"),LoStr("key window is not an Editor window"),NULL,NULL,NULL); return(self); } if ((article = [sendEditor sendArticle]) != nil) { } return(self); } // recursiveSendArticle is the common method for saves, posts, recursive // saves and recursive posts; menu tags will differentiate the actual // requests - recursiveSendArticle:sender { IMMEditor *sendEditor; IArticleD *article; int i; id externalObject; const char *multipleViewerFlag; sendEditor = [[NXApp keyWindow] delegate]; if ([sendEditor class] != [IMMEditor class]) { NXRunAlertPanel(LoStr("NewsBase"), LoStr("key window is not an Editor window"),NULL,NULL,NULL); return(self); } if ((article = [sendEditor sendArticle]) != nil) { if ([[article dataForKey:HEADER_INFO] infoForKey:GROUPNAME] == NULL) { NXRunAlertPanel(LoStr("NewsBase"), LoStr("Newsgroups field is missing, Please enter."), NULL,NULL,NULL); return (self); } switch ([[sender selectedCell] tag]) { case MENU_TAG_SAVE: case MENU_TAG_POST: // check if there exists hyper links if ([[article externalsList] count] > 0) { if (NXRunAlertPanel(LoStr(MMEDITOR), LoStr("Article has externally linked articles " "which will not be recursively saved."), LoStr("OK"), LoStr("Cancel"), NULL) == NX_ALERTDEFAULT) { break; } else { return(self); } } break; default: break; } switch ([[sender selectedCell] tag]) { case MENU_TAG_SAVE: [ILocalFileD save:article]; break; case MENU_TAG_POST: [INewsD save:article]; break; case MENU_TAG_RECURSIVE_SAVE: // recursive save requires multiple viewer mode so temporarily // set multiple viewer mode multipleViewerFlag = NXGetDefaultValue(OWNER, MULTIPLEVIEWERFLAG); NXSetDefault(OWNER, MULTIPLEVIEWERFLAG, "Yes"); [article recursiveSaveToDomain:[ILocalFileD domain]]; NXSetDefault(OWNER, MULTIPLEVIEWERFLAG, multipleViewerFlag); break; case MENU_TAG_RECURSIVE_POST: // recursive save requires multiple viewer mode so temporarily // set multiple viewer mode multipleViewerFlag = NXGetDefaultValue(OWNER, MULTIPLEVIEWERFLAG); NXSetDefault(OWNER, MULTIPLEVIEWERFLAG, "Yes"); [article recursiveSaveToDomain:[INewsD domain]]; NXSetDefault(OWNER, MULTIPLEVIEWERFLAG, multipleViewerFlag); break; case MENU_TAG_SAVE_AS_MIME: [ILocalFileD saveAsMIME:article]; break; } } return(self); } - printArticle:sender { IMMEditor *printEditor; printEditor = [[NXApp keyWindow] delegate]; if ([printEditor class] == [IMMEditor class]) { [printEditor printArticle]; } else { NXRunAlertPanel(LoStr("NewsBase"),LoStr("key window is not an Editor window"),NULL,NULL,NULL); } return(self); } - redisplayArticle:sender { IMMEditor *redisplayEditor; redisplayEditor = [[NXApp keyWindow] delegate]; if ([redisplayEditor class] == [IMMEditor class]) { [redisplayEditor redisplayArticle]; } else { NXRunAlertPanel(LoStr("NewsBase"),LoStr("key window is not an Editor window"),NULL,NULL,NULL); } return(self); } - getReferenceListOfArticle:sender { IMMEditor *currentEditor; MenuCell *menucell; const char *referenceList, *sptr; char messageId[512], *tptr; currentEditor = [[NXApp keyWindow] delegate]; if (currentEditor == nil) { currentEditor = sender; } if ([currentEditor class] == [IMMEditor class]) { if ((referenceList = [currentEditor getReferenceList]) != NULL) { sptr = referenceList; while (*sptr != '\0') { for (; *sptr != '\0' && *sptr != '<'; ++sptr); if (*sptr != '<') { break; } getNextMessageId: messageId[0] = '<'; for (++sptr, tptr = messageId + 1; *sptr != '\0' && *sptr != '>' && *sptr != '<'; ++sptr, ++tptr) { *tptr = *sptr; } if (*sptr == '<') { // error message id did not end and new begins goto getNextMessageId; } if (*sptr != '>') { break; } *tptr++ = *sptr++; *tptr = '\0'; menucell = [[oEditorGetReMenuCell target] addItem:messageId action:@selector(getArticleWithMessageID:) keyEquivalent:'\0']; [menucell setTarget:self]; } } // } else { // NXRunAlertPanel(LoStr("NewsBase"),LoStr("key window is not an Editor window"),NULL,NULL,NULL); } return(self); } - getArticleWithMessageID:sender { [INewsD loadFromName:[[sender selectedCell] title] inZone:NULL]; return(self); } - closeAllEditorWindows:sender { List *windowList; Window *window; int i; windowList = [NXApp windowList]; for (i = 0; (window = [windowList objectAt:i]) != nil; ++i) { if ([[window delegate] class] == [IMMEditor class]) { if ([[window delegate] windowWillClose:self] != nil) { [window close]; } } } return(self); } - openEditor:sender { IArticleD *article; id openPanel; const char *types[2] = {"mime", NULL}; NXStream *stream; id articleItem; id conv; switch ([[sender selectedCell] tag]) { case 0: // new editor window LoadLocalNib("MMRTFEditor.nib",self,NO,NULL); /* [NXApp loadNibSection:"MMRTFEditor.nib" owner:self withNames:NO fromZone:NXCreateZone(vm_page_size, vm_page_size, YES)]; */ [editor editNewArticle]; break; case 1: // post response editor = [[NXApp keyWindow] delegate]; if ([editor class] == [IMMEditor class]) { if ((article = [editor sendArticle]) != nil) { LoadLocalNib("MMRTFEditor.nib",self,NO,NULL); /* [NXApp loadNibSection:"MMRTFEditor.nib" owner:self withNames:NO fromZone:NXCreateZone(vm_page_size, vm_page_size, YES)]; */ [editor postResponseToArticle:article]; } } else { NXRunAlertPanel(LoStr("NewsBase"),LoStr("key window is not an Editor window"),NULL,NULL,NULL); } break; /* case 2: openPanel = [OpenPanel new]; [openPanel allowMultipleFiles:NO]; if ([openPanel runModalForTypes:types]) { stream = NXMapFile([openPanel filename], NX_READONLY); LoadLocalNib("MMRTFEditor.nib",self,NO,[self zone]); conv = [[IConvertMIME alloc] init]; articleItem = [conv convertToItem:stream]; [editor displayArticle:articleItem]; NXCloseMemory(stream, NX_FREEBUFFER); } */ } return(self); } - openHelpPanel:sender { if (iHelpPanel == nil) { iHelpPanel = [[IHelp allocFromZone:[self zone]] init]; } [iHelpPanel openHelpPanel:sender]; return self; } - openInfoPanel:sender { if (iInfoPanel == nil) { iInfoPanel = [[InfoPanel allocFromZone:[self zone]] init]; } [iInfoPanel openInfoPanel:sender]; return self; } - appWillInit:sender { [NXApp setAppListener:[[IReceiveListener alloc] init]]; [NXApp setAppSpeaker:[[IReceiveSpeaker alloc] init]]; return(self); } - appDidInit:sender { // initialize IMMEditor class to prevent lockup with workspace manager [IMMEditor class]; return(self); } - appWillTerminate:sender { int n; Window *window; List *windowList; Class isA; NXHashState state; const char *filename; id value; char command[512]; windowList = [NXApp windowList]; for (n = 0; window = [windowList objectAt:n]; ++n) { if (NXZoneFromPtr(window) == 0) { DBG(1, fprintf(stderr, "NXZoneFromPtr(window = %#x) = %#x\n", window, NXZoneFromPtr(window));); [windowList removeObject:window]; --n; continue; } if ((isA = ((struct windowDef *)window)->isa) != (Class)[Window class] && isA != (Class)[Panel class] && isA != (Class)[Menu class] && isA != (Class)[PopUpList class]) { DBG(1, fprintf(stderr, "(window = %#x)->isa = %#x\n", window, ((struct windowDef *)window)->isa);); [windowList removeObject:window]; --n; } } // remove all temporary files state = [listOfTempFiles initState]; while ([listOfTempFiles nextState:&state key:(const void **)&filename value:(void **)&value] == YES) { sprintf(command, "rm -r %.505s", (const char *)filename); system(command); } return(self); } - (BOOL)appAcceptsAnotherFile:sender { DBG(1, ;); return(YES); } - (BOOL)app:sender openFile:(const char *)filename type:(const char *)type { DBG(1, ;); launchedFromDoubleClickOnFile = YES; // initialize IMMEditor class to prevent lockup with workspace manager [IMMEditor class]; return([ILocalFileD openFromName:filename]); } - editorDidBecomeKey:sender { Menu *oEditorGetReSubMenu; Matrix *oEditorGetReSubMenuItemList; int nrows, ncols, i; [oEditorReMenuCell setEnabled:YES]; [oSaveMenuCell setEnabled:YES]; [oRecursiveSaveMenuCell setEnabled:YES]; [oSaveAsMenuCell setEnabled:YES]; [oPostMenuCell setEnabled:YES]; [oRecursivePostMenuCell setEnabled:YES]; [oPrintMenuCell setEnabled:YES]; [oFindMenuCell setEnabled:YES]; [oEditMenuCell setEnabled:YES]; [oCloseMenuCell setEnabled:YES]; [oRedisplayMenuCell setEnabled:YES]; oEditorGetReSubMenu = [oEditorGetReMenuCell target]; oEditorGetReSubMenuItemList = [oEditorGetReSubMenu itemList]; [oEditorGetReSubMenuItemList getNumRows:&nrows numCols:&ncols]; for (i = 0; i < nrows; ++i) { [oEditorGetReSubMenuItemList removeRowAt:i andFree:YES]; } [oEditorReMenuCell setEnabled:YES]; [self getReferenceListOfArticle:sender]; oEditorGetReSubMenu = [oEditorGetReMenuCell target]; [[oEditorGetReSubMenu itemList] sizeToCells]; [oEditorGetReSubMenu sizeToFit]; [oEditorGetReMenuCell setEnabled:YES]; return(self); } - editorDidResignKey:sender { Menu *oEditorGetReSubMenu; Matrix *oEditorGetReSubMenuItemList; int nrows, ncols, i; [oEditorReMenuCell setEnabled:NO]; [oSaveMenuCell setEnabled:NO]; [oRecursiveSaveMenuCell setEnabled:NO]; [oSaveAsMenuCell setEnabled:NO]; [oPostMenuCell setEnabled:NO]; [oRecursivePostMenuCell setEnabled:NO]; [oPrintMenuCell setEnabled:NO]; [oFindMenuCell setEnabled:NO]; [oEditMenuCell setEnabled:YES]; [oCloseMenuCell setEnabled:NO]; [oRedisplayMenuCell setEnabled:NO]; [oEditorGetReMenuCell setEnabled:NO]; oEditorGetReSubMenu = [oEditorGetReMenuCell target]; oEditorGetReSubMenuItemList = [oEditorGetReSubMenu itemList]; [oEditorGetReSubMenuItemList getNumRows:&nrows numCols:&ncols]; for (i = 0; i < nrows; ++i) { [oEditorGetReSubMenuItemList removeRowAt:i andFree:YES]; } [oEditorGetReSubMenuItemList sizeToCells]; [oEditorGetReSubMenu sizeToFit]; return(self); } static Window *iconEnteredWindow; - (int)iconEntered:(int)windowNum at:(double)x :(double)y iconWindow:(int)iconWindowNum iconX:(double)iconX iconY:(double)iconY iconWidth:(double)iconWidth iconHeight:(double)iconHeight pathList:(const char *)pathList { unsigned int iconEnteredWindowNum; // ## REWRITE! ## would be nice if this uniformly redirected the // message to the windows delegate NXConvertGlobalToWinNum(windowNum, &iconEnteredWindowNum); iconEnteredWindow = [NXApp findWindow:iconEnteredWindowNum]; [iconEnteredWindow makeKeyAndOrderFront:self]; if ([[iconEnteredWindow delegate] class] == [IMMEditor class]) { return([[[iconEnteredWindow delegate] text] iconEntered:windowNum at:x :y iconWindow:iconWindowNum iconX:iconX iconY:iconY iconWidth:iconWidth iconHeight:iconHeight pathList:pathList]); } return(0); } - (int)iconReleasedAt:(double)x :(double)y ok:(int *)flag { if ([[iconEnteredWindow delegate] class] == [IMMEditor class]) { return([[[iconEnteredWindow delegate] text] iconReleasedAt:x :y ok:flag]); } return(0); } - (int)iconExitedAt:(double)x :(double)y { if ([[iconEnteredWindow delegate] class] == [IMMEditor class]) { return([[[iconEnteredWindow delegate] text] iconExitedAt:x :y]); } return(0); } - setOEditorReMenuCell:editorReMenuCell { oEditorReMenuCell = editorReMenuCell; [oEditorReMenuCell setEnabled:NO]; return(self); } - setOEditorGetReMenuCell:editorGetReMenuCell { oEditorGetReMenuCell = editorGetReMenuCell; [oEditorGetReMenuCell setEnabled:NO]; [[oEditorGetReMenuCell target] setTitle:"Message ID's"]; [[oEditorGetReMenuCell target] setDelegate:self]; return(self); } - (int)requestForPost:(char *) newsgroups sourceWindow:(int)wnum { IMMEditor *sendEditor; IArticleD *article; char *groupName; unsigned int lwnum; id sourceWin; DBG(1,fprintf(stderr," ============ requestForPost %s\t %d", newsgroups, wnum)); [NXApp activateSelf:YES]; NXConvertGlobalToWinNum(wnum, &lwnum); if ((sourceWin=[NXApp findWindow:lwnum]) == nil) { NXRunAlertPanel(LoStr("NewsBase"), LoStr("err occured when posting, try again"),NULL,NULL,NULL); return(-1); } [sourceWin makeKeyAndOrderFront:self]; sendEditor = [sourceWin delegate]; if ([sendEditor class] != [IMMEditor class]) { NXRunAlertPanel(LoStr("NewsBase"), LoStr("key window is not an Editor window"),NULL,NULL,NULL); return(-1); } if ((article = [sendEditor sendArticle]) != nil) { // check if there exists hyper links if ([[article externalsList] count] > 0) { if (NXRunAlertPanel(LoStr(MMEDITOR), LoStr("Article has externally linked articles " "which will not be recursively saved."), LoStr("OK"), LoStr("Cancel"), NULL) != NX_ALERTDEFAULT) { return (-1); } } if ((groupName=[[article dataForKey:HEADER_INFO] infoForKey:GROUPNAME]) != NULL) { // article header has "Newsgroups:" if (strncmp(newsgroups,"",strlen(newsgroups))==0) { // Newstoups: is in editor header [INewsD save:article]; return (0); } else if (strncmp(groupName,newsgroups,strlen(groupName))==0) { // group name is same [INewsD save:article]; return (0); } else { // groupname is different NXRunAlertPanel(LoStr("NewsBase"), LoStr("Newsgroups: is not matched"),NULL,NULL,NULL); return(-1); } } else { // header does not have "Newsgroups:" if (strncmp(newsgroups,"",strlen(newsgroups))==0) { // posted to nextStation icon, so should have "Newsgroups:" NXRunAlertPanel(LoStr("NewsBase"), LoStr("Newsgroups field is missing, Please enter."), NULL,NULL,NULL); return (-1); } [[article dataForKey:HEADER_INFO] addInfoString:(const char *)newsgroups key:GROUPNAME]; [INewsD save:article]; return (0); } } return (0); } // save previous context which is usually NewsBase - setPreviousContext:(int)context { if (context != myContext) { previousContext = context; } return(self); } // probably NewsBase - (int)previousContext { return(previousContext); } - setMyContext:(int)context { myContext = context; return(self); } - (int)myContext { return(myContext); } // find distributes find menu selections to the appropriate editor - find:sender { IMMEditor *findEditor; findEditor = [[NXApp mainWindow] delegate]; if ([findEditor class] != [IMMEditor class]) { NXRunAlertPanel(LoStr("NewsBase"), LoStr("key window is not an Editor window"),NULL,NULL,NULL); return(self); } switch ([[sender selectedCell] tag]) { case FIND_NEXT_TAG: [[findEditor view] find:[oFindText stringValue] forward:YES ignoreCase:[oFindCase state]]; break; case FIND_PREVIOUS_TAG: [[findEditor view] find:[oFindText stringValue] forward:NO ignoreCase:[oFindCase state]]; break; case FIND_ENTER_SELECTION: [oFindText setStringValue:[[findEditor view] selection]]; break; } return(self); } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.