#########################################################################
# COPYRIGHT (C) 2003         EDF R&D              WWW.CODE-ASTER.ORG    #
#                                                                       #
# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR         #
# MODIFY IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS        #
# PUBLISHED BY THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE    #
# LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION.                       #
# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,       #
# BUT WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF        #
# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU      #
# GENERAL PUBLIC LICENSE FOR MORE DETAILS.                              #
#                                                                       #
# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE     #
# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO : EDF R&D CODE_ASTER,       #
#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.        #
#########################################################################

# $Id: tkselecteur.tcl 2336 2006-11-15 13:54:27Z courtois $

#################################################################
# Multi-machine and remote-command added for ASTK
# http://www.code-aster.org
#
# TKselecteur
# based on the previous
# Directory Selector TCL version 1.5
#
# Daniel Roche, <daniel.roche@bigfoot.com>
#
# thanks to :
#  Cyrille Artho <cartho@netlink.ch> for the 'saving pwd fix'
#  Terry Griffin <terryg@axian.com> for <Return> key bindings on buttons.
#  Kenneth Kehl  <Kenneth.Kehl@marconiastronics.com> for blocking at end of dir tree
#  Michael Barth <m.barth@de.bosch.com> for finding the "-fill on image" problem
#  Mike Avery <avery@loran.com> for finding the "myfont already exist" problem
#  Branko Rogic <b.rogic@lectra.com> for gif icons, parent and background options
#  Reinhard Holler <rones@augusta.de> for colors ,font and autovalid options
#
#################################################################


#################################################################
#
# tk_getDirectory [option value ...]
#
#  options are :
##  [-initialsrv srv]     display on server srv
##  [-initialdir dir]     display in dir
#   [-rescuedir  list]    list of "rescue directory" (one per host) which is used
#                         when initialdir doesn't exist on this host
#   [-parent string]      make string the parent of tkgetdir for transient window
#   [-geometry string]    make string the geometry (WxH+X+Y)
#   [-listbg string]      make string the list and entry background color
#   [-listfg string]      make string the list and entry foreground color
#   [-selectbg string]    make string the background color for selected directory
#   [-selectfg string]    make string the foreground color for selected directory
#   [-hilightbg string]   make string the background color for highlighted dir
#   [-hilightfg string]   make string the foreground color for highlighted dir
#   [-endcolor string]    make string the color for the last directory flag
#   [-autovalid]          if it is set : selecting no directory in the window
#                         will return the directory the window shows currently
#                         autovalid is always active in this version
#   [-font string]        make string the font name or font description
#                         for directory window
##  [-typeOut string]     'F' to force 'file' selection, 'R' to force directory selection
#                         'FR' or '' else
#   [-filetypes list]     only use for compatibility with tk_getOpenFile
#   [-debug]              print debug information
#
#################################################################

namespace eval tkgetdir {
   variable dirsel
   variable drives
   variable fini
   variable svwd
   variable msg
   variable geometry
   variable parent
   variable colors
   variable font
   variable myfont
   variable autovalid
   variable typeOut
   variable icurmach
   variable lsttmpd
   variable lsttmpf
   variable lidir
   variable fidir
   variable debug
   variable config
   variable inv
# interface add-ons
   variable bsf
   variable manip
   variable active_menu
   variable popup
   variable dir_popup
   variable dir_conf
   variable sel
   variable chrono
   variable status
# affichage
   variable fic_prefs
   variable pref
   variable ls_args
# save last browsed server and directory
   variable fic_last
   variable last_rep
   variable nbrep_max
   variable last_srv
   variable last_dir
   namespace export tk_getDirectory
}

