; $Id: davemenu_xml.pro,v 1.4 2006/01/04 16:43:34 kneller Exp $
;###############################################################################
;
;FILENAME:
;        davemenu_xml.pro
;
;PURPOSE:
;           The purpose of this program is to have an easy to edit
;           menuing system so that developers at other facilities can
;           add menu items to their local version of DAVE by simply
;           editing and ASCII (XML) file.
;CATEGORY:
;
;
;METHODS IN FILE:
;    DaveMenu_XML
;    makeTreeMenu
;    makeClassicMenu
;    makeChildren
;    makeTreeChildren
;
;
; AUTHOR:
; Larry Kneller
; NIST Center for Neutron Research
; 100 Bureau Drive, Gaithersburg, MD 20899
; United States
; kneller@nist.gov  301-975-8839
; Sep 9, 2005
;
; LICENSE:
; The software in this file is written by an employee of
; National Institute of Standards and Technology
; as part of the DAVE software project.
;
; The DAVE software package is not subject to copyright protection
; and is in the public domain. It should be considered as an
; experimental neutron scattering data reduction, visualization, and
; analysis system. As such, the authors assume no responsibility
; whatsoever for its use, and make no guarantees, expressed or
; implied, about its quality, reliability, or any other
; characteristic. The use of certain trade names or commercial
; products does not imply any endorsement of a particular product,
; nor does it imply that the named product is necessarily the best
; product for the stated purpose. We would appreciate acknowledgment
; if the DAVE software is used of if the code in this file is
; included in another product.
;
;###############################################################################
; AUTHOR    Larry Kneller
;
;
;
; PURPOSE   A PROGRAM TO CREATE BOTH THE CLASSIC AND TREE MENUING FOR
;           DAVE FROM AN XML SPECIFICATION FILE.
;
;
; NOTE      THIS CODE DOES NOT WORK FOR XML WITH COMMENTS.  WHY NOT?!?!?!?
;           COMMENTS ARE OK AS LONG AS THEY ARE INSIDE THE OUTERMOST
;           TAGS FOR THE DOCUMENT.
;
;###############################################################################
;
;NAME:
;        makeTreeMenu
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function makeTreeMenu,tlb,tbar,els,$;tree_top,tbar,els
                            app_icon,$
                            notebook_icon,$
                            vis_icon,$
                            reduction_icon,$
                            analysis_icon,$
                            tools_icon,$
                            help_icon


    if els->getlength() gt 0 then begin
        o=objarr(els->getlength())

        ;AT THIS POINT CREATE AN ARRAY OF STRUCTURES
        ;VIA THE replicate COMMAND.  THE STRUCTURES WILL
        ;EACH HAVE ALL OF THE TAGS POSSIBLE FOR THE SPECIFIED
        ;menu_items'S TO PRODUCE TREE OR CLASSIC MENUs.

        menu_item = {MENU_ITEM,         $
                 classic_widget_id:'void',      $
                 tree_widget_id:'void',      $
                 classic_parent:'',$
                 tree_parent:'',$
                 classic_bitmap:'NoBitmap',$
                 tree_bitmap:'NoBitmap',    $
                 event_pro:'dave_do_nothing', $
                 uname:'',$
                 uvalue:'',$
                 value:'',$
                 separator : '0',   $
                 folder : '0',  $
                 facility : 'ncnr',$
                 id:'0L'               $
                 }

        items=replicate(menu_item,n_elements(o))


        ;ASSIGN AN OBJECT REFERENCE TO EACH NENU ITEM
        for i=0,els->getlength()-1 do begin
            o[i] = els->item(i)   ;idlffxmlnode
        endfor;i

        ;
        omap=objarr(els->getlength())
        for i=0,els->getlength()-1 do begin
            omap[i] = o[i]->getattributes() ;idlffxmlnamednodemap
        endfor;i

        ;NOW THAT I CAN ACCESS ALL OF THE ATTRIBUTE VALUES, THE
        ;NEXT STEP IS TO CONVERT EACH NODE INTO A STRUCTURE.


        otype = objarr(els->getlength())
        classcount = 0
        taglist = tag_names(items[0])
        ;print,taglist

    ;TREE SECTION

        ;POPULATE THE LIST OF MENU ITEMS FROM THE node_list OBJECT.
        items=replicate(menu_item,n_elements(o))
        for i=0,els->getlength()-1 do begin


            ;WITH THE NEXT COMMAND I COULD LOOP THROUGH ALL OF THE
            ;STRUCTURE TAGS FOR THE menu_item STRUCTURE AND INSERT
            ;THE VALUES IF THEY ARE PRESENT.
            ;
            ;HOW DO I TEST FOR THEIR PRESENCE?
            ;A:  IF THE NODE IS NOT PRESENT, THEN THE CALL TO
            ;     omap[i]->getnameditem('type') RETURNS A NULL OBJECT.
            ;

            ;LOOP THROUGH TAGS AND POPULATE items STRUCTURES ;REDUNDANT HERE, BUT WHEN TREE AND CLASSIC
                                                             ;ARE SEPARATE PROCEDURES IT WILL BE NECESSARY
            for j=0,n_elements(taglist)-1 do begin
                ;PUT EACH VALUE FOR A GIVEN MENU ITEM INTO A STRUCTURE FOR THAT MENU ITEM.
                if obj_valid((omap[i]->getnameditem(STRLOWCASE(taglist[j])))) ne 0 then begin
                    items[i].(j) = $
                        (omap[i]->getnameditem(STRLOWCASE(taglist[j])))->getvalue()

                endif
            endfor;j
        endfor;i
        if ptr_valid(pitems) then ptr_free,pitems
        pitems = ptr_new(items)


