Logo Search packages:      
Sourcecode: xcircuit version File versions

filelist.c

/*-------------------------------------------------------------------------*/
/* filelist.c --- Xcircuit routines for the filelist widget          */ 
/* Copyright (c) 2002  Tim Edwards, Johns Hopkins University               */
/*-------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#ifdef HAVE_DIRENT_H
#include <dirent.h>
#include <unistd.h>
#define direct dirent
#else
#include <sys/dir.h>
#endif

#include <sys/stat.h>
#include <errno.h>
#include <limits.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>

#ifdef TCL_WRAPPER 
#include <tk.h>
#else
#include "Xw/Xw.h"
#include "Xw/WorkSpace.h"
#include "Xw/TextEdit.h"
#include "Xw/Toggle.h"
#endif

/*-------------------------------------------------------------------------*/
/* Local includes                                        */
/*-------------------------------------------------------------------------*/

#include "colordefs.h"
#include "xcircuit.h"

/*----------------------------------------------------------------------*/
/* Function prototype declarations                                      */
/*----------------------------------------------------------------------*/
#include "prototypes.h"

/*-------------------------------------------------------------------------*/
/* Local definitions                                           */
/*-------------------------------------------------------------------------*/

#define INITDIRS 10

/*-------------------------------------------------------------------------*/
/* Global Variable definitions                                       */
/*-------------------------------------------------------------------------*/

#ifdef TCL_WRAPPER
extern Tcl_Interp *xcinterp;
#endif

extern Display    *dpy;
extern Clientdata areastruct;
extern ApplicationData appdata;
extern int    *appcolors;
extern short        popups;     /* total number of popup windows */
extern char   _STR2[250];
extern char   _STR[150];
extern Globaldata xobjs;

Pixmap   flistpix = (Pixmap)NULL;    /* For file-selection widget */
short    flstart, flfiles, flcurrent;
int    flcurwidth;

GC     hgc = NULL, sgc = NULL;
char   *cwdname = NULL;
fileliststruct *files;

/*-------------------------------------------------------------------------*/
/* Compare two filenames (for use by qsort())                        */
/*-------------------------------------------------------------------------*/

int fcompare(const void *a, const void *b)
{
   return (strcmp((char *)(((fileliststruct *)a)->filename),
      (char *)(((fileliststruct *)b)->filename)));
}

/*-------------------------------------------------------------------------*/
/* Routines for drawing a box around the currently selected file     */
/*-------------------------------------------------------------------------*/

void dragfilebox(xcWidget w, caddr_t clientdata, XMotionEvent *event)
{
   short filenum;
   int twidth;
   Window lwin = xcWindow(w);

   filenum = (event->y - 10 + FILECHARHEIGHT) / FILECHARHEIGHT + flstart - 1;
   if (filenum < 0) filenum = 0;
   else if (filenum >= flfiles) filenum = flfiles - 1;
  
   if (filenum == flcurrent) return;

   if (flcurrent >= 0)        /* erase previous box */
      XDrawRectangle(dpy, lwin, areastruct.gc, 5,
         10 + FILECHARHEIGHT * (flcurrent
         - flstart), flcurwidth + 10, FILECHARHEIGHT);

   twidth = XTextWidth(appdata.filefont, files[filenum].filename,
          strlen(files[filenum].filename));
   XDrawRectangle(dpy, lwin, areastruct.gc, 5,
         10 + FILECHARHEIGHT * (filenum
         - flstart), twidth + 10, FILECHARHEIGHT);

   flcurrent = filenum;
   flcurwidth = twidth;
}

/*-------------------------------------------------------------------------*/
/* Begin tracking the cursor position relative to the files in the list    */
/*-------------------------------------------------------------------------*/