#################################################################
proc tkgetdir::tk_getDirectory {cfg args} {
   global tcl_platform
   upvar $cfg config
   #
   # main window (to allow multiple calls)
   set num [clock seconds]
   set tkgetdir::dirsel ".dirsel_$num"
   #
   # add-ons
   #  bsf autonome (sélecteur par défaut)
   set tkgetdir::bsf 0
   #  active le menu popup
   set tkgetdir::active_menu 1
   set tkgetdir::popup ".popup_$num"
   # popup liste des répertoires
   set tkgetdir::dir_popup ".dir_popup_$num"
   set tkgetdir::dir_conf  ".dir_conf_$num"
   #
   # initialisation de l'affichage
   set tkgetdir::ls_args "-lnF"
   set tkgetdir::pref(fic_cach) 0
   set tkgetdir::pref(rep_cach) 0
   set tkgetdir::pref(tri) "nom"
   set tkgetdir::pref(inv) 0
   set tkgetdir::status ""
   #
   # +1 pour home
   set tkgetdir::nbrep_max [expr 12 +1]
   #
   # default
   set tkgetdir::geometry "550x350"
   set tkgetdir::colors(lstfg) "#000000"
   if [string compare $tcl_platform(platform) windows] {
      set tkgetdir::colors(lstbg) ""
      set tkgetdir::font {-family lucida -size 14 -weight bold}
   } else {
      set tkgetdir::colors(lstbg) "#FFFFFF"
      set tkgetdir::font {-family courier -size 10}
   }
   set tkgetdir::colors(hilfg) "#FFFF00"
   set tkgetdir::colors(hilbg) "#808080"
   set tkgetdir::colors(selfg) "#FFFFFF"
   set tkgetdir::colors(selbg) "#000080"
   set tkgetdir::colors(selbg+) "#5050B0"
   set tkgetdir::colors(endcol) "#FF8000"
   set tkgetdir::parent ""
   set tkgetdir::autovalid 1
   set tkgetdir::svwd [pwd]
   set tmp -99
   catch { set tmp $tkgetdir::last_srv }
   set tkgetdir::last_srv $tmp
   set tmp ""
   catch { set tmp $tkgetdir::last_dir }
   set tkgetdir::last_dir $tmp
# on accepte fichier et répertoire
   set tkgetdir::typeOut "FR"
# debug
   set tkgetdir::debug 0
   #
   # arguments
   #
   set ind 0
   set max [llength $args]
   set tkgetdir::icurmach -99
   set inidir ""
   set inifilt ""
   while { $ind < $max } {
      switch -exact -- [lindex $args $ind] {
         "-initialdir" {
            incr ind
            if { [lindex $args $ind] != "" } {
               set inidir [lindex $args $ind]
               if {![string equal [lindex $inidir end] / ]} {append inidir /}
            }
            incr ind
         }
         "-initialsrv" {
            incr ind
            set tkgetdir::icurmach [lindex $args $ind]
            incr ind
         }
         "-initialfilt" {
            incr ind
            set inifilt [lindex $args $ind]
            incr ind
         }
         "-geometry" {
            incr ind
            set tkgetdir::geometry [lindex $args $ind]
            incr ind
         }
         "-parent" {
            incr ind
            set tkgetdir::parent [lindex $args $ind]
            incr ind
         }
         "-listfg" {
            incr ind
            set tkgetdir::colors(lstfg) [lindex $args $ind]
            incr ind
         }
         "-listbg" {
            incr ind
            set tkgetdir::colors(lstbg) [lindex $args $ind]
            incr ind
         }
         "-selectfg" {
            incr ind
            set tkgetdir::colors(selfg) [lindex $args $ind]
            incr ind
         }
         "-selectbg" {
            incr ind
            set tkgetdir::colors(selbg) [lindex $args $ind]
            incr ind
         }
         "-hilightfg" {
            incr ind
            set tkgetdir::colors(hilfg) [lindex $args $ind]
            incr ind
         }
         "-hilightbg" {
            incr ind
            set tkgetdir::colors(hilbg) [lindex $args $ind]
            incr ind
         }
         "-endcolor" {
            incr ind
            set tkgetdir::colors(endcol) [lindex $args $ind]
            incr ind
         }
         "-autovalid" {
            incr ind
            set tkgetdir::autovalid 1
         }
         "-font" {
            incr ind
            set tkgetdir::font [lindex $args $ind]
            incr ind
         }
         "-typeOut" {
            incr ind
            set tkgetdir::typeOut [lindex $args $ind]
            incr ind
         }
         "-filetypes" {
            incr ind
            incr ind
         }
         "-debug" {
            incr ind
            set tkgetdir::debug 1
         }
         "-bsf" {
            incr ind
            set tkgetdir::bsf 1
         }
         default {
            ashare::log "<ERROR> (tk_getDirectory) unknown option [lindex $args $ind]"
            return ""
         }
      }
   }
   #
   if { $tkgetdir::debug } {
      set tkgetdir::chrono 1
   } else {
      set tkgetdir::chrono 0
   }
   # messages
   switch -exact -- $tkgetdir::typeOut {
      "F" {
         set imtit 23
      }
      "R" {
         set imtit 22
      }
      default {
         set imtit 175
      }
   }
   set tkgetdir::msg(title)  [ashare::mess ihm $imtit]
   set imcan 85
   if { $tkgetdir::bsf } {
      set tkgetdir::msg(title)  [ashare::mess ihm 187 $astk::astk_version]
      set imcan  32
   }
   set tkgetdir::msg(ldir)   [ashare::mess ihm 177]
   set tkgetdir::msg(ldnam)  "[ashare::mess ihm 24] :"
   set tkgetdir::msg(filtre) "[ashare::mess ihm 176] :"
   set tkgetdir::msg(open)   " Ok "
   set tkgetdir::msg(cancel) [ashare::mess ihm $imcan]

   # tableau de config pour rexec_cmd
   set tkgetdir::config(nb_serv)        $config(nb_serv)
   for {set i -1} {$i < $config(nb_serv)} {incr i} {
      set tkgetdir::config($i,nom)         $config($i,nom)
      set tkgetdir::config($i,nom_complet) $config($i,nom_complet)
      set tkgetdir::config($i,login)       $config($i,login)
      set tkgetdir::config($i,home)        $config($i,home)
      if { $tkgetdir::config($i,home) == "" } {
         set tkgetdir::config($i,home) "/"
      }
      set tkgetdir::config($i,xterm)       $config($i,xterm)
      set tkgetdir::inv(serv,$tkgetdir::config($i,nom)) $i
      #
      set tkgetdir::last_rep($i,0)      $tkgetdir::config($i,home)
      set tkgetdir::last_rep($i,0,fixe) 1
      set tkgetdir::last_rep($i,nb_rep) 1
   }
   set tkgetdir::config(-1,remote_shell_protocol) $config(-1,remote_shell_protocol)
   set tkgetdir::config(-1,remote_copy_protocol)  $config(-1,remote_copy_protocol)
   if { $tkgetdir::debug } {
      ashare::log "<DEBUG> (tk_getDirectory) last_srv : $tkgetdir::last_srv"
      ashare::log "                          last_dir : $tkgetdir::last_dir"
   }
   if { $inidir == "" } {
      set inidir $tkgetdir::last_dir
      if { $inidir == "" } {
         set inidir $config(-1,home)
      }
   }
   if { $tkgetdir::icurmach == -99 } {
      set tkgetdir::icurmach $tkgetdir::last_srv
      if { $tkgetdir::icurmach == -99 } {
         set tkgetdir::icurmach -1
      }
   }
   if { $tkgetdir::debug } {
      ashare::log "<DEBUG> (tk_getDirectory) icurmach : $tkgetdir::icurmach"
      ashare::log "                          inidir   : $inidir"
   }

   #
   # variables et data
   #
   set tkgetdir::fini 0
   set tkgetdir::lsttmpd [list]
   set tkgetdir::lsttmpf [list]

   image create photo b_cmp -file $astk::icon(comp)
   image create photo b_up  -file $astk::icon(up)
   image create photo b_ref -file $astk::icon(refresh)
   image create photo b_new -file $astk::icon(new)
   image create photo b_fic -file $astk::icon(file)
   image create photo b_dir -file $astk::icon(dir)

   if {[lsearch -exact $tkgetdir::font -family] >= 0} {
      eval font create dlistfont $tkgetdir::font
      set tkgetdir::myfont dlistfont
   } else {
      set tkgetdir::myfont $tkgetdir::font
   }

   # lecture du fichier des préférences s'il existe
   set tkgetdir::fic_prefs [file join $astk::rcdir prefs.bsf]
   if { [file exists $tkgetdir::fic_prefs] } {
      set iret [ashare::lire_mc_val $tkgetdir::fic_prefs mots vale nlu]
      for {set j 1} {$j <= $nlu} {incr j} {
         switch $mots($j) {
            tri {
               set tkgetdir::pref($mots($j)) $vale($j)
               tkgetdir::ModifArgs tri_$tkgetdir::pref($mots($j))
            }
            rep_cach -
            fic_cach -
            inv {
               set tkgetdir::pref($mots($j)) $vale($j)
               tkgetdir::ModifArgs $mots($j) $tkgetdir::pref($mots($j))
            }
         }
      }
   }
   # lecture des derniers répertoires, format : Serveur.N : répertoire
   set tkgetdir::fic_last [file join $astk::rcdir last.bsf]
   if { [file exists $tkgetdir::fic_last] } {
      set iret [ashare::lire_mc_val $tkgetdir::fic_last mots vale nlu]
      for {set j 1} {$j <= $nlu} {incr j} {
         regsub {\.[0-9]+$} $mots($j) "" serv
         set srv -999
         catch {set srv $tkgetdir::inv(serv,$serv)}
         if { $srv != -999
           && $tkgetdir::last_rep($srv,nb_rep) < $tkgetdir::nbrep_max } {
            set ind $tkgetdir::last_rep($srv,nb_rep)
            if { [regexp {(.*)\ ([01]+)} $vale($j) mat1 nomrep fixe] != 1 } {
               set nomrep $vale($j)
               set fixe 0
            }
            set tkgetdir::last_rep($srv,$ind)      $nomrep
            set tkgetdir::last_rep($srv,$ind,fixe) $fixe
            incr tkgetdir::last_rep($srv,nb_rep)
         }
      }
   }
   if { $tkgetdir::debug } {
      for {set i -1} {$i < $tkgetdir::config(nb_serv)} {incr i} {
         set serv $tkgetdir::config($i,nom)
         for {set j 0} {$j < $tkgetdir::last_rep($i,nb_rep)} {incr j} {
            ashare::log "<DEBUG> $serv $j : $tkgetdir::last_rep($i,$j) /// $tkgetdir::last_rep($i,$j,fixe)"
         }
      }
   }
   #
   # widgets
   #
   catch { destroy $tkgetdir::dirsel }
   toplevel $tkgetdir::dirsel
   wm withdraw $tkgetdir::dirsel
   wm geometry $tkgetdir::dirsel $tkgetdir::geometry
   if {$tkgetdir::parent != ""} {
      set par $tkgetdir::parent
      set xOrgWin [expr [winfo rootx $par] + [winfo width $par] / 2 ]
      set yOrgWin [expr [winfo rooty $par] + [winfo height $par] / 2 ]
      wm geometry $tkgetdir::dirsel +$xOrgWin+$yOrgWin
      wm transient $tkgetdir::dirsel $tkgetdir::parent
   }
   wm title $tkgetdir::dirsel $tkgetdir::msg(title)

   event add <<RetEnt>> <Return> <KP_Enter>

   if { $tkgetdir::active_menu } {
      frame $tkgetdir::dirsel.f0 -relief raised -borderwidth 1
      pack $tkgetdir::dirsel.f0 -fill x -side top -anchor nw
   }
   frame $tkgetdir::dirsel.f1 -relief flat -borderwidth 0
   frame $tkgetdir::dirsel.f2 -relief sunken -borderwidth 2
   frame $tkgetdir::dirsel.f3 -relief flat -borderwidth 0
   frame $tkgetdir::dirsel.f3b -relief flat -borderwidth 0
   frame $tkgetdir::dirsel.f4 -relief flat -borderwidth 0
   frame $tkgetdir::dirsel.f5 -relief flat -borderwidth 0

   pack $tkgetdir::dirsel.f1 -fill x
   pack $tkgetdir::dirsel.f2 -fill both -expand 1 -padx 6 -pady 6
   pack $tkgetdir::dirsel.f3 -fill x
   pack $tkgetdir::dirsel.f3b -fill x
   pack $tkgetdir::dirsel.f4 -fill x
   pack $tkgetdir::dirsel.f5 -fill x

   menubutton $tkgetdir::dirsel.f1.mach -relief raised -indicatoron 1 -anchor w \
           -menu $tkgetdir::dirsel.f1.mach.m
   menu $tkgetdir::dirsel.f1.mach.m -tearoff 0
   for {set j -1} {$j < $tkgetdir::config(nb_serv)} {incr j} {
      $tkgetdir::dirsel.f1.mach.m add command -label $tkgetdir::config($j,nom) \
          -command "set tkgetdir::icurmach $j ; tkgetdir::ShowDir $tkgetdir::config($j,home) ; $tkgetdir::dirsel.f3.chosen delete 0 end ; $tkgetdir::dirsel.f1.mach configure -text $tkgetdir::config($j,nom)"
   }
    $tkgetdir::dirsel.f1.mach configure -text $tkgetdir::config($tkgetdir::icurmach,nom)
   label $tkgetdir::dirsel.f1.lab -text $tkgetdir::msg(ldir)
   menubutton $tkgetdir::dirsel.f1.dir -relief raised -indicatoron 1 -anchor w \
           -menu $tkgetdir::dirsel.f1.dir.m
   # popup des répertoires
   menu $tkgetdir::dir_popup -tearoff 0 -bd 1
   $tkgetdir::dir_popup add command -label [ashare::mess ihm 341] -font $astk::ihm(font,labmenuB) -state disabled -foreground $astk::ihm(couleur,background) -background $astk::ihm(couleur,foreground)
   $tkgetdir::dir_popup add command -label [ashare::mess ihm 33] -font $astk::ihm(font,labmenu) -command {tkgetdir::DirConf}
   bind $tkgetdir::dirsel.f1.dir <3> {tk_popup $tkgetdir::dir_popup %X %Y}
   
   menu $tkgetdir::dirsel.f1.dir.m -tearoff 0
   button $tkgetdir::dirsel.f1.cmp -image b_cmp -command {tkgetdir::OpenTerm}
   button $tkgetdir::dirsel.f1.ref -image b_ref -command {tkgetdir::ShowDir [$tkgetdir::dirsel.f1.dir cget -text]}
   button $tkgetdir::dirsel.f1.up  -image b_up  -command {tkgetdir::UpDir}
   button $tkgetdir::dirsel.f1.new -image b_new -command {tkgetdir::mkdir}
   set ashare::context($tkgetdir::dirsel.f1.cmp,bouton) [ashare::mess ihm 205]
   set ashare::context($tkgetdir::dirsel.f1.ref,bouton) [ashare::mess ihm 206]
   set ashare::context($tkgetdir::dirsel.f1.up,bouton)  [ashare::mess ihm 207]
   set ashare::context($tkgetdir::dirsel.f1.new,bouton) [ashare::mess ihm 208]
# bind
   foreach but {cmp ref up new} {
      bind $tkgetdir::dirsel.f1.$but <Enter>    {ShowStatus bouton %W bsf}
      bind $tkgetdir::dirsel.f1.$but <FocusIn>  {ShowStatus bouton %W bsf}
      bind $tkgetdir::dirsel.f1.$but <Leave>    {set tkgetdir::status ""; update idletasks}
      bind $tkgetdir::dirsel.f1.$but <FocusOut> {set tkgetdir::status ""; update idletasks}
   }
   bind $tkgetdir::dirsel.f1.cmp <<RetEnt>> {$tkgetdir::dirsel.f1.ref invoke}
   bind $tkgetdir::dirsel.f1.ref <<RetEnt>> {$tkgetdir::dirsel.f1.ref invoke}
   bind $tkgetdir::dirsel.f1.up  <<RetEnt>> {$tkgetdir::dirsel.f1.up  invoke}
   bind $tkgetdir::dirsel.f1.new <<RetEnt>> {$tkgetdir::dirsel.f1.new invoke}

   pack $tkgetdir::dirsel.f1.cmp  -side left  -padx 4 -pady 4
   pack $tkgetdir::dirsel.f1.mach -side left  -padx 4 -pady 4
   pack $tkgetdir::dirsel.f1.new  -side right -padx 2 -pady 4
   pack $tkgetdir::dirsel.f1.up   -side right -padx 2 -pady 4
   pack $tkgetdir::dirsel.f1.ref  -side right -padx 2 -pady 4
   pack $tkgetdir::dirsel.f1.lab  -side left  -padx 4 -pady 4
   pack $tkgetdir::dirsel.f1.dir  -side right -padx 4 -pady 4 -fill x -expand 1

   canvas $tkgetdir::dirsel.f2.cv -borderwidth 0 -yscrollcommand "$tkgetdir::dirsel.f2.sb set"
   if { $tkgetdir::colors(lstbg) != "" } {
      $tkgetdir::dirsel.f2.cv configure -background $tkgetdir::colors(lstbg)
   }
   scrollbar $tkgetdir::dirsel.f2.sb -command "$tkgetdir::dirsel.f2.cv yview"
   set scw 16
   place $tkgetdir::dirsel.f2.cv -x 0 -relwidth 1.0 -width [expr -$scw ] -y 0 \
           -relheight 1.0
   place $tkgetdir::dirsel.f2.sb -relx 1.0 -x [expr -$scw ] -width $scw -y 0 \
           -relheight 1.0
   unset scw

   $tkgetdir::dirsel.f2.cv bind TXT <Any-Enter> tkgetdir::EnterItem
   $tkgetdir::dirsel.f2.cv bind IMG <Any-Enter> tkgetdir::EnterItem
   $tkgetdir::dirsel.f2.cv bind TXT <Any-Leave> tkgetdir::LeaveItem
   $tkgetdir::dirsel.f2.cv bind IMG <Any-Leave> tkgetdir::LeaveItem
   $tkgetdir::dirsel.f2.cv bind TXT <1> tkgetdir::ClickItem
   $tkgetdir::dirsel.f2.cv bind IMG <1> tkgetdir::ClickItem
   $tkgetdir::dirsel.f2.cv bind TXT <2> tkgetdir::ClickItem
   $tkgetdir::dirsel.f2.cv bind IMG <2> tkgetdir::ClickItem
   $tkgetdir::dirsel.f2.cv bind TXT <Double-1> tkgetdir::DoubleClickItem
   $tkgetdir::dirsel.f2.cv bind IMG <Double-1> tkgetdir::DoubleClickItem
   if { $tkgetdir::bsf } {
      $tkgetdir::dirsel.f2.cv bind TXT <Control-1> {tkgetdir::ClickItem 1}
      $tkgetdir::dirsel.f2.cv bind IMG <Control-1> {tkgetdir::ClickItem 1}
      $tkgetdir::dirsel.f2.cv bind TXT <Shift-1>   {tkgetdir::ClickItem 2}
      $tkgetdir::dirsel.f2.cv bind IMG <Shift-1>   {tkgetdir::ClickItem 2}
   # raccourcis clavier
      event add <<Copier>> <Control-c> <Control-C>
      event add <<Couper>> <Control-x> <Control-X>
      event add <<Coller>> <Control-v> <Control-V>
      bind $tkgetdir::dirsel <<Copier>> {tkgetdir::AddRep ; tkgetdir::file_copy}
      bind $tkgetdir::dirsel <<Couper>> {tkgetdir::AddRep ; tkgetdir::file_cut}
      bind $tkgetdir::dirsel <<Coller>> {tkgetdir::AddRep ; tkgetdir::file_paste}
   }
   if { $tkgetdir::active_menu } {
   # menu popup
      init_outils
      tkgetdir::CreateMenu $tkgetdir::popup
      bind $tkgetdir::dirsel.f2.cv <3> { tkgetdir::RightClick %X %Y }
      if { $tkgetdir::bsf } {
         bind $tkgetdir::dirsel.f2.cv <Control-3> { tkgetdir::RightClick %X %Y 1}
         bind $tkgetdir::dirsel.f2.cv <Shift-3>   { tkgetdir::RightClick %X %Y 2}
      }
   # barre de menu
      # fichier
      menubutton $tkgetdir::dirsel.f0.fic -font $astk::ihm(font,labmenu) -text [ashare::mess ihm 26] -underline 0 -menu $tkgetdir::dirsel.f0.fic.mnu
      pack $tkgetdir::dirsel.f0.fic -side left
      tkgetdir::CreateMenu $tkgetdir::dirsel.f0.fic.mnu
      $tkgetdir::dirsel.f0.fic.mnu add separator
      $tkgetdir::dirsel.f0.fic.mnu add command -font $astk::ihm(font,labmenu) -label [ashare::mess ihm 32] -command {$tkgetdir::dirsel.f4.cancel invoke}
      # affichage
      menubutton $tkgetdir::dirsel.f0.aff -font $astk::ihm(font,labmenu) -text [ashare::mess ihm 197] -underline 0 -menu $tkgetdir::dirsel.f0.aff.mnu
      pack $tkgetdir::dirsel.f0.aff -side left
      menu $tkgetdir::dirsel.f0.aff.mnu -tearoff 0 -bd 1
      $tkgetdir::dirsel.f0.aff.mnu add checkbutton -font $astk::ihm(font,labmenu) -label [ashare::mess ihm 198] \
         -variable tkgetdir::pref(fic_cach) -command {tkgetdir::ModifArgs fic_cach $tkgetdir::pref(fic_cach)}
      $tkgetdir::dirsel.f0.aff.mnu add checkbutton -font $astk::ihm(font,labmenu) -label [ashare::mess ihm 321] \
         -variable tkgetdir::pref(rep_cach) -command { }
      $tkgetdir::dirsel.f0.aff.mnu add separator
      $tkgetdir::dirsel.f0.aff.mnu add radiobutton -font $astk::ihm(font,labmenu) -label [ashare::mess ihm 201] \
         -variable tkgetdir::pref(tri) -value nom -command {tkgetdir::ModifArgs tri_nom}
      $tkgetdir::dirsel.f0.aff.mnu add radiobutton -font $astk::ihm(font,labmenu) -label [ashare::mess ihm 202] \
         -variable tkgetdir::pref(tri) -value date -command {tkgetdir::ModifArgs tri_date}
      $tkgetdir::dirsel.f0.aff.mnu add checkbutton -font $astk::ihm(font,labmenu) -label [ashare::mess ihm 200] \
         -variable tkgetdir::pref(inv) -command {tkgetdir::ModifArgs inv $tkgetdir::pref(inv)}
      $tkgetdir::dirsel.f0.aff.mnu add separator
      $tkgetdir::dirsel.f0.aff.mnu add command -font $astk::ihm(font,labmenu) -label [ashare::mess ihm 203] -command {tkgetdir::SauvePrefs}
      
      # aide
      menubutton $tkgetdir::dirsel.f0.help -font $astk::ihm(font,labmenu) -text [ashare::mess ihm 105] -menu $tkgetdir::dirsel.f0.help.mnu
      pack $tkgetdir::dirsel.f0.help -side right
      menu $tkgetdir::dirsel.f0.help.mnu -tearoff 0 -bd 1
      
      if { $tkgetdir::bsf } {
         $tkgetdir::dirsel.f0.help.mnu add command -font $astk::ihm(font,labmenu) -label "[ashare::mess ihm 196]..." -command {show_fen $astk::ihm(log) force}
      }
      $tkgetdir::dirsel.f0.help.mnu add command -font $astk::ihm(font,labmenu) -label "[ashare::mess ihm 106]..." -command {tkgetdir::a_propos $tkgetdir::dirsel}
   }

   label $tkgetdir::dirsel.f3.lnam -text $tkgetdir::msg(ldnam) -width 15 -anchor e
   entry $tkgetdir::dirsel.f3.chosen -takefocus 0
   if { $tkgetdir::colors(lstbg) != "" } {
      $tkgetdir::dirsel.f3.chosen configure -background $tkgetdir::colors(lstbg)
   }
   pack $tkgetdir::dirsel.f3.lnam -side left -padx 4 -pady 4
   pack $tkgetdir::dirsel.f3.chosen -side right -fill x -expand 1 -padx 4 -pady 4

   label $tkgetdir::dirsel.f3b.lnam -text $tkgetdir::msg(filtre) -width 15 -anchor e
   entry $tkgetdir::dirsel.f3b.filtre -takefocus 0
   if { $tkgetdir::colors(lstbg) != "" } {
      $tkgetdir::dirsel.f3b.filtre configure -background $tkgetdir::colors(lstbg)
   }
   bind $tkgetdir::dirsel.f3b.filtre <<RetEnt>> {tkgetdir::ShowDir [$tkgetdir::dirsel.f1.dir cget -text]}
   
   pack $tkgetdir::dirsel.f3b.lnam -side left -padx 4 -pady 4
   pack $tkgetdir::dirsel.f3b.filtre -side right -fill x -expand 1 -padx 4 -pady 4

   button $tkgetdir::dirsel.f4.open -text $tkgetdir::msg(open) \
      -background $astk::ihm(couleur,valid) \
      -command tkgetdir::ValidItem
   bind $tkgetdir::dirsel.f4.open <<RetEnt>> {tkgetdir::ValidItem}

   button $tkgetdir::dirsel.f4.cancel -text $tkgetdir::msg(cancel) \
      -background $astk::ihm(couleur,annul) \
      -command {set tkgetdir::fini -1}
   bind $tkgetdir::dirsel.f4.cancel <<RetEnt>> {$tkgetdir::dirsel.f4.cancel invoke}

   if { $tkgetdir::bsf != 1 } {
      pack $tkgetdir::dirsel.f4.open  -side left -padx 10 -pady 4
   }
   pack $tkgetdir::dirsel.f4.cancel -side right -padx 10 -pady 4

# status
   label $tkgetdir::dirsel.f5.etat -font $astk::ihm(font,val) \
      -textvariable tkgetdir::status -anchor w -relief sunken
   if { $tkgetdir::colors(lstbg) != "" } {
      $tkgetdir::dirsel.f5.etat configure -background $tkgetdir::colors(lstbg)
   }
   pack $tkgetdir::dirsel.f5.etat -fill x -expand yes

   bind $tkgetdir::dirsel.f1 <Destroy> tkgetdir::CloseDirSel

   # sauvegarde les valeurs sélectionnées
   set old_filename $astk::sel(filename)
   set old_servname $astk::sel(servname)
   # initialisation sélection
   set tkgetdir::sel(file_copy) ""
   set tkgetdir::sel(serv_copy) ""
   # filtre initial
   $tkgetdir::dirsel.f3b.filtre insert end $inifilt
   #
   # realwork
   #
   
   tkgetdir::ShowDir $inidir
   wm deiconify $tkgetdir::dirsel
   if { $tkgetdir::bsf == 0 } {
      grab set $tkgetdir::dirsel
   }

   if { $tkgetdir::active_menu } {
      tkgetdir::UpdateMenu $tkgetdir::dirsel.f0.fic.mnu
   }

   # geometry
   ashare::trace_geom bsf $tkgetdir::dirsel

   #
   # wait user
   #
   tkwait variable tkgetdir::fini

   if { $tkgetdir::fini == 1 } {
      set curdir [$tkgetdir::dirsel.f1.dir cget -text]
      set nnam [$tkgetdir::dirsel.f3.chosen get]
      set retval [file join $curdir $nnam]
      if {[lsearch $tkgetdir::lidir $nnam] > -1 || $nnam == "" } {
         set rettyp "R"
      } else {
         set rettyp "F"
      }
      set retmach $tkgetdir::icurmach
      # save for next call to tkGetDir
      set tkgetdir::last_srv $retmach
      set tkgetdir::last_dir $curdir
   } else {
      set retval ""
      set rettyp "F"
      set retmach $tkgetdir::icurmach
   }

   destroy $tkgetdir::dirsel

   set lretour [list]
   lappend lretour $retmach
   lappend lretour $retval
   lappend lretour $rettyp

   # restaure les valeurs sélectionnées
   set astk::sel(filename) $old_filename
   set astk::sel(servname) $old_servname
   return $lretour
}

