Re: XForms: File Selector

Steve Lamont (spl@szechuan.ucsd.edu)
Tue, 3 Mar 98 06:24:16 PST

# To subscribers of the xforms list from spl@szechuan.ucsd.edu (Steve Lamont) :

> I am new in this list.I am using xForms for my project ( to develop a
> GUI) . I have the following problem:
>
> 1. In the FileSelector utility one can select a file ( you click on a
> file from list and then select Ready button) but I want to select
> a Directory name from the list ( like select a Directory name and then
> Ready button).
> I am not able to do that , can anyone tell me how to do that?

I "rolled my own" directory browser. I'm attaching it to the end of
this message. There are one or two spl-isms in it but you should be
able to sort them out.

Warning:

Everything you need should be there but since I ripped this out of an
existing piece of code it probably won't compile "out of the box" but
most of the problems you should have are probably going to be missing
function prototypes (I use an automatic prototype generation tool that
automagically creates headers for me containing all my prototypes --
saves a lot of manual updating when I change things). If someone
wants to clean it up and submit it to the XForms utilities archive,
they're welcome to do so. I place it in the Public Domain.

spl

- - -
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <limits.h>
#include <values.h>
#include <sys/param.h>
#include <stdlib.h>

#include <forms.h>

#define down_arrow_width 31
#define down_arrow_height 31
static char down_arrow_bits[] = {
0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00,
0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00,
0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00,
0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00,
0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x7f, 0x00,
0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x1f,
0xf8, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x03,
0xc0, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00, 0xff, 0x7f, 0x00,
0x00, 0xfe, 0x3f, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00,
0x00, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00,
0x00, 0x80, 0x00, 0x00};

#ifdef False
#undef False
#endif
#ifdef True
#undef True
#endif

typedef enum {
False,
True
} Logical;

typedef struct {
FL_FORM *directory_browser;
void *vdata;
char *cdata;
long ldata;
FL_OBJECT *down_arrow;
FL_OBJECT *directory_cascade;
FL_OBJECT *browser;
FL_OBJECT *directory_name;
FL_OBJECT *accept;
FL_OBJECT *scram;
FL_OBJECT *show_files;
} FD_directory_browser;

static void set_up_browser(
FL_OBJECT *browser,
const char *full_path
);

static int directory_filter(
const char *name,
int type
);

static FD_directory_browser * create_form_directory_browser(void);

const char *directory_browser( const char *title,
const char *path,
const char *search,
const char *default_directory )

{

FD_directory_browser *directory_browser = create_form_directory_browser();
const char *full_path =
( const char *) alloca( strlen( path ) +
strlen( default_directory ) +
2 );
FL_OBJECT *obj;
char *directory;

fl_set_dirlist_filter( directory_filter );

fl_set_browser_fontstyle( directory_browser->browser, FL_BOLD_STYLE );
fl_set_browser_fontsize( directory_browser->browser, FL_MEDIUM_SIZE );

fl_set_choice_fontstyle( directory_browser->directory_cascade,
FL_BOLD_STYLE );
fl_set_choice_fontsize( directory_browser->directory_cascade,
FL_MEDIUM_SIZE );

fl_setpup_default_fontstyle( FL_BOLD_STYLE );
fl_setpup_default_fontsize( FL_MEDIUM_SIZE );

sprintf( ( char *) full_path, "%s/%s", path, default_directory );
set_up_browser( directory_browser->browser, full_path );

fl_deactivate_all_forms();

fl_show_form( directory_browser->directory_browser,
FL_PLACE_CENTER,
FL_TRANSIENT,
title );

obj = fl_do_forms();
if ( obj != directory_browser->scram )
directory = ( char *) directory_browser->browser->u_vdata;
else
directory = strdup( full_path );

destroy_object_form( obj );

fl_activate_all_forms();

return directory;

}

static void set_up_browser( FL_OBJECT *browser, const char *full_path )