void startfiletrack(xcWidget w, caddr_t clientdata, XCrossingEvent *event)
{
#ifdef TCL_WRAPPER
   Tk_CreateEventHandler(w, PointerMotionMask,
            (Tk_EventProc *)xctk_dragfilebox, (ClientData)w);
#else
   xcAddEventHandler(w, PointerMotionMask, False, (xcEventHandler)dragfilebox, NULL);
#endif

   XSetFunction(dpy, areastruct.gc, GXcopy);
   XSetForeground(dpy, areastruct.gc, AUXCOLOR);
   XSetLineAttributes(dpy, areastruct.gc, 1, LineSolid, CapRound, JoinMiter);

   /* draw initial box */

   flcurrent = -1;
   dragfilebox(w, NULL, (XMotionEvent *)event);

   XSetFunction(dpy, areastruct.gc, GXxor);
   XSetForeground(dpy, areastruct.gc, AUXCOLOR ^ BACKGROUND);
}

/*-------------------------------------------------------------------------*/
/* Stop tracking the cursor and return to default state                    */
/*-------------------------------------------------------------------------*/

void endfiletrack(xcWidget w, caddr_t clientdata, XCrossingEvent *event)
{
   Window lwin = xcWindow(w);

   XDrawRectangle(dpy, lwin, areastruct.gc, 5,
         10 + FILECHARHEIGHT * (flcurrent
         - flstart), flcurwidth + 10, FILECHARHEIGHT);

#ifdef TCL_WRAPPER
   Tk_DeleteEventHandler(w, PointerMotionMask,
            (Tk_EventProc *)xctk_dragfilebox, (ClientData)w);
#else
   xcRemoveEventHandler(w, PointerMotionMask, False,
            (xcEventHandler)dragfilebox, NULL);
#endif

   /* Restore graphics state values */
   XSetForeground(dpy, areastruct.gc, areastruct.gccolor);
   XSetFunction(dpy, areastruct.gc, areastruct.gctype);
}

/*----------------------------------------------------------------------*/
/* Read a crash file to find the name of the original file.       */
/*----------------------------------------------------------------------*/

char *getcrashfilename()
{
   FILE *fi;
   char temp[256];
   char *retstr = NULL, *tpos, *spos;
   int slen;

   if ((fi = fopen(_STR2, "r")) != NULL) {
      while (fgets(temp, 255, fi) != NULL) {
       if ((tpos = strstr(temp, "Title:")) != NULL) {
          ridnewline(temp);
          tpos += 7;
          if ((spos = strrchr(temp, '/')) != NULL)
             tpos = spos + 1;
          retstr = (char *)malloc(1 + strlen(tpos));
          strcpy(retstr, tpos);
       }
       else if ((tpos = strstr(temp, "CreationDate:")) != NULL) {
          ridnewline(temp);
          tpos += 14;
          slen = strlen(retstr);
          retstr = (char *)realloc(retstr, 4 + slen + strlen(tpos));
          sprintf(retstr + slen, " (%s)", tpos);
          break;
       }
      }
   }
   return retstr;
}

/*----------------------------------------------------------------------*/
/* Crash recovery:  load the file, and link the tempfile name to it.    */
/*----------------------------------------------------------------------*/

void crashrecover()
{
   if (xobjs.tempfile != NULL) {
      unlink(xobjs.tempfile);
      free(xobjs.tempfile);
   }
   xobjs.tempfile = strdup(_STR2);

   startloadfile();
}

/*----------------------------------------------------------------------*/
/* Look for any files left over from a crash.                           */
/*----------------------------------------------------------------------*/

void findcrashfiles()
{
   DIR *cwd;
   struct direct *dp;
   struct stat sbuf;
   uid_t userid = getuid();
   time_t recent = 0;

   cwd = opendir(xobjs.tempdir);
   if (cwd == NULL) return;   /* No tmp directory, no tmp files! */

   while ((dp = readdir(cwd)) != NULL) {
      sprintf(_STR, "%s/%s", xobjs.tempdir, dp->d_name);
      if (!strncmp(_STR + strlen(xobjs.tempdir) + 1, "XC", 2)) {
         if ((!stat(_STR, &sbuf)) && (sbuf.st_uid == userid)) {
          if ((recent == 0) || (sbuf.st_ctime > recent)) {
             recent = sbuf.st_ctime;
             strcpy(_STR2, _STR);
          }
       }
      }
   }
   closedir(cwd);
   
   if (recent > 0) {    /* There exists at least one temporary file */
                  /* belonging to this user.  Ask to recover  */
                  /* the most recent one.                 */

      /* Warn user of existing tempfile, and ask user if file     */
      /* should be recovered immediately.             */

#ifdef TCL_WRAPPER
      char *cfile = getcrashfilename();
      sprintf(_STR, ".query.title.field configure -text "
            "\"Recover file \'%s\'?\"", 
            (cfile == NULL) ? "(unknown)" : cfile);
      Tcl_Eval(xcinterp, _STR);
      Tcl_Eval(xcinterp, ".query.bbar.okay configure -command "
            "{filerecover; wm withdraw .query}; wm deiconify .query");
#else
      getfile(NULL, (pointertype)RECOVER, NULL);   /* Crash recovery mode */
#endif
   }
}  