;ADD EXPAND/CONTRACT BUTTONS TO THE TREE WIDGET
bbase = widget_base(tlb,/row)
void = widget_button(bbase,value = 'expand tree',event_pro = 'dave_expand_menus', $
                     /dynamic_resize,uname = 'EXPAND_BUTTON')
void = widget_button(bbase,value = 'contract tree',event_pro = 'dave_expand_menus', $
                     /dynamic_resize,uname = 'CONTRACT_BUTTON')

;FROM dave_build_tree_menu:
;###########################
device,get_screen_size = screen_size
tot_y_size = 0.75*screen_size[1]
this_size = tot_y_size          ;-winysize

;tree_base = widget_base(tlb,/col,uname = 'TREE_BASE',xsize = 300, $ ;winxsize, $
;                        ysize = this_size)
;
;file_tree = widget_tree(tree_base,ysize = this_size,uname = 'TREE_WIDGET')
;
;###########################

        for i=0,els->getlength()-1 do begin

            ;SET UP TOP OF TREE WIDGET --- file_tree
            if items[i].tree_widget_ID eq 'file_tree' then begin



                tree_base = widget_base(tlb,/col,uname = 'TREE_BASE',xsize = 300, $ ;winxsize, $
                                        ysize = this_size)
                tree_top = tree_base
                tmp = widget_tree(tree_base,ysize = this_size,uname = 'TREE_WIDGET')


