This is eTDoc.m in view mode; [Download] [Up]
{\rtf0\ansi{\fonttbl\f0\fmodern Courier;\f1\ftech Symbol;\f2\fmodern Ohlfs;} \margl40 \margr40 {\colortbl;\red0\green0\blue0;} \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i0\ulnone\fs24\fc0\cf0 //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \i \b FILENAME \b0 : \b\i0 eTDoc.m\ \b0 // \i \b SUMMARY \b0 : \b\i0 Implementation of the abstract document controller. \b0 \ // \b\i SUPERCLASS \b0 : \i0 \b Object:eTDoc \b0 \ // \b\i PROTOCOLS \b0 : \i0 \b Uses <DocNotification> \b0 \ // \b\i INTERFACE \b0 : \i0 \b None \b0 \ // \b\i AUTHOR \b0 : \b\i0 Rohit Khare \b0 \ // \b\i COPYRIGHT \b0 : \f1\i0 Ó \f0\b 1993,94 California Institure of Technology, eText Project\ \b0 //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \b\i Implementation Comments \b0\i0 \ // Keep a careful eye on the construction/destruction process!\ // Also watch for the inanities of how file-reading is covered between \i etDoc \i0 \ // and \i eTAppUI \i0 .\ //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \b\i HISTORY \b0\i0 \ // 10/06/94: \b Revamped for eText5. \i \ \b0\i0 // 07/20/94: \b Added LaTeX as per Tim Berners-Lee's sed script; cleanup. \b0 \ // 06/17/94 \b Added writeHTMD isBold,isItalic,isFixedPitch. By RK and TRZ. \b0 \ // 01/14/94: \b Completely revised for version 4.0 \b0 \ // 09/11/93: \b Created (un)registerForDocNotification. <DocNotification> \b0 \ // 09/09/93: \b Added support for the docID member. \b0 \ // 08/22/93: \b Moved "Accessor Methods" to eTDoc \b0 \ // 08/21/93: \b Created. \b0 \ //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \b Imported Interfaces \b0 \ //\ #import " \b eTDoc.h \b0 "\ #import " \b eTDocInfoUI.h \b0 "\ #import " \b eTDocUI.h \b0 "\ \ \i @implementation eTDoc\ \i0 \ //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \b Class Management \b0 \ //\ - \b initForDocInfo \b0 :( \b eTDocInfo \b0 *) newDocInfo \{\ \b Panel \b0 * \b oPanel \b0 ;\ \b NXSelPt \b0 \b b \b0 , \b e \b0 ;\ \ [super init];\ \ // \i PHASE I: Initialize the internal model \i0 \ \b theDocInfo \b0 = \b newDocInfo \b0 ;\ \b notificationList \b0 = [[ \b List \b0 alloc] \b init \b0 ];\ [self \b registerNotification \b0 : \b navigator \b0 ];\ \b componentTable \b0 = [[ \b HashTable \b0 alloc] \b initKeyDesc \b0 :" \b % \b0 "];\ \b undoManager \b0 = [[ \b UndoManager \b0 alloc] \b init \b0 ];\ [ \b undoManager \b0 \b setLevelsOfUndo \b0 : \b 50 \b0 ]; // \i this should be an NXDefault \i0 \ [ \b theDocInfo \b0 \b setDoc \b0 : \b self \b0 ];\ \b selectedObj \b0 = \b theDocInfo \b0 ;\ if (*[theDocInfo \b agent \b0 ])\ [self \b attachAgent \b0 :[[[ \b etApp \b0 \b agentByName \b0 :[theDocInfo \b agent \b0 ]]\ \b alloc \b0 ] \b init \b0 :theDocInfo]];\ else \b theAgent \b0 = nil;\ [ \b undoManager \b0 \b disableUndoRegistration \b0 ];\ \ // \i PHASE II: Construct the UI \i0 \ \b oPanel \b0 = \b NXGetAlertPanel \b0 (" \b eTDoc \b0 ",\ " \b Opening the document titled %s \b0 .",\ NULL, NULL, NULL, [ \b theDocInfo \b0 \b docTitle \b0 ]);\ [oPanel setFloatingPanel:NO];\ [oPanel setHideOnDeactivate:YES];\ [oPanel \b orderFront \b0 :self];\ NXPing();\ \b docUI \b0 = [[[ \b eTDocUI \b0 alloc] \b init \b0 ] \b setDoc \b0 : \b self \b0 ];\ \ // \i PHASE III: Opening The Files \i0 \ [self \b openFrom \b0 :[theDocInfo \b docPath \b0 ]];\ \ // \i PHASE IV: Notifications \i0 \ // \i There's a little fudging between \i0 eTDoc \i and \i0 eTDocUI \i here because the \i0 \ // \i selection can get screwed up by the broadcast \i0 .\ [[docUI window] \b disableDisplay \b0 ];\ [[docUI eTextObj] \b getSel \b0 :&b :&e];\ \{ int count;\ count = [ \b notificationList \b0 \b count \b0 ];\ while (count--)\ if([[notificationList objectAt:count]\ respondsTo:@selector( \b docWillOpen: \b0 )])\ [[notificationList objectAt:count] \b docWillOpen \b0 : \b self \b0 ];\ \}\ [[docUI eTextObj] \b setSel \b0 :b.cp :e.cp];\ [[docUI eTextObj] \b scrollSelToVisible \b0 ];\ [[docUI window] \b setDocEdited \b0 : \b NO \b0 ];\ [[docUI window] \b reenableDisplay \b0 ];\ [ \b undoManager \b0 \b reenableUndoRegistration \b0 ];\ if (oPanel) \{\ [oPanel \b orderOut \b0 :self];\ \b NXFreeAlertPanel \b0 (oPanel);\ \}\ return self;\ \}\ - \b free \b0 \ \{\ [ \b undoManager \b0 \b emptyUndoManager \b0 ];\ undoManager = [ \b undoManager \b0 free];\ [ \b inspector \b0 \b inspect \b0 : \b nil \b0 ]; // \i invalidate would have gone back to the window. \i0 \ docUI = [ \b docUI \b0 free];\ [ \b theDocInfo \b0 \b setDoc \b0 : \b nil \b0 ];\ notificationList = [ \b notificationList \b0 free];\ return [super free];\ \}\ \ //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \b Document Management (by path) \b0 \ //\ - \b openFrom \b0 :(const char *)thePath \{\ if ( \b !access \b0 ( \b thePath \b0 , \b F_OK \b0 )) \{ // \i OK, we have a diskfile \i0 \ char tmp[MAXPATHLEN];\ \ sprintf( \b tmp \b0 , " \b %s/TXT.rtf \b0 ", \b thePath \b0 );\ if ( \b !access \b0 (tmp, \b R_OK \b0 )) \{\ // \i CASE I: We have ETFD/RTFD \i0 \ [[docUI \b eTextObj \b0 ] \b readETFfromPath \b0 : \b tmp \b0 ];\ \} else \{\ // \i CASE II: We have Text/RTF \i0 \ \b NXStream \b0 * \b memstream \b0 = NXMapFile( \b thePath \b0 , NX_READONLY);\ if (memstream) \{\ char magic[8];\ \ \b NXRead \b0 (memstream, \b magic \b0 ,6);\ NXSeek(memstream, 0, NX_FROMSTART);\ if (! \b strncmp \b0 (magic," \b \{\\\\rtf0 \b0 ",6)) \{\ [[docUI \b eTextObj \b0 ] \b readRichText \b0 :memstream];\ \} else \{\ [[docUI \b eTextObj \b0 ] \b readText \b0 :memstream];\ \}\ \b NXCloseMemory \b0 (memstream, NX_FREEBUFFER);\ \}\ \}\ [[docUI \b eTextObj \b0 ] \b setEditable \b0 :(![theDocInfo \b readOnly \b0 ])];\ \}\ return self;\ \}\ - \b saveTo \b0 :(const char*)thePath \b inFormat \b0 :( \b int \b0 )fmt \b changePath \b0 :( \b BOOL \b0 ) changeIt \{\ id \b sPanel \b0 ;\ char* \b desc[6] \b0 =\{ \b ETFD_DESC \b0 , \b\fc1\cf1 ASCII_DESC \b0\fc0\cf0 , \b\fc1\cf1 C_DESC \b0\fc0\cf0 , \b\fc1\cf1 TeXD_DESC \b0 , \b HTMD_DESC \b0 , \b RTF_DESC \b0\fc0\cf0 \};\ \ [[docUI \b window \b0 ] \b disableDisplay \b0 ];\ [inspector \b freeze \b0 ];\ \ // \i PHASE I: Notifications \i0 \ \{ int count;\ count = [notificationList count];\ while (count--)\ if([[notificationList objectAt:count]\ \b respondsTo \b0 :@selector( \b docWillWrite: \b0 )])\ [[ \b notificationList \b0 objectAt:count] \b docWillWrite \b0 : \b self \b0 ];\ \}\ \b sPanel \b0 = \b NXGetAlertPanel \b0 (" \b eTDoc \b0 ",\ " \b Saving document to \\"%s\\" in %s Format. \b0 ",\ NULL, NULL, NULL, \b thePath \b0 , \b desc \b0 [fmt]);\ [sPanel setFloatingPanel:NO];\ [sPanel setHideOnDeactivate:YES];\ [sPanel \b orderFront \b0 :self];\ NXPing();\ // \i PHASE II: Writing the files \i0 \ \b switch \b0 ( \b fmt \b0 )\{\ case \b ETFD_FMT \b0 : [self \b saveETFD \b0 :thePath \b changePath \b0 :changeIt]; break;\ case \b ASCII_FMT \b0 : [self \b saveASCII \b0 :thePath]; break;\ case \b C_FMT \b0 : [self \b saveC \b0 :thePath]; break;\ case \b TeXD_FMT \b0 : [self \b saveLaTeX \b0 :thePath]; break;\ case \b HTMD_FMT \b0 : [self \b saveHTMD \b0 :thePath]; break;\ case \b RTF_FMT \b0 : [self \b saveRTF \b0 :thePath]; break;\ \}\ if (sPanel) \{\ [sPanel \b orderOut \b0 :self];\ \b NXFreeAlertPanel \b0 ( \b sPanel \b0 );\ \}\ // \i PHASE III: Notifications \i0 \ \{ int count;\ count = [notificationList count];\ while (count--)\ if([[notificationList objectAt:count]\ \b respondsTo \b0 :@selector( \b docDidWrite: \b0 )])\ [[ \b notificationList \b0 objectAt:count] \b docDidWrite \b0 : \b self \b0 ];\ \}\ [inspector \b thaw \b0 ];\ [[[docUI \b window \b0 ] \b reenableDisplay \b0 ] \b display \b0 ];\ return self;\ \}\ - \b close \b0 :sender \b allowCancel \b0 :( \b BOOL \b0 )cancellable \{\ return [ \b docUI \b0 \b close \b0 :sender \b allowCancel \b0 :cancellable];\}\ - \b save \b0 :sender \{\ return [ \b docUI \b0 \b save \b0 :sender];\}\ \ - \b saveASCII \b0 :(const char *) thePath \{\ [[docUI \b eTextObj \b0 ] \b writeASCIItoPath \b0 :thePath];\ return self;\}\ - \b saveC \b0 :(const char *) thePath \{\ [[docUI \b eTextObj \b0 ] \b writeCtoPath \b0 :thePath];\ return self;\}\ - \b saveRTF \b0 :(const char *) thePath \{\ [[docUI \b eTextObj \b0 ] \b writeRTFtoPath \b0 :thePath];\ return self;\}\ - \b saveLaTeX \b0 :(const char *) thePath\ \{\ char \b LaTeXfile \b0 [MAXPATHLEN];\ int i;\ struct stat st;\ DIR *dirp;\ struct direct *dp;\ NXStream * \b s \b0 ;\ \b taggingInfo \b0 \b tags \b0 [8];\ \ // \i PHASE I: Prepare thePath \i0 \ if ( \b stat \b0 ( \b thePath \b0 , &st) || (((st. \b st_mode \b0 & S_IFMT) \b != \b0 \b S_IFDIR \b0 )))\{\ \b removeFile \b0 ( \b thePath \b0 );\ if ( \b mkdir \b0 ( \b thePath \b0 , 0777)) \{\ NXLogError(" \b Could not mkdir( \b0 \\"%s\\" \b ) \b0 ", \b thePath \b0 );\ perror("eText5");\ \b NXBeep \b0 ();\ return nil;\ \}\ \}\ [ \b componentTable \b0 \b empty \b0 ];\ \ // \i PHASE II: Prepare taggingInfo \i0 \ i=0; // \i is incremented to compact out undefined tagging fonts \i0 \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H1 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b \\\\part\{ \b0 "); // \i use \{book\} with \\chapter \i0 \ tags[i]. \b end \b0 = NXUniqueString(" \b \}\\n \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H2 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b \\\\section\{ \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b \}\\n \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H3 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b \\\\subsection\{ \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b \}\\n \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H4 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b \\\\subsubsection\{ \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b \}\\n \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H5 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b \\\\paragraph\{ \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b \}\\n \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H6 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b \\\\subparagraph\{ \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b \}\\n \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b QT \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b \\\\begin\{quote\} \b0 \\n");\ tags[i]. \b end \b0 = NXUniqueString(" \b \\\\end\{quote\} \b0 \\n");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 = \b NULL \b0 ; tags[i]. \b start \b0 = tags[i]. \b end \b0 = \b NULL \b0 ;\ \ // \i PHASE III: Collect Annotations\ \i0 sprintf( \b LaTeXfile \b0 , " \b %s/%s.tex \b0 ", \b thePath \b0 , [theDocInfo \b docTitle \b0 ]);\ \b s \b0 = \b NXOpenMemory \b0 (NULL, 0, NX_WRITEONLY);\ \b NXPrintf \b0 (s," \b \\\\documentstyle[times,epsf]\{article\}\\n\\\\begin\{document\}\\n \b0 ");\ [ \b theDocInfo \b0 \b writeLaTeXHeader \b0 :s];\ [[docUI \b eTextObj \b0 ] \b writeLaTeX \b0 :s \b withTags \b0 : \b tags \b0 ];\ \b NXPrintf \b0 (s," \b \\n\\\\end\{document\}\\n \b0 ");\ \b NXSaveToFile \b0 (s, \b LaTeXfile \b0 );\ \b NXCloseMemory \b0 (s, \b NX_FREEBUFFER \b0 );\ \ // \i PHASE IV: Notifications \i0 \ \{ int count;\ count = [ \b notificationList \b0 count];\ while (count--)\ if([[notificationList objectAt:count]\ \b respondsTo \b0 :@selector( \b writeComponentToPath:inFormat: \b0 )])\ [[notificationList objectAt:count]\ \b writeComponentToPath \b0 : \b thePath \b0 \b inFormat \b0 : \b TeXD_FMT \b0 ];\ \}\ \ // \i PHASE V: Garbage Collection \i0 \ // \i Iterate through the directory, deleting bastard objects \i0 \ [self \b registerComponent \b0 :NXUniqueString( \b rindex \b0 ( \b LaTeXfile \b0 , ' \b / \b0 ') \b +1 \b0 )];\ [self \b registerComponent \b0 :NXUniqueString(" \b . \b0 ")];\ [self \b registerComponent \b0 :NXUniqueString(" \b .. \b0 ")];\ dirp = \b opendir \b0 ( \b thePath \b0 );\ dp = readdir(dirp); \ while (dp != NULL) \{\ if (![ \b componentTable \b0 \b isKey \b0 :NXUniqueString( \b dp->d_name \b0 )]) \{\ sprintf(LaTeXfile, " \b %s/%s \b0 ", \b thePath \b0 , \b dp->d_name \b0 );\ \b removeFile \b0 (LaTeXfile);\ \}\ dp = readdir(dirp);\ \}\ closedir(dirp);\ [ \b componentTable \b0 \b empty \b0 ];\ return self;\ \}\ - \b saveHTMD \b0 :(const char *) thePath\ \{\ char \b HTMLfile \b0 [MAXPATHLEN];\ int i;\ struct stat st;\ DIR *dirp;\ struct direct *dp;\ NXStream * \b s \b0 ;\ taggingInfo \b tags \b0 [8];\ \ // \i PHASE I: Prepare thePath \i0 \ if ( \b stat \b0 ( \b thePath \b0 , &st) || (((st. \b st_mode \b0 & S_IFMT) \b != \b0 \b S_IFDIR \b0 )))\{\ \b removeFile \b0 ( \b thePath \b0 );\ if ( \b mkdir \b0 ( \b thePath \b0 , 0777)) \{\ NXLogError(" \b Could not mkdir( \b0 \\"%s\\" \b ) \b0 ", \b thePath \b0 );\ perror("eText5");\ \b NXBeep \b0 ();\ return nil;\ \}\ \}\ [ \b componentTable \b0 \b empty \b0 ];\ \ // \i PHASE II: Prepare taggingInfo \i0 \ i=0; // \i is incremented to compact out undefined tagging fonts \i0 \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H1 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b <H1> \b0 "); // \i use \{book\} with \\chapter \i0 \ tags[i]. \b end \b0 = NXUniqueString(" \b </H1> \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H2 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b <H2> \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b </H2> \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H3 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b <H3> \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b </H3> \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H4 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b <H4> \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b </H4> \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H5 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b <H5> \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b </H5> \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b H6 \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b <H6> \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b </H6> \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 =[theDocInfo \b tagFont \b0 : \b QT \b0 ];\ tags[i]. \b start \b0 = NXUniqueString(" \b <BLOCKQUOTE> \b0 ");\ tags[i]. \b end \b0 = NXUniqueString(" \b </BLOCKQUOTE> \b0 ");\ if (tags[i].font) i++;\ \ tags[i]. \b font \b0 = \b NULL \b0 ; tags[i]. \b start \b0 = tags[i]. \b end \b0 = \b NULL \b0 ;\ \ // \i PHASE III: Collect Annotations\ \i0 sprintf( \b HTMLfile \b0 , " \b %s/ \b0 " \b HTML_INDEX \b0 , \b thePath \b0 );\ \b s \b0 = \b NXOpenMemory \b0 (NULL, 0, NX_WRITEONLY);\ NXPrintf(s," \b <HTML>\\n \b0 ");\ [theDocInfo \b writeHTMLHeader \b0 :s];\ NXPrintf(s," \b \\n<BODY>\\n \b0 ");\ [[docUI \b eTextObj \b0 ] \b writeHTML \b0 : \b s \b0 \b withTags \b0 : \b tags \b0 ];\ [theDocInfo \b writeHTMLTrailer \b0 : \b s \b0 ];\ NXPrintf(s," \b \\n</BODY>\\n</HTML>\\n \b0 ");\ \b NXSaveToFile \b0 (s, \b HTMLfile \b0 );\ \b NXCloseMemory \b0 (s, \b NX_FREEBUFFER \b0 );\ \ // \i PHASE IV: Notifications \i0 \ \{ int count;\ count = [ \b notificationList \b0 count];\ while (count--)\ if([[notificationList objectAt:count]\ \b respondsTo \b0 :@selector( \b writeComponentToPath:inFormat: \b0 )])\ [[notificationList objectAt:count]\ \b writeComponentToPath \b0 : \b thePath \b0 \b inFormat \b0 : \b HTMD_FMT \b0 ];\ \}\ \ // \i PHASE V: Garbage Collection \i0 \ // \i Iterate through the directory, deleting bastard objects \i0 \ [self \b registerComponent \b0 :NXUniqueString( \b HTML_INDEX \b0 )];\ [self \b registerComponent \b0 :NXUniqueString(" \b . \b0 ")];\ [self \b registerComponent \b0 :NXUniqueString(" \b .. \b0 ")];\ dirp = \b opendir \b0 ( \b thePath \b0 );\ dp = readdir(dirp); \ while (dp != NULL) \{\ if (![ \b componentTable \b0 \b isKey \b0 :NXUniqueString( \b dp->d_name \b0 )]) \{\ sprintf(HTMLfile, " \b %s/%s \b0 ", \b thePath \b0 , \b dp->d_name \b0 );\ \b removeFile \b0 (HTMLfile);\ \}\ dp = readdir(dirp);\ \}\ closedir(dirp);\ [ \b componentTable \b0 \b empty \b0 ];\ return self;\ \}\ - \b saveETFD \b0 :(const char *) thePath \b changePath \b0 :( \b BOOL \b0 ) changeIt\ \{\ NXAtom oldPath;\ char ETFfile[MAXPATHLEN];\ struct stat st;\ DIR *dirp;\ struct direct *dp;\ \ // \i PHASE I: Prepare thePath \i0 \ if ( \b stat \b0 ( \b thePath \b0 , &st) || (((st. \b st_mode \b0 & S_IFMT) \b != \b0 \b S_IFDIR \b0 )))\{\ \b removeFile \b0 ( \b thePath \b0 );\ if ( \b mkdir \b0 ( \b thePath \b0 , 0777)) \{\ NXLogError(" \b Could not mkdir( \b0 \\"%s\\" \b ) \b0 ", \b thePath \b0 );\ perror("eText5");\ \b NXBeep \b0 ();\ return nil;\ \}\ \}\ [ \b componentTable \b0 \b empty \b0 ];\ \ \b oldPath \b0 =[theDocInfo \b docPath \b0 ];\ [theDocInfo \b setDocPath \b0 : \b thePath \b0 ]; // \i this confuses saveTo: \i0 \ \ // \i PHASE II: Collect Annotations\ \i0 sprintf( \b ETFfile \b0 , " \b %s/TXT.rtf \b0 ", \b thePath \b0 );\ [[docUI \b eTextObj \b0 ] \b writeETFtoPath \b0 : \b ETFfile \b0 ];\ \ // \i PHASE III: Notifications \i0 \ \{ int count;\ count = [ \b notificationList \b0 count];\ while (count--)\ if([[notificationList objectAt:count]\ \b respondsTo \b0 :@selector( \b writeComponentToPath:inFormat: \b0 )])\ [[notificationList objectAt:count]\ \b writeComponentToPath \b0 : \b thePath \b0 \b inFormat \b0 : \b ETFD_FMT \b0 ];\ \}\ \ // \i PHASE IV: Garbage Collection \i0 \ // \i Iterate through the directory, deleting bastard objects \i0 \ [self \b registerComponent \b0 :NXUniqueString(" \b TXT.rtf \b0 ")];\ [self \b registerComponent \b0 :NXUniqueString(" \b . \b0 ")];\ [self \b registerComponent \b0 :NXUniqueString(" \b .. \b0 ")];\ dirp = \b opendir \b0 ( \b thePath \b0 );\ dp = readdir(dirp); \ while (dp != NULL) \{\ if (![ \b componentTable \b0 \b isKey \b0 :NXUniqueString( \b dp->d_name \b0 )]) \{\ sprintf(ETFfile, " \b %s/%s \b0 ", \b thePath \b0 , \b dp->d_name \b0 );\ \b removeFile \b0 (ETFfile);\ \}\ dp = readdir(dirp);\ \}\ closedir(dirp);\ [ \b componentTable \b0 \b empty \b0 ];\ if (! \b changeIt \b0 ) [ \b theDocInfo \b0 \b setDocPath \b0 : \b oldPath \b0 ];\ return self;\ \}\ \ //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \b <DocNotification> Registration & Callbacks \b0 \ //\ - \b registerNotification \b0 :theListener \{\ [notificationList \b addObjectIfAbsent \b0 :theListener]; return self;\}\ - \b unregisterNotification \b0 :theListener \{\ [notificationList \b removeObject \b0 :theListener]; return self;\}\ - \b registerComponent \b0 :(NXAtom)component \{\ [componentTable \b insertKey \b0 :NXUniqueString( \b component \b0 ) \b value \b0 : \b nil \b0 ];\ return self;\}\ \ //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\ // \b Accessors & API \b0 \ //\ - (UndoManager *) \b undoManager \b0 \{\ return \b undoManager \b0 ;\}\ - (eTDocInfo *) \b docInfo \b0 \{\ return \b theDocInfo \b0 ;\}\ - (eTDocUI *) \b docUI \b0 \{ // \i Private\ \i0 return \b docUI \b0 ;\}\ \ - \b touch \b0 \{\ return [ \b docUI \b0 \b touch \b0 ];\}\ - ( \b BOOL \b0 ) \b needsSaving \b0 \{\ return [ \b docUI \b0 \b needsSaving \b0 ];\}\ \ - ( \b BOOL \b0 ) \b acceptsAnnotation \b0 \{\ \b NXSelPt \b0 \b a \b0 , \b b \b0 ;\ \ [[docUI \b eTextObj \b0 ] \b getSel \b0 :& \b a \b0 :& \b b \b0 ];\ return (( \b a.cp \b0 \b >= 0 \b0 ) && [[docUI \b eTextObj \b0 ] \b isEditable \b0 ]);\}\ - \b insertAnnotation \b0 :theAnnotation \{\ return [[docUI \b eTextObj \b0 ] \b insertAnnotation \b0 :theAnnotation];\}\ \ - ( \b BOOL \b0 ) \b acceptsAgent \b0 \{\ return \b theAgent \b0 ? \b NO \b0 : \b YES \b0 ;\}\ - \b attachAgent \b0 :newAgent \{\ if (![ \b newAgent \b0 \b conformsTo \b0 :@protocol( \b Agent \b0 )]) return \b nil \b0 ;\ \b theAgent \b0 = \b newAgent \b0 ;\ [theDocInfo \b setAgent \b0 :NXUniqueString([ \b theAgent \b0 \b name \b0 ])];\ return [ \b docUI \b0 \b attachAgent \b0 :theAgent];\}\ - \b detachAgent \b0 \{\ [ \b theDocInfo \b0 \b setAgent \b0 :NXUniqueString("")];\ [ \b docUI \b0 \b detachAgent \b0 ];\ \b theAgent \b0 = \b nil \b0 ;\ return self;\ \}\ \ - \b selectedObj \b0 \{\ return \b selectedObj \b0 ;\}\ - \b setSelectedObj \b0 :it \{\ selectedObj = \b it \b0 ; \ return self;\}\ - \b makeVisible \b0 \{\ [[docUI \b window \b0 ] \b makeKeyAndOrderFront \b0 :self]; \ return self;\}\ - \b inspect \b0 \{\ selectedObj = \b theDocInfo \b0 ;\ return [ \b inspector \b0 \b inspect \b0 : \b selectedObj \b0 ];\}\ \ \i @end }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.