/*----------------------------------------------------------------------*/
/* Match a filename extension against the file filter string.           */
/*----------------------------------------------------------------------*/

Boolean match_filter(char *fname, char *filter)
{
   char *dotptr = strrchr(fname, '.');

   if ((dotptr != NULL) && (filter != NULL) &&
       (filter[0] != '\0') && (strstr(dotptr, filter) != NULL))
      return True;

   return False;
}

/*----------------------------------------------------------------------*/
/* Make a list of the files in the list widget window             */
/*----------------------------------------------------------------------*/

void listfiles(xcWidget w, popupstruct *okaystruct, caddr_t calldata)
{
   XGCValues      values;
   Arg wargs[2];
   DIR *cwd;
   char *filter;
   Window lwin = xcWindow(w);
   short allocd = INITDIRS;
   short n = 0;
   struct direct *dp;
   struct stat statbuf;
   int pixheight;
   Dimension textwidth, textheight;

   filter = okaystruct->filter;

   if (sgc == NULL) {
      values.foreground = FOREGROUND;
      values.font = appdata.filefont->fid;
      values.function = GXcopy;
      values.graphics_exposures = False;
      sgc = XCreateGC(dpy, lwin, GCForeground | GCFont | GCFunction
            | GCGraphicsExposures, &values);
   }

#ifdef TCL_WRAPPER
   textwidth = Tk_Width(w);
   textheight = Tk_Height(w);
#else
   XtnSetArg(XtNwidth, &textwidth);
   XtnSetArg(XtNheight, &textheight);
   XtGetValues(w, wargs, n);
#endif

   /* Generate a new flistpix pixmap if currently nonexistent */

   if (!flistpix) {

      /* get list of files in the current directory (cwd) */

      if (files == NULL) 
         files = (fileliststruct *) malloc (INITDIRS * sizeof(fileliststruct));
      flfiles = 0;
      if (cwdname == NULL) {
       cwdname = (char *) malloc (sizeof(char));
       cwdname[0] = '\0';
      }
      if (cwdname[0] == '\0')
         cwd = opendir(".");
      else
         cwd = opendir(cwdname);

      /* If current directory cannot be accessed for some reason, */
      /* print "Invalid Directory" to the file list window.   */

      if (cwd == NULL) {
         XSetForeground(dpy, sgc, BACKGROUND);
         XFillRectangle(dpy, lwin, sgc, 0, 0, textwidth, textheight);
         XSetForeground(dpy, sgc, AUXCOLOR);
         XDrawString(dpy, lwin, sgc, 10, textheight / 2,
          "(Invalid Directory)", 19);
       return;
      }
      else {

       /* write the contents of the current directory into the   */
       /* array "filenames[]" (except for current directory ".") */

         while ((dp = readdir(cwd)) != NULL) {
          /* don't put current directory in list */
          if (!strcmp(dp->d_name, ".")) continue;

          /* record the type of file */
      
          sprintf(_STR2, "%s%s", cwdname, dp->d_name); 
          if (stat(_STR2, &statbuf)) continue;
          if ((statbuf.st_mode & S_IFDIR) != 0) /* is a directory */
             files[flfiles].filetype = DIRECTORY;
          else if (match_filter(dp->d_name, filter))
             files[flfiles].filetype = MATCH;
          else {
             if (areastruct.filefilter)
              continue;
             else
                files[flfiles].filetype = NONMATCH;
          }

          /* save the filename */

          files[flfiles].filename = (char *) malloc ((strlen(dp->d_name) + 
             ((files[flfiles].filetype == DIRECTORY) ? 2 : 1)) * sizeof(char));
          strcpy(files[flfiles].filename, dp->d_name);
          if (files[flfiles].filetype == DIRECTORY)
             strcat(files[flfiles].filename, "/");
          if (++flfiles == allocd) {
             allocd += INITDIRS;
             files = (fileliststruct *) realloc(files,
                  allocd * sizeof(fileliststruct));
          }
         }
      }
      closedir(cwd);

      /* sort the files[] array into alphabetical order (like "ls") */

      qsort((void *)files, (size_t)flfiles, sizeof(fileliststruct), fcompare);

      pixheight = flfiles * FILECHARHEIGHT + 25;
      if (pixheight < textheight) pixheight = textheight;

      flistpix = XCreatePixmap(dpy, areastruct.areawin, textwidth, pixheight,
         DefaultDepthOfScreen(xcScreen(w)));

      /* Write the filenames onto the pixmap */

      XSetForeground(dpy, sgc, BACKGROUND);
      XFillRectangle(dpy, flistpix, sgc, 0, 0, textwidth, pixheight);
      XSetForeground(dpy, sgc, FOREGROUND);
      for (n = 0; n < flfiles; n++) {
       switch (files[n].filetype) {
          case DIRECTORY:
             XSetForeground(dpy, sgc, SELECTCOLOR);
             break;
          case MATCH:
             XSetForeground(dpy, sgc, FILTERCOLOR);
             break;
          case NONMATCH:
             XSetForeground(dpy, sgc, FOREGROUND);
             break;
       }
         XDrawString(dpy, flistpix, sgc, 10, 10 + FILECHARASCENT + n * FILECHARHEIGHT,
          files[n].filename, strlen(files[n].filename));
      }
   }

   /* Copy the pixmap of filenames into the file list window */

   XSetForeground(dpy, sgc, BACKGROUND);
   XFillRectangle(dpy, lwin, sgc, 0, 0, textwidth, textheight);
   XCopyArea(dpy, flistpix, lwin, sgc, 0, flstart * FILECHARHEIGHT,
      textwidth, textheight, 0, 0);
}