;                tmp = widget_tree(tree_top,folder=fix(items[i].folder),$
;                                           value=items[i].value,$
;                                           xsize=300,$
;                                           ysize=this_size,$;400,$
;                                           uname = 'TREE_WIDGET');uname=strtrim(string(items[i].uname),2))
;                print,strtrim(string(items[i].uname),2)

                items[i].id = strtrim(string(tmp),2)
                file_tree = long(items[i].id)
            endif


            ;SET UP THE FILE MENU ON THE MENU BAR
            if items[i].classic_parent eq 'bar' then begin

                ;THIS CREATES THE BASE AND THE MENUS, HOWEVER, THE ORDERING MUST BE SPECIFIED
                ;SOMEHOW.  SHOULD THIS BE DONE BY THE ORDER OF APPEARANCE IN THE XML FILE???

                if items[i].classic_widget_id eq 'filemenu' then begin
                    tmp = widget_button(tbar,value=items[i].value,menu=items[i].folder,separator=fix(items[i].separator),$
                                                uname=items[i].uname)
                    items[i].id = strtrim(string(tmp),2)
                    if items[i].classic_widget_id eq 'filemenu' then begin
                        tFileMenu = long(items[i].id)
                    endif;filemenu
                endif
            endif
        endfor;i

        ;NOW THAT I HAVE THE MENUS, I CAN POPULATE THEM.
        for i=0,els->getlength()-1 do begin
            case items[i].tree_parent of
            'filemenu':begin    ;NOTE SPECIAL TREATMENT OF filemenu
                    tmp = widget_button(tFileMenu,value=items[i].value,menu=items[i].folder,$
                                    separator=fix(items[i].separator),event_pro=items[i].event_pro,$
                                    uname=items[i].uname)
                    items[i].id = strtrim(string(tmp),2)
                    makeChildren,els,pitems,items[i]
            end
            'file_tree':begin
                    case strlowcase(items[i].tree_bitmap) of
                    'app_icon':tree_icon = app_icon
                    'notebook_icon':tree_icon = notebook_icon
                    'vis_icon':tree_icon = vis_icon
                    'reduction_icon':tree_icon = reduction_icon
                    'analysis_icon':tree_icon = analysis_icon
                    'tools_icon':tree_icon = tools_icon
                    'help_icon':tree_icon = help_icon
                    else: tree_icon = -1;E_NOTEBOOK CASE.
                    endcase

                    if tree_icon[0] ne -1 then begin
                        tmp = widget_tree(file_tree,value=items[i].value,$
                                                folder=items[i].folder,$
                                                event_pro=items[i].event_pro,$
                                                bitmap = tree_icon,$
                                                uname=items[i].uname)
                    endif else begin
                        ;START E-NOTEBOOK CASE
                        tmp = widget_tree(file_tree,value=items[i].value,$
                                                folder=items[i].folder,$
                                                event_pro=items[i].event_pro,$
                                                uname=items[i].uname)
                    endelse

                    items[i].id = strtrim(string(tmp),2)
                    makeTreeChildren,els,pitems,items[i], $
                            app_icon,$
                            notebook_icon,$
                            vis_icon,$
                            reduction_icon,$
                            analysis_icon,$
                            tools_icon,$
                            help_icon

            end;help_menu
            else:begin
            end
            endcase
        endfor;i





    endif;else->getLength()

    ;101405
    if ptr_valid(pitems) then ptr_free,pitems

    return,1
end;makeTreeMenu

;###############################################################################
;
;NAME:
;        makeClassicMenu
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;RETURN VALUE:
;
;###############################################################################
function makeClassicMenu,base,bar,els

    ;CREATE THE CLASSIC DAVE MENU GIVEN THE SET OF VALUES FROM THE
    ;XML MENU SPECIFICATION FILE.


    if els->getlength() gt 0 then begin
        o=objarr(els->getlength())

           ;AT THIS POINT I WOULD CREATE AN ARRAY OF STRUCTURES
           ;VIA THE replicate COMMAND.  THE STRUCTURES WILL
           ;EACH HAVE ALL OF THE TAGS POSSIBLE FOR THE SPECIFIED
           ;menu_items'S TO PRODUCE TREE OR CLASSIC MENUs.

           menu_item = {MENU_ITEM,         $
                     classic_widget_id:'void',      $
                     tree_widget_id:'void',      $
                     classic_parent:'',$
                     tree_parent:'',$
                     classic_bitmap:'NoBitmap',$
                     tree_bitmap:'NoBitmap',    $
                     event_pro:'DoNothing', $
                     uname:'',$
                     uvalue:'',$
                     value:'Zero',       $
                     separator : '0',   $
                     folder : '0',  $
                     facility : 'ncnr',$
                     id:'0L'               $
                     }

           items=replicate(menu_item,n_elements(o))


            ;ASSIGN AN OBJECT REFERENCE TO EACH NENU ITEM
           for i=0,els->getlength()-1 do begin
               o[i] = els->item(i)   ;idlffxmlnode
           endfor;i

            ;
           omap=objarr(els->getlength())
           for i=0,els->getlength()-1 do begin
               omap[i] = o[i]->getattributes() ;idlffxmlnamednodemap
           endfor;i

           ;NOW THAT I CAN ACCESS ALL OF THE ATTRIBUTE VALUES, THE
           ;NEXT STEP IS TO CONVERT EACH NODE INTO A STRUCTURE.


        otype = objarr(els->getlength())
        classcount = 0
        taglist = tag_names(items[0])
        ;print,taglist
