This is rtfController.m in view mode; [Download] [Up]
/***********************************************************************\ controller class for Convert RTF which converts between Mac and NeXT rtf formats. Copyright (C) 1993 David John Burrowes This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author, David John Burrowes, can be reached at: davidjohn@kira.net.netcom.com David John Burrowes 1926 Ivy #10 San Mateo, CA 94403-1367 \***********************************************************************/ /* ==================================================================== This is $Revision: 1.8 $ of this file It was last modified by $Author: death $ on $Date: 93/04/04 23:28:27 $ Note that this file was created while using the New Century Schoolbook Roman typeface. You may find that some things line up strangely if you don't use that family. $Log: rtfController.m,v $ Revision 1.8 93/04/04 23:28:27 death Sun Apr 4 23:28:27 PDT 1993 Revision 1.7 93/02/21 12:00:05 death Sun Feb 21 12:00:05 PST 1993 Revision 1.6 93/01/10 08:27:28 death Sun Jan 10 08:27:28 PST 1993 Revision 1.5 93/01/02 23:41:36 death Sat Jan 2 23:41:36 PST 1993 Revision 1.4 93/01/02 13:39:06 death Sat Jan 2 13:39:06 PST 1993 Revision 1.3 92/12/25 16:26:51 death Fri Dec 25 16:26:51 PST 1992 Revision 1.2 92/12/21 07:01:18 death Mon Dec 21 07:01:18 PST 1992 Revision 1.1 92/12/19 08:19:11 death Sat Dec 19 08:19:10 PST 1992 ==================================================================== */ #import "rtfController.h" #import "rtfFile.h" #import "rtfConverter.h" #import <appkit/Matrix.h> // For matrix stuff for preferences setting #import <libc.h> // for mkdir and rmdir #import <string.h> // for strrchr #import <appkit/Listener.h> // for the drag-and-drop of files facility #import <appkit/Speaker.h> // ibid #import <appkit/Application.h> // To get NXApp (I thought that is what defaults was...) #import <errno.h> // for errno. #import "djbflag.h" @implementation rtfController ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: init // Parameters: none // Returns: self // Stores: none // Description: // This overrides the defalut init method. and sets up some strings used during // some of the user interaction. time. We also create the pict converter instance // needed later. // Bugs: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - init { static NXDefaultsVector theDefaults = { {CONVERTTYPE, "YES"}, {REMOVEUNDERLINE, "NO"}, {CONVERTTEXT, "ALL"}, {CONVERTQUOTES, "NO"}, {CONVERTPICTS, "YES"}, {DELETEPICTS, "YES"}, {NULL, NULL} }; CString tempPref; [super init]; DefaultsOwner = "RTFConverter"; NXRegisterDefaults(DefaultsOwner, theDefaults); convertMacRTF = [self GetBoolPref: CONVERTTYPE]; StripFirstUL0 = [self GetBoolPref: REMOVEUNDERLINE]; // // 93.02.15 djb Changed from a boolean(yes/no) to a string parameter to support // doing no conversion whatsoever. Checks for yes and no for // backward compatability. =) // tempPref = [self GetPref: CONVERTTEXT]; if ((strcmp(tempPref, "ALL") == 0) || (strcmp(tempPref,"YES") == 0)) ConvertAllFonts = ConvertAll; else if ((strcmp(tempPref, "STANDARD") == 0)|| (strcmp(tempPref,"NO") == 0)) ConvertAllFonts = ConvertStandard; else if (strcmp(tempPref, "NONE") == 0) ConvertAllFonts = ConvertNone; FreeCString(tempPref); ConvertSingleQuotes = [self GetBoolPref: CONVERTQUOTES]; ConvertPictData = [self GetBoolPref: CONVERTPICTS]; DeletePictData = [self GetBoolPref: DELETEPICTS]; if (convertMacRTF == YES) { ConversionString = "Converting Mac rtf to NeXT rtf"; SourcePrompt = "Mac file:"; DestPrompt = "NeXT file:"; if (ForDavidJohnBurrowesOnly == 1) DestExtension = ".mac.rtf"; else DestExtension = ".next.rtf"; } else { ConversionString = "Converting NeXT rtf to Mac rtf"; SourcePrompt = "NeXT file:"; DestPrompt = "Mac file:"; if (ForDavidJohnBurrowesOnly == 1) DestExtension = ".next.rtf"; else DestExtension = ".mac.rtf"; } MenuOpen = NO; converterInst = [[rtfConverter alloc] init]; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: free // Parameters: none // Returns: ? // Stores: none // Description: // This cleans up before being deallocated. (derezed, in tron terms, I suppose). // Bugs: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - free { if (converterInst != NullInstance) [converterInst free]; return [super free]; } // // Added this because the free method is apparently not being called, and we // need to kill the converter instance so it can kill the pict converter (so much for // modularity, eh? thank you NeXT/Interface Builder (or maybe my stupidity) // - appWillTerminate: sender { if (converterInst != NullInstance) [converterInst free]; converterInst = NullInstance; return [super appWillTerminate: sender]; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: displayPreferences: // Parameters: the object that called us // Returns: self // Stores: none // This is called whenever we need to bring the preferences panel onto the screen. // Using the value in our several preferences variables, we set the buttons in // the preferences panel to reflect the current values, and then shows the panel. // Bugs: // As pointed out elsewhere, we don't really need to do this after the first time, // since the buttons keep their own state. So my frakework needs revising!! ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -displayPreferences: target { // // Get the default preference values, and compare judge what buttons to // highlight for the user. // if (convertMacRTF == YES) [MacSourceButton selectCellWithTag: 1]; else [MacSourceButton selectCellWithTag: 0]; if (StripFirstUL0 == YES) [RemoveUnderlineButton setIntValue: 1]; else [RemoveUnderlineButton setIntValue: 0]; // // 93.02.15 djb Added support for three types of conversion, rather than 2 // if (ConvertAllFonts == ConvertAll) [ConvertAllFontsButton selectCellWithTag: 0]; else if (ConvertAllFonts == ConvertStandard) [ConvertAllFontsButton selectCellWithTag: 1]; else [ConvertAllFontsButton selectCellWithTag: 2]; if (ConvertSingleQuotes == YES) [ConvertSingleQuotesButton selectCellWithTag: 1]; else [ConvertSingleQuotesButton selectCellWithTag: 0]; if (ConvertPictData == YES) [ConvertPictButton selectCellWithTag: 0]; else [ConvertPictButton selectCellWithTag: 1]; if (DeletePictData == YES) [DeletePictDataButton selectCellWithTag: 0]; else [DeletePictDataButton selectCellWithTag: 1]; [prefPanel makeKeyAndOrderFront:self]; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: ChangeConvertSource: // Parameters: the object that called us // Returns: self; // Description: // Specifies whether the source is a Mac or a NeXT rtf file. This is relevant when // dealing with drag-and-drop or double clicked files where it is otherwise ambiguous. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -ChangeConvertSource: sender { if ( [[sender selectedCell] tag] == 1) { convertMacRTF = YES; ConversionString = "Converting Mac rtf to NeXT rtf"; SourcePrompt = "Mac file:"; DestPrompt = "NeXT file:"; if (ForDavidJohnBurrowesOnly == 1) DestExtension = ".mac.rtf"; else DestExtension = ".next.rtf"; } else { convertMacRTF = NO; ConversionString = "Converting NeXT rtf to Mac rtf"; SourcePrompt = "NeXT file:"; DestPrompt = "Mac file:"; if (ForDavidJohnBurrowesOnly == 1) DestExtension = ".next.rtf"; else DestExtension = ".mac.rtf"; } [self SetBoolPref: CONVERTTYPE To: convertMacRTF]; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: SetUnderlineRemoval: // Parameters: the object that called us // Returns: self // Description: // Sets the boolean preference that indicates whether or not we should remove // the first \ul0 in a NeXT rtf file. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SetUnderlineRemoval: sender { if ( [sender intValue] == 1) StripFirstUL0 = YES; else StripFirstUL0 = NO; [self SetBoolPref: REMOVEUNDERLINE To: StripFirstUL0]; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: SetFontConversion: // Parameters: the object that called us // Returns: self // Description: // Sets the preference that indicates whether or not we should convert // text in all fonts, or in the standard fonts, or in none at all. // History // 93.02.15 djb Added suport for three types of conversion, rather than two. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SetFontConversion: sender { if ( [[sender selectedCell] tag] == 0) { ConvertAllFonts = ConvertAll; [self SetPref: CONVERTTEXT To: "ALL"]; } else if ( [[sender selectedCell] tag] == 1) { ConvertAllFonts = ConvertStandard; [self SetPref: CONVERTTEXT To: "STANDARD"]; } else { ConvertAllFonts = ConvertNone; [self SetPref: CONVERTTEXT To: "NONE"]; } return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: SetSingleQuoteChange: // Parameters: the object that called us // Returns: self // Description: // Sets the boolean preference that indicates whether or not we should produce // MacStyle single quotes ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SetSingleQuoteChange: sender { if ( [[sender selectedCell] tag] == 1) ConvertSingleQuotes = YES; else ConvertSingleQuotes = NO; [self SetBoolPref: CONVERTQUOTES To: ConvertSingleQuotes]; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: SetPictDataDeletion: // Parameters: the object that called us // Returns: self // Description: // Sets the boolean preference that indicates what we should do with PICT data // found in the rtf file. If the value is YES, then we wish to delete the data entirely // If it is NO, then we store the pict data in another file ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SetPictDataDeletion: sender { if ( [[sender selectedCell] tag] == 0) DeletePictData = YES; else DeletePictData = NO; [self SetBoolPref: DELETEPICTS To: DeletePictData]; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: SetPictConversion: // Parameters: the object that called us // Returns: self // Description: // Sets the boolean preference that indicates whether we should try to do a // conversion of any pictures we find in the rtf file. If the value is YES, then // we will convert the pictures, otherwise we won't. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SetPictConversion: sender { if ( [[sender selectedCell] tag] == 0) ConvertPictData = YES; else ConvertPictData = NO; [self SetBoolPref: CONVERTPICTS To: ConvertPictData]; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: PrepareForNeXTConversion: // Parameters: the object that called us // Returns: self // Description: // If the user chooses to convert a NeXT file via the menus, this routine is // called first, so we can set up the right conversion options. // Note that we store ptrs to all the strings used by the user interface stuff, // and substitute ones for this routine, and then restore later. This is because // the default strings are all about what happens when one drags and drops // files, wheras this is when someone chooses a menu item. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - PrepareForNeXTConversion: sender { CString tempString = ConversionString; CString sourceString = SourcePrompt; CString destString = DestPrompt; CString extenString = DestExtension; ConversionString = "Converting NeXT rtf to Mac rtf"; SourcePrompt = "NeXT file:"; DestPrompt = "Mac file:"; if (ForDavidJohnBurrowesOnly == 1) DestExtension = ".next.rtf"; else DestExtension = ".mac.rtf"; [converterInst SetConversionDirection: NO]; MenuOpen = YES; [self PrepareForConversion: self]; ConversionString = tempString; SourcePrompt = sourceString; DestPrompt = destString; DestExtension = extenString; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: PrepareForMacConversion: // Parameters: the object that called us // Returns: self // Description: // If the user chooses to convert a Mac file via the menus, this routine is // called first, so we can set up the right conversion options. // Note that we store ptrs to all the strings used by the user interface stuff, // and substitute ones for this routine, and then restore later. This is because // the default strings are all about what happens when one drags and drops // files, wheras this is when someone chooses a menu item. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - PrepareForMacConversion: sender { CString tempString = ConversionString; CString sourceString = SourcePrompt; CString destString = DestPrompt; CString extenString = DestExtension; ConversionString = "Converting Mac rtf to NeXT rtf"; SourcePrompt = "Mac file:"; DestPrompt = "NeXT file:"; if (ForDavidJohnBurrowesOnly == 1) DestExtension = ".mac.rtf"; else DestExtension = ".next.rtf"; [converterInst SetConversionDirection: YES]; MenuOpen = YES; [self PrepareForConversion: self]; ConversionString = tempString; SourcePrompt = sourceString; DestPrompt = destString; DestExtension = extenString; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: openSourceFile: // Parameters: the name of the file we are to open // Returns: the new file object // Stores: error // Description: // This simply attempts to open the source file. If we are successfull, we // return it to the caller, otherwise we return an error. // Bugs: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - openSourceFile: (roCString) theFile { Instance fileInstance; [self ResetResults]; fileInstance = [[rtfFile alloc] initAndUse: theFile]; if ([fileInstance GetErrorCode] == ERR_OK) [fileInstance OpenExistingFor: FILE_READ]; if ([fileInstance GetErrorCode] != ERR_OK) { [self StoreErrorCode: ERR_CANTOPEN AndText: "Unable to open that file."]; [fileInstance free]; fileInstance = NullInstance; } return fileInstance; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: openDestFile: // Parameters: the name of the file we are to open // Returns: the new file object // Stores: error // Description: // This simply attempts to open the destination file. If we are successfull, we // return it to the caller, otherwise we return an error. // Bugs: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - openDestFile: (roCString) theFile { Instance fileInstance; [self ResetResults]; fileInstance = [[rtfFile alloc] initAndUse: theFile]; if ([fileInstance GetErrorCode] == ERR_OK) [fileInstance ClearAndOpenFor: FILE_WRITE]; if ([fileInstance GetErrorCode] != ERR_OK) { [self StoreErrorCode: ERR_CREATEFAILED AndText: "We were not able to create and/or open that file"]; [fileInstance free]; fileInstance = NullInstance; } return fileInstance; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: ConvertFrom:To: // Parameters: // The file to be converted from // the file to be converted to // Returns: self // Stores: error // Description: // This asks the super class to do any initalizing it needs to, and then goes // ahead and asks the converter object to go at it. // Bugs ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ConvertFrom: sourceFile To: destinationFile { [self ResetResults]; [super ConvertFrom: sourceFile To: destinationFile]; // // If we were started via a menu selection, then the convert // direction has already been set. Otherwise, we need to set it based on // the default stored in convertMacRTF // if (MenuOpen == NO) [converterInst SetConversionDirection: convertMacRTF]; [converterInst RemoveFirstNeXTUnderline: StripFirstUL0]; [converterInst SetTextConversion: ConvertAllFonts]; [converterInst ConvertTheSingleQuotes: ConvertSingleQuotes]; [converterInst SetPictConversion: ConvertPictData AndDataRemoval: DeletePictData]; [MacConvertCommand setEnabled: NO]; [NeXTConvertCommand setEnabled: NO]; destFileHolder = destinationFile; [converterInst ConvertFrom: sourceFile To: destinationFile]; [MacConvertCommand setEnabled: YES]; [NeXTConvertCommand setEnabled: YES]; MenuOpen = NO; if ( [converterInst GetErrorCode] < ERR_OK) [self StoreErrorCode: [converterInst GetErrorCode] AndText: [converterInst GetErrorText] ]; else [self StoreErrorCode: ERR_OK AndText: "Converted Successfully" ]; return destFileHolder; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: MakeDestAnRTFD // Parameters: none // Returns: self // Stores: error // Description: // This semi-hack routine allows the converter to call us and ask that the destination // file be converted into being an rtfd instead of an rtf file. This involves closeing // the rtf file earlier allocated, and creating a directory and subfile for the rtfd. // It also involves using a definite hack by way of destFileHolder, which allows // us to implicitly change the value that the above routine will return. // Bugs ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - MakeDestAnRTFD { id newFile; CString buffer = NewCString(1024); CString oldPathName; CString rtfdName; CString pathname; Integer result; oldPathName = [destFileHolder GetPathname]; [destFileHolder CloseAndDelete]; // // Create an RTFD folder and file by // 1) getting the name for the rtfd folder (the rtf name + d) // 2) Creating a directory with this name // 3) Create a TXT.rtf file in said directory // rtfdName = NewCString(strlen(oldPathName) + 1); strcat(rtfdName, oldPathName); strcat(rtfdName, "d"); // // 2) Creating a directory with the name of the requested font // errno = 0; result = mkdir(rtfdName, 0700 | 0070 | 0007); // strange perms if (result != 0) { sprintf(buffer, "The rtfd folder could not be created. (mkdir error: %d)", errno); [self StoreErrorCode: ERR_CREATEFAILED AndText:buffer]; rmdir(rtfdName); newFile = NullInstance; } else { // // Allocate space for path to font folder, plus font or font.afm name // pathname = NewCString(strlen(rtfdName) + 1 +7); strcpy(pathname, rtfdName); strcat(pathname, "/TXT.rtf"); // // 3) Create a font file in said directory // newFile = [[rtfFile alloc] initAndUse: pathname]; if ([newFile GetErrorCode] == ERR_OK) [newFile CreateAndOpenFor: FILE_WRITE]; if ([newFile GetErrorCode] != ERR_OK) { [self StoreErrorCode: ERR_CREATEFAILED AndText: "We failed to create the rtf file"]; newFile = NullInstance; rmdir(rtfdName); } FreeCString(pathname); } FreeCString(oldPathName); FreeCString(rtfdName); FreeCString(buffer); destFileHolder = newFile; destIsDead = YES; return newFile; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.