/*-------------------------------------------------------------------------*/
/* Generate a new pixmap for writing the filelist and set the scrollbar    */
/* size accordingly.                                           */
/*-------------------------------------------------------------------------*/

void newfilelist(xcWidget w, popupstruct *okaystruct)
{
   short n;
   xcWidget textw = okaystruct->textw;

#ifdef TCL_WRAPPER
   int bval;
   int result;
   char *cstr = Tcl_GetVar(xcinterp, "filter", TCL_NAMESPACE_ONLY);
   if (cstr == NULL) {
      Wprintf("Error: No variable $filter in Tcl!");
      return;
   }
   result = Tcl_GetBoolean(xcinterp, cstr, &bval);
   if (result != TCL_OK) {
      Wprintf("Error: Bad variable $filter in Tcl!");
      return;  
   }
   areastruct.filefilter = bval;
#endif

   for (n = 0; n < flfiles; n++)
      free(files[n].filename);
   free(files);
   if (flistpix != (Pixmap)NULL) XFreePixmap(dpy, flistpix);
   files = NULL;
   flistpix = (Pixmap)NULL;
   flstart = 0;
   listfiles(w, okaystruct, NULL);
#ifdef TCL_WRAPPER
   showlscroll(Tk_NameToWindow(xcinterp, ".filelist.listwin.sb", w), NULL, NULL);
   Tcl_Eval(xcinterp, ".filelist.textent.txt delete 0 end");
   sprintf(_STR2, ".filelist.textent.txt insert 0 %s", cwdname);
   Tcl_Eval(xcinterp, _STR2);
#else
   showlscroll(XtNameToWidget(xcParent(w), "LScroll"), NULL, NULL);
   XwTextClearBuffer(textw);
   XwTextInsert(textw, cwdname);
   XwTextResize(textw);
#endif
}

/*-------------------------------------------------------------------------*/
/* Button press handler for file list window                         */
/*-------------------------------------------------------------------------*/

