From: weegink@ictser.UUCP (Han Weegink)
Newsgroups: comp.sys.sun.misc
Subject: Re: XView file browser?
Date: 4 Mar 92 14:01:13 GMT

vita@gloucester.dab.ge.com (Mark Vita) writes:

>Hello all,

>Does anyone have XView code for a Macintosh-style file browser that you'd
>be willing to give away?  I.e., a widget that lets the user choose a file
>by browsing through a scrolling list of files, navigating through the
>directory structure, etc., like SFGetFile on the Mac.  I remember seeing
>several implementations back in my SunView days, so I figure there must be
>something around for XView...

>Thanks in advance...

>--
>Mark Vita                                  vita@sunny.dab.ge.com
>Advanced Engineering
>GE Simulation and Control Systems
>Daytona Beach, FL



Re: XView file browser ?


I picked up some sources from the net a while ago. Don't remember who originally
posted them, but thanks anyway. They contain some (minor) bugs but show you how
it could be done.

The example consists of two scrolling lists, one presenting the directories,
the other the files. You can 'change directory' by selecting an entry in the
directory list. You can also select files in the other list. The selection can
be passed to a routine, e.g. for loading the file.

I rewrote some parts to solve some of the problems, but my version is too 
specific to post it on the net.
Therefore, this posting contains the original sources.
However, let me know if you encounter serious problems.

I have included the source file and the makefile below, hope this is what
you want,

 
Han Weegink


---------------------------------------------------------------------------
IIIII  CCCCC  TTTTTTT  Han Weegink                                info only
  I   C     C    T     ICT Automatisering Deventer BV
  I   C          T     Aerospace Group        Holland
  I   C          T     E-mail:    weegink@ict.nl
  I   C     C    T     Telefax:   +31 (0)5700 21362
