README for the MAEstro File Browser.

The File Browser is a tool, written with the XView toolkit, to include
in your XView-based applications.  The Browser provides a simple panel
that lets users choose filenames by using only the mouse; it also
provides file completion (through the use of the Escape and Tab keys)
and simple filetyping, so that only files of a particular type are
shown.

The following shows how to incorporate the Browse / SavePanel File
Browser into your code.

Add the following definitions to your Makefile (this assumes that the
MAEstro Source directory is in /home/sioux/collab/Source):

SourceDir		= /home/sioux/collab/Source
BrowseSourceDir		= $(SourceDir)/Browse
ExtraObjects = \
	$(BrowseSourceDir)/Browse.o $(BrowseSourceDir)/Browse_ui.o

If your Makefile has a definition for "CPPFLAGS", add this to it:

	-I$(BrowseSourceDir)

Otherwise, add this whereever appropriate to your compiler flags.

If your Makefile was generated by GUIDE, then you will likely want to
modify the following lines to include the $(ExtraObjects) variable, as
shown here:

objects: $(SOURCES.c) $(TARGETS.c) $(TARGETS.h) $(OBJECTS) $(ExtraObjects)

$(PROGRAM): $(SOURCES.c) $(TARGETS.c) $(TARGETS.h) $(OBJECTS) $(ExtraObjects)
	$(LINK.c) -o $(PROGRAM) $(OBJECTS) $(ExtraObjects) $(LDFLAGS) $(LDLIBS)

stest: $(SOURCES.c) $(TARGETS.c) $(TARGETS.h) $(OBJECTS) $(ExtraObjects)
	#load $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) \
		-o $(PROGRAM) $(SOURCES.c) $(TARGETS.c) $(ExtraObjects) $(LDLIBS)



Be sure to include the following file in any .c file that calls the browse routine:
	#include <Browse.h>


Declare the following routines as globals (I put this line just after I've declared the 
pointer to the base window objects):
	int OpenHandler(), SaveHandler(); 


After you've initialized the base window objects, call the following
function with three parameters. The third parameter is most likely the
same argument that you passed into xv_main_loop():

	CreateBrowse(OpenHandler, SaveHandler, BaseWindow->baseWindow);

Now whenever you want the browser to open just call the following routine:
        void Browse(path, function, id, firstLine, appName)
		char *path;       /* absolute or relative or NULL  */
		int function;     /* BrowseOpen, BrowseSave, BrowseCheckOpen, 
				     BrowseCheckSave, or BrowseMultiple */
	        int id;           /* will be passed to OpenHandler or SaveHandler */
		char *firstLine   /* either NULL or match first line of edit files */
		char *appName     /* either NULL or the name of the application */

	If path is a null string then the browser will start browsing with the 
	current working directory loaded in.  If path is an absolute pathname
	(perhaps generated with the realpath() function) then this will be the
	starting browse directory.  If path is a non-absolute pathname then the 
	starting browse directory will be that specified by path beginning at the 
	current directory node.  If path specifies an invalid directory	then the 
	current working directory will be the one loaded in.
	
	If function is BrowseOpen or BrowseSave then the Browser will appear and the
	user can select a single filename for opening or saving. If function is
	BrowseCheckOpen then the permission checking is performed on the file and it
	is passed to the OpenHandler without the Browser panel appearing; this 
	feature is useful for doing permission checking on a filename passed in as
	a command line argument. BrowseCheckSave performs the analogous function for
	saving without bringing up the Browser panel; this may be useful for 
	implementing a Save function different from the Save As function. If function 
	is BrowseMultiple then several files can be selected simultaneously from the 
	Browser for opening.

	The id argument is an integer that will be passed to the OpenHandler() 
	or SaveHandler() routine, in case you have different versions of your program 
	accessing Browse() simultaneously. This could be used to help facilitate the 
	implementation of multiple documents. In general you probably don't need to 
	worry about this and you can just pass in NULL as the id argument.

        The firstLine string should either be NULL (if all files should always be
        displayed), or it should be identical to the first line of the files that
        you wish to have displayed. For ShellEdit I use "#Shell Edit File#".  
	This provides for very simple file typing; currently, all
	MAEstro applications use the first line of their documents to
	denote file type.

	The appName string should either be NULL or the application name. This is
        used in the field that asks whether only files of this type should be 
        displayed.

	Browse() will open the file browser.  Once a file is selected either
	OpenHandler() or SaveHandler() will be called depending on whether
	Browse was called with BrowseOpen or BrowseSave.


You should write two functions, OpenHandler() and SaveHandler() which are passed 
the proposed pathname, as well as the integer id that you passed to Browse(). 

	int OpenHandler(proposedPath, id)
		char *proposedPath;
		int id;

	int SaveHandler(proposedPath, id)
		char *proposedPath;
		int id;

If you "like" the pathname (after trying to open the pathname or after trying to save 
to the pathname) then simply return a 0 and the file browser will hide itself.  If 
you don't like the pathname then return any nonzero integer and the file browser will 
remain shown and active, waiting to generate another selection.  In ShellEdit.c the 
OpenHandler() and SaveHandler() look very similar.  Here is the former:

	int OpenHandler(char *proposedPath, int id)
	  {	
	    xv_set(ShellEdit_baseWindow->filename, PANEL_VALUE, proposedPath, NULL);
	    if (OpenEditFile() == 1)
	      return 0;
	    else
	      return 1;
	  }

If you have any questions or problems, take a look at the ShellEdit.c
code as an example.

Bryant Marks