void fileselect(xcWidget w, popupstruct *okaystruct, XButtonEvent *event)
{
   Arg wargs[2];
   Window lwin = xcWindow(w);
   Dimension textwidth, textheight;
   short filenum, n = 0;
   char *tbuf, *ebuf;
   xcWidget textw = okaystruct->textw;

   flcurrent = -1;

#ifdef TCL_WRAPPER
   textwidth = Tk_Width(w);
   textheight = Tk_Height(w);
#else
   XtnSetArg(XtNwidth, &textwidth);
   XtnSetArg(XtNheight, &textheight);
   XtGetValues(w, wargs, n);
#endif

   /* third mouse button cancels selection and reverts buffer to cwd name */

   if (event->button == Button3) {
      newfilelist(w, okaystruct);
      return;
   }

   filenum = (event->y - 10 + FILECHARHEIGHT) / FILECHARHEIGHT + flstart - 1;
   if (filenum < 0) filenum = 0;
   else if (filenum >= flfiles) filenum = flfiles - 1;

   /* Attempt to enter invalid directory. . . treat like button 3 */

   if (filenum < 0) {
      newfilelist(w, okaystruct);
      return;
   }
   
   /* check if this file is a directory or not */

   if (strchr(files[filenum].filename, '/') == NULL)  {

      /* highlight the entry. . . */

      XSetForeground(dpy, sgc, AUXCOLOR);
      XDrawString(dpy, flistpix, sgc, 10, 10 + FILECHARASCENT + filenum * FILECHARHEIGHT,
         files[filenum].filename, strlen(files[filenum].filename));
      XCopyArea(dpy, flistpix, lwin, sgc, 0, flstart * FILECHARHEIGHT,
         textwidth, textheight, 0, 0);

      /* . . .and append it to the text field */

#ifdef TCL_WRAPPER
      Tcl_Eval(xcinterp, ".filelist.textent.txt get");
      ebuf = (char *)Tcl_GetStringResult(xcinterp);
      tbuf = (char *)malloc((strlen(ebuf) +
            strlen(files[filenum].filename) + 6) * sizeof(char));
#else
      ebuf = (char *)XwTextCopyBuffer(textw);
      tbuf = (char *)malloc((XwTextGetLastPos(textw)
           + strlen(files[filenum].filename) + 5) * sizeof(char));
#endif
      strcpy(tbuf, ebuf);

      /* add a comma if there is already text in the destination buffer */

      if (tbuf[0] != '\0') {
         if (tbuf[strlen(tbuf) - 1] != '/') strcat(tbuf, ",");
      }
      else {
       if (cwdname != NULL) {
          if (cwdname[0] != '\0') {
             tbuf = (char *)realloc(tbuf, (strlen(cwdname) +
                  strlen(files[filenum].filename) + 5) * sizeof(char));
             strcpy(tbuf, cwdname);
          }
       }
      }
      strcat(tbuf, files[filenum].filename);
#ifdef TCL_WRAPPER
      Tcl_Eval(xcinterp, ".filelist.textent.txt delete 0 end");
      sprintf(_STR2, ".filelist.textent.txt insert 0 %s", tbuf);
      Tcl_Eval(xcinterp, _STR2);
#else
      XwTextClearBuffer(textw);
      XwTextInsert(textw, tbuf);
      XwTextResize(textw);
#endif
      free(tbuf);
   }
   else {  /* move to new directory */

      if (!strcmp(files[filenum].filename, "../")) {
         char *cptr, *sptr = cwdname;
       if (!strcmp(cwdname, "/")) return; /* no way up from root dir. */
       while(strstr(sptr, "../") != NULL) sptr += 3;
       if ((cptr = strrchr(sptr, '/')) != NULL) {
          *cptr = '\0';
          if ((cptr = strrchr(sptr, '/')) != NULL) *(cptr + 1) = '\0';
          else *sptr = '\0';
         }
       else {
                cwdname = (char *)realloc(cwdname, (strlen(cwdname) +
              4) * sizeof(char));
            strcat(cwdname, "../");
       }
      }
      else {
       cwdname = (char *)realloc(cwdname, (strlen(cwdname) +
              strlen(files[filenum].filename) + 1) * sizeof(char));
         strcat(cwdname, files[filenum].filename);
      }
      newfilelist(w, okaystruct);
   }
}