;        base = widget_base(mbar=bar,xsize=300,ysize=300)

    ;CLASSIC SECTION
        for i=0,els->getlength()-1 do begin
              ;WITH THE NEXT COMMAND I COULD LOOP THROUGH ALL OF THE
              ;STRUCTURE TAGS FOR THE menu_item STRUCTURE AND INSERT
              ;THE VALUES IF THEY ARE PRESENT.
              ;
              ;HOW DO I TEST FOR THEIR PRESENCE?
              ;A:  IF THE NODE IS NOT PRESENT, THEN THE CALL TO
              ;     omap[i]->getnameditem('type') RETURNS A NULL OBJECT.
              ;
            for j=0,n_elements(taglist)-1 do begin

                ;PUT EACH VALUE FOR A GIVEN MENU ITEM INTO A STRUCTURE FOR THAT MENU ITEM.
                if obj_valid((omap[i]->getnameditem(STRLOWCASE(taglist[j])))) ne 0 then begin
                    items[i].(j) = $
                        (omap[i]->getnameditem(STRLOWCASE(taglist[j])))->getvalue()
;                    if STRLOWCASE(taglist[j]) eq 'classic_parent' then begin
;                        classcount++
;                    endif
                endif
            endfor;j
        endfor;i
        if ptr_valid(pitems) then ptr_free,pitems
        pitems = ptr_new(items)

        for i=0,els->getlength()-1 do begin

            if items[i].classic_parent eq 'bar' then begin

                ;THIS CREATES THE BASE AND THE MENUS, HOWEVER, THE ORDERING MUST BE SPECIFIED
                ;SOMEHOW.  SHOULD THIS BE DONE BY THE ORDER OF APPEARANCE IN THE XML FILE???
                ;OR SHOULD I CODE THE ORDER HERE AND RUN for LOOP FOR EACH MENU???

                tmp = widget_button(bar,value=items[i].value,menu=items[i].folder,event_pro=items[i].event_pro,$
                                                uname=items[i].uname)
                items[i].id = strtrim(string(tmp),2)
                makeChildren,els,pitems,items[i]
            endif
        endfor;i

    endif;else->getLength()

    ;101405
    if ptr_valid(pitems) then ptr_free,pitems

    return,1
end;makeClassicMenu




;###############################################################################
;
;NAME:
;        makeChildren
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro makeChildren,els,pitems,item


    ;THIS IS RECURSIVE SO IT CALLS ITSELF EACH TIME A FOLDER IS CREATED.

    if fix(item.folder) eq 1 then begin

        for j=0,els->getLength()-1 do begin
            ;010405 Added strlowcase to the next line.
            if strlowcase((*pitems)[j].classic_parent) eq $
                                strlowcase(item.classic_widget_id) then begin

;090105
;CHANGES TO NEXT COMMAND WERE REQUIRED TO SET CORRECT VALUES
;FOR EACH BUTTON.  NOW EVENTS APPEAR TO WORK CORRECTLY IN CLASSIC DAVE.
;

                ;print,(*pitems)[j].value
                ;HANDLE THE SPECIAL CASE OF THE DEBUG File MENU ITEM AVAILABLE WHEN RUN
                ;FROM THE DEVELOPMENT ENVIRONMENT.
                if stregex((*pitems)[j].value,'Switch on debug flag',/fold_case) gt 0 then begin
                    if (not lmgr(/runtime)) then $  ; debug flag widget should not appear in embedded version
                        ;void = widget_button(filemenu,value='Switch on debug flag',event_pro='fdaveSwapDebugFlag')
                        tmp = widget_button(long(item.id),value=(*pitems)[j].value,$
                                                          menu=fix((*pitems)[j].folder),$
                                                          separator=fix((*pitems)[j].separator),$
                                                          event_pro=(*pitems)[j].event_pro,$
                                                          uvalue = (*pitems)[j].uvalue,$
                                                          uname=(*pitems[j]).uname)
                endif else begin

                    tmp = widget_button(long(item.id),value=(*pitems)[j].value,$
                                                      menu=fix((*pitems)[j].folder),$
                                                      separator=fix((*pitems)[j].separator),$
                                                      event_pro=(*pitems)[j].event_pro,$
                                                      uvalue = (*pitems)[j].uvalue,$
                                                      uname=(*pitems)[j].uname)
    ;                                                  separator=fix(item.separator),$
    ;                                                  event_pro=item.event_pro)
                    (*pitems)[j].id = strtrim(string(tmp),2)

                endelse


                makeChildren,els,pitems,(*pitems)[j]
            endif
        endfor;j
    endif;folder

