home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.next.bugs
- Path: sparky!uunet!elroy.jpl.nasa.gov!sdd.hp.com!spool.mu.edu!umn.edu!csus.edu!netcom.com!netcomsv!yamanote!gordie
- From: gordie@cyclesoft.com (Gordie Freedman)
- Subject: Bug in subclassed Text object in scrollview? (Long)
- Message-ID: <1992Dec27.201506.8391@netcom.com>
- Keywords: text subclass appkit.555 scrollview font
- Sender: gordie@netcom.com
- Reply-To: gordie@cyclesoft.com
- Organization: Dolphin Software
- Date: Sun, 27 Dec 1992 20:15:06 GMT
- Lines: 396
-
- Hi,
-
- (On a NeXTStation Color (non turbo) running 3.0, 16/400, 21" color monitor.)
-
- I have a problem with subclassing the Text object, and than replacing the Text
- object in a scrollview with my custom subclass, as explained in NeXTanswer
- appkit.555.
-
- For the most part it works as advertised, however if I read ascii into the Text
- object (after setting it to MonoFont:YES), and than try to change the font from
- the Font Panel - the old text (with the old font) is not cleared, and the new
- text (with the new font) is painted over it. Not a pretty sight. As well, I
- have to do some mucking around when reading in a new document into the Text,
- otherwise it does the same thing (paints the new text over the old instead of
- replacing it).
-
- I don't have these problems with the same code/nib keeping the original text
- object.
-
- In the nib, I have a Controller object (which inherits from Object, and doesn't
- really do a whole lot in this example). The controller is the delegate for the
- Application, and there is one window (besides the main menu). The Controller
- has three outlets related to the window, an id for the window itself (set in
- the nib), an id for the scrollview (set in the nib), and an id for the text
- object (set in appDidInit: after getting the new custom Text object). The
- controller is also set to be the delegate of the window from IB, and
- programmatically set to be the delegate of the subclassed Text object.
-
- I don't know if I am doing something wrong here (possibly with font stuff, see
- code example), or if there is a problem with the Text object that this usage
- uncovers.
-
- Here's the code in the implementation of the Controller object:
-
- ------------------------------------------------
-
- #import "Controller.h"
- #import <strings.h>
- #include <sys/types.h>
- #include <sys/uio.h>
- #include <sys/file.h>
-
- //
- // This app illustrates a problem using the code from NeXTAnswers
- // appkit.555 - replacing a Text object in a ScrollView with a custom
- // Text object (in this case a PText object - see below).
- //
-
- // This app is for NeXTSTEP 3.0 using all standard dev tools/etc., and
- // can be built using project builder.
-
- // The Controller is set up as the delegate for the Window with the
- // ScrollView and the Text, and is also set as the delegate for the
- // Application object via IB.
-
- // To see the problem, launch the App, use the Display menu item to
- // display the Text window, than use the Open... menu item to open a file.
- // Select a file that is ascii (not rich text). Bring up the Font panel
- // (Command-t), set focus in the Text in the Text Window, than select
- // a different font from the font panel. The result will be that the
- // old text is left in the window and the new text is painted over it.
-
- // Note that this does not happen with Rich Text, although without the code
- // in [Controller clearText] reading in a new document has similar problems.
-
- // Questions:
- //
- // 1. Why doesn't setting the font from the Font Panel work correctly on
- // non-rich text?
- //
- // 2. Why is the "clearText" method needed when reading in new text?
- //
-
- /*---------------------------------------------------------------------------*/
-
- // This is the subclassed PText - it doesn't do anything now,
- // but would be used to specialize methods such as addToPageSetup
- // When it replaces the standard text object in a ScrollView, modifying
- // the font for a MonoFont document does not work correctly. It paints
- // the new text (with the new font setting) on top of the previous text,
- // rather than replacing the old text. When this program is run without
- // replacing the Text object with the PText, the problems go away.
-
- @interface PText: Text
- {
- }
-
- @end
-
- @implementation PText
-
- - addToPageSetup
- {
- [super addToPageSetup];
-
- return self;
-
- }
-
- @end
-
-
- // Some private methods for the Controller object.
-
- @interface Controller (Private)
-
- - clearText;
- - (BOOL) openTextFile:(const char*) fileName;
- - doit:(const char*) name;
-
- @end
-
- @implementation Controller (Private)
-
- // This method is needed when reading in new text from a stream -
- // Without it, the old text is still present in the window, and
- // the new text is painted over it. This is not needed when a standard
- // Text object is used.
-
- - clearText
- {
- NXRect r;
- [text getFrame:&r];
-
- [text setTextGray:NX_WHITE];
- [text display];
- [text setTextGray:NX_BLACK];
- [text renewRuns:NULL text:"" frame:&r tag:[text tag]];
- return self;
- }
-
- #define BUF_SIZE 5
- #define RTF_SIG "{\\rtf"
- #define NUM_TABS 10
- static char buf[BUF_SIZE];
-
- // Method to open a text file. Checks to see if it is rich text,
- // and if so, sets MonoFont:NO and reads in as such. Otherwise, sets
- // MonoFont:YES and reads in ascii text.
- //
- - (BOOL) openTextFile:(const char*) fileName
- {
- int fd ;
- NXStream *stream ;
-
- fd = open (fileName, O_RDONLY) ;
- if (fd == 0)
- {
- return NO ;
- }
- stream = NXOpenFile (fd, NX_READONLY) ;
- if (stream == 0)
- {
- close (fd) ;
- return NO ;
- }
-
- // read in the beginning of the text to see if rtf. Seek back to
- // the beginning of the file before reading from the stream.
-
- buf [0] = '\0';
- read (fd, buf, BUF_SIZE);
- lseek (fd, 0, L_SET);
- [self clearText];
- if (!strncmp (buf, RTF_SIG, BUF_SIZE))
- {
- [text setMonoFont:NO];
- [text readRichText:stream];
- }
- else
- {
- [text setMonoFont:YES];
- [text readText:stream];
- // Set whatever font the user last selected in Font Panel
- // [text setFont:font];
- }
- NXClose (stream);
- close (fd);
- return YES;
- }
-
- //
- // Method to find out if the text file is rtfd or not. Gets the
- // text into the PText object via openTextFile (if not rtfd), or
- // openRTFDFrom (if rtfd).
- //
- - doit:(const char*) name
- {
- id newFont;
- const char* type;
- NXSize oldSize;
-
- // Save the old size to see if the paper size changes
- oldSize.width = pageSize.width;
- oldSize.height = pageSize.height;
-
- if ((!name) || (*name == '\0'))
- {
- return nil;
- }
-
- // Get whatever font is in the font panel, free previous
- // font if not the same ...
- newFont = [fontPanel panelConvertFont:font];
- if (font != newFont)
- {
- [font free];
- font = newFont;
- }
-
- // Get the type of the file
- if ((type = rindex (name, '.')) == NULL)
- {
- type = "";
- }
- else
- {
- type ++;
- }
- if (!strcmp (type, "rtfd"))
- {
- [text setMonoFont:NO];
- [self clearText];
- if ([text openRTFDFrom:name] != NX_RTFDErrorNone)
- {
- return nil;
- }
- }
- else
- {
- if ([self openTextFile:name] == NO)
- {
- return nil;
- }
- }
-
- // If the paper size changed, resize the window
- if (pageSize.width != oldSize.width)
- {
- NXSize size;
- [scrollView getContentSize:&size];
- [textWindow sizeWindow:pageSize.width+NX_SCROLLERWIDTH
- :size.height];
- }
- // Set the window title and return
- [textWindow setTitle:name];
- return self;
- }
-
- @end
-
- @implementation Controller
-
- //
- // appDidInit - gets size from old text object, and sets up
- // new PText object in its place in the scrollview. Makes the
- // Controller the delegate of the PText to get the textDidRead msg.
- //
- - appDidInit:sender
- {
- id stdText;
- NXRect r;
-
- // Get a font opanel and an initial font
- fontPanel = [FontPanel new];
- font = [Font newFont:"Helvetica" size:12.0];
-
- // Straight out of appkit.555, only the names were
- // changed to protect the innocent
-
- // If this code is skipped, everything works as advertised ...
- // If skipping it, have to do:
- // [text setDelegate:self];
-
- stdText = [scrollView docView];
- [stdText getFrame:&r];
-
- [scrollView setVertScrollerRequired:YES];
- [scrollView setHorizScrollerRequired:NO];
- [scrollView setDynamicScrolling:YES];
-
- text = [[PText alloc] initFrame:&r];
- [text moveTo:0.0:0.0];
- [text notifyAncestorWhenFrameChanged: YES];
- [text setVertResizable:YES];
- [text setSelectable:YES];
- [text setEditable: YES];
- [text setAutosizing:NX_WIDTHSIZABLE];
- [text setMinSize:&r.size];
- r.size.height = 1.0e30;
- [text setMaxSize:&r.size];
- [scrollView setDocView:text];
- [stdText free];
-
- // Set oursleves as the delegate for the new PText object
- [text setDelegate:self];
-
- return self;
- }
-
-
- // Invoked in response to user selecting Display menu item
- // Displays the window with text in it.
- - showText:sender
- {
-
- [textWindow makeKeyAndOrderFront:self];
- return self;
- }
-
- // Window delegate method for the text window, invoked when
- // the window resizes. Saves the new size
- - windowDidResize:sender
- {
- NXSize size;
- [scrollView getContentSize:&size];
- pageSize.width = size.width;
- pageSize.height = size.height;
- return self;
- }
-
- // PText delegate method invoked when reading an rtf stream
- // and the papersize directives are read. Saves the size for later.
- - textDidRead:sender paperSize:(NXSize*) psize
- {
- pageSize.width = psize->width;
- pageSize.height = psize->height;
- return self;
- }
-
- // Private routine to make a full path name out of dir and file name
- static char*
- makeFileName (const char* const file, const char* const dir)
- {
- char* name ;
- name = calloc (strlen (dir) + strlen (file) + 2, 1) ;
- strcpy (name, dir) ;
- strcat (name, "/") ;
- strcat (name, file) ;
- return name ;
- }
-
- // Method invoked in reponse to user selecting "Open..." menu item.
- // Displays the standard open panel, and opens files selected.
- const char* typeList[] = { NULL };
-
- - openFile:sender
- {
- OpenPanel* op ;
- const char* const* filenames ;
- const char* directory ;
- char* name ;
- int rc;
-
- op = [OpenPanel new] ;
- [op allowMultipleFiles:YES] ;
- rc = [op runModalForTypes:typeList] ;
-
- if (rc == NX_CANCELTAG)
- {
- return self;
- }
- filenames = [op filenames] ;
- directory = [op directory] ;
-
- if ((! directory) || (! filenames))
- {
- return self;
- }
-
- while (*filenames)
- {
- name = makeFileName (*filenames, directory);
- [self doit:name];
- free (name);
- filenames++;
- }
- return self;
- }
-
- @end
-
- ----------------------------
-
- I can supply the .nib as well, I didn't want to make the post too huge, and
- hopefully the description is enough to recreate the problem. I have a full
- project (around 25KBytes uncompiled) that illustrates this problem. I can
- NeXTMail it if this post does not give enough of a description to recreate, and
- anyone would like to explore this further.
-
- Thanks,
-
- Gordie Freedman
- --
- Gordie Freedman gordie@cyclesoft.com -> NextMail encouraged
-
-