home *** CD-ROM | disk | FTP | other *** search
- # $Header: P:/source/ppee/macros/dtree.pev 1.2 20 Sep 1990 13:43:14 ericj $
-
- ##############################################################################
- #
- # Sage Software - POLYTRON Division
- # 1700 NW 167th Place
- # Beaverton, OR 97006
- #
- # Copyright 1990, Sage Software, Inc.
- #
- # Permission is hereby granted for licensed users of Sage Professional
- # Editor and PolyAwk to copy and modify this source code for their own
- # personal use. These derivative works may be distributed only to other
- # licensed Sage Professional Editor and PolyAwk users. All other usage
- # is prohibited without express written permission from Sage Software.
- #
- ##############################################################################
-
- #### $Workfile: dtree.pel $:
- #
- # Build a tree structure of the given directory
- #
-
-
-
-
- local file_list[] # list of files in current directory
- local file_selection # current file selected to be edited, if any
- local dir_selection # current directory highlighted in tree
-
- local new_eol_str = "" # new eol string in file list buffer
-
-
- local tree_winid = 0;
- local tree_keymap
- local tree_buffer
- local tree_drive
- local tree_cwd
- global tree_lines;
-
- local tree_array[];
-
-
-
- ## tree
- #
- # drv - Specified the drive/path for which to build a directory tree of.
- # If drv is not specified, the current drive is used (from the root on).
- #
- # A tree diagram of the directory structure is constructed an inserted into
- # a buffer. Once displayed, the tree can be used to changed directories and
- # display contents of.
- #
- # Once displayed, the following keystrokes are valid:
- # <ESC> - return to caller
- # <DOWN> - goto next directory in tree
- # <UP> - goto previos directory in tree
- # <TAB> - display the contents of the current directory selected
- # <ENTER> - make the directory selected the current working directory
- # <PGUP> - goto previous page in directory tree
- # <PGDN> - goto next page in directory tree
- # <LEFT_PRESS> - select directory under mouse
- # <LEFT_CLICK> - display the contents of the current directory selected
- #
- function dtree( drv ){
- local tree_win_height = display_height - 6;
- local tree_win_width = 35;
- local tree_win_x0 = 0;
- local tree_win_y0 = 3;
- local save_window = current_window;
- local save_buffer = current_buffer;
- local eolstr = default_buffer_eol_string;
- local cdrive = (argcount() == 1 ? trim(ltrim(drv)) : dos_drive());
- local level;
- local valid_drv = TRUE;
- local fmode;
-
- init_menu_colors();
- file_selection = ""
-
-
- # If the tree window doesn't exist create one.
- #
- if (!tree_winid) {
- current_window =
- tree_winid = create_factory_window( tree_win_x0, \
- tree_win_y0, \
- tree_win_width, \
- tree_win_height, \
- WINDOW_BORDER + WINDOW_SYSTEM);
-
- color_text = color_border = BAR_COLOR
- color_highlight = HBAR_COLOR;
-
- visible_end_buffer = ""
- visible_tabs = ""
- visible_virtual_lines = ""
-
- # hide the window until all other messages have been
- # put on the screen
- #
- hide_window( tree_winid );
- }
-
- # if the tree buffer doesn't exist create one.
- #
- if (!tree_buffer){
- tree_drive = " ";
- # create a new buffer to put the filenames into
- default_buffer_eol_string = new_eol_str
- tree_buffer = \
- create_buffer( "", "", BUFFER_SYSTEM + BUFFER_NO_UNDO )
- default_buffer_eol_string = eolstr;
- }
-
- attach_window_buffer( tree_winid, tree_buffer );
-
- # if the tree keymap doesn't exists create one.
- #
- if (!tree_keymap) {
- tree_keymap = create_keymap(empty_keymap)
- push_keymap(tree_keymap)
-
- assign_key( "<ESC>", "process_end" );
- assign_key( "<down>", "tree_down 1" );
- assign_key( "<up>", "tree_up 1" );
- assign_key( "<TAB>", "tree_expand" );
- assign_key( "<ENTER>","tree_chdir" );
- assign_key( "<PGUP>", "tree_up " tree_win_height - 2 );
- assign_key( "<PGDN>", "tree_down " tree_win_height - 2 );
-
- assign_key( "#61440", "tree_mouse_key" ) # left press
- assign_key( "#62976", "tree_mouse_key" ) # left click
-
-
- pop_keymap();
- }
-
-
-
- #
- # validate the drive and path given by first checking to see
- # if a valid drive was provided (if any) and then ensuring
- # that the path is valid.
- #
- fmode = 0;
- if (index( cdrive, ":" )) {
- fmode = 1; # a drive is specified
- drv = dos_drive();
- if ( !dos_drive( cdrive ))
- valid_drv = FALSE;
- dos_drive( drv );
- }
-
-
- # if the drive/path is valid so far, check to see if it is valid
- #
- if (valid_drv) {
- cdrive = buildpath( cdrive "\\" );
- if ( !(fmode && length(cdrive)==3) )
- #
- # in DOS, filemode() doesn't always work
- # on a network directory, so use filetime()
- #
- if ( filetime( trim(cdrive, "\\")) <= 0)
- valid_drv = FALSE;
- }
-
-
- # if still valid, read the directory structure for the path
- #
- if (valid_drv) {
- cdrive = trim( cdrive, "\\" );
- push_keymap(tree_keymap)
-
-
- # if the drive/path is the same as last time, use the
- # previous reading, otherwise create a new one.
- #
- if (tree_drive != cdrive){
-
- # delete all references to previous read
- #
- tree_unmark();
- tree_drive = cdrive;
- delete( tree_array )
- delete( tree_lines )
-
- # delete buffer contents
- #
- goto_buffer_bottom();
- drop_anchor();
- goto_buffer_top()
- delete_chars();
-
- # read all of the directory names and store
- # in an array.
- #
- message( "Scanning directories..." );
- build_tree( 0, cdrive )
-
- # Actually insert the names of the directories
- # into the tree_buffer and format them using
- # vertical bars to designate hierarchy structure.
- #
- message( "Constructing tree..." );
- current_window = tree_winid;
- current_buffer = tree_buffer;
- tree_lines[ current_line ] = cdrive;
- insert_string( " " cdrive "\\\n" );
- create_tree_graph( 0, cdrive, " " );
- backspace();
-
- goto_buffer_top();
- tree_mark_cwd( cdrive );
- }
-
- current_window = tree_winid;
- current_buffer = tree_buffer;
- restore_window();
-
- message( "Scanning complete." );
-
- display_update();
- process_begin();
- pop_keymap();
- } else {
- notify( "invalid path specification '" cdrive "'." );
- }
-
- if (window_valid(save_window)) {
- current_window = save_window; # restore original window.
- current_buffer = save_buffer; # restore original buffer.
- }
-
- # Don't worry about hiding the window, just delete it and
- # we'll create it again later.
- #
- delete_window( tree_winid );
- tree_winid = 0;
-
- display_update(); # !!?? this shouldn't have to be here but there is
- # a bug in the windows code which leaves a
- # highlight on the screen
-
- if (file_selection)
- edit_file( file_selection );
-
- }
-
-
-
-
- ## build_tree
- #
- # Build the tree structure by reading all or the directories and insert
- # them into the tree_array.
- #
- # build_tree is called recursively to collect all of the directory names
- #
- # tree_array is a 2 dimensional array containing the path and directory name
- # dimension
- # 1 - <tree level 0..n> " " <directory path>
- # 2 - <directory name>
- #
- #
- function build_tree( level, dir_path ){
- local dname;
-
- dname = findfirst( dir_path "\\*.*" , _SUBDIR );
- while (dname) {
- tree_array[ level " " dir_path ][ dname ] = 0;
- dname = findnext();
- }
-
- # don't include the "." or "..", if any
- #
- delete( tree_array[ level " " dir_path ][ "." ] )
- delete( tree_array[ level " " dir_path ][ ".." ] )
-
- # recurse through each directory
- #
- for (dname in tree_array[ level " " dir_path ])
- build_tree( level + 1, dir_path "\\" dname );
- }
-
-
-
-
- ## create_tree_graph
- #
- # Create a tree graph by traversing the tree_array array and extracting each
- # level directories.
- #
- function create_tree_graph( level, dir_path, p_pattern ){
- local dname;
- local last_dname;
-
- # Insert all of the directories into a list but don't process
- # the last directory at each level.
- #
- for (dname in tree_array[ level " " dir_path ]) {
- if (last_dname) {
- tree_lines[ current_line ] = dir_path "\\" last_dname;
- insert_string( p_pattern "├──" last_dname "\n" );
- create_tree_graph( level + 1,
- tree_lines[ current_line - 1] ,
- p_pattern "│ ");
- }
- last_dname = dname;
- }
-
- # Process the last directory at each level by inserting a closing
- # graph angle before the directory name.
- #
- if (last_dname) {
- tree_lines[ current_line ] = dir_path "\\" last_dname;
- insert_string( p_pattern "└──" last_dname "\n" );
- create_tree_graph( level + 1,
- tree_lines[ current_line - 1],
- p_pattern " ");
- }
- }
-
-
- function tree_down( cnt ){
- tree_unmark();
- down( cnt );
- tree_mark();
- }
-
- function tree_up( cnt ){
- tree_unmark();
- up( cnt );
- tree_mark();
- }
-
-
- function tree_mark(){
- goto_bol();
- search( "[^ " chr(179) chr(192) chr( 195 ) chr( 196 ) "]",
- SEARCH_REGEX + SEARCH_FORWARD )
- save_position();
- goto_eol();
- drop_anchor();
- restore_position( 1 );
- }
-
- function tree_unmark(){
- raise_anchor();
- }
-
-
- function tree_mark_cwd( drv ){
- local level;
-
- tree_cwd = getcwd( drv ); # contains a trailing "\"
-
- # removed trailing "\"
- tree_cwd = substr( tree_cwd, 0, length( tree_cwd ) - 1 );
- tree_mark();
- }
-
-
-
- function tree_expand(){
-
-
- if (tree_lines[ current_line ]) {
- message( "Reading directory: %s", tree_lines[ current_line ] "\\" );
- file_selection = ""
- directory_list( dir_selection = tree_lines[ current_line ] "\\" );
- message( "Current directory: %s", getcwd() );
- if (file_selection)
- process_end()
- dir_selection = ""
- } else {
- beep();
- }
- }
-
-
- function tree_mouse_key(){
- local x = -1;
- local y = -1;
- local pos;
-
- if (window_contains( mouse_event_x, mouse_event_y, tree_winid )){
- pos = mouse_position( 1 );
-
- if ( pos == MOUSE_IN_TEXT ){
- do {
- if ((x != mouse_display_x) || (y != mouse_display_y)){
- tree_unmark();
- current_line = mouse_display_y - window_text_y0 + window_first;
- tree_mark();
- display_update();
- x = mouse_display_x;
- y = mouse_display_y - window_y0 - window_height;
- }
- } while ( and(mouse_buttons, LEFT_BUTTON) );
- } else if (and(pos,MOUSE_N) || and(pos,MOUSE_S)){
- left_press( 1 );
- }
-
- if (current_key == LEFT_CLICK)
- tree_expand();
- }
- }
-
-
-
- function tree_chdir(){
- if (tree_lines[ current_line ]) {
- message( "Current directory: %s", tree_lines[ current_line ] "\\" );
- chdir( tree_lines[ current_line ] );
- tree_expand();
- } else {
- beep();
- }
- }
-
- #---------------------------------------------------------#
-
-
-
-
- ## directory_list
- #
- # Create a window and display the contents of the specified directory.
- # Once displayed, the following keystrokes are valid:
- #
- # <ENTER> - Edit the item highlighted
- # <LEFT_RELEASE> - Edit the item highlighted
- # <UP> - Select previous item in list
- # <DOWN> - Select next item in list
- # <ESC> - Return without setting file_selection
- # <PGUP> - List previous page of items
- # <PGDN> - List next page of items
- #
- # Upon return, the variable file_selection will be set to the selected
- # item, otherwise "".
- #
- function directory_list( dirpath ){
- local dirlist_keymap # keymap used while directory is displayed
- local dirlist_cwd = "" # current directory displayed
- local dirlist_win_height = display_height - 10;
- local dirlist_win_width = 51;
- local dirlist_win_x0 = 20;
- local dirlist_win_y0 = 5;
- local fname_pattern = "*.*"
- local save_window = current_window;
- local save_buffer = current_buffer;
- local eolstr = default_buffer_eol_string;
-
- #
- # get the directory specified if any, otherwise use the cwd
- #
- if (argcount())
- dirlist_cwd = dirpath;
-
-
- # create the window to display the directory file list
- #
- current_window = create_factory_window( dirlist_win_x0, \
- dirlist_win_y0, \
- dirlist_win_width, \
- dirlist_win_height, \
- WINDOW_BORDER + WINDOW_SB_RIGHT + WINDOW_SYSTEM);
-
- color_text = color_border = BAR_COLOR
- color_highlight = HBAR_COLOR;
-
- visible_end_buffer = ""
- visible_tabs = ""
- visible_virtual_lines = " │ │";
-
-
- # create a new buffer to put the filenames into
- default_buffer_eol_string = new_eol_str
- current_buffer = \
- create_buffer( "", "", BUFFER_SYSTEM + BUFFER_NO_UNDO )
- default_buffer_eol_string = eolstr;
- buffer_tabs = "11 15"
-
- attach_window_buffer( current_window, current_buffer );
-
-
-
- # read the contents of the directory into the current buffer
- #
- if ( dirlist_read_directory( dirlist_cwd fname_pattern ) ) {
- dirlist_keymap = create_keymap(empty_keymap)
- push_keymap(dirlist_keymap)
-
- assign_key( "<ESC>", "process_end" );
- assign_key( "<down>", "dirlist_down 1" );
- assign_key( "<up>", "dirlist_up 1" );
- assign_key( "<pgdn>", "dirlist_down " dirlist_win_height - 2);
- assign_key( "<pgup>", "dirlist_up " dirlist_win_height - 2);
- assign_key( "<ENTER>","dirlist_enter" );
- assign_key( "#61440", "menu_mouse_key" ) # left press
- assign_key( "#62976", "menu_mouse_key" ) # left click
-
- drop_anchor( LINE_SELECTION )
-
- # begin processing withing the directory listing
- #
- process_begin();
- pop_keymap();
- delete_keymap( dirlist_keymap );
- } else {
- # the directory read failed
- #
- beep();
- }
-
- delete_buffer();
- delete_window();
- }
-
-
-
- ## dirlist_read_directory
- #
- # Read all of the normal files using the fname_pattern specified (which
- # contains the full path with the pattern) and insert the name, size, time
- # and date string into the current buffer
- #
- function dirlist_read_directory( fname_pattern ){
- local find_flags
- local fname
- local i;
- local orig_name
-
- find_flags = _NORMAL # include all normal files
-
- delete( file_list )
-
- fname = findfirst( fname_pattern, find_flags );
- fname = path_fname( fname ) path_ext( fname )
-
- if (!fname)
- return FALSE;
-
-
- # read all of the filenames out of the directory specified
- # and format them.
- #
- while (fname) {
-
- orig_name = fname
- # format the filename string so that no .'s are displayed
- # and so the extension is separated from the basename.
- #
- if (!sub( "\\.", "\t", fname ))
- fname = fname "\t"
-
- fname = sprintf( "%-s\t│%9.9ld│%s", toupper( fname ), \
- filesize(), ctime(filetime()));
- file_list[ fname ] = orig_name;
-
- fname = findnext()
- }
-
-
- # insert new file names into the buffer
- #
- for (i in file_list)
- insert_string( i new_eol_str )
-
- backspace(); # remove the last newline character
- goto_buffer_top();
- return TRUE;
- }
-
-
- ## process a down key press from within a menu
- #
- global function dirlist_down( lines ) {
-
- if ( down( lines )) {
- #
- # redisplay the highlight on the new selection
- #
- raise_anchor()
- drop_anchor( LINE_SELECTION )
- }
- }
-
-
-
- ## process an up key press from within a menu
- #
- global function dirlist_up( lines ){
-
- if ( up( lines )) {
- #
- # redisplay the highlight on the new selection
- #
- raise_anchor()
- drop_anchor( LINE_SELECTION )
- }
- }
-
- ## process a home key press from within a menu
- #
- global function dirlist_home(){
-
- raise_anchor()
- goto_buffer_top();
- drop_anchor( LINE_SELECTION )
- }
-
- ## process an end key press from within a menu
- #
- global function dirlist_end(){
-
- raise_anchor()
- goto_buffer_bottom();
- drop_anchor( LINE_SELECTION )
- }
-
- function dirlist_enter(){
- file_selection = dir_selection file_list[ read_buffer() ];
- process_end();
- }
-
-
-
- #---------------------------------------------------------#
-
-