# 
# $Id :            $
# $Date :          $
# $Revision :      $
# 

package provide stead 2.0

## stead:makeEditMenuFromSpecs -- Construit une série de menus d'édition
# 
# Construit une série de menu à partir d'une specification sous
# la forme d'une liste de listes
#     A DOCUMENTER PUIS A DEPLACER
# 
#     # Spécification de menu d'édition
#     # 
#     #  type label                     gpatterne
#     # 
#     set editSpec {
#        file bin/stead                 $stead(exe)
#        file lib/stead/core/main.tcl   $stead(install)/core/main.tcl
#        sep  ----------------------    ----------------------
#        dir  "lib/stead/core/ (A...i)" $stead(install)/lib/stead/core/\[a-i\]*
#        dir  "lib/stead/core/ (j...z)" $stead(install)/lib/stead/core/\[j-z\]*
#        dir  lib/stead/xtext/...       $stead(install)/lib/stead/xtext/*
#        dir  lib/stead/xentry...       $stead(install)/lib/stead/xentry/*
#        sep  ----------------------    ----------------------
#        dir  etc/...                   $stead(install)/etc/*
#        dir  lib/local/...             $stead(install)/lib/local/*
#        dir  lib/modes/...             $stead(install)/lib/modes/*
#     }
#     set editSpec [subst $editSpec]
#     stead:makeEditMenuFromSpecs  .stead1.menu.admin  $editSpec
#     
# TODO : 
#  1 - transformer le format d'une editSpec dans l'esprit de mon package 
#      parsargs (plus puissant, plus extensible et plus simple à retenir)
#  2 - rajouter une type "tree" pour supporter les menus hiérarchiques
#      du genre pist ou tcllib du menu admin de stead
#  
proc stead:makeEditMenuFromSpecs {menu  editSpec } {
    
    foreach {type label lib}  $editSpec {
    
        switch -exact -- $type {
            sep {
                # Traitement des séparateurs
                $menu add separator
            }
            file {
                # Edition d'un fichier unique
                $menu add command -label "Edit $label" \
                                  -command [list stead $lib]
            }
            dir {
                # création d'un sous-menu hiérachique
                menu:makeEditSubmenuFromDirectory2  \
                    $menu  $menu.$::U  "Edit $label"  $lib 
            }
            tree {
                # création d'un arbre de menu
                
                # TODO :
                #   1 - créer un menu avec le label
                #   2 - construire l'arbre à partir du préfixe commun
                #       dans le path de la pattern appliquée
                #    
                bgerror "Le type tree n'est pas encore implémenté !"
            }
            default {
                bgerror "Type $type inconnu !"
            }
        }
    } 
}

## menu:makeEditMenuFromDirectory
# 
# Crée un nouveau bouton de menu $menubutton à la barre de menu 
# principale avec comme label $menulabel, et y rajoute les commandes
# pour chacun des fichiers satisfaisant la patterne (glob) $pattern
# 
# Si on boutton de même nom préexiste : il est detruit
# 
# exemple d'utilisation :
# 
#   proc mkMenuExut {} {
#   
#     # Crée un menu bouton ".menu.exut" (et le menu associé ".menu.exut.m"
#     # et y rajoute la commande d'édition des fichiers du répertoire
#     set exut_dir ~/doc/unix/exemples
#     menu:makeEditMenuFromDirectory \
#           .menu.exut Exut $exut_dir/*
#     
#     # On ajoute un séparateur
#     .menu.exut.m add separator 
#     
#     # Crée un sous-menu ".menu.exutm.applis" pour éditer d'autre fichiers
#     set applis_dir ~/doc/unix/applis
#     menu:makeEditSubmenuFromDirectory \
#           .menu.exut.m .menu.exut.m.applis $applis_dir/*
#     
#     menu:addDestroyMenuCommand .menu.exut "Détruire ce menu"
#     
#   }
# 
proc menu:makeEditMenuFromDirectory {menubutton menulabel pattern} {
    global env
    if {![info exist env(EDITOR)]} {
        set env(EDITOR) stead
    }
    
    # set firstTime 1
    set fileOrDirs [lsort [glob -nocomplain $pattern] ]
    
    set files {}
    foreach f $fileOrDirs {
        if {[file isfile $f] && [file readable $f]} {
            lappend files $f
        }
    } ;# endforeach
    
    if {![llength $files]} return
    
    # On détruit éventuellement le bouton de menu de même nom
    catch {destroy $menubutton}
    
    # Création du bouton de menu
    menubutton $menubutton  -text $menulabel -menu $menu
    
    # Création du menu
    set menu $menubutton.m
    menu $menu
    
    # Pour afficher ce nouveau bouton en glissant sur la barre des menus
    # (Ceci est inutile avec les version récente de tk)
    set menubar [winfo parent $menubutton]

    foreach f $files  {
        $menu add command -label [file tail $f] -command "stead $f"
    } 
    
    pack $menubutton -side left

}
## menu:makeEditSubmenuFromDirectory
# 
# crée un sous menu $subMenu au menu préexistant $menu,
# et y rajoute les commandes d'édition pour chacun des fichiers
# satisfaisant la patterne (glob) $pattern
# 
# exemple d'utilisation :
# 
#     catch {menu:makeEditSubmenuFromDirectory $menu $menu.sub[getUid]\
#                                       [file join $gred(setup) local *]}