#################################################################
proc tkgetdir::CloseDirSel {} {
   # sauve les répertoires rémanents
   set id [open $tkgetdir::fic_last w]
   for {set i -1} {$i < $tkgetdir::config(nb_serv)} {incr i} {
      for {set j 1} {$j < $tkgetdir::last_rep($i,nb_rep)} {incr j} {
         puts $id "$tkgetdir::config($i,nom).$j : $tkgetdir::last_rep($i,$j) $tkgetdir::last_rep($i,$j,fixe)"
         if { $tkgetdir::debug } {
            ashare::log "<DEBUG> (CloseDirSel) $tkgetdir::config($i,nom).$j : $tkgetdir::last_rep($i,$j) $tkgetdir::last_rep($i,$j,fixe)"
         }
      }
   }
   close $id
   #
   set wt [font names]
   if {[lsearch -exact $wt dlistfont] >= 0} {
      font delete dlistfont
   }
   event delete <<RetEnt>>
   cd $tkgetdir::svwd
   set tkgetdir::fini 0
}

#################################################################
proc tkgetdir::ShowDir {curdir} {
   global tcl_platform
   variable drives

   $tkgetdir::dirsel.f1.dir configure -text [tkgetdir::Nettoie $curdir]

   set hi1 [font metrics $tkgetdir::myfont -linespace]
   set hi2 [image height b_dir]
   if { $hi1 > $hi2 } {
      set hi $hi1
   } else {
      set hi $hi2
   }
   set wi1 [image width b_dir]
   incr wi1 4
   set wi2 [winfo width $tkgetdir::dirsel.f2.cv]

   set tkgetdir::lidir [list]
   set tkgetdir::fidir [list]
   if {[llength $tkgetdir::lsttmpd] > 0 || [llength $tkgetdir::lsttmpf] > 0} {
      set tkgetdir::lidir $tkgetdir::lsttmpd
      if { $tkgetdir::typeOut == "R" } {
      # ce n'est pas la peine de lister les fichiers
         set tkgetdir::fidir [list]
      } else {
         set tkgetdir::fidir $tkgetdir::lsttmpf
      }
      set tkgetdir::lsttmpd [list]
      set tkgetdir::lsttmpf [list]
   } else {
      set tkgetdir::status [ashare::mess ihm 231]
      update idletasks
      set rdir $tkgetdir::config($tkgetdir::icurmach,home)
      if { [string index $rdir end] != "/" } { append rdir "/" }
      if { [string index $curdir end] != "/" } { append curdir "/" }
      set curdirls $curdir
#      set cmd "/bin/sh -c \"if test -d $curdirls ; then echo $curdirls ; /bin/ls $tkgetdir::ls_args $curdirls ; else echo $rdir ; /bin/ls $tkgetdir::ls_args $rdir ; fi\""
      set cmd "/bin/sh -c \"if test -d '$curdirls' ; then echo '$curdirls' ; /bin/ls $tkgetdir::ls_args '$curdirls' ; else echo '$rdir' ; /bin/ls $tkgetdir::ls_args '$rdir' ; fi\""
      set t0 [clock clicks -milliseconds]
      set iret [ ashare::rexec_cmd $tkgetdir::icurmach tkgetdir::config $cmd "" 0 retour_ls $tkgetdir::dirsel]
      ashare::pointeur off
      if { $tkgetdir::chrono } {
         set dt [expr [clock clicks -milliseconds] - $t0]
         ashare::log "<TIME> (ShowDir) ls : $dt ms"
      }
      if { $iret != 0 } {
         ashare::log "<ERROR> (ShowDir) Remote command failed, exit code : $iret\nOutput :\n$retour_ls\n=========="
         return
      }
      set curdir [lrange $retour_ls 0 0]
      $tkgetdir::dirsel.f1.dir configure -text [tkgetdir::Nettoie $curdir]
      tkgetdir::CreeList [lrange  $retour_ls 3 end] tkgetdir::lidir tkgetdir::fidir
   }
   set sldir [concat $tkgetdir::lidir $tkgetdir::fidir]

# calcul le nombre de colonnes
   set tkgetdir::status [ashare::mess ihm 232]
   update idletasks
   set larg [winfo width $tkgetdir::dirsel]
   if { $larg == 1 } {
      set larg 550
   }
   # enlever 2*padx + largeur(scrollbar)
   set larg [expr $larg - 28]

   set max 0
   foreach file $sldir {
      set wtxt [font measure $tkgetdir::myfont $file]
      if { $wtxt > $max } {
         set max $wtxt
      }
   }

   set max [expr $max + $wi1 + 4]
   # nb de colonnes
   set nbc [expr $larg / $max]
   if { $nbc <= 0 } { set nbc 1 }
   # nb de lignes au total
   set nbl [llength $sldir]
   # nb de lignes par colonne
   set nlc [expr $nbl / $nbc]
   if { $nlc < 1 } { set nlc 1 }
   set rab [expr ($nbl-$nlc*$nbc)]
#ashare::log "larg=$larg max=$max nbc=$nbc nbl=$nbl nlc=$nlc rab=$rab"

   set t0 [clock clicks -milliseconds]
   $tkgetdir::dirsel.f2.cv delete all
   if { $tkgetdir::chrono } {
      set dt [expr [clock clicks -milliseconds] - $t0]
      ashare::log "<TIME> (ShowDir) delete : $dt ms"
   }

   set t0 [clock clicks -milliseconds]
   # Adjust the position of the text wi1 with an offset.
   if { $hi1 < $hi2 } {
      set offset [expr $hi2 - $hi1]
   } else {
      set offset 0
   }
   set numc 0
   set rabn $rab
   set rabc 0
   set ind 0
   foreach file $tkgetdir::lidir {
      $tkgetdir::dirsel.f2.cv create image [expr 2 + $max*$numc] [expr $ind * $hi] \
          -anchor nw -image b_dir -tags IMG
      $tkgetdir::dirsel.f2.cv create text [expr $wi1 + $max*$numc] [expr ($ind * $hi) + $offset] \
          -anchor nw -text $file -fill $tkgetdir::colors(lstfg) \
          -font $tkgetdir::myfont -tags TXT
      set ind [ expr $ind + 1 ]
      if { $ind >= $nlc } {
         if { $rab > 0 && $rabc == 0 } {
            set rabc 1
            incr rabn -1
         } else {
            set ind 0
            set rabc 0
            incr numc
         }
      }
   }
   foreach file $tkgetdir::fidir {
      $tkgetdir::dirsel.f2.cv create image [expr 2 + $max*$numc] [expr $ind * $hi] \
          -anchor nw -image b_fic -tags IMG
      $tkgetdir::dirsel.f2.cv create text [expr $wi1 + $max*$numc] [expr ($ind * $hi) + $offset] \
          -anchor nw -text $file -fill $tkgetdir::colors(lstfg) \
          -font $tkgetdir::myfont -tags TXT
      set ind [ expr $ind + 1 ]
      if { $ind >= $nlc } {
         if { $rab > 0 && $rabc == 0 } {
            set rabc 1
            incr rabn -1
         } else {
            set ind 0
            set rabc 0
            incr numc
         }
      }
   }

   if { $rab } {
      incr nlc
   }
   set ha [expr $nlc * $hi]
   $tkgetdir::dirsel.f2.cv configure -scrollregion [list 0 0 $wi2 $ha]

   # raffraichir la liste des répertoires (au moins le rép. courant)
   tkgetdir::RefrRep

   $tkgetdir::dirsel.f2.cv yview moveto 0
   if { $tkgetdir::chrono } {
      set dt [expr [clock clicks -milliseconds] - $t0]
      ashare::log "<TIME> (ShowDir) affich : $dt ms"
   }
   set tkgetdir::status [ashare::mess ihm 204 $nbl]
   ashare::pointeur on
}

