This is Controller.m in view mode; [Download] [Up]
/* Controller.m -- Controller object for MailHelper application. Copyright 1991, Izumi Ohzawa and Manuel Alberto Ricart, All rights reserved. 3-17-91 V1.0 (IO) * Starting project. * Some codes are borrowed from AtYourService NeXT demo application. 4-6-91 V1.0 (IO) * Bug fix: fclose(fpin); was missing in method insertSignature. 9-18-91 V1.1 (MAR) * Preferences panel and use of default database to store them. Joint venture with Izumi? Perhaps. Izumi sent me his code for MailHelper. I told him I implement some basic prefs for him. 9-22-91 V1.1 (IO) * Defaults now written out as soon as OK button in Pref panel is pressed. * Signature insertion now adds a separator '---' within the code to remove requirement of having it in signature file itself (to make MailHelper conform with other programs which use .signature). * RTF signature insertion added. 9-29-91 V1.1 (VD) <vince@whatnxt.cuc.ab.ca> * Added several methods to set and retrive the default settings of the Control object To implement: Gray-out RTF quoting if RTF text is found on pasteboard. User selectable command keys for various functions. */ #import "Controller.h" #import <appkit/Application.h> #import <appkit/Listener.h> #import <appkit/Pasteboard.h> #import <appkit/defaults.h> #import <stdlib.h> #import <strings.h> #import <mach_init.h> #import <vm/vm_user.h> #import <sys/stat.h> @implementation Controller - init { self = [super init]; [self setQuoteString: (char *)NXGetDefaultValue([NXApp appName],"Quote")]; [self setSigFile: (char *)NXGetDefaultValue([NXApp appName],"Sigfile")]; [self setRtfSigFile: (char *)NXGetDefaultValue([NXApp appName],"Rtfsigfile")]; [self setWrapWidth: atoi((char *)NXGetDefaultValue([NXApp appName],"Width"))]; return self; } - setQuoteString:(char *)string { strcpy(quoteString,string); return self; } - (char *)quoteString { return quoteString; } - setSigFile:(char *)string { strcpy(sigFile,string); return self; } - (char *)sigFile { return sigFile; } - setRtfSigFile:(char *)string { strcpy(rtfSigFile,string); return self; } - (char *)RtfSigFile { return rtfSigFile; } - setWrapWidth:(int)value { wrapWidth = value; return self; } - (int)wrapWidth { return wrapWidth; } /* Reformats selected text so that it fits into a specified column width. * Alberto's Modifications: * initialized colLimit to wrapWidth global variable. */ - reformatSelection:(id)pbid userData:(const char *)udata error:(char **)errmsg { char *data; int length; const char *const *types; int hasAscii, i; int column=1, nextcolumn=1, colLimit=wrapWidth; types = [pbid types]; /* get a list of pasteboard types */ hasAscii = 0; for(i=0; !hasAscii && types[i]; i++) if(!strcmp(types[i], NXAsciiPboardType)) hasAscii = 1; if(hasAscii){ [pbid readType:NXAsciiPboardType data:&data length:&length]; if(data && length){ char *returnData, *dataptr, *endptr; char *wordptr, *nextwordptr; returnData=malloc(length+10); dataptr = strncpy(returnData, data, length); wordptr = nextwordptr = dataptr; endptr = dataptr+length; for (i=1;i<=length;i++){ /* remove all line breaks execpt doubles */ if((*dataptr == '\n') && (*(dataptr+1) == '\n')){ dataptr += 2; continue; }else if(*dataptr == '\n') *dataptr = ' '; dataptr++; } column = nextcolumn = 1; while(nextwordptr < endptr){ while((wordptr < endptr) && (*wordptr != ' ') && (*wordptr != '\n')){ wordptr++; column++; } /* on exit from above while(), wordptr should still be at ' ' or '\n' */ if(*wordptr++ == '\n'){ column = nextcolumn = 1; continue; } nextwordptr = wordptr; nextcolumn = column; while((nextwordptr < endptr) && (*nextwordptr != ' ') && (*nextwordptr != '\n')){ nextwordptr++; nextcolumn++; } if(nextcolumn >= colLimit){ *(wordptr-1) = '\n'; column = nextcolumn =1; } } *endptr= '\n'; *(endptr+1) = '\0'; [pbid declareTypes:&NXAsciiPboardType num:1 owner:self]; [pbid writeType:NXAsciiPboardType data:returnData length:strlen(returnData)]; free(returnData); } else { /* end if(data && length) */ *errmsg = "Selection is empty."; fprintf(stderr,"SpotLight: Selection is empty.\n"); } vm_deallocate(task_self(), data, length); }else { /* end if(hasAscii) */ *errmsg = "No ASCII text found in your selection."; fprintf(stderr,"SpotLight: No ASCII text found in your selection.\n"); } return self; } /* Adds quotation marks "> " to the head of each line of selected text. * Alberto's Modification: * Only changed the definition of quotestr to point to the quoteString global. */ - quoteSelection:(id)pbid userData:(const char *)udata error:(char **)errmsg { char *data; int length; const char *const *types; char *quotestr = quoteString; int hasAscii, i, quotelen; quotelen = strlen(quotestr); types = [pbid types]; /* get a list of pasteboard types */ hasAscii = 0; for(i=0; !hasAscii && types[i]; i++) if(!strcmp(types[i], NXAsciiPboardType)) hasAscii = 1; if(hasAscii){ [pbid readType:NXAsciiPboardType data:&data length:&length]; if(data && length){ int numlines; char ch; char *returnData, *dataptr, *endptr, *outptr; numlines = 1; dataptr = data; /* ptr to original data */ endptr = data+length; /* ptr to end of data */ while(dataptr < endptr) /* count the number of lines */ if(*dataptr++ == '\n') numlines++; returnData=malloc(length+numlines*quotelen+10); dataptr = data; /* reinitialize ptr to orig data */ outptr = returnData; for(i=0;i<quotelen;i++) *outptr++ = quotestr[i]; while(dataptr < endptr){ if((ch = *dataptr++) == '\n'){ *outptr++ = ch; for(i=0;i<quotelen;i++) *outptr++ = quotestr[i]; }else *outptr++ = ch; } *outptr = '\n'; *(outptr+1) = '\0'; [pbid declareTypes:&NXAsciiPboardType num:1 owner:self]; [pbid writeType:NXAsciiPboardType data:returnData length:strlen(returnData)]; free(returnData); } else{ /* end if(data && length) */ *errmsg = "Selection is empty."; fprintf(stderr,"SpotLight: Selection is empty.\n"); } vm_deallocate(task_self(), data, length); }else{ /* end if(hasAscii) */ *errmsg = "No ASCII text found in your selection."; fprintf(stderr,"SpotLight: No ASCII text found in your selection.\n"); } return self; } // Adds the content of ~/.signature at the current cursor location. - insertSignature:(id)pbid userData:(const char *)udata error:(char **)errmsg { char *data, *dataptr; char *signaturefile = sigFile; char signaturepath[1024]; int length, i; struct stat filestat; FILE *fpin; sprintf(signaturepath, "%s/%s", NXHomeDirectory(), signaturefile); if(stat(signaturepath, &filestat)){ data = ""; length = 0; *errmsg = "No signature file found in your home directory."; fprintf(stderr,"SpotLight: No signature file found in your home directory.\n"); }else{ length = filestat.st_size; if((fpin = fopen(signaturepath, "r")) != NULL){ dataptr = data = malloc(length+NUMSIGDASH+10); /* data remains unchanged */ for(i=0; i<NUMSIGDASH; i++) /* Add '---' signature separator here */ *dataptr++ = '-'; *dataptr++ = '\n'; fread((void *)dataptr, 1, length, fpin); fclose(fpin); /* This was missing in V1.0 release */ *(dataptr+length) = '\0'; [pbid declareTypes:&NXAsciiPboardType num:1 owner:self]; [pbid writeType:NXAsciiPboardType data:data length:strlen(data)]; free(data); }else{ *errmsg = "Cannot open signature file."; fprintf(stderr,"SpotLight: Cannot open signature file.\n"); } } return self; } // Adds the content of ~/.signature.rtf at the current cursor location. // RTF signature insertion method. - insertRtfSignature:(id)pbid userData:(const char *)udata error:(char **)errmsg { char *data; char *signaturefile = rtfSigFile; char signaturepath[1024]; int length; struct stat filestat; FILE *fpin; sprintf(signaturepath, "%s/%s", NXHomeDirectory(), signaturefile); if(stat(signaturepath, &filestat)){ data = ""; length = 0; *errmsg = "No RTF signature file found in your home directory."; fprintf(stderr,"SpotLight: No RTF signature file found in your home directory.\n"); }else{ length = filestat.st_size; if((fpin = fopen(signaturepath, "r")) != NULL){ data = malloc(length+10); fread((void *)data, 1, length, fpin); fclose(fpin); *(data+length) = '\000'; [pbid declareTypes:&NXRTFPboardType num:1 owner:self]; [pbid writeType:NXRTFPboardType data:data length:strlen(data)]; free(data); }else{ *errmsg = "Cannot open RTF signature file."; fprintf(stderr,"SpotLight: Cannot open RTF signature file.\n"); } } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.