end;makeChildren
;###############################################################################
;
;NAME:
;        makeTreeChildren
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro makeTreeChildren,els,pitems,item,$
                            app_icon,$
                            notebook_icon,$
                            vis_icon,$
                            reduction_icon,$
                            analysis_icon,$
                            tools_icon,$
                            help_icon


    ;THIS IS RECURSIVE SO IT CALLS ITSELF EACH TIME A FOLDER IS CREATED.

    if fix(item.folder) eq 1 then begin

        for j=0,els->getLength()-1 do begin

;010405 MADE THE NEXT COMMAND CASE INSENSITIVE by adding strlowcase
;            if (*pitems)[j].tree_parent eq item.tree_widget_id then begin
            if strlowcase((*pitems)[j].tree_parent) eq $
                                    strlowcase(item.tree_widget_id) then begin

            ;090205
            ;CORRECTING THE NEXT STATEMENT TO GET THE RIGHT EVENT HANDLER
;                print,(*pitems)[j].tree_bitmap
                case strlowcase((*pitems)[j].tree_bitmap) of
                'app_icon':tree_icon = app_icon
                'notebook_icon':tree_icon = notebook_icon
                'vis_icon':tree_icon = vis_icon
                'reduction_icon':tree_icon = reduction_icon
                'analysis_icon':tree_icon = analysis_icon
                'tools_icon':tree_icon = tools_icon
                'help_icon':tree_icon = help_icon
                else: tree_icon = app_icon
                endcase

                if (*pitems)[j].tree_bitmap eq 'NoBitmap' then begin
                    tmp = widget_tree(long(item.id),value=(*pitems)[j].value,$
                                                    folder=fix((*pitems)[j].folder),$
                                                    event_pro=(*pitems)[j].event_pro,$
                                                    uvalue = (*pitems)[j].uvalue,$
                                                    uname=(*pitems)[j].uname)
    ;                tmp = widget_tree(long(item.id),value=(*pitems)[j].value,$
    ;                                                folder=fix((*pitems)[j].folder),$
    ;                                                event_pro=item.event_pro)
                endif else begin
                    tmp = widget_tree(long(item.id),value=(*pitems)[j].value,$
                                                    folder=fix((*pitems)[j].folder),$
                                                    event_pro=(*pitems)[j].event_pro,$
                                                    bitmap = tree_icon,$
                                                    uvalue = (*pitems)[j].uvalue,$
                                                    uname=(*pitems)[j].uname)
    ;                tmp = widget_tree(long(item.id),value=(*pitems)[j].value,$
    ;                                                folder=fix((*pitems)[j].folder),$
    ;                                                event_pro=item.event_pro)
                endelse

                (*pitems)[j].id = strtrim(string(tmp),2)
                makeTreeChildren,els,pitems,(*pitems)[j],$
                            app_icon,$
                            notebook_icon,$
                            vis_icon,$
                            reduction_icon,$
                            analysis_icon,$
                            tools_icon,$
                            help_icon
            endif
        endfor;j
    endif;folder

end;makeTreeChildren


