## Quelques procédures fondamentales pour la recherche/remplacement

package provide xtext 2.0

## xtext_transcodeAll -- surcouche à string_transcode appliqué au widget w
# 
#   
# Syntaxe et options : 
#   les memes que string_transcode (sans le widget text à traiter)
#   
# Exemple :
#   xtext_transcodeAll $w utf2iso
# 
proc xtext_transcodeAll {w args} {
  
    set filterCmd [concat string_transcode  $args]
    xtext_applyToAll $w $filterCmd
    stead:log  "xtext_transcodeAll ... done"
}

## xtext_transcodeSel -- surcouche à string_transcode appliqué au widget w
# 
#   
# Syntaxe et options : 
#   les memes que string_transcode (sans le widget text à traiter)
# 
# # # # EN TEST le 07/08/02
# 
proc xtext_transcodeSel {w args} {
  
    set filterCmd [concat string_transcode  $args]
    xtext_applyToSel $w $filterCmd
    stead:log  "xtext_transcodeSel ... done"
}


## xtext_replaceAll -- 
# 
# Syntaxe :
#   
#   xtext_replaceAll $w ?options? ?--? pat1 pat2
#   
# options : les memes que string_replace (sans le widget text à traiter)
# 
# Historique :
# 
#   31/10/01 (diam) refonte pour faire appel à la nouvelle proc string_replace
# 
# A FAIRE :
#   - trouver le bon niveau entre stead:replaceAll et string_replace
#   - il faudra probablement integrer l'état de la boite de recherche
#     dans xtext(find,XXX) et non pas dans stead_find(XXX)
# 
#   - créer xtext_replace polyvalent
#       - gère le undo et le comportement de la sélection
#       - l'intervale d'action (-range xxx  -sel  -all ...)
#       - les modif du curseur
#       - ...
#    
# # # # EN TEST le 07/08/02
# 
proc xtext_replaceAll {w args} {
  
    set filterCmd [concat string_replace  $args]
    xtext_applyToAll $w $filterCmd
    stead:log  "xtext_replaceAll ... done"
}

## xtext_replaceInSel --
# 
# Syntaxe :
#   
#   xtext_replaceInSel $w ?options? ?--? pat1 pat2
#   
# options : les memes que string_replace (sans le texte à traiter)
# 
# Historique :
# 
#   09/12/99 (diam) : création
#   31/10/01 (diam) refonte pour faire appel à la nouvelle proc string_replace
#  
# 
proc xtext_replaceInSel {w args} {
  
    global xtext
    if { ![xtext_hasSel $w] } {
        stead:log "There is no selection"
        return
    }
    # diam : commenté le 14/11/01
    # set text [xtext_getSel $w]
    # 
    set filterCmd [concat string_replace  $args]
    xtext_applyToSel $w $filterCmd
    stead:log  "Replace in Selection ... done"
}

## xtext_applyTo__norect -- applique un filtre à un intervale (interne)
# 
# C'est une procédure de **bas niveau** que ne modifie pas la sélection,
# conserve le point d'insertion.
# Le point d'insertion reste inchangé, et seule la sélection cheveauchant
# l'intervale traité est supprimée,
# 
# Syntaxe :
# 
#   xtext_applyTo__norect w ?options? filterProcName startIdx endIdx
# 
# Options :
# 
#   -p
#   -push <1|0> effectue ou non un pushState
#   -tags <lagList> liste de tag à appliquer
#   
# A faire :
# 
#   -rect <1|0> NON IMPLÉMENTÉ POUR L'INSTANT
# 
# Exemples :
# 
#   xtext_applyTo__norect $w {exec -keepnewline tr a A <<}  1.0 end
#   xtext_applyTo__norect $w {string toupper}   112.1 112.11
#   
proc xtext_applyTo__norect {w args } {
  
    Parsarg_fullSpec opt {
        p  -
        push  {
            -type     enum
            -values   {1 0}
            -label   "si vrai : l'état du texte est sauvegardé (pour undo)"
        }
        tags  {}
        
    }
    set filterProcName [lindex $args 0]
    set startIdx       [lindex $args 1]
    set endIdx         [lindex $args 2]
                     
    if {![string length $startIdx]} {
        set startIdx 1.0
    }    
    if {![string length $endIdx]} {
        set endIdx end-1c
    }    
    
    # La procédure xtext_get n'existe pas encore !
    # set text [xtext_get -rect $opt(-rect) $w $startIdx $endIdx]
    set text [$w get $startIdx $endIdx]
    
    if {![string length $text]} {
        stead:log -error "Aucun texte à filtrer"
        return
    }
    
    # On mémorise l'ancien point d'insertion pour y revenir
    set oldInsert [$w index insert]
     
    stead:log  "xtext_applyTo__norect : ..." 
  
    set cmd $filterProcName
    lappend cmd $text
    # # set text [xtcl_catch 1 $cmd]
    set text [xtcl_catch -level 1 $cmd]

    if {$opt(-push)} {
        xtext_pushState $w
    }
    $w delete $startIdx $endIdx
    $w insert $startIdx $text $opt(-tags)
        
    # on reposition l'ancien point d'insertion **SANS DEPLACER LE CURSEUR**
    $w mark set insert $oldInsert
    
    stead:log  "xtext_applyTo__norect : ... done" 
}