/*-------------------------------------------------------------------------*/
/* Scrollbar handler for file list widget                      */
/*-------------------------------------------------------------------------*/

void showlscroll(xcWidget w, caddr_t clientdata, caddr_t calldata)
{
   Arg wargs[2];
   Window swin = xcWindow(w);
   Dimension swidth, sheight;
   int pstart, pheight, finscr;
   short n = 0;

#ifdef TCL_WRAPPER
   swidth = Tk_Width(w);
   sheight = Tk_Height(w);
#else
   XtnSetArg(XtNwidth, &swidth);
   XtnSetArg(XtNheight, &sheight);
   XtGetValues(w, wargs, n);
#endif

   XClearWindow(dpy, swin);

   if (flfiles > 0) {   /* no files, no bar */

      finscr = sheight / FILECHARHEIGHT;
      if (finscr > flfiles) finscr = flfiles;

      pstart = (flstart * sheight) / flfiles;
      pheight = (finscr * sheight) / flfiles;

      XSetForeground(dpy, sgc, BARCOLOR);
      XFillRectangle(dpy, swin, sgc, 0, pstart, swidth, pheight);
   }
   flcurrent = -1;
}

/*-------------------------------------------------------------------------*/
/* Button Motion handler for moving the scrollbar up and down              */
/*-------------------------------------------------------------------------*/

void draglscroll(xcWidget w, popupstruct *okaystruct, XButtonEvent *event)
{
   Arg wargs[1];
   Dimension sheight;
   int phheight, finscr, flsave = flstart;
   short n = 0;
   xcWidget filew = okaystruct->filew;

#ifdef TCL_WRAPPER
   sheight = Tk_Height(w);
#else
   XtnSetArg(XtNheight, &sheight);
   XtGetValues(w, wargs, n);
#endif

   finscr = sheight / FILECHARHEIGHT;
   if (finscr > flfiles) finscr = flfiles;

   /* center scrollbar on pointer vertical position */   

   phheight = (finscr * sheight) / (flfiles * 2);
   flstart = (event->y > phheight) ? ((event->y - phheight) * flfiles) / sheight : 0;
   if (flstart > (flfiles - finscr + 2)) flstart = (flfiles - finscr + 2);

   if (flstart != flsave) {
      showlscroll(w, NULL, NULL);
      listfiles(filew, okaystruct, NULL); 
   }
}

/*----------------------------------------------------------------------*/
/* Set/unset the file filtering function                    */
/*----------------------------------------------------------------------*/

#ifndef TCL_WRAPPER

void setfilefilter(xcWidget w, popupstruct *okaystruct, caddr_t calldata)
{
   areastruct.filefilter = (areastruct.filefilter) ? False : True;

   /* Force regeneration of the file list */

   newfilelist(okaystruct->filew, okaystruct);
}

#endif

/*----------------------------------------------------------------------*/
/* Generate the file list window                            */
/*----------------------------------------------------------------------*/

#ifdef TCL_WRAPPER

void genfilelist(xcWidget parent, popupstruct *okaystruct, Dimension width)
{
   xcWidget       listarea, lscroll, entertext;

   entertext = okaystruct->textw;
   listarea = Tk_NameToWindow(xcinterp, ".filelist.listwin.win", parent);

   xcAddEventHandler(listarea, ButtonPressMask, False,
        (xcEventHandler)fileselect, okaystruct);
   xcAddEventHandler(listarea, EnterWindowMask, False,
        (xcEventHandler)startfiletrack, NULL);
   xcAddEventHandler(listarea, LeaveWindowMask, False,
        (xcEventHandler)endfiletrack, NULL);
   flstart = 0;
   okaystruct->filew = listarea;

   lscroll = Tk_NameToWindow(xcinterp, ".filelist.listwin.sb", parent);

   Tk_CreateEventHandler(lscroll, Button1MotionMask | Button2MotionMask,
            (Tk_EventProc *)xctk_draglscroll, (ClientData)okaystruct);

   /* force new file list, in case the highlight filter changed */

   if (flistpix != (Pixmap)NULL) XFreePixmap(dpy, flistpix);
   flistpix = (Pixmap)NULL;
}