;###############################################################################
;
;NAME:
;        DaveMenu_XML
;
;PURPOSE:
;
;PARAMETERS:
;
;KEYWORDS:
;
;_EXTRA - is used to pass keywords meant for the superclass.
;
;###############################################################################
pro DaveMenu_XML,tlb,tree=tree

    if n_elements(tree) eq 0 then tree = 0

    ;fn = 'C:\Documents and Settings\kneller\My Documents\DAVE_SOURCEFORGE\dave\programs\NSE\DaveMenuXMLSpecification.xml'
    fn = !DAVE_AUXILIARY_DIR+'DaveMenuXMLSpecification.xml'

    ;READING FROM FILE
    oDocument = OBJ_NEW('IDLffXMLDOMDocument', FILENAME=fn)

    child = odocument->getFirstChild()

    ;help,child->getAttribute('parent')    ;string

    ;THE NEXT COMMAND GETS A NODELIST OF ALL THE ITEMS WITH
    ;THE TAG NAME 'menu_item'
    els = child->GetElementsByTagName ('menu_item')


    ;el3 = child->GetElementsByTagName('some_other_tag')    ;A TEST STATEMENT.
    ;help,els                   ;idlffxmldomnodelist


    if els->getlength() gt 0 then begin

;        tree_top = widget_base(xsize=300,ysize=400,mbar=tbar,title='DAVE Tree View')
;        base = widget_base(mbar=bar,xsize=500,ysize=300,title='DAVE Classic View')

        if tree eq 0 then begin
;            base = widget_base(mbar=bar,xsize=500,ysize=300,title='DAVE Classic View')


            ;##############################################
            ;TAKEN FROM dave_build_menu,tlb:
            ;##############################################
            ; Determine the color depth of the computer
            device,get_visual_depth = thisDepth
            if thisDepth eq 8 then begin
                image = read_png(!DAVE_AUXILIARY_DIR+'DAVE_title.png',r,g,b)
                s = size(image)
                sx = s[1] & sy = s[2]
            endif else begin
                read_jpeg,!DAVE_AUXILIARY_DIR+'DAVE_title.jpg',image
                s = size(image)
                sx = s[2] & sy = s[3]
            endelse

            aspect = 1.0*sy/sx              ; find the aspect ratio of the image...
            ; ...and set the display window's dimensions based on this
            ; aspect ratio.
            winxsize = 600 & winysize = fix(aspect*winxsize)
            if (lmgr(/runtime)) then tlb_title = 'DAVE: Data Analysis and Visualization Environment' $
            else tlb_title = 'DAVE: Data Analysis and Visualization Environment - running under IDLDE'
            tlb = widget_base(/row,tlb_frame_attr = 0,mbar = bar, title = tlb_title,uname = 'DAVE')
            win = widget_draw(tlb,xsize = winxsize,ysize = winysize)
            ;##############################################


            print,makeClassicMenu(tlb,bar,els)
;            print,makeClassicMenu(base,bar,els)
;            tlb = base


            ;NOW DISPLAY THE IMAGE:
            ;###################################
            ;TAKEN DIRECTLY FROM dave_build_menu
            ;###################################
            if file_search(!DAVE_DIR,'dave_users.pro',/fully_qualify_path) ne '' then begin
                result = dave_users(bar)
            endif

            centertlb,tlb

            widget_control,tlb,/realize
            widget_control,win,get_value = winVis
            window,/free,/pixmap,xsize = winxsize,ysize = winysize
            winPix = !d.window

            ;wset,winPix
            if thisDepth eq 8 then begin
                device,decomposed = 0
                tvlct,r,g,b                 ; load the proper color tables as found in
                                            ; read_png above.
                dispImage = congrid(image,winxsize,winysize)
            endif else begin
                device,decomposed = 1
                dispimage = image
            endelse

            wset,winPix
            tvimage,dispImage
            wset,winVis
            device,copy = [0,0,!d.x_size,!d.y_size,0,0,winPix]
            wdelete,winPix
            ;###################################



        endif else begin

        ;#############################################################################
        ;090205
        ;GET THE ICONS HERE SO WE DON'T HAVE TO CALL THESE STATEMENTS MULTIPLE TIMES
            ;###################################
            ;TAKEN DIRECTLY FROM dave_build_tree_menu
            ;###################################
            ; Application icon
            bmp_file = !DAVE_AUXILIARY_DIR+'dm.bmp'
            app_icon = convert_bmp(bmp_file)

            ; notebook icon
            bmp_file = !DAVE_AUXILIARY_DIR+'copy.bmp'
            notebook_icon = convert_bmp(bmp_file)

            ; Visualization icon
            bmp_file = !DAVE_AUXILIARY_DIR+'image.bmp'
            vis_icon = convert_bmp(bmp_file)

            ; Reduction icon
            bmp_file = !DAVE_AUXILIARY_DIR+'hist.bmp'
            reduction_icon = convert_bmp(bmp_file)

            ; Analysis icon
            bmp_file = !DAVE_AUXILIARY_DIR+'scatter.bmp'
            analysis_icon = convert_bmp(bmp_file)

            ; Tools icon
            bmp_file = !DAVE_AUXILIARY_DIR+'cut.bmp'
            tools_icon = convert_bmp(bmp_file)

            ; Help icon
            bmp_file = !DAVE_AUXILIARY_DIR+'help.bmp'
            help_icon = convert_bmp(bmp_file)

            if (lmgr(/runtime)) then tlb_title = 'DAVE: Data Analysis and Visualization Environment' $
            else tlb_title = 'DAVE: Data Analysis and Visualization Environment - running under IDLDE'
            tlb = widget_base(/col,mbar = bar, title = tlb_title,uname = 'DAVE', $
                              xoff = 10,yoff = 20,/tlb_size_events)

            ;###################################
        ;#############################################################################