#################################################################
proc tkgetdir::UpDir {} {
   set curdir [$tkgetdir::dirsel.f1.dir cget -text]
   set curlst [file split $curdir]

   set nbr [llength $curlst]
   if { $nbr < 2 } {
      return
   }
   set tmp [expr $nbr - 2]

   set newlst [ lrange $curlst 0 $tmp ]
   set newdir [ eval file join $newlst ]

   $tkgetdir::dirsel.f3.chosen delete 0 end
   tkgetdir::ShowDir $newdir
}

#################################################################
proc tkgetdir::DownDir { } {
   set curdir [$tkgetdir::dirsel.f1.dir cget -text]
   set nnam [$tkgetdir::dirsel.f3.chosen get]
   # si plusieurs sélections, on ne fait rien car pas dans lidir
   if {[lsearch $tkgetdir::lidir $nnam] > -1} {
      set newdir [ file join $curdir $nnam ]
      # If there are more dirs, permit display of one level down.
      # Otherwise, block display and hilight selection in red.
      set tkgetdir::status [ashare::mess ihm 231]
      update idletasks
      set areDirs 0
#      set cmd "/bin/sh -c \"/bin/ls $tkgetdir::ls_args $newdir/\""
      set cmd "/bin/sh -c \"/bin/ls $tkgetdir::ls_args '$newdir/'\""
      set t0 [clock clicks -milliseconds]
      set iret [ ashare::rexec_cmd $tkgetdir::icurmach tkgetdir::config $cmd "" 0 retour_ls $tkgetdir::dirsel]
      set t1 [clock clicks -milliseconds]
      ashare::pointeur off
      if { $tkgetdir::chrono } {
         set dt [expr $t1 - $t0]
         ashare::log "<TIME> (DownDir) ls : $dt ms"
      }
      if { $iret != 0 } {
         ashare::log "<ERROR> (DownDir> Remote command failed"
         #return
      }
      tkgetdir::CreeList [lrange $retour_ls 2 end] tkgetdir::lsttmpd tkgetdir::lsttmpf
      if {[llength $tkgetdir::lsttmpd] > 0} {
         set areDirs 1
      }

      if { $areDirs || $tkgetdir::typeOut != "R" } {
         $tkgetdir::dirsel.f3.chosen delete 0 end
         tkgetdir::ShowDir $newdir
      } else {
         set id [$tkgetdir::dirsel.f2.cv find withtag HASBOX ]
         $tkgetdir::dirsel.f2.cv itemconfigure $id -fill $tkgetdir::colors(endcol)
      }
   }
   ashare::pointeur on
}

#################################################################
proc tkgetdir::EnterItem {} {
   global tcl_platform

   set id [$tkgetdir::dirsel.f2.cv find withtag current]
   set wt [$tkgetdir::dirsel.f2.cv itemcget $id -tags]
   if {[lsearch -exact $wt IMG] >= 0} {
      set id [$tkgetdir::dirsel.f2.cv find above $id]
   }

   $tkgetdir::dirsel.f2.cv itemconfigure $id -fill $tkgetdir::colors(hilfg)
   set bxr [$tkgetdir::dirsel.f2.cv bbox $id]
   eval $tkgetdir::dirsel.f2.cv create rectangle $bxr \
       -fill $tkgetdir::colors(hilbg) -outline $tkgetdir::colors(hilbg) \
       -tags HILIT
   $tkgetdir::dirsel.f2.cv lower HILIT
}

#################################################################
proc tkgetdir::LeaveItem {} {
   $tkgetdir::dirsel.f2.cv delete HILIT
   set id [$tkgetdir::dirsel.f2.cv find withtag current]
   set wt [$tkgetdir::dirsel.f2.cv itemcget $id -tags]
   if {[lsearch -exact $wt IMG] >= 0} {
      set id [$tkgetdir::dirsel.f2.cv find above $id]
   }
   set wt [$tkgetdir::dirsel.f2.cv itemcget $id -tags]
   if { [lsearch -exact $wt HASBOX] >= 0 } {
      $tkgetdir::dirsel.f2.cv itemconfigure HASBOX -fill $tkgetdir::colors(selfg)
   } elseif { [lsearch -exact $wt HSELBOX] >= 0 } {
      $tkgetdir::dirsel.f2.cv itemconfigure HSELBOX -fill $tkgetdir::colors(selfg)
   } else {
      $tkgetdir::dirsel.f2.cv itemconfigure $id -fill $tkgetdir::colors(lstfg)
   }
}

# tags utilisés dans le canvas : (">" signifie "porté par")
#  IMG     > icones (répertoire ou fichier)
#  TXT     > texte du nom de répertoire ou fichier
#  HILIT   > texte du nom de répertoire ou fichier quand on passe dessus
#  HASBOX  > texte du nom de répertoire ou fichier du dernier sélectionné
#            (en bleu foncé)
#  BOX     > rectangle derrière le nom des fichiers ou répertoires sélectionnés
#            (en bleu foncé)
#  HSELBOX > texte du nom des répertoires ou fichiers sélectionnés
#            (en bleu)
#  SELBOX  > rectangle derrière le nom des fichiers ou répertoires sélectionnés
#            (en bleu)

