home *** CD-ROM | disk | FTP | other *** search
- /*
- * browser.c : Device-independent browser routines
- *
- * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
- */
-
- #include <stdio.h>
- #include "stringdefs.h"
- #include "pfs.h"
- #include "db.h"
- #include "xtypes.h"
- #include "appres.h"
- #include "query.h"
- #include "actions.h"
- #include "browser.h"
- #include "selection.h"
- #include "display.h"
- #include "ftp-actions.h"
- #include "alert.h"
- #include "status.h"
- #include "debug.h"
- extern DbEntry *db;
-
- /*
- * Functions defined here:
- */
- void resetBrowser();
- int paneDepth();
- void selectBrowserItem(),unselectBrowserItem();
- void displayEntries();
- void resortBrowser();
- int openBrowserAll(),openBrowserDirectories(),openBrowserFiles();
- void shiftBrowserDown(), shiftBrowserUp(), shiftBrowserTop();
- void setBrowserState();
- int getBrowserState();
-
- static void clearInfoForDepth(),displayInfoForDepth();
- static void updateButtons(),resetParentEntries();
- static void openBrowserDirectory();
-
- /*
- * Data defined here:
- */
- /*
- * These are the parents of the heads of the lists being displayed in
- * the browser panes.
- */
- static DbEntry *parentEntries[MAX_DEPTH];
-
- /*
- * This is the index of the leftmost pane's contents in the previous arrays.
- */
- static int currentRootDepth;
-
- static int browserState;
-
- /* - - - - - - - - */
-
- void
- resetBrowser()
- {
- clearBrowser();
- currentRootDepth = 0;
- resetSelections(0);
- resetParentEntries(0);
- setUpSensitive(0);
- setDownSensitive(0);
- }
-
- int
- paneDepth(pane)
- int pane;
- {
- return(currentRootDepth+pane);
- }
-
- #ifdef DEBUG
- /*ARGSUSED*/
- static void
- doPrint(dbp,list_index)
- DbEntry dbp;
- int list_index;
- {
- printf("%d ",list_index);
- }
- #endif
-
- void
- selectBrowserItem(pane,item)
- int pane,item;
- {
- DbEntry *dbp;
- int depth;
-
- /* Adjust for shifted browser */
- depth = paneDepth(pane);
- #ifdef DEBUG
- fprintf(stderr,"selecting item %d, pane=%d, depth=%d\n",item,pane,depth);
- fprintf(stderr," before: selections[] = ");
- if (hasSelection(depth))
- forEachSelectedItemAtDepth(depth,doPrint);
- else
- fprintf(stderr,"None");
- fprintf(stderr,"\n");
- #endif
- if (isSelected(depth,item)) {
- DEBUG1("item %d already selected\n",item);
- return;
- }
- dbp = findEntryFromIndex(parentEntries[depth],item);
- DEBUG2("selected item is \"%s\"(%lx)\n",dbp->name,dbp);
- DEBUG1("clearing parents depth >= %d\n",depth+1);
- resetParentEntries(depth+1);
- DEBUG1("resetting selections for depth >= %d\n",depth+1);
- resetSelections(depth+1);
- DEBUG3("adding selection at depth %d = \"%s\"(%lx)\n",depth,dbp->name,dbp);
- addSelection(depth,dbp,item);
- DEBUG3("setting parentEntries[%d] = \"%s\"(%lx)\n",depth+1,dbp->name,dbp);
- parentEntries[depth+1] = dbp;
- DEBUG3("displaying entry \"%s\"(%lx) in pane %d\n",dbp->name,dbp,pane);
- /* Highlight the selected item */
- redrawSelectionsForPane(pane);
- /* Show selected info */
- displayInfoForDepth(depth);
- /* If we're not at the rightmost pane, then show the choices. */
- if (pane < NUM_BROWSER_PANES-1) {
- displayEntries(dbp,pane+1);
- }
- #ifdef DEBUG
- fprintf(stderr," after: selections[] = ");
- if (hasSelection(depth))
- forEachSelectedItemAtDepth(depth,doPrint);
- else
- fprintf(stderr,"None");
- fprintf(stderr,"\n");
- fprintf(stderr,"done selecting item\n");
- #endif
- }
-
- void
- unselectBrowserItem(pane,item)
- int pane,item;
- {
- int depth,i;
-
- /* Adjust for shifted browser */
- depth = paneDepth(pane);
- #ifdef DEBUG
- fprintf(stderr,"unselecting item %d, pane=%d, depth=%d\n",item,pane,depth);
- fprintf(stderr," before: selections[] = ");
- if (hasSelection(depth))
- forEachSelectedItemAtDepth(depth,doPrint);
- else
- fprintf(stderr,"None");
- fprintf(stderr,"\n");
- #endif
- unhighlightBrowserItem(pane,item);
- /* Clear all panes below this one */
- for (i=NUM_BROWSER_PANES-1; i > pane; i--)
- clearBrowserPane(i);
- /* Clear all info including this one since de-selected */
- clearInfoForDepth(depth);
- DEBUG2("removing selection at depth %d = item %d\n",depth,item);
- removeSelection(depth,NULL,item);
- DEBUG1("clearing parents depth >= %d\n",depth+1);
- resetParentEntries(depth+1);
- #ifdef DEBUG
- printf(" after: selections[] = ");
- if (hasSelection(depth))
- forEachSelectedItemAtDepth(depth,doPrint);
- else
- printf("None");
- printf("\n");
- fprintf(stderr,"done deselecting item\n");
- #endif
- }
-
- static void
- clearInfoForDepth(depth)
- int depth;
- {
- switch (depth) {
- case 0: setHostText("");
- /* fall through */
- case 1: setLocationText("");
- /* fall through */
- case 2: setFileText("");
- setSizeText("");
- setModesText("");
- setDateText("");
- break;
- }
- DEBUG1("cleared info for depth %d\n",depth);
- }
-
- static void
- displayInfoForDepth(depth)
- int depth;
- {
- SelectedItem *item;
- char buf[MAX_VPATH];
- int i;
-
- DEBUG1(" display info for depth %d:\n",depth);
- if ((item=getSelection(0)) != NULL) {
- setHostText(item->entry->name);
- DEBUG1(" host: \"%s\"\n",item->entry->name);
- }
- /* Special case if location was selected */
- if (depth == 1) {
- if ((item=getSelection(1)) != NULL) {
- setLocationText(item->entry->name);
- DEBUG1(" loc: \"%s\"\n",item->entry->name);
- }
- } else { /* Otherwise normal case, get location and file */
- strcpy(buf,"");
- for (i=1; i < depth; i++)
- if ((item=getSelection(i)) != NULL) {
- (void)strcat(buf,item->entry->name);
- if (i < depth-1 &&
- buf[strlen(buf)-1] != '/')
- strcat(buf,"/");
- }
- setLocationText(buf);
- DEBUG1(" loc: \"%s\"\n",buf);
- if ((item=getSelection(depth)) != NULL) {
- setFileText(item->entry->name);
- #ifdef MSDOS
- sprintf(buf,"%lu",item->entry->size);
- #else
- sprintf(buf,"%d",item->entry->size);
- #endif
- setSizeText(buf);
- setModesText(item->entry->modes);
- setDateText(item->entry->date);
- DEBUG1(" file: \"%s\"\n",item->entry->name);
- }
- }
- }
-
- void
- displayEntries(parent,pane)
- DbEntry *parent;
- int pane;
- {
- DbEntry *dbp;
- SelectedItem *sel;
- int i,depth;
-
- depth = paneDepth(pane);
- if (parent == NULL) {
- fprintf(stderr,"DB error: attempt to display entries from NULL list");
- return;
- }
- DEBUG3("displaying parent \"%s\" in pane %d (depth %d)\n",
- (parent?parent->name:"<NIL>"),pane,depth);
- /* Clear this and all subordinate panes */
- for (i=pane; i < NUM_BROWSER_PANES; i++) {
- DEBUG1(" clearing pane %d\n",i);
- clearBrowserPane(i);
- }
- /* Set the strings to be displayed in this pane */
- for (i=0, dbp=parent->entries; dbp != NULL; dbp=dbp->next) {
- DEBUG2(" item %d: \"%s\"\n",i,dbp->name);
- setBrowserItem(pane,i++,dbp->name);
- }
- /* If there's anything to display, display it */
- if (i > 0)
- redrawBrowserPane(pane);
- /* If there's only one thing then select it */
- if (i == 1) {
- DEBUG0(" solo -> select\n");
- addSelection(depth,parent->entries,0);
- }
- /* If there's something selected (either because we just selected the
- only thing or because we're scrolling left), then redo the
- highlighting and display the correct info. If we're not at the
- rightmost pane, then recusively draw the next pane. */
- if ((sel=getSelection(depth)) != NULL) {
- redrawSelectionsForPane(pane);
- displayInfoForDepth(depth);
- if (pane < NUM_BROWSER_PANES - 1)
- displayEntries(sel->entry,pane+1);
- } else {
- /* Otherwise there's nothing selected here */
- clearInfoForDepth(depth);
- }
- /* Save which list is being displayed in the pane */
- parentEntries[paneDepth(pane)] = parent;
- /* Get the shift buttons right */
- updateButtons();
- }
-
- static void
- updateButtons()
- {
- SelectedItem *sel;
-
- setUpSensitive(currentRootDepth > 0);
- if ((sel=getSelection(currentRootDepth+NUM_BROWSER_PANES-1)) != NULL &&
- sel->entry->entries != NULL)
- setDownSensitive(1);
- else
- setDownSensitive(0);
- }
-
- static void
- resetParentEntries(first)
- int first;
- {
- int i;
-
- for (i=first; i < MAX_DEPTH; i++)
- parentEntries[i] = NULL;
- }
-
- /* - - - - - - - - */
- /* Resort the browser based on the appResources */
-
- void
- resortBrowser()
- {
- /* Reset browser to leftmost position */
- DEBUG0("resortBrowser: resetting browser\n");
- resetBrowser();
- DEBUG0("resortBrowser: sorting entries\n");
- switch(appResources.sortType) {
- case GfName:
- sortEntriesRecursively(db,cmpEntryNames);
- break;
- case GfDate:
- sortEntriesRecursively(db,cmpEntryDates);
- break;
- case GfWeight:
- sortEntriesRecursively(db,cmpEntryWeights);
- break;
- }
- /* Display results in browser */
- DEBUG0("resortBrowser: displaying entries\n");
- displayEntries(db,0);
- DEBUG0("resortBrowser: done\n");
- }
-
- /* - - - - - - - - */
- /* Routines to open (ie. expand) the browser */
-
- static int numOpened;
-
- /*
- * Open any selected items in the browser. Return the number of items
- * that were successfully opened.
- */
- int
- openBrowserAll()
- {
- DEBUG1("openBrowserAll: depth = %d\n",currentRootDepth);
- if (!hasSelection(NUM_BROWSER_PANES-1)) {
- alert0("You must select something to open.");
- return(0);
- }
- numOpened = 0;
- /* Do the directories */
- forEachSelectedItem(openBrowserDirectory);
- /* Do the files */
- ftpOpenSelectedItems();
- status0("Ready");
- DEBUG1("done openBrowserAll, returning %d\n",numOpened);
- return(numOpened);
- }
-
- int
- openBrowserDirectories()
- {
- DEBUG1("openBrowserDirectories: depth = %d\n",currentRootDepth);
- if (!hasSelection(2)) {
- alert0("You must select a directory to open.");
- return(0);
- }
- numOpened = 0;
- forEachSelectedItem(openBrowserDirectory);
- status0("Ready");
- DEBUG1("done openBrowserDirectories, returning %d\n",numOpened);
- return(numOpened);
- }
-
- int
- openBrowserFiles()
- {
- DEBUG1("openBrowserFiles: depth = %d\n",currentRootDepth);
- if (!hasSelection(2)) {
- alert0("You must select a file to open.");
- return(0);
- }
- numOpened = 0;
- ftpOpenSelectedItems();
- status0("Ready");
- DEBUG1("done openBrowserFiles, returning %d\n",numOpened);
- return(numOpened);
- }
-
- /*
- * Open a selected item. Ignore any selections that aren't directories.
- */
- /*ARGSUSED*/
- static void
- openBrowserDirectory(dbp,list_index)
- DbEntry *dbp;
- int list_index;
- {
- VLINK vl,links;
-
- DEBUG1("openBrowserDirectory: \"%s\"\n",dbp->name);
- if (dbp->type != DB_DIRECTORY)
- return;
- if (dbp->entries == NULL) {
- /* It's not been expanded already... */
- if ((vl=dbp->vlink) == NULL) {
- alert0("ERROR: NULL vlink to openBrowserDirectory!");
- return;
- }
- /* Disable querying */
- setBrowserState(BROWSER_DIRSEND);
- DEBUG1("getting entries for \"%s\"\n",dbp->name);
- links = stringQuery(vl->host,vl->filename);
- DEBUG0("calling handleProsperoErrors\n");
- (void)handleProsperoErrors();
- if (links != NULL)
- numOpened += 1;
- #ifdef DEBUG
- fprintf(stderr,"unprocessed results of stringQuery:\n");
- for (vl=links; vl != NULL; vl=vl->next)
- fprintf(stderr," \"%s\"\n",vl->filename);
- fprintf(stderr,"calling parseStringQueryResults\n");
- #endif
- /* Process the results into the database */
- switch(appResources.sortType) {
- case GfName:
- (void)parseStringQueryResults(dbp,links,cmpEntryNames);
- break;
- case GfDate:
- (void)parseStringQueryResults(dbp,links,cmpEntryDates);
- break;
- case GfWeight:
- (void)parseStringQueryResults(dbp,links,cmpEntryWeights);
- break;
- }
- /* Re-enable querying */
- setBrowserState(BROWSER_READY);
- }
- DEBUG0("done openBrowserDirectory\n");
- }
-
- /* - - - - - - - - */
- /* Routines for shifting the browser up, down, top. */
-
- void
- shiftBrowserDown()
- {
- DEBUG1("doing shiftDown, depth = %d\n",currentRootDepth);
- if (currentRootDepth >= MAX_DEPTH-1) {
- alert1("Browser only goes %d levels deep!",(char *)MAX_DEPTH);
- return;
- }
- if (parentEntries[currentRootDepth+1] == NULL) {
- alert0("Nothing to display below!");
- return;
- }
- currentRootDepth += 1;
- DEBUG1("currentRootDepth is now %d\n",currentRootDepth);
- displayEntries(parentEntries[currentRootDepth],0);
- DEBUG0("done shiftDown\n");
- }
-
- void
- shiftBrowserUp()
- {
- DEBUG1("doing shiftUp, depth = %d\n",currentRootDepth);
- if (currentRootDepth == 0) {
- beep();
- return;
- }
- currentRootDepth -= 1;
- DEBUG1("currentRootDepth is now %d\n",currentRootDepth);
- displayEntries(parentEntries[currentRootDepth],0);
- DEBUG0("done shiftUp\n");
- }
-
- void
- shiftBrowserTop()
- {
- DEBUG1("doing shiftTop, depth = %d\n",currentRootDepth);
- currentRootDepth = 0;
- DEBUG1("currentRootDepth is now %d\n",currentRootDepth);
- displayEntries(db,0);
- DEBUG0("done shiftTop\n");
- }
-
- /* - - - - - - - - */
- /* Routines for getting/setting the state of the browser */
- /*
- * Non-zero state => busy
- */
-
- void
- setBrowserState(state)
- int state;
- {
- setQuerySensitive(state == BROWSER_READY);
- setAbortSensitive(state != BROWSER_READY);
- browserState = state;
- }
-
- int
- getBrowserState()
- {
- return(browserState);
- }
-
-