## xtext_applyToSel -- applique un filtre à la sélection
# 
# Le filtre est une commande tcl pouvant avoir des arguments prépositionnés,
# le texte de la sélection est ajouté à la liste formant le filtre
# 
# 26/03/01 (diam) : création
#    à partir de xtext_replaceInSel
# 
# Exemple :  (OK avec ou sans selRect) 
#    xtext_applyToSel $w {string toupper}
#    xtext_applyToSel $w {exec -keepnewline tr s S <<}
#    xtext_applyToSel $w {exec -keepnewline sort <<}
# 
# A FAIRE
# 
#   Fusionner les deux procedure xtext_applyToSel et xtext_applyToAll
#   avec option -all ou -sel (-sel par défaut)
#   
#   
proc xtext_applyToSel {w filterProcName} {
  
    global xtext
  
    # calcul de l'ancien debut de selection
    if {[xtext_hasSel $w]} {
        set isRect [xtext_hasRectSel $w]
        set text   [xtext_getSel $w]
        set selfirst [$w index sel.first]
    } else {
        stead:log -error "There is no selection"
        return
    }
    stead:log  "xtext_applyToSel : ..." 
  
    set cmd $filterProcName
    lappend cmd $text
    # # # set text [xtcl_catch 1 $cmd]
    set text [xtcl_catch -level 1 $cmd]

    # Cette commande :
    #   - mémorise l'état pour le undo (pushState),
    #   - mémorise et détruit la sélection précédente,
    #   - insertion de facon rectangulaire ou non du résultat,
    #   - et resélectionne le texte inséré.

    xtext_insert $w -rect $isRect -push 1 -tags sel -- $text
        
    stead:log  "xtext_applyToSel : ... done" 
}
## xtext_applyToAll -- applique un filtre à la tout le texte
# 
# Le filtre est ... (idem que pour  xtext_applyToSel)
# 
# 07/08/02 (diam) : création à partir de xtext_applyToSel et accentsIso2Html
# 14/11/02 (diam) : suppression du vérouillage de cette proc en cas d'une 
#       sélection non nulle. Cette précaution entrainait un bug dans la 
#       recherche remplacement (apres un search qui sélectionne un morceau)
# 
# Exemple   (OK le 07/08/02) 
#    xtext_applyToAll $w {string toupper}
#    xtext_applyToAll $w {exec -keepnewline tr s S <<}
#    xtext_applyToAll $w {exec -keepnewline sort <<}
#                 
proc xtext_applyToAll {w filterProcName} {
  
    # # IMPORTANT : 
    # #    On vérifie qu'il n'y a pas de sélection Au cas où l'utilisateur
    # #    appel par erreur xtext_applyToAll au lieu de xtext_applyToAll 
    # if {[xtext_hasSel $w]} {
    #     stead:log -error "There should NO be any selection."
    #     return
    # }
    
    # on récupère le texte complet dans la variable text:
    set text [$w get 1.0 end-1c]

    # On mémorise la position courante dans le texte :
    # # .main.t mark set old_insert [.main.t index insert]
    # # old_insert est détruit par .main.t delete ... => inexploitable
    set oldIdx  [$w index insert]
   
     
    stead:log  "xtext_applyToAll : processing command ..." 
    set cmd $filterProcName
    lappend cmd $text
    # # # set text [xtcl_catch 1 $cmd]
    set text [xtcl_catch -level 1 $cmd]



    # On sauvegarde l'état de l'éditeur (en RAM) pour le undo éventuel
    # 
    stead:log  "xtext_applyToAll : save state ..." 
    xtext_pushState $w
    xtext_markDirty $w

    # Le complacement du texte :
    # 
    stead:log  "xtext_applyToAll : insert new text ..." 
    # diam 17/02/2003 : ajout de -style 0 pour éviter une colataion 
    # intermédiaire inutile (et le bug associé)!
    xtext_delete $w -push 0 -style 0 -- all
    xtext_insert $w -push 0 -- $text
    xtext_setCursor $w $oldIdx
        
    stead:log  "xtext_applyToAll : ... done" 
}

## xtext_wrapSel - encadre la sélection entre prefix et suffix
#
# A DEPLACER DANS xtext_proc.tcl
#
proc xtext_wrapSel {w prefix suffix} {

    if {[xtext_hasSel $w]} {
        xtext_applyToSel $w [list xtext_wrapString $prefix $suffix]
        # xtext_updateFocusIn $w
        xtext_updateInsertPos $w

    } else {
        xtext_insert $w -string "$prefix$suffix"
        $w mark set insert "insert - [string length $suffix]c"
        # xtext_updateFocusIn $w
        xtext_updateInsertPos $w
    }

}
## xtext_wrapString -- entour le troisième parametre par les deux premiers
#
# A DEPLACER DANS xtext_proc.tcl
#
proc xtext_wrapString {prefix suffix str} {
    return "$prefix$str$suffix"
}

# ./