# add=0 : sélection unique
# add=1 : ajoute un item à la sélection (control+bouton)
# add=2 : étend la sélection jusqu'à l'item (shift+bouton)
#################################################################
proc tkgetdir::ClickItem { {add 0} } {
   # put old selected item in normal state
   set id0 [$tkgetdir::dirsel.f2.cv find withtag HASBOX]
   if { $add == 0 } {
      tkgetdir::ClearSel
   }
   # supprime les box
   $tkgetdir::dirsel.f2.cv delete HILIT
   $tkgetdir::dirsel.f2.cv itemconfigure HASBOX -fill $tkgetdir::colors(lstfg)
   $tkgetdir::dirsel.f2.cv dtag HASBOX HASBOX
   $tkgetdir::dirsel.f2.cv delete BOX
   # put new selected item in selected state
   set id [$tkgetdir::dirsel.f2.cv find withtag current]
   set wt [$tkgetdir::dirsel.f2.cv itemcget $id -tags]
   if {[lsearch -exact $wt IMG] >= 0} {
      set id [$tkgetdir::dirsel.f2.cv find above $id]
   }
   tkgetdir::AddToSel $add $id0 $id
   # bounding box
   set bxr [$tkgetdir::dirsel.f2.cv bbox $id]
   $tkgetdir::dirsel.f2.cv addtag HASBOX withtag $id
   $tkgetdir::dirsel.f2.cv itemconfigure $id -fill $tkgetdir::colors(selfg)
   eval $tkgetdir::dirsel.f2.cv create rectangle $bxr \
       -fill $tkgetdir::colors(selbg) -outline $tkgetdir::colors(selbg) \
       -tags BOX
   $tkgetdir::dirsel.f2.cv lower BOX $id
# menus
   tkgetdir::UpdateMenu $tkgetdir::popup
   tkgetdir::UpdateMenu $tkgetdir::dirsel.f0.fic.mnu
   set tkgetdir::status ""
}

#################################################################
proc tkgetdir::DoubleClickItem {} {
   tkgetdir::ClickItem
   tkgetdir::file_open
}

# Vide la sélection
#################################################################
proc tkgetdir::ClearSel {} {
   # vide la zone de texte et astk::sel où on stocke la sélection
   $tkgetdir::dirsel.f3.chosen delete 0 end
   set astk::sel(filename) [list]
   set astk::sel(servname) ""
   # supprime la sélection graphique
   $tkgetdir::dirsel.f2.cv itemconfigure HSELBOX -fill $tkgetdir::colors(lstfg)
   $tkgetdir::dirsel.f2.cv dtag HSELBOX HSELBOX
   $tkgetdir::dirsel.f2.cv delete SELBOX
}

# Control + Bouton : ajoute à la sélection
# add : type de clic
# id0 : dernier sélectionné
#################################################################
proc tkgetdir::AddToSel { add id0 id } {
# crée une bounding box sous l'item it
   proc AddSELB { it } {
      set bxr [$tkgetdir::dirsel.f2.cv bbox $it]
      if { $bxr == "" } {
         return
      }
      $tkgetdir::dirsel.f2.cv addtag HSELBOX withtag $it
      $tkgetdir::dirsel.f2.cv itemconfigure $it -fill $tkgetdir::colors(selfg)
      eval $tkgetdir::dirsel.f2.cv create rectangle $bxr \
          -fill $tkgetdir::colors(selbg+) -outline $tkgetdir::colors(selbg+) \
          -tags SELBOX
      $tkgetdir::dirsel.f2.cv lower SELBOX
   }

   # selecteur : 1 seul choix pour le moment
   if { $tkgetdir::bsf == 0 } {
      tkgetdir::ClearSel
   }
   # shift+bouton mais 1er : comme sélection simple
   if { $add == 2 && [llength $astk::sel(filename)] == 0 } {
      set add 0
   }
   # si sélection simple (add=0), ClickItem a déjà réinitialisé la sélection
   switch $add {
      0 -
      1 {
         set name [$tkgetdir::dirsel.f2.cv itemcget $id -text]
         set cmpl [file join [$tkgetdir::dirsel.f1.dir cget -text] $name]
         if { [lsearch -exact $astk::sel(filename) $cmpl] == -1 } {
            lappend astk::sel(filename) $cmpl
            if { [llength $astk::sel(filename)] > 1 } {
               $tkgetdir::dirsel.f3.chosen insert end " ; "
               AddSELB $id0
            }
            $tkgetdir::dirsel.f3.chosen insert end $name
         } else {
           AddSELB $id0
         }
      }
      2 {
         tkgetdir::ClearSel
         set dern $id
         if { $id0 > $id } {
            set bid $id0
            set id0 $id
            set id  $bid
            set dern $id0
         }
         for {set i $id0} {$i <= $id} {incr i} {
            set wt [$tkgetdir::dirsel.f2.cv itemcget $i -tags]
            if {[lsearch -exact $wt IMG] == -1} {
               set name [$tkgetdir::dirsel.f2.cv itemcget $i -text]
               set cmpl [file join [$tkgetdir::dirsel.f1.dir cget -text] $name]
               lappend astk::sel(filename) $cmpl
               if { [llength $astk::sel(filename)] > 1 } {
                  $tkgetdir::dirsel.f3.chosen insert end " ; "
               }
               # bounding box sauf le dernier (car HASBOX)
               if { $i != $dern } {
                  AddSELB $i
               }
               $tkgetdir::dirsel.f3.chosen insert end $name
            }
         }
      }
   }
   # nom du serveur
   set astk::sel(servname) $tkgetdir::config($tkgetdir::icurmach,nom)
#ashare::log "AddToSel ($tkgetdir::icurmach $astk::sel(servname)) : $astk::sel(filename)"
}

# action clic droit : affiche le menu popup
#################################################################
proc tkgetdir::RightClick { x y {add 0} } {
   set id [$tkgetdir::dirsel.f2.cv find withtag current]
   set wt [$tkgetdir::dirsel.f2.cv itemcget $id -tags]
   if {[lsearch -exact $wt IMG] >= 0} {
      set id [$tkgetdir::dirsel.f2.cv find above $id]
   }
   set nam [$tkgetdir::dirsel.f2.cv itemcget $id -tags]
   if { $nam != "" } {
      if { [lsearch $nam HASBOX] > -1 ||
           [lsearch $nam HSELBOX] > -1 ||
           [lsearch $nam BOX] > -1 } {
         set add 1
      }
      tkgetdir::ClickItem $add
   } else {
      # de-sélectionne l'item
      $tkgetdir::dirsel.f2.cv delete BOX
      set id [$tkgetdir::dirsel.f2.cv find withtag HASBOX]
      $tkgetdir::dirsel.f2.cv itemconfigure $id -fill $tkgetdir::colors(lstfg)
      $tkgetdir::dirsel.f2.cv dtag HASBOX HASBOX
      # vide le champ sélection
      #$tkgetdir::dirsel.f3.chosen delete 0 end
      tkgetdir::ClearSel
      tkgetdir::UpdateMenu $tkgetdir::popup
      tkgetdir::UpdateMenu $tkgetdir::dirsel.f0.fic.mnu
   }
   tk_popup $tkgetdir::popup $x $y
}

# valide l'item sélectionné - bouton Ok
#################################################################
proc tkgetdir::ValidItem {} {
   if { $tkgetdir::bsf } {
      return
   }
   # fichier ou répertoire sélectionné
   set tmp [$tkgetdir::dirsel.f3.chosen get]
   set typ "NEW"
   if { [lsearch $tkgetdir::lidir $tmp] > -1 } {
      set typ "R"
   }
   if { [lsearch $tkgetdir::fidir $tmp] > -1 } {
      set typ "F"
   }
   # nouveau fichier
   if { $tmp != "" && $typ == "NEW" } {
      set tkgetdir::fini 1
   } else {
      # a-t-on le type demandé ?
      # ou on a demandé R ou FR et pas de valeur sélectionnée et autovalid
      if { [regexp $typ $tkgetdir::typeOut] ||
           ( $tmp == "" && $tkgetdir::autovalid && [regexp R $tkgetdir::typeOut])} {
         set tkgetdir::fini 1
      } else {
      # message pour avertir qu'il faut choisir un fichier (car autovalid vaut toujours 1)
         set msg [ashare::mess ihm 25]
         tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info -parent $tkgetdir::dirsel
      }
   }
}

# convertit l'output du ls en listes
#################################################################
proc tkgetdir::CreeList { outls list_dir list_fic } {
   set t0 [clock clicks -milliseconds]
   upvar $list_dir ldir
   upvar $list_fic lfic
   set filtre [tkgetdir::fil2exp [$tkgetdir::dirsel.f3b.filtre get]]
   set length_temp [llength $outls]
   lappend ldir ".."
   set nb 0
   set j 0
   set lty "ini"
   set lva "?"
   set step 1
   set ind0 -1
   set shift_info 0
   # <= pour faire un tour de plus pour prendre le dernier
   while {$j<=$length_temp} {
      # buffer : flags drwx de celui qu'on lit actuellement
      # lva, lty : nom et type de celui qu'on a lu au tour précédent,
      #            et qu'on stocke maintenant dans lidir ou lific
      set buffer [lindex $outls $j]
      while {[regexp {[-dls]+[-rwxsStTlL]{9}} $buffer] == 0 && $j<$length_temp} {
         incr j
         # message pour avertir qu'il y a eu un décalage
         #  pas quand step>1 (car step n'est pas encore calculé),
         #  pas quand lty="l" (lien) car il FAUT décaler de 2.
         if { $step>1 && $lty!="l" && $shift_info == 0} {
            ashare::log "j=$j ind0=$ind0 lty=$lty buffer=$buffer lva=$lva"
            set shift_info 1
            set msg [ashare::mess info 25 $buffer]
            tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info -parent $tkgetdir::dirsel
         }
         set buffer [lindex $outls $j]
      }
      if { $step == 1 && $ind0 == -1 } {
         set ind0 $j
      } elseif { $step == 1 } {
         set step [expr $j - $ind0]
         if { $lty == "l" } {
            incr step -2
         }
         #ashare::log "step=$step j=$j ind0=$ind0 lty=$lty buffer=$buffer"
      }
      set i [expr $j-1]
      set lva [lindex $outls $i]
      if { $lty == "l" } {
         if { [string index $lva end] == "/" } {
            set lty "d"
         } else {
            set lty "-"
         }
         set i [expr $i-2]
         set lva [lindex $outls $i]
      }
#DEBUT MODIF
# Voir l'impact sur les perfs pour les gros répertoires
# le répertoire doit être entre ' ou " pour le ls
# set i0 [expr $i - $step]
# while {[regexp {[0-9]+} [lindex $outls [expr $i - 1]]] != 1 
#     && $i > $i0 } {
#    incr i -1
#    set lva "[lindex $outls $i] $lva"
# }
#FIN MODIF
      regsub {[\*/=@\|]$} $lva "" lva

      if { $lva != "." && $lva != ".." } {
         if { $lty == "d" } {
         # masque ou non les répertoires
            if { $tkgetdir::pref(rep_cach) == 0 } {
               lappend ldir $lva
               incr nb
            }
         } elseif { ($lty == "l" || $lty == "-") && [regexp "$filtre" $lva] && $tkgetdir::typeOut != "R" } {
            lappend lfic $lva
            incr nb
         }
      }
      set lty [string index $buffer 0]
      incr j +$step
   }
   if { $tkgetdir::chrono } {
      set dt [expr [clock clicks -milliseconds] - $t0]
      ashare::log "<TIME> (CreeList) $dt ms ($nb elts)"
   }
   return $nb
}

