lib / tools_dlg.tclon commit git-gui: Add a Tools menu for arbitrary commands. (0ce76de)
   1# git-gui Tools menu dialogs
   2
   3class tools_add {
   4
   5field w              ; # widget path
   6field w_name         ; # new remote name widget
   7field w_cmd          ; # new remote location widget
   8
   9field name         {}; # name of the tool
  10field command      {}; # command to execute
  11field add_global    0; # add to the --global config
  12field no_console    0; # disable using the console
  13field needs_file    0; # ensure filename is set
  14field confirm       0; # ask for confirmation
  15
  16constructor dialog {} {
  17        global repo_config
  18
  19        make_toplevel top w
  20        wm title $top [append "[appname] ([reponame]): " [mc "Add Tool"]]
  21        if {$top ne {.}} {
  22                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
  23                wm transient $top .
  24        }
  25
  26        label $w.header -text [mc "Add New Tool Command"] -font font_uibold
  27        pack $w.header -side top -fill x
  28
  29        frame $w.buttons
  30        checkbutton $w.buttons.global \
  31                -text [mc "Add globally"] \
  32                -variable @add_global
  33        pack $w.buttons.global -side left -padx 5
  34        button $w.buttons.create -text [mc Add] \
  35                -default active \
  36                -command [cb _add]
  37        pack $w.buttons.create -side right
  38        button $w.buttons.cancel -text [mc Cancel] \
  39                -command [list destroy $w]
  40        pack $w.buttons.cancel -side right -padx 5
  41        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
  42
  43        labelframe $w.desc -text [mc "Tool Details"]
  44
  45        label $w.desc.name_cmnt -anchor w\
  46                -text [mc "Use '/' separators to create a submenu tree:"]
  47        grid x $w.desc.name_cmnt -sticky we -padx {0 5} -pady {0 2}
  48        label $w.desc.name_l -text [mc "Name:"]
  49        set w_name $w.desc.name_t
  50        entry $w_name \
  51                -borderwidth 1 \
  52                -relief sunken \
  53                -width 40 \
  54                -textvariable @name \
  55                -validate key \
  56                -validatecommand [cb _validate_name %d %S]
  57        grid $w.desc.name_l $w_name -sticky we -padx {0 5}
  58
  59        label $w.desc.cmd_l -text [mc "Command:"]
  60        set w_cmd $w.desc.cmd_t
  61        entry $w_cmd \
  62                -borderwidth 1 \
  63                -relief sunken \
  64                -width 40 \
  65                -textvariable @command
  66        grid $w.desc.cmd_l $w_cmd -sticky we -padx {0 5} -pady {0 3}
  67
  68        grid columnconfigure $w.desc 1 -weight 1
  69        pack $w.desc -anchor nw -fill x -pady 5 -padx 5
  70
  71        checkbutton $w.confirm \
  72                -text [mc "Ask for confirmation before running"] \
  73                -variable @confirm
  74        pack $w.confirm -anchor w -pady {5 0} -padx 5
  75
  76        checkbutton $w.noconsole \
  77                -text [mc "Don't show the command output window"] \
  78                -variable @no_console
  79        pack $w.noconsole -anchor w -padx 5
  80
  81        checkbutton $w.needsfile \
  82                -text [mc "Run only if a diff is selected (\$FILENAME not empty)"] \
  83                -variable @needs_file
  84        pack $w.needsfile -anchor w -padx 5
  85
  86        bind $w <Visibility> [cb _visible]
  87        bind $w <Key-Escape> [list destroy $w]
  88        bind $w <Key-Return> [cb _add]\;break
  89        tkwait window $w
  90}
  91
  92method _add {} {
  93        global repo_config
  94
  95        if {$name eq {}} {
  96                error_popup [mc "Please supply a name for the tool."]
  97                focus $w_name
  98                return
  99        }
 100
 101        set item "guitool.$name.cmd"
 102
 103        if {[info exists repo_config($item)]} {
 104                error_popup [mc "Tool '%s' already exists." $name]
 105                focus $w_name
 106                return
 107        }
 108
 109        set cmd [list git config]
 110        if {$add_global} { lappend cmd --global }
 111        set items {}
 112        if {$no_console} { lappend items "guitool.$name.noconsole" }
 113        if {$confirm}    { lappend items "guitool.$name.confirm" }
 114        if {$needs_file} { lappend items "guitool.$name.needsfile" }
 115
 116        if {[catch {
 117                eval $cmd [list $item $command]
 118                foreach citem $items { eval $cmd [list $citem yes] }
 119            } err]} {
 120                error_popup [mc "Could not add tool:\n%s" $err]
 121        } else {
 122                set repo_config($item) $command
 123                foreach citem $items { set repo_config($citem) yes }
 124
 125                tools_populate_all
 126        }
 127
 128        destroy $w
 129}
 130
 131method _validate_name {d S} {
 132        if {$d == 1} {
 133                if {[regexp {[~?*&\[\0\"\\\{]} $S]} {
 134                        return 0
 135                }
 136        }
 137        return 1
 138}
 139
 140method _visible {} {
 141        grab $w
 142        $w_name icursor end
 143        focus $w_name
 144}
 145
 146}
 147
 148class tools_remove {
 149
 150field w              ; # widget path
 151field w_names        ; # name list
 152
 153constructor dialog {} {
 154        global repo_config global_config system_config
 155
 156        load_config 1
 157
 158        make_toplevel top w
 159        wm title $top [append "[appname] ([reponame]): " [mc "Remove Tool"]]
 160        if {$top ne {.}} {
 161                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
 162                wm transient $top .
 163        }
 164
 165        label $w.header -text [mc "Remove Tool Commands"] -font font_uibold
 166        pack $w.header -side top -fill x
 167
 168        frame $w.buttons
 169        button $w.buttons.create -text [mc Remove] \
 170                -default active \
 171                -command [cb _remove]
 172        pack $w.buttons.create -side right
 173        button $w.buttons.cancel -text [mc Cancel] \
 174                -command [list destroy $w]
 175        pack $w.buttons.cancel -side right -padx 5
 176        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
 177
 178        frame $w.list
 179        set w_names $w.list.l
 180        listbox $w_names \
 181                -height 10 \
 182                -width 30 \
 183                -selectmode extended \
 184                -exportselection false \
 185                -yscrollcommand [list $w.list.sby set]
 186        scrollbar $w.list.sby -command [list $w.list.l yview]
 187        pack $w.list.sby -side right -fill y
 188        pack $w.list.l -side left -fill both -expand 1
 189        pack $w.list -fill both -expand 1 -pady 5 -padx 5
 190
 191        set local_cnt 0
 192        foreach fullname [tools_list] {
 193                # Cannot delete system tools
 194                if {[info exists system_config(guitool.$fullname.cmd)]} continue
 195
 196                $w_names insert end $fullname
 197                if {![info exists global_config(guitool.$fullname.cmd)]} {
 198                        $w_names itemconfigure end -foreground blue
 199                        incr local_cnt
 200                }
 201        }
 202
 203        if {$local_cnt > 0} {
 204                label $w.colorlbl -foreground blue \
 205                        -text [mc "(Blue denotes repository-local tools)"]
 206                pack $w.colorlbl -fill x -pady 5 -padx 5
 207        }
 208
 209        bind $w <Visibility> [cb _visible]
 210        bind $w <Key-Escape> [list destroy $w]
 211        bind $w <Key-Return> [cb _remove]\;break
 212        tkwait window $w
 213}
 214
 215method _remove {} {
 216        foreach i [$w_names curselection] {
 217                set name [$w_names get $i]
 218
 219                catch { git config --remove-section guitool.$name }
 220                catch { git config --global --remove-section guitool.$name }
 221        }
 222
 223        load_config 0
 224        tools_populate_all
 225
 226        destroy $w
 227}
 228
 229method _visible {} {
 230        grab $w
 231        focus $w_names
 232}
 233
 234}