proc menu:makeEditSubmenuFromDirectory {menu subMenu pattern} {


    menu:makeEditSubmenuFromDirectory2 $menu $subMenu $pattern $pattern

}
## menu:makeEditSubmenuFromDirectory2
# 
# Exemple voir mode tcl :  $m correspond au menu template
#  
#  ## Sous menu pour les fichiers tcl du répertoire courant
#  menu:makeEditSubmenuFromDirectory2  $m $m.files[xtcl_uid]  \
#         "Current directory Tcl files"  \
#        [file dirname $stead(file)]/*.tcl
#           
#           
proc menu:makeEditSubmenuFromDirectory2 {menu subMenu subMenuLabel pattern} {
    
    # set firstTime 1
    set fileOrDirs [lsort [glob -nocomplain $pattern] ]
    
    set files {}
    foreach f $fileOrDirs {
        if {[file isfile $f] && [file readable $f]} {
            lappend files $f
        }
    }
    
    if {![llength $files]} {
        return
    }
    
    # Un widget ne doit pas commencer par une majuscule
    # set subMenu [string tolower $subMenu]
    set subMenu \
       "[string tolower [string index $subMenu 0][string range $subMenu 1 end]]"
    # set subMenu "m_$subMenu"
    menu  $subMenu
    $menu add cascade -label $subMenuLabel -menu $subMenu
    foreach file $files  {
        $subMenu add command -label "edit [file tail $file]" \
                             -command "stead $file"
    } 
}

##  menu:addEditFilesToMenu $menu $files
# 
#   ajoute au menu les commandes pour éditer les fichiers de la liste
#   précondition : le menu doit exister.
# 
# exemple d'utilisation :
# 
#   menu:addEditFilesToMenu  .menu.pist.m $my_fileList
# 
# modif :
# 
#   09/09/99 (diam) : création.
# 
proc menu:addEditFilesToMenu {menu files} {
    foreach file $files {
        if {![file isfile $file] || ![file readable $file]} {continue}
        $menu add command -label "Edit $file" -command "stead $file"
    }
}


##  menu:addDestroyMenuCommand $menubutton $label
# 
#   ajoute au menu une commande pour détruire celui-ci
# 
# 
# Pour une raison de cohérence avec les autres procédure de ce package,
# on passe le menubutton et nom pas le menu en parametre
# car l'utilisatuer ne le connait pas en principe
# 
# 
# exemple d'utilisation :
# 
#   menu:addDestroyMenuCommand  .menu.pist "Détruire ce menu"
# 
# modif :
#   09/09/99 (diam) : création.
# 
proc menu:addDestroyMenuCommand {menubutton {label "Destroy menu"}} {
    $menubutton.m add command -label $label \
                      -command "destroy $menubutton"
}
# ./