# ajoute le répertoire courant dans la liste des rép. rémanents
#################################################################
proc tkgetdir::AddRep { } {
   set srv $tkgetdir::icurmach
   set dir [$tkgetdir::dirsel.f1.dir cget -text]
   regsub {/$} $dir "" dir
   if { $dir == "" } { set dir "/" }
   set new -1
   for {set i 0} {$i < $tkgetdir::last_rep($srv,nb_rep)} {incr i} {
      regsub {/$} $tkgetdir::last_rep($srv,$i) "" rep
      if { $rep == "" } { set rep "/" }
      if { $dir == $rep } {
         set new $i
         break
      }
   }
   if { $new == -1 } {
      if { $tkgetdir::last_rep($srv,nb_rep) >= $tkgetdir::nbrep_max } {
         set tkgetdir::last_rep($srv,nb_rep) $tkgetdir::nbrep_max
         # cherche le premier non fixe (qui va sauter)
         set prem_nonfixe 999
         for {set i 0} {$i < $tkgetdir::last_rep($srv,nb_rep)} {incr i} {
            if { $tkgetdir::last_rep($srv,$i,fixe) == 0 } {
               set prem_nonfixe $i
               break
            }
         }
         # décaler les non fixes
         set i1 $prem_nonfixe
         set i2 [expr $i1 + 1]
         set last $tkgetdir::last_rep($srv,nb_rep)
         for {set i $i2} {$i < $last} {incr i} {
            if { $tkgetdir::last_rep($srv,$i,fixe) == 0 } {
               set tkgetdir::last_rep($srv,$i1)      $tkgetdir::last_rep($srv,$i)
               set tkgetdir::last_rep($srv,$i1,fixe) $tkgetdir::last_rep($srv,$i,fixe)
               set i1 $i
            }
         }
         set inew $i1
      } else {
         set inew $tkgetdir::last_rep($srv,nb_rep)
         incr tkgetdir::last_rep($srv,nb_rep)
      }
      if { $inew != 999 } {
         set tkgetdir::last_rep($srv,$inew)      $dir
         set tkgetdir::last_rep($srv,$inew,fixe) 0
         # raffraichit la liste
         tkgetdir::RefrRep
      }
   } elseif { $new > 0 && $tkgetdir::last_rep($srv,$new,fixe) == 0 } {
      # le replacer en fin de liste (le plus récent des non fixes)
      set i1 $new
      set i2 [expr $i1 + 1]
      set last $tkgetdir::last_rep($srv,nb_rep)
      for {set i $i2} {$i < $last} {incr i} {
         if { $tkgetdir::last_rep($srv,$i,fixe) == 0 } {
            set tkgetdir::last_rep($srv,$i1)      $tkgetdir::last_rep($srv,$i)
            set tkgetdir::last_rep($srv,$i1,fixe) $tkgetdir::last_rep($srv,$i,fixe)
            set i1 $i
         }
      }
      set inew $i1
      set tkgetdir::last_rep($srv,$inew)      $rep
      set tkgetdir::last_rep($srv,$inew,fixe) 0
   }
   # sinon home ou fixe
}

# raffraichit la liste des répertoires rémanents du serveur courant
#################################################################
proc tkgetdir::RefrRep { } {
   $tkgetdir::dirsel.f1.dir.m delete 0 last
   set srv $tkgetdir::icurmach
# reordonne les répertoires sauf home
   set ltmp [list]
   for {set i 1} {$i < $tkgetdir::last_rep($srv,nb_rep)} {incr i} {
      lappend ltmp [list $i $tkgetdir::last_rep($srv,$i) $tkgetdir::last_rep($srv,$i,fixe)]
   }
   set ltmp [lsort -decreasing -index 2 [lsort -index 1 $ltmp]]
# insert le home en premier
   set i 0
   set ltmp [linsert $ltmp -1 [list $i $tkgetdir::last_rep($srv,$i) $tkgetdir::last_rep($srv,$i,fixe)]]
# reconstruit le menu
   $tkgetdir::dirsel.f1.dir.m add command -label "----- Direct -----" \
       -command "tkgetdir::ShowDirect"
# liste les répertoires
   for {set ind 0} {$ind<[llength $ltmp]} {incr ind} {
      set i      [lindex [lindex $ltmp $ind] 0]
      set tmpdir [lindex [lindex $ltmp $ind] 1]
      set fixe   [lindex [lindex $ltmp $ind] 2]
      if { $fixe == 1 } {
         $tkgetdir::dirsel.f1.dir.m add checkbutton \
            -variable tkgetdir::last_rep($srv,$i,fixe) \
            -font $astk::ihm(font,labmenu) -label $tmpdir \
            -command "set tkgetdir::last_rep($srv,$i,fixe) $fixe ; tkgetdir::ShowDir {$tmpdir}"
      } else {
         $tkgetdir::dirsel.f1.dir.m add command \
            -font $astk::ihm(font,labmenu) -label $tmpdir \
            -command "tkgetdir::ShowDir {$tmpdir}"
      }
   }
}

# configure la liste des répertoires rémanents du serveur courant
#################################################################
proc tkgetdir::DirConf { } {
   global tmp_last_rep

   set srv $tkgetdir::icurmach

   set fen $tkgetdir::dir_conf
   catch {destroy $fen}
   toplevel $fen
   wm withdraw $fen
   wm title $fen "[ashare::mess ihm 33]"
   wm transient $fen $tkgetdir::dirsel
   grab set $fen

   copie_tabl tkgetdir::last_rep tmp_last_rep

   pack [frame $fen.liste -relief solid -bd 1] -fill both -expand 1
# titre
   set tit [ashare::mess ihm 341]
   append tit " (max. "
   append tit [expr $tkgetdir::nbrep_max - 1]
   append tit ")"
   pack [frame $fen.liste.tit1 -relief solid -bd 0] -fill x
   label $fen.liste.tit1.lbl -font $astk::ihm(font,labbout) -text $tit -width 50
   pack $fen.liste.tit1.lbl -pady 3 -side left -fill x

# répertoires
   set w $fen.liste.rep
   pack [frame $w -relief solid -bd 1] -fill both -expand 1 -padx 5 -pady 5

   # labels de colonne
   set lig 0
   label $w.it0_$lig -font $astk::ihm(font,labbout) -text [ashare::mess ihm 342]
   label $w.it1_$lig -font $astk::ihm(font,labbout) -text [ashare::mess ihm 177] -width 50
   grid $w.it0_$lig -row $lig -column 0 -sticky nw -pady 3
   grid $w.it1_$lig -row $lig -column 1 -sticky new -pady 3
   
# reordonne les répertoires sauf home
   set ltmp [list]
   for {set i 1} {$i < $tmp_last_rep($srv,nb_rep)} {incr i} {
      lappend ltmp [list $i $tmp_last_rep($srv,$i) $tmp_last_rep($srv,$i,fixe)]
   }
   set ltmp [lsort -decreasing -index 2 [lsort -index 1 $ltmp]]
# insert le home en premier
   set i 0
   set ltmp [linsert $ltmp -1 [list $i $tkgetdir::last_rep($srv,$i) $tkgetdir::last_rep($srv,$i,fixe)]]
   # on complète jusqu'au nbre max
   for {set i $tmp_last_rep($srv,nb_rep)} {$i < $tkgetdir::nbrep_max} {incr i} {
      set tmp_last_rep($srv,$i) ""
      set tmp_last_rep($srv,$i,fixe) 0
      lappend ltmp [list $i $tmp_last_rep($srv,$i) $tmp_last_rep($srv,$i,fixe)]
   }
   set tmp_last_rep($srv,nb_rep) $tkgetdir::nbrep_max
   
# liste les répertoires
   for {set ind 0} {$ind<[llength $ltmp]} {incr ind} {
      set i      [lindex [lindex $ltmp $ind] 0]
      set lig [expr $ind + 1]
      if { $ind == 0 } {
         set tmp $tmp_last_rep($srv,$i)
         append tmp " (\$HOME)"
         set etat disabled
         label $w.it1_$lig -font $astk::ihm(font,lab) -text $tmp -anchor w
      } else {
         set etat normal
         entry $w.it1_$lig -font $astk::ihm(font,lab) -textvariable tmp_last_rep($srv,$i)
      }
      checkbutton $w.it0_$lig -variable tmp_last_rep($srv,$i,fixe) -state $etat
      grid $w.it0_$lig -row $lig -column 0 -sticky nw -pady 3
      grid $w.it1_$lig -row $lig -column 1 -sticky new -pady 3
   }
   grid columnconfigure $w 1 -weight 1

# ok
   pack [frame $fen.valid -relief solid -bd 0]
   button $fen.valid.annuler -font $astk::ihm(font,labbout) -text [ashare::mess ihm 85] \
       -bg $astk::ihm(couleur,annul) \
      -command "destroy $fen ; grab release $fen"
   button $fen.valid.ok -font $astk::ihm(font,labbout) -text "Ok" \
       -bg $astk::ihm(couleur,valid) \
      -command "tkgetdir::DirConf_accept ; destroy $fen ; grab release $fen"
   pack $fen.valid.ok $fen.valid.annuler -side left -padx 10 -pady 5
   
   ashare::centre_fen $fen $tkgetdir::dirsel
   wm deiconify $fen
}

# action Ok sur ConfDir
#################################################################
proc tkgetdir::DirConf_accept { } {
   global tmp_last_rep
   # 
   for {set srv -1} {$srv < $tkgetdir::config(nb_serv)} {incr srv} {
      set newi 0
      for {set i 0} {$i < $tmp_last_rep($srv,nb_rep)} {incr i} {
         regsub -all -- { +} $tmp_last_rep($srv,$i) "" tmp_last_rep($srv,$i)
         regsub {/$} $tmp_last_rep($srv,$i) "" tmp_last_rep($srv,$i)
         if { $tmp_last_rep($srv,$i) != "" } {
            set tkgetdir::last_rep($srv,$newi)      $tmp_last_rep($srv,$i)
            set tkgetdir::last_rep($srv,$newi,fixe) $tmp_last_rep($srv,$i,fixe)
            incr newi
         }
      }
      set tkgetdir::last_rep($srv,nb_rep) $newi
   }
   tkgetdir::RefrRep
}

# Va directement dans un répertoire saisi par l'utilisateur
#################################################################
proc tkgetdir::ShowDirect { } {
   global getValue_val
   getValue_fen $tkgetdir::dirsel 24 177 {} "" non_vide
   tkwait window .fen_getv
   if { $getValue_val != "_VIDE" } {
      set new [file join [$tkgetdir::dirsel.f1.dir cget -text] $getValue_val]
      tkgetdir::ShowDir $new
   }
}

#################################################################
proc tkgetdir::Nettoie {idir} {
   # retirer /./ et /xxxx/../
   regsub {/$} $idir "" dir
   if { [regexp {(.*)/.*/\.\.$} $dir mat1 dir0] } { set dir $dir0 }
   regsub {/\.\.$} $dir "" dir
   regsub {/\.$} $dir "" dir
   append dir "/"
   if { $tkgetdir::debug } {
      ashare::log "<DEBUG> (Nettoie) in=$idir   out=$dir"
   }
   return $dir
}

# "convertit" un filtre du type *.comm en l'expression régulière correspondante
#################################################################
proc tkgetdir::fil2exp { fil } {
# retire les espaces
   if { $fil != "" } {
      regsub -all -- { $} $fil "" fil
      regsub -all -- {^ } $fil "" fil
      regsub -all -- { +} $fil "|" fil
      regsub -all -- {\.} $fil "\\." fil
      regsub -all -- {\*} $fil ".*" fil
      regsub -all -- {\?} $fil "." fil
      set fil "^$fil\$"
   }
# resultat
   return $fil
}