#else

void genfilelist(xcWidget parent, popupstruct *okaystruct, Dimension width)
{
   Arg            wargs[8];
   xcWidget       listarea, lscroll, entertext, dofilter;
   short    n = 0;
   int            wwidth;

   XtnSetArg(XtNx, 20);
   XtnSetArg(XtNy, FILECHARHEIGHT - 10);
   XtnSetArg(XtNwidth, width - SBARSIZE - 40);
   XtnSetArg(XtNheight, LISTHEIGHT - FILECHARHEIGHT);
   XtnSetArg(XtNfont, appdata.filefont);

   entertext = okaystruct->textw;

   listarea = XtCreateManagedWidget("Filelist", XwworkSpaceWidgetClass,
        parent, wargs, n); n = 0;
   XtAddCallback(listarea, XtNexpose, (XtCallbackProc)listfiles, okaystruct);

   xcAddEventHandler(listarea, ButtonPressMask, False,
        (xcEventHandler)fileselect, okaystruct);
   xcAddEventHandler(listarea, EnterWindowMask, False,
        (xcEventHandler)startfiletrack, NULL);
   xcAddEventHandler(listarea, LeaveWindowMask, False,
        (xcEventHandler)endfiletrack, NULL);
   flstart = 0;
   okaystruct->filew = listarea;

   XtnSetArg(XtNx, width - SBARSIZE - 20);
   XtnSetArg(XtNy, FILECHARHEIGHT - 10);
   XtnSetArg(XtNwidth, SBARSIZE);
   XtnSetArg(XtNheight, LISTHEIGHT - FILECHARHEIGHT);
   XtnSetArg(XtNfont, appdata.xcfont);

   lscroll = XtCreateManagedWidget("LScroll", XwworkSpaceWidgetClass,
           parent, wargs, n); n = 0;

   XtAddCallback(lscroll, XtNexpose, (XtCallbackProc)showlscroll, NULL);
   xcAddEventHandler(lscroll, Button1MotionMask | Button2MotionMask,
           False, (xcEventHandler)draglscroll, okaystruct);

   /* Add a toggle widget to turn file filtering on/off */

   wwidth = XTextWidth(appdata.xcfont, "filter", strlen("filter"));
   XtnSetArg(XtNx, width - wwidth - 50);
   XtnSetArg(XtNy, LISTHEIGHT + 10);
   XtnSetArg(XtNset, areastruct.filefilter);
   XtnSetArg(XtNsquare, True);
   XtnSetArg(XtNborderWidth, 0);
   XtnSetArg(XtNfont, appdata.xcfont);
   XtnSetArg(XtNlabelLocation, XwLEFT);
   dofilter = XtCreateManagedWidget("Filter", XwtoggleWidgetClass,
            parent, wargs, n); n = 0;
   XtAddCallback(dofilter, XtNselect, (XtCallbackProc)setfilefilter, okaystruct);
   XtAddCallback(dofilter, XtNrelease, (XtCallbackProc)setfilefilter, okaystruct);

   /* force new file list, in case the highlight filter changed */

   if (flistpix != (Pixmap)NULL) XFreePixmap(dpy, flistpix);
   flistpix = (Pixmap)NULL;
}

#endif      /* TCL_WRAPPER */

/*-------------------------------------------------------------------------*/
/* Look for a directory name in a string and update cwdname accordingly    */
/*-------------------------------------------------------------------------*/

int lookdirectory(char *lstring)
{
   int slen;

   xc_tilde_expand(lstring);
   slen = strlen(lstring);

   if (lstring[slen - 1] == '/' || (opendir(lstring) != NULL)) {
      if (lstring[slen - 1] != '/') strcat(lstring, "/");
      cwdname = (char *)realloc(cwdname, (slen + 2) * sizeof(char));
      strcpy(cwdname, lstring);
      return(1);
   }
   return(0);
}

/*-------------------------------------------------------------------------*/

Generated by  Doxygen 1.6.0   Back to index