sz@cci632.cci.com (Stephen Zehl) (05/25/91)
- I'm looking for a little help with scrolling lists under OpenWindows (XView). I'm using DevGuide to generate C code stubs of scrolling lists, I'm having trouble getting the information into the lists. Volume Seven of the XView Programming Manual gives two examples of how to hard code these choices into the code on pages 155 and 157. As shown below: xv_create(panel, PANEL_LIST, PANEL_LIST_STRINGS, "One", "Two", "Three", NULL, NULL); This is fine if you know what you want in the list ahead of time, but what if you want to read in a list of files from a directory? I figured I could just substitute a pointer to an array of strings in place of the strings themselves as shown below: static char *mylist[3] = { "One", "Two", "Three" }; xv_create(panel, PANEL_LIST, PANEL_LIST_STRINGS, *mylist, NULL, NULL); This will give me the first string in the list, but not the rest. And if I tack the NULL onto the list itself and remove it from after *mylist, I get a segmentation fault and a core in my lap. If anyone out there has worked on this, Please, Please send me some e-mail with an explaination of how you did this. I'd really appreciate it. Thanks again, Steve. CCCC CCCC IIII Stephen Zehl Internet: sz@cci.com CC CC II Computer Consoles. Inc. Usenet: uupsi!cci632!sz CC CC II Rochester, New York. or : uunet!ccicpg!cci632!sz CCCC CCCC IIII DISCLAIMER: I speak for myself, not for my employer.
brentb@montagne.Eng.Sun.COM (Brent Browning) (05/28/91)
In article <1991May24.211132.10282@cci632.cci.com> sz@cci632.cci.com (Stephen Zehl) writes: > This is fine if you know what you want in the list ahead of time, but >what if you want to read in a list of files from a directory? I figured I >could just substitute a pointer to an array of strings in place of the >strings themselves as shown below: > > static char *mylist[3] = { "One", "Two", "Three" }; PANEL_LIST_STRINGS must *really* have a NULL terminated list of strings, *not* a char ** pointing at a NULL terminated list of strings. I've included a sample program that does just what you need to do. Type in a filename, then hit the load button. It will load that file into the scrolling list. Hitting the save button saves it out to a file. This particular example was written for someone else. It also saves the contents of the scrolling list when the application is quit from the window menu. Brent Browning Internet: brentb@Eng.Sun.COM Sun Microsystems, Inc UUCP: ...!sun!brentb 2550 Garcia Ave. MTV 01-40 Phone: (415) 336-5573 Mountain View, CA 94043 --------8<--------8<---- Cut here ----8<--------8<-------- #include <stdio.h> #include <sys/param.h> #include <sys/types.h> #include <xview/xview.h> #include <xview/panel.h> void load_file(); void save_file(); void load_list_from_file(); void save_list_to_file(); Notify_value destroy_func(); Xv_opaque File_name; Xv_opaque File_list; main(argc, argv) int argc; char **argv; { Xv_opaque frame; Xv_opaque panel; xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL); frame = xv_create(NULL, FRAME, NULL); notify_interpose_destroy_func(frame, destroy_func); panel = xv_create(frame, PANEL, PANEL_LAYOUT, PANEL_VERTICAL, NULL); File_name = xv_create(panel, PANEL_TEXT, PANEL_VALUE_DISPLAY_LENGTH, 30, PANEL_VALUE_STORED_LENGTH, 80, PANEL_LABEL_STRING, "File:", PANEL_VALUE, "TEST", NULL); File_list = xv_create(panel, PANEL_LIST, PANEL_LIST_WIDTH, 250, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, FALSE, NULL); xv_set(panel, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL); xv_create(panel, PANEL_BUTTON, PANEL_NEXT_ROW, -1, PANEL_LABEL_STRING, "Load From File", PANEL_NOTIFY_PROC, load_file, NULL); xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Save To File", PANEL_NOTIFY_PROC, save_file, NULL); window_fit(panel); window_fit(frame); xv_main_loop(frame); } void load_file(item, event) Panel_item item; Event *event; { load_list_from_file(); } void save_file(item, event) Panel_item item; Event *event; { save_list_to_file(); } Notify_value destroy_func(frame, status) Frame frame; Destroy_status status; { if (status == DESTROY_CLEANUP) save_list_to_file(); return notify_next_destroy_func(frame, status); } void load_list_from_file() { int i = 0; FILE *fp; char buf[MAXPATHLEN]; char *file = (char *)xv_get(File_name, PANEL_VALUE); if ((fp = fopen(file, "r")) == NULL) { perror(file); return; } for (i = 0; fgets(buf, MAXPATHLEN, fp); i++) { buf[strlen(buf)-1] = '\0'; xv_set(File_list, PANEL_LIST_INSERT, i, PANEL_LIST_STRING, i, buf, NULL); } fclose(fp); } void save_list_to_file() { int i; int n; FILE *fp; char *file = (char *)xv_get(File_name, PANEL_VALUE); if ((fp = fopen(file, "w")) == NULL) { perror(file); return; } n = xv_get(File_list, PANEL_LIST_NROWS); for (i = 0; i < n; i++) { fprintf(fp, "%s\n", (char *)xv_get(File_list, PANEL_LIST_STRING, i)); } fclose(fp); } -- Brent Browning Internet: brentb@Eng.Sun.COM Sun Microsystems, Inc UUCP: ...!sun!brentb 2550 Garcia Ave. MTV 01-40 Phone: (415) 336-5573 Mountain View, CA 94043
nicolas@bmsr9.usc.edu (Nicolas Rouquette) (05/29/91)
In article <14063@exodus.Eng.Sun.COM> brentb@montagne.Eng.Sun.COM (Brent Browning) writes:
I've included a sample program that does just what you
need to do. Type in a filename, then hit the load button. It
will load that file into the scrolling list. Hitting the
save button saves it out to a file.
This particular example was written for someone else. It
also saves the contents of the scrolling list when the application
is quit from the window menu.
Can someone post a an example of code to use PANEL_LIST_INSERT &
PANEL_LIST_DELETE? There are two problems: 1) intense flashing
and 2) after using PANEL_LIST_DELETE in descending order as suggested
in O'Reilly, I get bus errors.
If there is a bug with no practical workaround until OW3, is it safe
to delete the list instance and create a fresh new one?
--
Nicolas Rouquette email: nrouquet@pollux.usc.edu
Computer Science Department
Los Angeles, CA 90089-0782
--
Nicolas Rouquette email: nrouquet@pollux.usc.edu
Computer Science Department
Los Angeles, CA 90089-0782
paccini@uni2a.unige.ch (05/29/91)
In article <NICOLAS.91May28132821@bmsr9.usc.edu>, nicolas@bmsr9.usc.edu (Nicolas Rouquette) writes: > > In article <14063@exodus.Eng.Sun.COM> brentb@montagne.Eng.Sun.COM (Brent Browning) writes: > > Can someone post a an example of code to use PANEL_LIST_INSERT & > PANEL_LIST_DELETE? There are two problems: 1) intense flashing > and 2) after using PANEL_LIST_DELETE in descending order as suggested > in O'Reilly, I get bus errors. A simple way to avoid the flashing is to hide the panel list by using the XV_SHOW attribute: xv_set( panel, XV_SHOW, FALSE, NULL); <delete items...> xv_set( panel, XV_SHOW, TRUE, NULL); This works pretty well with OW 2.0 and gives a very clean behaviour. ------------------------------------------------------------------------------ Jean-Francois Paccini paccini@cui.unige.ch University of Geneva Switzerland
brentb@montagne.Eng.Sun.COM (Brent Browning) (05/30/91)
In article <NICOLAS.91May28132821@bmsr9.usc.edu> you write: > >Can someone post a an example of code to use PANEL_LIST_INSERT & >PANEL_LIST_DELETE? There are two problems: 1) intense flashing >and 2) after using PANEL_LIST_DELETE in descending order as suggested >in O'Reilly, I get bus errors. It sure would have been nice to have some sort of batching for scrolling lists - eh? XView doesn't really provide any support for this. The recommended way to do this is to set XV_SHOW to FALSE on the list, then do the update, the set XV_SHOW to TRUE. There are times that it is faster to just destroy the old list and then recreate it again. If you are using the instance pointers provided by gxv make sure you store the new handle back in the instance pointer. We do our batching as follows. We call a routine "list_add" that stores the string in a large dynamically allocated array. Then when we really want to do the list update we destroy the old list, create a new one (calling ..._list_create), then do the batch update in chunks with attr lists. Here's our function: char **String_list; /* Dynamically allocated array of strings */ /* * Insert internal list into scrolling list in chunks. */ void list_batch_insert(ip) ..._window_objects *ip; { int i = 0; void *attr_array[ATTR_STANDARD_SIZE]; void **attr_ptr; void **attr_end; /* * Destroy old list (faster than delete all entries) then * create a fresh one. */ xv_set(ip->list, XV_SHOW, FALSE, NULL); xv_destroy_safe(ip->list); ip->list = ..._window_list_create(ip, ip->controls); xv_set(ip->list, XV_SHOW, FALSE, NULL); attr_ptr = attr_array; attr_end = &attr_array[ATTR_STANDARD_SIZE - 20]; for (i = 0; i < Gfm_list_count; i++) { *attr_ptr++ = (void *) PANEL_LIST_INSERT; *attr_ptr++ = (void *) i; *attr_ptr++ = (void *) PANEL_LIST_STRING; *attr_ptr++ = (void *) i; *attr_ptr++ = (void *) String_list[i]; /* * Check for overflow or completion, if full terminate * the ATTR_LIST and set it on the scrolling list. */ if (attr_ptr >= attr_end || i >= Gfm_list_count - 1) { *attr_ptr = (void *) 0; xv_set(ip->list, ATTR_LIST, attr_array, NULL); attr_ptr = attr_array; } } /* * Select first item and make list visible */ xv_set(ip->list, PANEL_LIST_SELECT, 0, TRUE, XV_SHOW, TRUE, NULL); } -- Brent Browning Internet: brentb@Eng.Sun.COM Sun Microsystems, Inc UUCP: ...!sun!brentb 2550 Garcia Ave. MTV 01-40 Phone: (415) 336-5573 Mountain View, CA 94043
toone@looney.Corp.Sun.COM (Nolan Toone) (05/31/91)
brentb@montagne.Eng.Sun.COM (Brent Browning) writes: > In article <1991May24.211132.10282@cci632.cci.com> sz@cci632.cci.com (Stephen Zehl) writes: > > This is fine if you know what you want in the list ahead of time, but > >what if you want to read in a list of files from a directory? I figured I > >could just substitute a pointer to an array of strings in place of the > >strings themselves as shown below: > > > > static char *mylist[3] = { "One", "Two", "Three" }; > > PANEL_LIST_STRINGS must *really* have a NULL terminated list > of strings, *not* a char ** pointing at a NULL terminated list > of strings. > > I've included a sample program that does just what you > need to do. Type in a filename, then hit the load button. It > will load that file into the scrolling list. Hitting the > save button saves it out to a file. > The way Brent indicated is probably the best for this example, but just FYI: Another way is to use ATTR_LIST. This allows you to create a list of char ** and pass them to xv_{create/set}. The one thing to watch for is that you MUST include the ATTRIBUTE in the array as well as the NULL termiator and the max size for the list is 256. For example: if the array were: char *list[10]; list[0] = (char *)PANEL_LIST_STRINGS; list[1] = "item 1"; list[2] = "item 2"; list[3] = "item 3"; list[4] = "item 4"; list[5] = "item 5"; list[6] = "item 6"; list[7] = "item 7"; list[8] = (char *)NULL; list[9] = (char *)NULL; The first NULL to termiate PANEL_LIST_STRINGS the second to termiate the attribute list. Then you could use the above list in: xv_create(panel, PANEL_LIST, ATTR_LIST, list, NULL); which is the the same as: xv_create(panel, PANEL_LIST, PANEL_LIST_STRINGS, "item 1", "item 2", "item 3", "item 4", "item 5", "item 6", "item 7", NULL, NULL); Regards, /\ \\ \ Nolan C. Toone, ISV Engineering \ \\ / Sun Microsystems / \/ / / MailStop PAL1-316 / / \//\ 2550 Garcia Avenue \//\ / / Mountain View, California 94043 / / /\ / / \\ \ Phone: 415-336-0391 \ \\ EMail: toone@Corp.Sun.Com \/
ed@Canada.Sun.COM (Edward Lycklama - KL Group Inc.) (06/04/91)
> > In article <NICOLAS.91May28132821@bmsr9.usc.edu> you write: > > > >Can someone post a an example of code to use PANEL_LIST_INSERT & > >PANEL_LIST_DELETE? There are two problems: 1) intense flashing > >and 2) after using PANEL_LIST_DELETE in descending order as suggested > >in O'Reilly, I get bus errors. > > It sure would have been nice to have some sort of batching > for scrolling lists - eh? XView doesn't really provide any > support for this. The recommended way to do this is to set XV_SHOW > to FALSE on the list, then do the update, the set XV_SHOW to TRUE. > > Brent Browning Internet: brentb@Eng.Sun.COM > Sun Microsystems, Inc UUCP: ...!sun!brentb > 2550 Garcia Ave. MTV 01-40 Phone: (415) 336-5573 > Mountain View, CA 94043 > Actually, there is a way to batch request to scrolling lists; just set PANEL_PAINT to PANEL_NONE while inserting/deleting, and no updates occur. When you are done, set PANEL_PAINT to PANEL_CLEAR, and the new list is drawn. Ed Lycklama KL Group Inc. | Phone: (416) 594-1026 Ext. 22 134 Adelaide St. E, Suite 204 | Fax: (416) 594-1919 Toronto, Ontario, M5C 1K9 | UUCP: sun!suncan!klg!ed CANADA