# Arguments du ls
#################################################################
proc tkgetdir::ModifArgs { arg {actif 1} } {
# init : -lnF
   set out $tkgetdir::ls_args
   if { [regexp {tri_} $arg] } {
      # retirer les tris possibles
      regsub -all "t" $out "" out
   }
   switch $arg {
      tri_nom    { }
      tri_date   { append out "t" }
      fic_cach {
         if { $actif } {
            append out "a"
         } else {
            regsub -all "a" $out "" out
         }
      }
      inv {
         if { $actif } {
            append out "r"
         } else {
            regsub -all "r" $out "" out
         }
      }
   }
   if { $tkgetdir::debug } {
      ashare::log "<DEBUG> (ModifArgs) in=$tkgetdir::ls_args   out=$out"
   }
   set tkgetdir::ls_args $out
   return 0
}

# construit le popup menu
#################################################################
proc tkgetdir::CreateMenu { m } {
# menu popup
   create_popup $m
   # supprime "valeur par défaut" sans objet hors d'une liste d'astk
   if { $ashare::origine == "from_salome" } {
      set isupD 6
      set isupF 6
   } else {
      set isupD 5
      set isupF 5
   }
   $m delete $isupD $isupF
   complete_popup $m
   # action par defaut en fonction de l'extension
   $m entryconfigure [ashare::mess ihm 169] -command {tkgetdir::file_open}
   $m entryconfigure [ashare::mess ihm 171] -command {tkgetdir::AddRep ; ashare::file_open edit}
   # manipulation des fichiers
   if { $tkgetdir::bsf } {
      # part de la fin pour toujours insérer en $isupF
      $m insert $isupF separator
      # execute une commande
      $m insert $isupF command -label [ashare::mess ihm 245] -font $astk::ihm(font,labmenu) -command {tkgetdir::AddRep ; tkgetdir::ExecCmde $tkgetdir::dirsel}
      # separateur
      $m insert $isupF separator
      # new dir
      $m insert $isupF command -label [ashare::mess ihm 183] -font $astk::ihm(font,labmenu) -command {tkgetdir::mkdir ; tkgetdir::AddRep}
      # new file
      $m insert $isupF command -label [ashare::mess ihm 212] -font $astk::ihm(font,labmenu) -command {tkgetdir::file_new ; tkgetdir::AddRep}
      # separateur
      $m insert $isupF separator
      # rename
      $m insert $isupF command -label [ashare::mess ihm 182] -font $astk::ihm(font,labmenu) -command {tkgetdir::AddRep ; tkgetdir::file_rename}
      # delete
      $m insert $isupF command -label [ashare::mess ihm 181] -font $astk::ihm(font,labmenu) -command {tkgetdir::AddRep ; tkgetdir::file_delete}
      # paste
      $m insert $isupF command -label [ashare::mess ihm 185] -font $astk::ihm(font,labmenu) -command {tkgetdir::AddRep ; tkgetdir::file_paste}
      # cut
      $m insert $isupF command -label [ashare::mess ihm 184] -font $astk::ihm(font,labmenu) -command {tkgetdir::AddRep ; tkgetdir::file_cut}
      # copy
      $m insert $isupF command -label [ashare::mess ihm 180] -font $astk::ihm(font,labmenu) -command {tkgetdir::AddRep ; tkgetdir::file_copy}
   } else {
   # ajout selectionner (faire à la fin pour ne pas décaler)
      $m insert 0 command -label [ashare::mess ihm 178] -font $astk::ihm(font,labmenuB) -command {tkgetdir::AddRep ; tkgetdir::ValidItem}
      $m entryconfigure [ashare::mess ihm 169] -font $astk::ihm(font,labmenu)
   }
   # desactive les outils "auto_cfg" sans objet hors d'astk
   $m.opw entryconfigure 0 -state disabled
   $m.opw entryconfigure 1 -state disabled
   $m.opw entryconfigure 2 -state disabled
}

# modifie les menus : popup et barre de menu
#################################################################
proc tkgetdir::UpdateMenu { m } {
   set nnam [$tkgetdir::dirsel.f3.chosen get]
   # dans tous les cas (répertoire, fichier ou fond)
   if { $tkgetdir::bsf } {
      if { $tkgetdir::sel(file_copy) != "" } {
         $m entryconfigure [ashare::mess ihm 185] -state normal
      } else {
         $m entryconfigure [ashare::mess ihm 185] -state disabled
      }
   }
   # dans le vide
   if { [lsearch -exact $tkgetdir::lidir $nnam] == -1
     && [lsearch -exact $tkgetdir::fidir $nnam] == -1
     && [llength $astk::sel(filename)]          <=  1 } {
      $m entryconfigure [ashare::mess ihm 169] -state disabled
      $m entryconfigure [ashare::mess ihm 171] -state disabled
      $m entryconfigure [ashare::mess ihm 170] -state disabled
      $m entryconfigure [ashare::mess ihm 172] -state disabled
      if { $tkgetdir::bsf } {
      # comportement bsf
         $m entryconfigure [ashare::mess ihm 179] -state disabled
         $m entryconfigure [ashare::mess ihm 180] -state disabled
         $m entryconfigure [ashare::mess ihm 181] -state disabled
         $m entryconfigure [ashare::mess ihm 182] -state disabled
         $m entryconfigure [ashare::mess ihm 184] -state disabled
      } else {
      # comportement selecteur
         $m entryconfigure [ashare::mess ihm 178] -state disabled
      }
   } else {
      $m entryconfigure [ashare::mess ihm 169] -state normal
      $m entryconfigure [ashare::mess ihm 172] -state normal
      if { $tkgetdir::bsf } {
      # comportement bsf
         $m entryconfigure [ashare::mess ihm 180] -state normal
         $m entryconfigure [ashare::mess ihm 181] -state normal
         $m entryconfigure [ashare::mess ihm 182] -state normal
         $m entryconfigure [ashare::mess ihm 184] -state normal
      } else {
      # comportement selecteur
         $m entryconfigure [ashare::mess ihm 178] -state normal
      }
      # sur un repertoire
      if { [lsearch -exact $tkgetdir::lidir $nnam] > -1 } {
         $m entryconfigure [ashare::mess ihm 171] -state disabled
         $m entryconfigure [ashare::mess ihm 170] -state disabled
         if { $tkgetdir::bsf } {
         # comportement bsf
            $m entryconfigure [ashare::mess ihm 179] -state disabled
            $m entryconfigure [ashare::mess ihm 179] -state disabled
         } else {
         # comportement selecteur
            $m entryconfigure [ashare::mess ihm 178] -font $astk::ihm(font,labmenu)
            $m entryconfigure [ashare::mess ihm 169] -font $astk::ihm(font,labmenuB)
         }
      }
      # sur un fichier ou sélection multiple
      if { [lsearch -exact $tkgetdir::fidir $nnam] > -1 
        || [llength $astk::sel(filename)]          >  1 } {
         $m entryconfigure [ashare::mess ihm 171] -state normal
         $m entryconfigure [ashare::mess ihm 170] -state normal
         if { $tkgetdir::bsf } {
         # comportement bsf
            $m entryconfigure [ashare::mess ihm 179] -state normal
            $m entryconfigure [ashare::mess ihm 179] -state normal
         } else {
         # comportement selecteur
            $m entryconfigure [ashare::mess ihm 178] -font $astk::ihm(font,labmenuB)
            $m entryconfigure [ashare::mess ihm 169] -font $astk::ihm(font,labmenu)
         }
      }
   }
}

# ouvre un fichier avec l'appli par défaut ou parcourt un répertoire
#################################################################
proc tkgetdir::file_open {} {
   set nnam [$tkgetdir::dirsel.f3.chosen get]
   if { [lsearch -exact $tkgetdir::lidir $nnam] > -1
     && [llength $astk::sel(filename)]          <= 1 } {
      tkgetdir::DownDir
   } else {
      # ajoute le répertoire dans la liste
      tkgetdir::AddRep
      #
      if { $tkgetdir::bsf } {
         # ouvre avec l'appli par défaut en fonction de l'extension
         ashare::file_open ext
      } else {
         # simule la validation
         tkgetdir::ValidItem
      }
   }
}

# copie un fichier ou répertoire (stocke seulement les infos fich+serv)
#################################################################
proc tkgetdir::file_copy { } {
   set nnam [$tkgetdir::dirsel.f3.chosen get]
   if { $astk::sel(filename) == "" || $nnam == "" } {
      set msg [ashare::mess ihm 25]
      tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info
      change_status $msg
      return
   }
   set tkgetdir::sel(delete) 0
   set tkgetdir::sel(file_copy) $astk::sel(filename)
   set tkgetdir::sel(serv_copy) $astk::sel(servname)
   if { $ashare::dbg >= 2 } {
      ashare::log "<DEBUG> (file_copy) copie de $tkgetdir::sel(file_copy) de $tkgetdir::sel(serv_copy)"
   }
   set tkgetdir::status [ashare::mess ihm 199]
}

# "coupe" un fichier ou répertoire (stocke seulement les infos fich+serv)
#################################################################
proc tkgetdir::file_cut { } {
   tkgetdir::file_copy
   set tkgetdir::sel(delete) 1
   set tkgetdir::status [ashare::mess ihm 199]
}

# colle un fichier ou répertoire (où l'on se trouve)
#################################################################
proc tkgetdir::file_paste { } {
   set srv_out $tkgetdir::icurmach
   set dir_out [$tkgetdir::dirsel.f1.dir cget -text]
   if { $ashare::dbg >= 2 } {
      ashare::log "<DEBUG> (file_paste) colle dans $dir_out sur $astk::sel(servname)"
   }
   set srv_in $tkgetdir::inv(serv,$tkgetdir::sel(serv_copy))
   set lfich $tkgetdir::sel(file_copy)
   for {set ind 0} {$ind < [llength $lfich]} {incr ind} {
      set nam_in [lindex $lfich $ind]
      # si même serveur et même endroit, on sort
      # (sinon on effacerait le fichier en cas de cut)
      set dir_in [file dirname $nam_in]
      append dir_in "/"
      if { $srv_in == $srv_out && $dir_in == $dir_out } {
         return
      }
   # doit-on effacer la source ?
      if { $tkgetdir::sel(delete) } {
         set cmd "/bin/sh -c \""
         append cmd [ashare::rcp_cmd tkgetdir::config $srv_in $nam_in $srv_out $dir_out commande]
         append cmd " ; /bin/rm -rf $nam_in"
         append cmd "\""
         set jret [ashare::rexec_cmd $srv_in tkgetdir::config $cmd "" 0 out $tkgetdir::dirsel]
      } else {
         set jret [ashare::rcp_cmd tkgetdir::config $srv_in $nam_in $srv_out $dir_out action $tkgetdir::dirsel]
      }
      if { $jret != 0 } {
         set msg [ashare::mess erreur 16]
         tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info -parent $tkgetdir::dirsel
      }
   }
# doit-on effacer la source ?
   if { $tkgetdir::sel(delete) } {
      set tkgetdir::sel(delete) 0
      set tkgetdir::sel(file_copy) ""
      set tkgetdir::sel(serv_copy) ""
   }
# raffraichir
   tkgetdir::ShowDir [$tkgetdir::dirsel.f1.dir cget -text]
   set tkgetdir::status ""
}