{

char *path = strdup( ( char *) full_path );
int i;
int n_files;
const FL_Dirlist *dirlist;
FD_directory_browser *directory_browser = DUI( FD_directory_browser,
browser );
Logical show_files;
char *p;

dirlist =
fl_get_dirlist( *path == '\0' ? "/" : path, "*", &n_files, True );
fl_set_dirlist_filter( NULL );

fl_freeze_form( browser->form );

fl_clear_browser( browser );

show_files = fl_get_button( directory_browser->show_files );

for ( i = 0; i < n_files; i++ )
if ( ( *(dirlist[i].name) != '.' ) &&
( ( dirlist[i].type == FT_DIR ) ) )
fl_add_browser_line( browser, dirlist[i].name );
else if ( show_files &&
( ( dirlist[i].type == FT_FILE ) ||
( dirlist[i].type == FT_LINK ) ) ) {

char buffer[MAXPATHLEN + 10];

/*
* These guys are non-selectable.
*/

sprintf( buffer, "@N@C%d@x%s", FL_GRAY75, dirlist[i].name );
fl_add_browser_line( browser, buffer );

}

fl_clear_choice( directory_browser->directory_cascade );
fl_redraw_form( directory_browser->directory_browser );

while ( p = strrchr( ( char *) path, '/' ) ) {

const char *directory;

*p = '\0';
directory = ( const char *) p + 1;
if ( strcmp( directory, "auto" ) == 0 )
break;
fl_addto_choice( directory_browser->directory_cascade, directory );

};
fl_addto_choice( directory_browser->directory_cascade, "/" );

fl_set_object_label( directory_browser->directory_name,
full_path );
fl_unfreeze_form( browser->form );

path = strdup( full_path );
if ( browser->u_vdata )
free( browser->u_vdata );
browser->u_vdata = path;

}

static int directory_filter( const char *name, int type )

{

return False;

}

static void directory_browser_cb( FL_OBJECT *ob, long data )

{

char *default_directory = strdup( ( char *) ob->u_vdata );
const char *line = fl_get_browser_line( ob, fl_get_browser( ob ) );

if ( line ) {

const char *new_default_directory;

new_default_directory =
( const char *) alloca( strlen( default_directory ) +
strlen( line ) + 2 );

sprintf( ( char *) new_default_directory, "%s/%s",
default_directory, line );

set_up_browser( ob, new_default_directory );

}

}

static void directory_rescan_cb( FL_OBJECT *ob, long data )

{

FL_OBJECT *browser = DUI( FD_directory_browser, ob )->browser;

set_up_browser( browser, ( char *) browser->u_vdata );

}

static void directory_cascade_cb( FL_OBJECT *ob, long data )

{

FL_OBJECT *browser = DUI( FD_directory_browser, ob )->browser;
int choice = fl_get_choice( ob );
char *path = ( char *) calloc( 1, 1 );
int choices = fl_get_choice_maxitems( ob );
int i;

fl_redraw_form( browser->form );
for ( i = choices - 1; i >= choice; i-- ) {

const char *choice_item = fl_get_choice_item_text( ob, i );

path = ( char *) realloc( path,
strlen( path ) +
strlen( choice_item ) + 2 );
strcat( path, "/" );
strcat( path, choice_item );

}

set_up_browser( browser, path );

free( path );

}

static void directory_show_files_cb( FL_OBJECT *ob, long data )

{

FL_OBJECT *browser = DUI( FD_directory_browser, ob )->browser;

set_up_browser( browser, ( char *) browser->u_vdata );

}

static void destroy_object_form( FL_OBJECT *obj )

{

FL_FORM *form = obj->form;
void *dui = form->fdui;

fl_hide_form( form );
fl_free_form( form );
free( dui );

}

