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.