# efface le fichier ou répertoire sélectionné
#################################################################
proc tkgetdir::file_delete { } {
   set srv $tkgetdir::inv(serv,$astk::sel(servname))
   set nam $astk::sel(filename)
   if { $ashare::dbg >= 2 } {
      ashare::log "<DEBUG> (file_delete) efface $nam sur $astk::sel(servname)"
   }
   set confirm [tk_messageBox -title [ashare::mess ihm 143] -message [ashare::mess ihm 186] -type yesno -icon question -parent $tkgetdir::dirsel]
   if { $confirm == "yes" } {
      set cmd "/bin/rm -rf $nam"
      set jret [ashare::rexec_cmd $srv tkgetdir::config $cmd "" 0 out $tkgetdir::dirsel]
      if { $jret != 0 } {
         set msg [ashare::mess erreur 17]
         tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info -parent $tkgetdir::dirsel
      }
   # raffraichir
      tkgetdir::ShowDir [$tkgetdir::dirsel.f1.dir cget -text]
      # vide le champ sélection
      tkgetdir::ClearSel
   }
}

# renomme le fichier ou répertoire sélectionné
#################################################################
proc tkgetdir::file_rename { } {
   global getValue_val

   set lfich $astk::sel(filename)
   set valint $tkgetdir::lidir
   append valint $tkgetdir::fidir
   for {set ind 0} {$ind < [llength $lfich]} {incr ind} {
      set fich [lindex $lfich $ind]
      set vinit [file tail $fich]
      getValue_fen $tkgetdir::dirsel 182 188 $tkgetdir::lidir $vinit non_vide
      tkwait window .fen_getv

      if { $getValue_val != "_VIDE" && $getValue_val != $vinit } {
         set new [file join [$tkgetdir::dirsel.f1.dir cget -text] $getValue_val]
         set cmd "/bin/mv -f $fich $new"
         set srv $tkgetdir::icurmach
         set jret [ashare::rexec_cmd $srv tkgetdir::config $cmd "" 0 out $tkgetdir::dirsel]
         if { $jret != 0 } {
            set msg [ashare::mess erreur 19]
            tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info -parent $tkgetdir::dirsel
         }
      }
   }
   # raffraichir
   tkgetdir::ShowDir [$tkgetdir::dirsel.f1.dir cget -text]
}

# créer un nouveau fichier (vide)
#################################################################
proc tkgetdir::file_new { } {
   global getValue_val

   set valint $tkgetdir::lidir
   append valint $tkgetdir::fidir
   getValue_fen $tkgetdir::dirsel 212 212 $tkgetdir::lidir "" non_vide
   tkwait window .fen_getv

   if { $getValue_val != "_VIDE" } {
      set fich [file join [$tkgetdir::dirsel.f1.dir cget -text] $getValue_val]
      set cmd "touch $fich"
      set srv $tkgetdir::icurmach
      set jret [ashare::rexec_cmd $srv tkgetdir::config $cmd "" 0 out $tkgetdir::dirsel]
      if { $jret != 0 } {
         set msg [ashare::mess erreur 20]
         tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info -parent $tkgetdir::dirsel
      }
   # raffraichir
      tkgetdir::ShowDir [$tkgetdir::dirsel.f1.dir cget -text]
   }
}

# créer un répertoire
#################################################################
proc tkgetdir::mkdir { } {
   global getValue_val

   set valint $tkgetdir::lidir
   append valint $tkgetdir::fidir
   getValue_fen $tkgetdir::dirsel 183 183 $tkgetdir::lidir "" non_vide
   tkwait window .fen_getv

   if { $getValue_val != "_VIDE" } {
      set dir [file join [$tkgetdir::dirsel.f1.dir cget -text] $getValue_val]
      set cmd "/bin/mkdir $dir"
      set srv $tkgetdir::icurmach
      set jret [ashare::rexec_cmd $srv tkgetdir::config $cmd "" 0 out $tkgetdir::dirsel]
      if { $jret != 0 } {
         set msg [ashare::mess erreur 21]
         tk_messageBox -title [ashare::mess ihm 138] -message $msg -type ok -icon info -parent $tkgetdir::dirsel
      }
   # on va dans le nouveau répertoire
      tkgetdir::ShowDir $dir
   }
}

# ouvre une fenetre sur la machine sélectionnée
#################################################################
proc tkgetdir::OpenTerm { } {
   set srv $tkgetdir::icurmach
   set dir [$tkgetdir::dirsel.f1.dir cget -text]
   set xt $tkgetdir::config($srv,xterm)
   if { $xt != "" } {
      set cmd "/bin/sh -c \"cd $dir ; "
      if { [regexp -- {@D} $xt] == 0 } {
         append xt " -display @D"
      }
      append cmd $xt
      append cmd "\""
	   ashare::rexec_cmd $srv tkgetdir::config $cmd "" 1 out
   } else {
      set msg [ashare::mess erreur 15 [ashare::mess ihm 82] $tkgetdir::config($srv,nom)]
      tk_messageBox -message $msg -type ok -icon info -parent $tkgetdir::dirsel
   }
}

# exécute une commande dans le répertoire courant
#################################################################
proc tkgetdir::ExecCmde { parent } {
   global ExecCmde_cmde ExecCmde_shell
   set srv $tkgetdir::icurmach
   set dir [$tkgetdir::dirsel.f1.dir cget -text]

   if { [llength $astk::sel(filename)] > 0 } {
      set ExecCmde_cmde [lindex $astk::sel(filename) 0]
   }

   set fen .fen_exec_cmde
   catch {destroy $fen}
   toplevel $fen
   wm title $fen "[ashare::mess ihm 245] - $tkgetdir::config($srv,nom)"
   wm withdraw $fen
   wm transient $fen $parent
   frame $fen.txt -relief flat -bd 0
   label $fen.txt.lbl -font $astk::ihm(font,lab) -text "[ashare::mess ihm 156] :"
   entry $fen.txt.chp -width 40 -font $astk::ihm(font,val) -textvariable ExecCmde_cmde
   $fen.txt.chp icursor end
   label $fen.rep -font $astk::ihm(font,lab) -text "[ashare::mess ihm 177] : $dir"
   button $fen.ok -font $astk::ihm(font,labbout) -text "Ok" \
      -background $astk::ihm(couleur,valid) \
      -command {tkgetdir::ExecCmde_action $ExecCmde_shell $ExecCmde_cmde}
   button $fen.cancel -font $astk::ihm(font,labbout) -text [ashare::mess ihm 85] \
      -background $astk::ihm(couleur,annul) \
      -command "destroy $fen"
   bind $fen <Return> "$fen.ok invoke"

   # shells
   frame $fen.sh -relief flat -bd 0
   set ini "/bin/sh"
   catch {set ini $ExecCmde_shell}
   set ExecCmde_shell $ini
	radiobutton $fen.sh.sh   -font $astk::ihm(font,lab) -text /bin/sh   -value /bin/sh   -variable ExecCmde_shell
	radiobutton $fen.sh.csh  -font $astk::ihm(font,lab) -text /bin/csh  -value /bin/csh  -variable ExecCmde_shell
	radiobutton $fen.sh.ksh  -font $astk::ihm(font,lab) -text /bin/ksh  -value /bin/ksh  -variable ExecCmde_shell
	radiobutton $fen.sh.bash -font $astk::ihm(font,lab) -text /bin/bash -value /bin/bash -variable ExecCmde_shell
	radiobutton $fen.sh.tcsh -font $astk::ihm(font,lab) -text /bin/tcsh -value /bin/tcsh -variable ExecCmde_shell
	radiobutton $fen.sh.zsh  -font $astk::ihm(font,lab) -text /bin/zsh  -value /bin/zsh  -variable ExecCmde_shell

   pack $fen.txt -fill x -expand 1
   pack $fen.txt.lbl -padx 10 -pady 5 -side left -anchor w
   pack $fen.txt.chp -padx 10 -pady 5 -side right
   pack $fen.rep -padx 10 -pady 5 -anchor w
   pack $fen.sh -fill x -expand yes
   pack $fen.sh.sh $fen.sh.csh $fen.sh.ksh $fen.sh.bash $fen.sh.tcsh $fen.sh.zsh -padx 3 -pady 5 -side left
   pack $fen.ok $fen.cancel -padx 20 -pady 10 -side left
   
   # position
   ashare::centre_fen $fen $parent
   wm deiconify $fen
   focus $fen.txt.chp
   update
}

# execute la commande
#################################################################
proc tkgetdir::ExecCmde_action { shell cmde } {
   if { $cmde != "" } {
      set srv $tkgetdir::icurmach
      set dir [$tkgetdir::dirsel.f1.dir cget -text]
      set cmde "cd $dir ; $cmde"
      set cmd "$shell -c \""
      append cmd $cmde
      append cmd "\""
	   ashare::rexec_cmd $srv tkgetdir::config $cmd "" 0 out $tkgetdir::dirsel
   # output
      set num [clock seconds]
      set fen .fen_output_$num
      toplevel $fen
      wm title $fen [ashare::mess ihm 245]
      wm transient $fen .
      set msg [ashare::mess ihm 156]
      append msg " : "
      append msg $cmde
      label $fen.lbl -font $astk::ihm(font,lab) -text $msg
      pack $fen.lbl -anchor w -side top -padx 5 -pady 3

      pack [frame $fen.f -relief flat -bd 0] -anchor w -side top -padx 5 -pady 3 -fill both -expand yes
      text $fen.f.tx -xscrollcommand "$fen.f.scrollx set" -yscrollcommand "$fen.f.scrolly set" \
         -width 90 -height 24 -font $astk::ihm(font,txtfix) -bg $astk::ihm(couleur,entry_background) -wrap none
      scrollbar $fen.f.scrolly -command "$fen.f.tx yview"
      scrollbar $fen.f.scrollx -command "$fen.f.tx xview" -orient h
      pack $fen.f.scrolly -side right  -fill y
      pack $fen.f.scrollx -side bottom -fill x
      pack $fen.f.tx -expand yes -fill both
      $fen.f.tx insert end $out
      $fen.f.tx configure -state disabled

      button $fen.ok -font $astk::ihm(font,labbout) -text "Ok" \
         -background $astk::ihm(couleur,valid) \
         -command "grab release $fen ; destroy $fen"
      pack $fen.ok -side top -pady 10
   }
   destroy .fen_exec_cmde
}

# sauve les prefs
#################################################################
proc tkgetdir::SauvePrefs { } {
   set id [open $tkgetdir::fic_prefs w]
   foreach mot { fic_cach rep_cach tri inv } {
      puts $id "$mot : $tkgetdir::pref($mot)"
   }
   ashare::save_geom
   close $id
}

# a propos...
#################################################################
proc tkgetdir::a_propos { parent } {
   set fen .fen_about
   catch {destroy $fen}
   toplevel $fen
   wm title $fen "[ashare::mess ihm 105] - [ashare::mess ihm 106]"
   wm geometry $fen "+300+200"
   wm transient $fen $parent
   grab set $fen

#  titre
   pack [frame $fen.titre -relief raised -bd 1] -anchor c -fill x -expand 1
   label $fen.titre.lbl -font $astk::ihm(font,tit) -text [ashare::mess ihm 187 $astk::astk_version] -anchor w
   pack $fen.titre.lbl -padx 20 -pady 10

#  texte
   pack [frame $fen.txt -relief raised -bd 1] -anchor c -fill x -expand 1
   label $fen.txt.bla -font $astk::ihm(font,txt) -text [ashare::mess ihm 108] -anchor w
   pack $fen.txt.bla -padx 20 -pady 10

#  fermer
   pack [frame $fen.valid -relief solid -bd 0]
   button $fen.valid.ok -font $astk::ihm(font,labbout) -text "Ok" \
      -background $astk::ihm(couleur,valid) \
      -command "destroy $fen ; grab release $fen"
   pack $fen.valid.ok -padx 10 -pady 3
}
