home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!cs.utexas.edu!news
- From: cpg@cs.utexas.edu (Carlos M. Puchol)
- Newsgroups: alt.toolkits.xview
- Subject: Re: HELP! Find all files of a directory in Xview
- Date: 31 Dec 1992 11:29:44 -0600
- Organization: Department of Computer Sciences, UT Austin
- Lines: 494
- Message-ID: <lk6bg8INN6ks@thor.cs.utexas.edu>
- References: <lk0avrINN228@thor.cs.utexas.edu> <RICKG.92Dec29084107@irondude.eng.sun.com> <hue.725789508@coney>
- NNTP-Posting-Host: thor.cs.utexas.edu
-
- In article <hue.725789508@coney> hue@island.COM (Pond Scum) writes:
- >rickg@eng.sun.com (The Tankster) writes:
- >>according to the SunSoft toolkit strategy annoncement that
- >>appeared awhile back, the XView toolkit itself will eventually
- >>contain such an object. i guess it depends on when you need it...
- >
- >Here in the Graphic Arts Division of Island Graphics we have at least
- >four different file requesters (fortunately they are in four separate
- >applications, not all in the same one). I needed one and didn't find one
-
- ...
-
- >So a month ago I decided to write the "ultimate file requester" which would
- >hopefully make everyone here happy. The main goal was to make it easy
- >to use, and not force anyone into buying into my particular style of
- >programming or force them to carry a lot of baggage around, so I did
- >it as an XView extension. Also, I wanted to emulate the behavior of
-
- Well, sounds pretty nice to me. Judging from the name of the uuencoded file,
- it is a snapshot of your "ultimate file requester". Are you going to contribute
- your code to the net :-)
-
- BTW, the code I posted had a minor error. I have fixed it and I had intorduced
- sorting for the file & direcotry names (There wasn't at the beginning!).
- Now it also remembers the CWD from invocation to invocation.
-
- Help yourself.
-
- -- Carlos
-
- /*
- * XGed : Graph Editor for the X Window System
- *
- * Carlos Puchol (cpg@cs.utexas.edu)
- *
- * This file is public domain. Do with it what you please.
- * I am not to be held responsible for any damage caused by the use of this
- * code. I would appreciate if you quote the authors, if you use this code.
- *
- * %W% %G%
- */
-
- /*************************************************************************\
- * *
- * FILE: dir_list.c *
- * *
- * EXPORTED ROUTINES: *
- * *
- * - get_filename_popup(char *label, void (*action)()) *
- * *
- * This procedure creates two scrolling lists, one with directories *
- * and one with files. It allows the user to search through *
- * directories for files and then select a file. The label is *
- * attached to the frame and the actual button "ok" button. *
- * *
- * The procedure "action" will be called when the button is pressed *
- * or <cr> is pressed in the "file" line. It will be called with *
- * the absolute file name of the selected file. *
- * *
- * The popup window will remember the "current" directory from *
- * invocation to invocation. *
- * *
- * - destroy_filename_frame() *
- * *
- * You can guess what it does! *
- * *
- \*************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <xview/xview.h>
- #include <xview/panel.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <xvged_objects.h>
-
- #define DESELECT 0
- #define SELECT 1
- #define ENTRY_KEY 5877
- #define NULL_STR ""
-
- static Frame frame;
- static Panel panel;
- static Panel_item pi_dir, pi_file, ti_file, mi_dir, bi_open;
- static DIR *dirp;
- static struct dirent *entry;
- static char *current;
-
- static int num_files, num_dirs;
- static void (*action_to_call)();
-
- static int Action ();
- static int Cancel ();
- static void setup_list ();
- static void dir_proc ();
- static void file_proc ();
- static int check_read ();
- static void create_frame();
-
- void destroy_filename_frame()
- {
- xv_destroy_safe (frame);
- }
-
- void get_filename_popup(label, action)
- char *label;
- void (*action)();
- {
- static char initial[MAXPATHLEN]={'\0'};
-
- if (initial[0]=='\0') {
- getwd(initial);
- current = (char *) malloc (strlen (initial) + 1);
- memset (current, '\0', strlen (initial) + 1);
- strcat (current, initial);
- create_frame();
- }
- xv_set(bi_open, PANEL_LABEL_STRING, label, NULL);
- xv_set(frame, FRAME_LABEL, label, NULL);
-
- /* xv_set(frame, FRAME_LABEL, label, NULL); */
-
- action_to_call=action;
-
- if (check_read (current, NULL_STR))
- setup_list ();
-
- xv_set(frame, XV_SHOW, TRUE, NULL);
-
- }
-
- static void create_frame()
- {
-
- frame = (Frame) xv_create (NULL, FRAME,
- FRAME_LABEL, "File Open",
- NULL);
-
- panel = (Panel) xv_create (frame, PANEL, NULL);
-
- mi_dir = (Panel_item) xv_create (panel, PANEL_MESSAGE,
- PANEL_LABEL_STRING, current,
- PANEL_LABEL_BOLD, TRUE,
- XV_X, 20,
- XV_Y, 20,
- NULL);
-
- ti_file = (Panel_item) xv_create (panel, PANEL_TEXT,
- PANEL_LABEL_STRING, "File:",
- PANEL_VALUE_DISPLAY_LENGTH, 50,
- PANEL_VALUE_STORED_LENGTH, 256,
- PANEL_NEXT_ROW, -1,
- PANEL_VALUE, NULL_STR,
- PANEL_NOTIFY_PROC, Action,
- NULL);
-
- pi_dir = (Panel_item) xv_create (panel, PANEL_LIST,
- PANEL_LABEL_STRING, "Directories:",
- PANEL_LIST_DISPLAY_ROWS, 10,
- PANEL_CHOOSE_ONE, TRUE,
- PANEL_CHOOSE_NONE, TRUE,
- PANEL_READ_ONLY, TRUE,
- PANEL_NOTIFY_PROC, dir_proc,
- PANEL_NEXT_ROW, -1,
- PANEL_LIST_WIDTH, 150,
- PANEL_LAYOUT, PANEL_VERTICAL,
- NULL);
-
- pi_file = (Panel_item) xv_create (panel, PANEL_LIST,
- PANEL_LABEL_STRING, "Files:",
- PANEL_LIST_DISPLAY_ROWS, 10,
- PANEL_CHOOSE_ONE, TRUE,
- PANEL_CHOOSE_NONE, TRUE,
- PANEL_READ_ONLY, TRUE,
- PANEL_NOTIFY_PROC, file_proc,
- PANEL_LIST_WIDTH, 150,
- PANEL_LAYOUT, PANEL_VERTICAL,
- NULL);
-
- bi_open = (Panel_item) xv_create (panel, PANEL_BUTTON,
- PANEL_LABEL_STRING, "Open",
- PANEL_NOTIFY_PROC, Action,
- XV_X, 370,
- XV_Y, 73,
- NULL);
-
- (void) xv_create (panel, PANEL_BUTTON,
- PANEL_LABEL_STRING, "Cancel",
- PANEL_NOTIFY_PROC, Cancel,
- XV_X, 367,
- XV_Y, 103,
- NULL);
-
- window_fit (panel);
- window_fit (frame);
-
- }
-
-
- /*
- * Re-read the directory entries for the scrolling lists
- */
-
- static void setup_list ()
- {
- char *tmpname;
- int i;
-
- xv_set (ti_file,
- PANEL_VALUE, NULL_STR,
- NULL);
-
- xv_set (bi_open,
- XV_SHOW, FALSE,
- NULL);
-
- xv_set (mi_dir,
- PANEL_LABEL_STRING, current,
- NULL);
-
- /*
- * Hide the scroll lists while re-computing the lists. Saves on re-draw
- * time.
- */
-
- xv_set (pi_dir,
- XV_SHOW, FALSE,
- NULL);
-
- xv_set (pi_file,
- XV_SHOW, FALSE,
- NULL);
-
- /*
- * First delete the old entries
- */
-
- for (i = num_dirs - 1; i >= 0; i--)
- xv_set (pi_dir, PANEL_LIST_DELETE, i, NULL);
-
- for (i = num_files - 1; i >= 0; i--)
- xv_set (pi_file, PANEL_LIST_DELETE, i, NULL);
-
- num_files = 0;
- num_dirs = 0;
- /*
- * Now read the new entries
- */
- dirp = opendir (current);
-
- while ((entry = readdir (dirp)) != NULL) {
- tmpname = (char *) malloc (strlen (current) + entry->d_namlen + 2);
- memset (tmpname, '\0', strlen (current) + entry->d_namlen + 2);
- strcat (tmpname, current);
- strcat (tmpname, "/");
- strcat (tmpname, entry->d_name);
- if (dir_test (tmpname)) {
- /*
- * A directory
- */
- if (strcmp (entry->d_name, ".")) {
- for (i=0; i < num_dirs; i++) {
- if (0 > strcmp (entry->d_name,
- xv_get (pi_dir, PANEL_LIST_STRING,
- i, NULL, NULL)))
- break;
- }
- xv_set (pi_dir,
- PANEL_LIST_INSERT, i,
- PANEL_LIST_STRING, i, entry->d_name,
- NULL);
- num_dirs++;
- }
- }
- else {
- /*
- * A file
- */
- if (strncmp (entry->d_name, ".", 1)) {
- for (i=0; i < num_files; i++) {
- if (0 > strcmp (entry->d_name,
- xv_get (pi_file, PANEL_LIST_STRING,
- i, NULL, NULL)))
- break;
- }
- xv_set (pi_file,
- PANEL_LIST_INSERT, i,
- PANEL_LIST_STRING, i, entry->d_name,
- NULL);
- num_files++;
- }
- }
- free (tmpname);
- }
-
- /*
- * Done, show the new scroll panels
- */
-
- xv_set (pi_dir,
- XV_SHOW, TRUE,
- NULL);
- xv_set (pi_file,
- XV_SHOW, TRUE,
- NULL);
-
- closedir (dirp);
- }
-
-
- /*
- * Handle the selection of a directory entry in the scroll list
- */
-
- static void dir_proc (item, string, client_data, op, event)
- Panel_item item;
- char *string;
- caddr_t client_data;
- Panel_list_op op;
- Event *event;
-
- {
- char *oldcurrent;
- int i;
-
- /*
- * Make sure the user selected and didn't drag. Dragging may cause unwanted
- * changes
- */
-
- /*
- * Make sure we can read the directory before making any changes
- */
-
- if (op == SELECT && event_id (event) != LOC_DRAG &&
- check_read (current, string)) {
-
- oldcurrent = (char *) malloc (strlen (current) + 1);
- memset (oldcurrent, '\0', strlen (current) + 1);
- strcat (oldcurrent, current);
- free (current);
-
- if (strcmp (string, "..")) {
-
- /*
- * Add the new directory to the "current" directory string
- */
-
- current = (char *) malloc (strlen (oldcurrent) + strlen (string) + 2);
- memset (current, '\0', strlen (oldcurrent) + strlen (string) + 2);
- strcat (current, oldcurrent);
- if (strlen (oldcurrent) > 1)
- strcat (current, "/");
- strcat (current, string);
- }
- else {
-
- /*
- * Go back one directory
- */
-
- i = strlen (oldcurrent);
-
- while (oldcurrent[i] != '/') {
- oldcurrent[i] = '\0';
- i--;
- }
-
- /*
- * Tried to go back from the root directory?
- */
-
- if (i < 1) {
- oldcurrent[0] = '/';
- oldcurrent[1] = '\0';
- i = 1;
- }
- else
- oldcurrent[i] = '\0';
-
- current = (char *) malloc (i);
- memset (current, '\0', i);
- strcat (current, oldcurrent);
- }
-
- free (oldcurrent);
-
- setup_list ();
- }
- }
-
-
- /*
- * Handle a selection on the file list
- */
-
- static void file_proc (item, string, client_data, op, event)
- Panel_item item;
- char *string;
- caddr_t client_data;
- Panel_list_op op;
- Event *event;
-
- {
- if (op == SELECT) {
- xv_set (ti_file,
- PANEL_VALUE, string,
- NULL);
- xv_set (bi_open,
- XV_SHOW, TRUE,
- NULL);
- }
- else if (op == DESELECT) {
- xv_set (ti_file,
- PANEL_VALUE, NULL_STR,
- NULL);
- xv_set (bi_open,
- XV_SHOW, FALSE,
- NULL);
- }
- }
-
-
- /*
- * Acknowledge an Action button press
- */
-
- static int Action (item, event)
- Panel_item item;
- Event *event;
-
- {
- if (strcmp (NULL_STR, (char *) xv_get (ti_file, PANEL_VALUE))) {
- xv_set (frame, XV_SHOW, FALSE, NULL);
- xv_set (XGedObjects.BaseFrame, FRAME_BUSY, TRUE, NULL);
- (*action_to_call)(xv_get (ti_file, PANEL_VALUE));
- xv_set (XGedObjects.BaseFrame, FRAME_BUSY, FALSE, NULL);
- }
- }
-
- static int Cancel (item, event)
- Panel_item item;
- Event *event;
-
- {
- xv_set (frame, XV_SHOW, FALSE, NULL);
- }
-
-
- /*
- * This routine tests to see if a file name is a directory entry
- */
-
- static dir_test (filename)
- char *filename;
-
- {
- struct stat statbuf;
-
- stat (filename, &statbuf);
- return (S_ISDIR (statbuf.st_mode));
- }
-
-
- /*
- * Check to see if the directory is readable
- */
-
- static int check_read (oldpath, newdir)
- char *oldpath, *newdir;
-
- {
- char *both;
- DIR *test_open;
-
- both = (char *) malloc (strlen (oldpath) + strlen (newdir) + 2);
- memset (both, '\0', strlen (oldpath) + strlen (newdir) + 2);
- strcat (both, oldpath);
- strcat (both, "/");
- strcat (both, newdir);
-
- if (!(test_open = opendir (both))) {
- free (both);
- return 0;
- }
- else {
- free (both);
- closedir (test_open);
- return 1;
- }
- }
-
-