FD_directory_browser *create_form_directory_browser(void)
{
FL_OBJECT *obj;
FD_directory_browser *fdui = (FD_directory_browser *) fl_calloc(1, sizeof(*fdui));

fdui->directory_browser = fl_bgn_form(FL_NO_BOX, 390, 340);
obj = fl_add_box(FL_FLAT_BOX,0,0,390,340,"");
fl_set_object_color(obj,FL_DODGERBLUE,FL_COL1);
fdui->down_arrow = obj = fl_add_bitmap(FL_NORMAL_BITMAP,345,10,35,35,"");
fl_set_object_color(obj,FL_DODGERBLUE,FL_COL1);
fl_set_bitmap_data(obj,down_arrow_width, down_arrow_height, (unsigned char *)down_arrow_bits);
obj = fl_add_frame(FL_BORDER_FRAME,10,10,370,35,"");
fdui->directory_cascade = obj = fl_add_choice(FL_NORMAL_CHOICE,10,10,370,35,"");
fl_set_object_boxtype(obj,FL_NO_BOX);
fl_set_object_color(obj,FL_DODGERBLUE,FL_BLACK);
fl_set_object_lcolor(obj,FL_WHEAT);
fl_set_object_callback(obj,directory_cascade_cb,0);
fdui->browser = obj = fl_add_browser(FL_SELECT_BROWSER,10,50,370,210,"");
fl_set_object_color(obj,FL_DARKVIOLET,FL_YELLOW);
fl_set_object_lcolor(obj,FL_WHEAT);
fl_set_object_lsize(obj,FL_MEDIUM_SIZE);
fl_set_object_lstyle(obj,FL_BOLD_STYLE);
fl_set_object_callback(obj,directory_browser_cb,0);
fdui->directory_name = obj = fl_add_text(FL_NORMAL_TEXT,10,270,370,25,"");
fl_set_object_boxtype(obj,FL_EMBOSSED_BOX);
fl_set_object_color(obj,FL_DODGERBLUE,FL_DARKCYAN);
fl_set_object_lcolor(obj,FL_WHEAT);
fl_set_object_lsize(obj,FL_NORMAL_SIZE);
fl_set_object_lalign(obj,FL_ALIGN_RIGHT|FL_ALIGN_INSIDE);
fl_set_object_lstyle(obj,FL_BOLD_STYLE);
obj = fl_add_button(FL_NORMAL_BUTTON,95,300,85,30,"Rescan");
fl_set_object_color(obj,FL_DARKGOLD,FL_DARKTOMATO);
fl_set_object_lcolor(obj,FL_WHEAT);
fl_set_object_lsize(obj,FL_MEDIUM_SIZE);
fl_set_object_lstyle(obj,FL_BOLD_STYLE+FL_EMBOSSED_STYLE);
fl_set_object_callback(obj,directory_rescan_cb,0);
fdui->accept = obj = fl_add_button(FL_RETURN_BUTTON,295,300,85,30,"Accept");
fl_set_object_color(obj,FL_GREEN,FL_PALEGREEN);
fl_set_object_lsize(obj,FL_MEDIUM_SIZE);
fl_set_object_lstyle(obj,FL_BOLD_STYLE+FL_ENGRAVED_STYLE);
fdui->scram = obj = fl_add_button(FL_NORMAL_BUTTON,10,300,85,30,"Scram!");
fl_set_object_color(obj,FL_RED,FL_DEEPPINK);
fl_set_object_lsize(obj,FL_MEDIUM_SIZE);
fl_set_object_lstyle(obj,FL_BOLD_STYLE+FL_ENGRAVED_STYLE);
fdui->show_files = obj = fl_add_checkbutton(FL_PUSH_BUTTON,180,300,115,30,"Show Files");
fl_set_object_color(obj,FL_BLACK,FL_YELLOW);
fl_set_object_lcolor(obj,FL_WHEAT);
fl_set_object_lsize(obj,FL_MEDIUM_SIZE);
fl_set_object_lstyle(obj,FL_BOLD_STYLE+FL_EMBOSSED_STYLE);
fl_set_object_callback(obj,directory_show_files_cb,0);
fl_end_form();

fl_adjust_form_size(fdui->directory_browser);
fdui->directory_browser->fdui = fdui;

return fdui;
}
- - -
_________________________________________________
To unsubscribe, send the message "unsubscribe" to
xforms-request@bob.usuf2.usuhs.mil or see
http://bob.usuf2.usuhs.mil/mailserv/xforms.html
XForms Home Page: http://bloch.phys.uwm.edu/xforms
List Archive: http://bob.usuf2.usuhs.mil/mailserv/list-archives/