This is Article.m in view mode; [Download] [Up]
#import "Alexandra.h" #import "Article.h" #import "descriptors.h" #import "headerfields.h" #import "parsedate.h" #import "rfc822realname.h" #import "parse-header.h" #import "plain-subject.h" #import <time.h> #import <misckit/MiscAppDefaults.h> #import "Preferences.subproj/preferences.h" static BOOL showAuthor,showSubject,showSize; static int smallIs,largeIs; static int sortType=0; @implementation Article + initialize // Ein Article wird erst erzeugt nachdem das main-nib { // geladen wurde, d.h. die Default-Defaults sind schon // vom Preferences Manager gesetzt! if(self==[Article class]) { [self prefsChanged]; [ERROR_MANAGER addObserver:self selector:@selector(prefsChanged) forError:ENOTEPrefsChanged]; } return self; } + prefsChanged; { showAuthor=[NXApp defaultBoolValue:DEFAULT_SHOW_AUTHOR]; showSubject=[NXApp defaultBoolValue:DEFAULT_SHOW_SUBJECT]; showSize=[NXApp defaultBoolValue:DEFAULT_SHOW_SIZE]; smallIs=[NXApp defaultIntValue:DEFAULT_SMALL_ARTICLE]; largeIs=[NXApp defaultIntValue:DEFAULT_LARGE_ARTICLE]; return self; } + setSortType:(int)t { sortType=t; return self; } + (int)sortType { return sortType; } - initWithNumber:(long)number { [self initTextCell:NULL]; [self setWrap:NO]; size=0; unread=TRUE; myNumber=number; myHeader.fieldBody=(char **)calloc(FIELD_COUNT,sizeof(char *)); timeOfPosting=0; authorRealName=NULL; killed=FALSE; return self; } - composeTitle { char *buf,*p=NULL; BOOL a=FALSE; BOOL b=FALSE; int from,to,tsize=1; if(showSubject && (p=myHeader.fieldBody[SUBJECT])){ a=TRUE; tsize+=strlen(p); } if(showAuthor && (myHeader.fieldBody[FROM]!=NULL)){ rfc822_realname(myHeader.fieldBody[FROM],&from,&to); if(from<to) b=TRUE; tsize+=to-from+6; } buf=calloc(tsize,sizeof(char)); if(a) strcpy(buf,p); if(b){ strcat(buf," ("); strncat(buf,myHeader.fieldBody[FROM]+from,to-from+1); strcat(buf,")"); } [self setStringValueNoCopy:buf shouldFree:YES]; return self; } - parseHeader:(NXStream *)headerStream; { char *stream_buffer; int len,a; NXGetMemoryBuffer(headerStream,&stream_buffer,&len,&a); parse_header(stream_buffer, len, myHeader.fieldBody, h_field_name, FIELD_COUNT,YES); return self; } -free { int i; for(i=0;i<FIELD_COUNT;i++) if(myHeader.fieldBody[i]!=NULL) free(myHeader.fieldBody[i]); free(myHeader.fieldBody); if(authorRealName!=NULL) free(authorRealName); return([super free]); } - (long)number { return myNumber; } - (headerDesc *)header { return &myHeader; } - (time_t)time { if((timeOfPosting==0)&&(myHeader.fieldBody[DATE]!=NULL)){ timeOfPosting=parsedate(myHeader.fieldBody[DATE]); if(timeOfPosting==-1){ timeOfPosting=0; free(myHeader.fieldBody[DATE]); myHeader.fieldBody[DATE]=NULL; } } return timeOfPosting; } - (const char *)realName; { if((authorRealName==NULL)&&(myHeader.fieldBody[FROM]!=NULL)){ int from,to; rfc822_realname(myHeader.fieldBody[FROM],&from,&to); if(from<to){ authorRealName=(char *)malloc((to-from+2)*sizeof(char)); strncpy(authorRealName,myHeader.fieldBody[FROM]+from,to-from+1); authorRealName[to-from+1]='\0'; } } return authorRealName; } - setRead { unread=FALSE; return self; } - setUnread { unread=TRUE; return self; } - (BOOL)isRead { return((unread==FALSE)||(killed==TRUE)); } - kill { killed=TRUE; return self; } - unkill { killed=FALSE; return self; } - (BOOL)isKilled { return killed; } - setTextAttributes:textObj { [super setTextAttributes:textObj]; if (unread==FALSE) [textObj setTextGray:NX_DKGRAY]; else [textObj setTextGray:NX_BLACK]; return textObj; } - unsetTag { myTag=0; return self; } - setTag { myTag=1; return self; } - (BOOL)isTaged { return((myTag==1)&&(killed==FALSE)); } - (int)size { return size; } - setSize:(int)asize; { size=asize; return self; } - (int)lines; { return lines; } - setLines:(int)lineCount; { lines=lineCount; return self; } //------------------------------------ // MiscCompare protocol implementation //------------------------------------ - (int)compare:anObject { int result=0; BOOL r1,r2; const char *s1,*s2; headerDesc *h1,*h2; switch (sortType) { case SORT_BY_DATE: result=[self time]-[anObject time]; break; case SORT_BY_SUBJECT: h1=[self header]; h2=[anObject header]; if(!h1 || !h2){ NXLogError("Article.m: article header is NULL pointer"); return 0; } s1=plain_subject(h1->fieldBody[SUBJECT],&r1); s2=plain_subject(h2->fieldBody[SUBJECT],&r2); if((s1==NULL)&&(s2==NULL)) result=0; else if(s1==NULL) result=-1; else if(s2==NULL) result=1; else result=strcasecmp(s1,s2); if(result==0) if(r1!=r2) result=(r1? 1:-1); else result=[self time]-[anObject time]; break; case SORT_BY_NUMBER: result=[self number]-[anObject number]; break; case SORT_BY_REAL_NAME: s1=[self realName]; s2=[anObject realName]; if((s1==NULL)&&(s2==NULL)) result=0; else if(s1==NULL) result=-1; else if(s2==NULL) result=1; else result=strcasecmp(s1,s2); break; } return result; } //----------------------------------------------------------- // fancy drawing... //----------------------------------------------------------- #define IMAGEMARGIN 1.0 - calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect { [super calcCellSize:theSize inRect:aRect]; theSize->height+=1; return self; } - drawInside:(const NXRect *)cellFrame inView:controlView { static NXImage *dotImages[] = { nil, nil, nil }; NXRect rect = *cellFrame; NXPoint imageOrigin; NXSize dotSize; int sizecat; struct _cFlags1 buf; if(!dotImages[0]) { dotImages[0] = [NXImage findImageNamed:"Article-short"]; dotImages[1] = [NXImage findImageNamed:"Article-medium"]; dotImages[2] = [NXImage findImageNamed:"Article-long"]; } [dotImages[2] getSize:&dotSize]; PSsetgray((cFlags1.state || cFlags1.highlighted) ? NX_WHITE : NX_LTGRAY); NXRectFill(cellFrame); if(showSize && (lines>0)) { imageOrigin.x = NX_MAXX(cellFrame) - IMAGEMARGIN * 2.0 - dotSize.width; imageOrigin.y = NX_Y(cellFrame) + NX_HEIGHT(cellFrame) - (NX_HEIGHT(cellFrame) - dotSize.height) / 2.0; if(lines<=smallIs) sizecat=0; else if(lines<=largeIs) sizecat=1; else sizecat=2; [dotImages[sizecat] composite:NX_SOVER toPoint:&imageOrigin]; NX_WIDTH(&rect) -= (dotSize.width + IMAGEMARGIN * 2.0 - NX_X(&rect)); } buf=cFlags1; cFlags1.highlighted=cFlags1.state=0; [super drawInside:&rect inView:controlView]; cFlags1=buf; PSsetgray(NX_DKGRAY); if (cFlags1.state || cFlags1.highlighted) { NXRect rectArray[2]; NXSetRect(&(rectArray[0]),NX_X(cellFrame),NX_Y(cellFrame), NX_WIDTH(cellFrame),1); NXSetRect(&(rectArray[1]),NX_X(cellFrame),NX_MAXY(cellFrame)-1, NX_WIDTH(cellFrame), 1.0); NXRectFillList(rectArray, 2); } return self; } - highlight:(const NXRect *)cellFrame inView:controlView lit:(BOOL)flag { if(cFlags1.highlighted != flag) { cFlags1.highlighted = flag; [self drawInside:cellFrame inView:controlView]; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.