;            tree_top = widget_base(xsize=300,ysize=400,mbar=tbar,title='DAVE Tree View')
;            tlb = tree_top
;            print,makeTreeMenu(tree_top,tbar,els)
;            widget_control,tlb,/realize

            print,makeTreeMenu(tlb,bar,els,app_icon,$
                            notebook_icon,$
                            vis_icon,$
                            reduction_icon,$
                            analysis_icon,$
                            tools_icon,$
                            help_icon)

            ;###################################
            ;TAKEN DIRECTLY FROM dave_build_tree_menu
            ;###################################
            if file_search(!DAVE_DIR,'dave_users.pro',/fully_qualify_path) ne '' then begin
                result = dave_users(bar)
            endif

            dave_defs=*!dave_defaults


;090705
;REALIZE THE tlb HERE FIRST
            widget_control,tlb,/realize
            ;###################################

;FOR SOME REASON THE NEXT SECTION CRASHES THE PROGRAM IF tlb IS NOT
;YET REALIZED.

;RESTORE THE TREE WIDGET TO THE USER'S PREVIOUS STATE BASED ON
;INFORMATION IN THE !dave_defaults VARIABLE.
            if (n_elements(*dave_defs.tree_menu_pointer) gt 0) then begin
                button_names=(*dave_defs.tree_menu_pointer).button_names
                button_state=(*dave_defs.tree_menu_pointer).button_state

                id = widget_info(tlb,find_by_uname = 'TREE_WIDGET')
;090705
;THE NEXT STATEMENT SEEMS TO CAUSE THE CRASHING PROBLEMS WHEN tlb IS NOT REALIZED.
                ids = get_all_ids(id)

;SO FOR SOME REASON, THE CALL TO widget_TreeView IN get_all_ids
;FAILS CATASTROPHICALLY IF THE id IS NOT REALIZED!!!
;HOWEVER, EVERYTHING WORKS FINE IF tlb IS REALIZED WITH THE
;SMALL EXCEPTION THAT THE USER HAS TO WATCH AS THE TREE LEAVES
;OPEN TO THEIR PREVIOUS STATE.
;

                nids=n_elements(ids)
                bnames=strarr(nids)
                for k=0,nids-1 do begin
                    widget_control,ids[k],get_value=temp
                    bnames[k]=temp
                    ;print,temp
                endfor
                if (nids eq n_elements(button_names)) then begin

                    if (min(bnames eq button_names) eq 1) then begin
                        for k=0,nids-1 do widget_control,ids[k],set_tree_expanded=button_state[k]
                    endif
                endif
            endif

;            widget_control,tlb,/realize
;            ;###################################

        endelse

        OBJ_DESTROY, oDocument
    endif else begin

        print,'No elements in "els" nodelist.'
    endelse

end;DaveMenu_XML