IIIII  CCCCC     T     TelePhone: +31 (0)5700 33888
---------------------------------------------------------------------------

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile dir_list.c
# Wrapped by cpg@thor on Tue Dec 29 04:43:26 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(586 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# -------------------- make file ----------------------------
X#
X#	Makefile for the dirlist example program
X#
X
XINCLUDE 	= -I${OPENWINHOME}/include
X
X#
X# If you want to compile for debugging, change "-O" to "-g"
X#
X
XCFLAGS		= ${INCLUDE} -g
X
X# if you want special to pass special loader options to ld, set
X# LDFLAGS= ...
X#
X
XXVIEW_LIBS 	= -L${OPENWINHOME}/lib \
X		  -lxview -lolgx -lX11
X
XCFILES		= dir_list.c 
X	   
XOBJS		= dir_list
X
Xall:  ${OBJS}
X
X${OBJS}: $$@.c $$@.o 
X	${CC} ${CFLAGS} ${LDFLAGS} -o $@ $@.o ${XVIEW_LIBS}
X
X#---------------------- end of makefile --------------------------
X
END_OF_FILE
if test 586 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'dir_list.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dir_list.c'\"
else
echo shar: Extracting \"'dir_list.c'\" \(7548 characters\)
sed "s/^X//" >'dir_list.c' <<'END_OF_FILE'
X/*
X * dirlist.c
X * This program creates two scrolling lists, one with directories and one
X * with files.  It allows the user to search through directories for files
X * and then select a file to "open".
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <xview/xview.h>
X#include <xview/panel.h>
X#include <dirent.h>
X#include <sys/stat.h>
X#include <sys/types.h>
X
X#define DESELECT 0
X#define SELECT 1
X#define ENTRY_KEY 5877
X#define NULL_STR ""
X
XFrame frame;
XPanel panel;
XPanel_item pi_dir, pi_file, ti_file, mi_dir, bi_open;
XDIR *dirp;
Xstruct dirent *entry;
Xchar *current;
X
Xint num_files, num_dirs;
X
Xint Open();
Xint Cancel();
Xvoid setup_list();
Xvoid dir_proc();
Xvoid file_proc();
Xint check_read();
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X
X{
X  char *tmpname;
X
X/*
X * Start in the HOME directory
X */
X
X  if (argc<1)
X  	tmpname = getenv("HOME");
X  else
X	tmpname=argv[1];
X  current = (char *)malloc(strlen(tmpname)+1);
X  memset(current, '\0', strlen(tmpname)+1);
X  strcat(current, tmpname);
X  free(tmpname);
X
X  xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
X
X  frame = (Frame)xv_create(NULL, FRAME,
X    FRAME_LABEL,		"File Open",
X    NULL);
X
X  panel = (Panel)xv_create(frame, PANEL, NULL);
X
X  mi_dir = (Panel_item)xv_create(panel, PANEL_MESSAGE,
X    PANEL_LABEL_STRING,		current,
X    PANEL_LABEL_BOLD,		TRUE,
X    NULL);
X
X  ti_file = (Panel_item)xv_create(panel, PANEL_TEXT,
X    PANEL_LABEL_STRING, 	"File:",
X    PANEL_VALUE_DISPLAY_LENGTH,	50,
X    PANEL_VALUE_STORED_LENGTH,	256,
X    PANEL_NEXT_ROW,		-1,
X    PANEL_VALUE,		NULL_STR,
X    NULL);
X
X  pi_dir = (Panel_item)xv_create(panel, PANEL_LIST,
X    PANEL_LABEL_STRING,		"Directories:",
X    PANEL_LIST_DISPLAY_ROWS,	10,
X    PANEL_CHOOSE_ONE,		TRUE,
X    PANEL_CHOOSE_NONE,          TRUE,
X    PANEL_READ_ONLY,		TRUE,
X    PANEL_NOTIFY_PROC,		dir_proc,
X    PANEL_NEXT_ROW,		-1,
X    PANEL_LIST_WIDTH,		150,
X    PANEL_LAYOUT,		PANEL_VERTICAL,
X    NULL);
X
X  pi_file = (Panel_item)xv_create(panel, PANEL_LIST,
X    PANEL_LABEL_STRING,		"Files:",
X    PANEL_LIST_DISPLAY_ROWS,	10,
X    PANEL_CHOOSE_ONE,		TRUE,
X    PANEL_CHOOSE_NONE,		TRUE,
X    PANEL_READ_ONLY,		TRUE,
X    PANEL_NOTIFY_PROC,		file_proc,
X    PANEL_LIST_WIDTH,		150,
X    PANEL_LAYOUT,		PANEL_VERTICAL,
X    NULL);
X
X  bi_open = (Panel_item)xv_create(panel, PANEL_BUTTON,
X    PANEL_LABEL_STRING,		"Open",
X    PANEL_NOTIFY_PROC,		Open,
X    XV_X,			370,
X    XV_Y,			73,
X    NULL);
X
X  (void)xv_create(panel, PANEL_BUTTON,
X    PANEL_LABEL_STRING,		"Cancel",
X    PANEL_NOTIFY_PROC,		Cancel,
X    XV_X,			367,
X    XV_Y,			103,
X    NULL);
X
X  if (check_read(current))
X    setup_list();
X
X  window_fit(panel);
X  window_fit(frame);
X
X  xv_main_loop(frame);
X}
X
X
X/*
X * Re-read the directory entries for the scrolling lists
X */
X
Xvoid setup_list()
X
X{
X  char *tmpname;
X  int i;
X
X  xv_set(ti_file,
X    PANEL_VALUE,	NULL_STR,
X    NULL);
X
X  xv_set(bi_open,
X    XV_SHOW, FALSE,
X    NULL);
X
X  xv_set(mi_dir,
X    PANEL_LABEL_STRING,	current,
X    NULL);
X
X/*
X * Hide the scroll lists while re-computing the lists.  Saves on re-draw
X * time.
X */
X
X  xv_set(pi_dir,
X    XV_SHOW,		FALSE,
X    NULL);
X
X  xv_set(pi_file,
X    XV_SHOW,		FALSE,
X    NULL);
X
X/*
X * First delete the old entries
X */
X
X  for (i = num_dirs - 1; i >= 0; i--)
X    xv_set(pi_dir, PANEL_LIST_DELETE, i, NULL);
X
X  for (i = num_files - 1; i >= 0; i--)
X    xv_set(pi_file, PANEL_LIST_DELETE, i, NULL);
X
X  num_files = 0;
X  num_dirs = 0;
X
X/*
X * Now read the new entries
X */
X
X  dirp = opendir(current);
X
X  while ((entry = readdir(dirp)) != NULL) {
X    tmpname = (char *)malloc(strlen(current) + entry->d_namlen + 2);
X    memset(tmpname, '\0', strlen(current) + entry->d_namlen + 2);
X    strcat(tmpname, current);
X    strcat(tmpname, "/");
X    strcat(tmpname, entry->d_name);
X    if (dir_test(tmpname)) {
X
X/*
X * A directory
X */
X
X      if (strcmp(entry->d_name, ".")) {
X        xv_set(pi_dir,
X          PANEL_LIST_INSERT,	num_dirs,
X          PANEL_LIST_STRING,	num_dirs, entry->d_name,
X          NULL);
X        num_dirs++;
X      }
X    }
X    else {
X
X/*
X * A file
X */
X
X      if (strncmp(entry->d_name, ".", 1)) {
X        xv_set(pi_file,
X	  PANEL_LIST_INSERT,	num_files,
X	  PANEL_LIST_STRING,	num_files, entry->d_name,
X	  NULL);
X        num_files++;
X      }
X    }
X    free(tmpname);
X  }
X
X/*
X * Done, show the new scroll panels
X */
X
X  xv_set(pi_dir,
X    XV_SHOW,		TRUE,
X    NULL);
X  xv_set(pi_file,
X    XV_SHOW,		TRUE,
X    NULL);
X
X  closedir(dirp);
X}
X
X
X/*
X * Handle the selection of a directory entry in the scroll list
X */
X
Xvoid dir_proc(item, string, client_data, op, event)
XPanel_item item;
Xchar *string;
Xcaddr_t client_data;
XPanel_list_op op;
XEvent *event;
X
X{
X  char *oldcurrent;
X  int i;
X
X/*
X * Make sure the user selected and didn't drag.  Dragging may cause unwanted
X * changes
X */
X
X  if (op == SELECT && event_id(event) != LOC_DRAG &&
X
X/*
X * Make sure we can read the directory before making any changes
X */
X
X      check_read(current, string)) {
X
X      oldcurrent = (char *)malloc(strlen(current)+1);
X      memset(oldcurrent, '\0', strlen(current)+1);
X      strcat(oldcurrent, current);
X      free(current);
X
X      if (strcmp(string, "..")) {
X
X/*
X * Add the new directory to the "current" directory string
X */
X
X        current = (char *)malloc(strlen(oldcurrent) + strlen(string) + 2);
X        memset(current, '\0', strlen(oldcurrent) + strlen(string) + 2);
X        strcat(current, oldcurrent);
X        if (strlen(oldcurrent) > 1)
X          strcat(current, "/");
X        strcat(current, string);
X      }
X      else {
X
X/*
X * Go back one directory
X */
X
X        i = strlen(oldcurrent);
X
X        while(oldcurrent[i] != '/') {
X	  oldcurrent[i] = '\0';
X	  i--;
X        }
X
X/*
X * Tried to go back from the root directory?
X */
X
X        if (i < 1) {
X	  oldcurrent[0] = '/';
X	  oldcurrent[1] = '\0';
X	  i = 1;
X        }
X        else
X          oldcurrent[i] = '\0';
X
X        current = (char *)malloc(i);
X        memset(current, '\0', i);
X        strcat(current, oldcurrent);
X      }
X
X      free(oldcurrent);
X
X      setup_list();
X  }
X}
X
X
X/*
X * Handle a selection on the file list
X */
X
Xvoid file_proc(item, string, client_data, op, event)
XPanel_item item;
Xchar *string;
Xcaddr_t client_data;
XPanel_list_op op;
XEvent *event;
X
X{
X  if (op == SELECT) {
X    xv_set(ti_file,
X      PANEL_VALUE,	string,
X      NULL);
X    xv_set(bi_open,
X      XV_SHOW,		TRUE,
X      NULL);
X  }
X  else if (op == DESELECT) {
X    xv_set(ti_file,
X      PANEL_VALUE,	NULL_STR,
X      NULL);
X    xv_set(bi_open,
X      XV_SHOW,		FALSE,
X      NULL);
X  }
X}
X
X
X/*
X * Acknowledge an Open button press
X */
X
Xint Open(item, event)
XPanel_item item;
XEvent *event;
X
X{
X  if (strcmp(NULL_STR, (char *)xv_get(ti_file, PANEL_VALUE))) {
X    printf("Open: %s\n", xv_get(ti_file, PANEL_VALUE));
X    xv_destroy_safe(frame);
X  }
X}
X
Xint Cancel(item, event)
XPanel_item item;
XEvent *event;
X
X{
X  xv_destroy_safe(frame);
X}
X
X
X/*
X * This routine tests to see if a file name is a directory entry
X */
X
Xdir_test(filename)
Xchar *filename;
X
X{
X  struct stat statbuf;
X
X  stat(filename, &statbuf);
X  return(S_ISDIR(statbuf.st_mode));
X}
X
X
X/*
X * Check to see if the directory is readable
X */
X
Xint check_read(oldpath, newdir)
Xchar *oldpath, *newdir;
X
X{
X  char *both;
X  DIR *test_open;
X
X  both = (char *)malloc(strlen(oldpath) + strlen(newdir) + 2);
X  memset(both, '\0', strlen(oldpath) + strlen(newdir) + 2);
X  strcat(both, oldpath);
X  strcat(both, "/");
X  strcat(both, newdir);
X
X  if (!(test_open = opendir(both))) {
X    free(both);
X    return 0;
X  }
X  else {
X    free(both);
X    closedir(test_open);
X    return 1;
X  }
X}
X
X/*---------------- end of dirlist.c ------------------------------------------*/
END_OF_FILE
if test 7548 -ne `wc -c <'dir_list.c'`; then
    echo shar: \"'dir_list.c'\" unpacked with wrong size!
fi
# end of 'dir_list.c'
fi
echo shar: End of shell archive.
exit 0
Newsgroups: alt.toolkits.xview,uw.sun,pnw.sys.sun