git-gui / lib / tools_dlg.tclon commit Merge branch 'maint' (90c3302)
   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
  15field ask_branch    0; # ask for a revision
  16field ask_args      0; # ask for additional args
  17
  18constructor dialog {} {
  19        global repo_config
  20
  21        make_toplevel top w
  22        wm title $top [append "[appname] ([reponame]): " [mc "Add Tool"]]
  23        if {$top ne {.}} {
  24                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
  25                wm transient $top .
  26        }
  27
  28        label $w.header -text [mc "Add New Tool Command"] -font font_uibold
  29        pack $w.header -side top -fill x
  30
  31        frame $w.buttons
  32        checkbutton $w.buttons.global \
  33                -text [mc "Add globally"] \
  34                -variable @add_global
  35        pack $w.buttons.global -side left -padx 5
  36        button $w.buttons.create -text [mc Add] \
  37                -default active \
  38                -command [cb _add]
  39        pack $w.buttons.create -side right
  40        button $w.buttons.cancel -text [mc Cancel] \
  41                -command [list destroy $w]
  42        pack $w.buttons.cancel -side right -padx 5
  43        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
  44
  45        labelframe $w.desc -text [mc "Tool Details"]
  46
  47        label $w.desc.name_cmnt -anchor w\
  48                -text [mc "Use '/' separators to create a submenu tree:"]
  49        grid x $w.desc.name_cmnt -sticky we -padx {0 5} -pady {0 2}
  50        label $w.desc.name_l -text [mc "Name:"]
  51        set w_name $w.desc.name_t
  52        entry $w_name \
  53                -borderwidth 1 \
  54                -relief sunken \
  55                -width 40 \
  56                -textvariable @name \
  57                -validate key \
  58                -validatecommand [cb _validate_name %d %S]
  59        grid $w.desc.name_l $w_name -sticky we -padx {0 5}
  60
  61        label $w.desc.cmd_l -text [mc "Command:"]
  62        set w_cmd $w.desc.cmd_t
  63        entry $w_cmd \
  64                -borderwidth 1 \
  65                -relief sunken \
  66                -width 40 \
  67                -textvariable @command
  68        grid $w.desc.cmd_l $w_cmd -sticky we -padx {0 5} -pady {0 3}
  69
  70        grid columnconfigure $w.desc 1 -weight 1
  71        pack $w.desc -anchor nw -fill x -pady 5 -padx 5
  72
  73        checkbutton $w.confirm \
  74                -text [mc "Show a dialog before running"] \
  75                -variable @confirm -command [cb _check_enable_dlg]
  76
  77        labelframe $w.dlg -labelwidget $w.confirm
  78
  79        checkbutton $w.dlg.askbranch \
  80                -text [mc "Ask the user to select a revision (sets \$REVISION)"] \
  81                -variable @ask_branch -state disabled
  82        pack $w.dlg.askbranch -anchor w -padx 15
  83
  84        checkbutton $w.dlg.askargs \
  85                -text [mc "Ask the user for additional arguments (sets \$ARGS)"] \
  86                -variable @ask_args -state disabled
  87        pack $w.dlg.askargs -anchor w -padx 15
  88
  89        pack $w.dlg -anchor nw -fill x -pady {0 8} -padx 5
  90
  91        checkbutton $w.noconsole \
  92                -text [mc "Don't show the command output window"] \
  93                -variable @no_console
  94        pack $w.noconsole -anchor w -padx 5
  95
  96        checkbutton $w.needsfile \
  97                -text [mc "Run only if a diff is selected (\$FILENAME not empty)"] \
  98                -variable @needs_file
  99        pack $w.needsfile -anchor w -padx 5
 100
 101        bind $w <Visibility> [cb _visible]
 102        bind $w <Key-Escape> [list destroy $w]
 103        bind $w <Key-Return> [cb _add]\;break
 104        tkwait window $w
 105}
 106
 107method _check_enable_dlg {} {
 108        if {$confirm} {
 109                $w.dlg.askbranch configure -state normal
 110                $w.dlg.askargs configure -state normal
 111        } else {
 112                $w.dlg.askbranch configure -state disabled
 113                $w.dlg.askargs configure -state disabled
 114        }
 115}
 116
 117method _add {} {
 118        global repo_config
 119
 120        if {$name eq {}} {
 121                error_popup [mc "Please supply a name for the tool."]
 122                focus $w_name
 123                return
 124        }
 125
 126        set item "guitool.$name.cmd"
 127
 128        if {[info exists repo_config($item)]} {
 129                error_popup [mc "Tool '%s' already exists." $name]
 130                focus $w_name
 131                return
 132        }
 133
 134        set cmd [list git config]
 135        if {$add_global} { lappend cmd --global }
 136        set items {}
 137        if {$no_console} { lappend items "guitool.$name.noconsole" }
 138        if {$needs_file} { lappend items "guitool.$name.needsfile" }
 139        if {$confirm} {
 140                if {$ask_args}   { lappend items "guitool.$name.argprompt" }
 141                if {$ask_branch} { lappend items "guitool.$name.revprompt" }
 142                if {!$ask_args && !$ask_branch} {
 143                        lappend items "guitool.$name.confirm"
 144                }
 145        }
 146
 147        if {[catch {
 148                eval $cmd [list $item $command]
 149                foreach citem $items { eval $cmd [list $citem yes] }
 150            } err]} {
 151                error_popup [mc "Could not add tool:\n%s" $err]
 152        } else {
 153                set repo_config($item) $command
 154                foreach citem $items { set repo_config($citem) yes }
 155
 156                tools_populate_all
 157        }
 158
 159        destroy $w
 160}
 161
 162method _validate_name {d S} {
 163        if {$d == 1} {
 164                if {[regexp {[~?*&\[\0\"\\\{]} $S]} {
 165                        return 0
 166                }
 167        }
 168        return 1
 169}
 170
 171method _visible {} {
 172        grab $w
 173        $w_name icursor end
 174        focus $w_name
 175}
 176
 177}
 178
 179class tools_remove {
 180
 181field w              ; # widget path
 182field w_names        ; # name list
 183
 184constructor dialog {} {
 185        global repo_config global_config system_config
 186
 187        load_config 1
 188
 189        make_toplevel top w
 190        wm title $top [append "[appname] ([reponame]): " [mc "Remove Tool"]]
 191        if {$top ne {.}} {
 192                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
 193                wm transient $top .
 194        }
 195
 196        label $w.header -text [mc "Remove Tool Commands"] -font font_uibold
 197        pack $w.header -side top -fill x
 198
 199        frame $w.buttons
 200        button $w.buttons.create -text [mc Remove] \
 201                -default active \
 202                -command [cb _remove]
 203        pack $w.buttons.create -side right
 204        button $w.buttons.cancel -text [mc Cancel] \
 205                -command [list destroy $w]
 206        pack $w.buttons.cancel -side right -padx 5
 207        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
 208
 209        frame $w.list
 210        set w_names $w.list.l
 211        listbox $w_names \
 212                -height 10 \
 213                -width 30 \
 214                -selectmode extended \
 215                -exportselection false \
 216                -yscrollcommand [list $w.list.sby set]
 217        scrollbar $w.list.sby -command [list $w.list.l yview]
 218        pack $w.list.sby -side right -fill y
 219        pack $w.list.l -side left -fill both -expand 1
 220        pack $w.list -fill both -expand 1 -pady 5 -padx 5
 221
 222        set local_cnt 0
 223        foreach fullname [tools_list] {
 224                # Cannot delete system tools
 225                if {[info exists system_config(guitool.$fullname.cmd)]} continue
 226
 227                $w_names insert end $fullname
 228                if {![info exists global_config(guitool.$fullname.cmd)]} {
 229                        $w_names itemconfigure end -foreground blue
 230                        incr local_cnt
 231                }
 232        }
 233
 234        if {$local_cnt > 0} {
 235                label $w.colorlbl -foreground blue \
 236                        -text [mc "(Blue denotes repository-local tools)"]
 237                pack $w.colorlbl -fill x -pady 5 -padx 5
 238        }
 239
 240        bind $w <Visibility> [cb _visible]
 241        bind $w <Key-Escape> [list destroy $w]
 242        bind $w <Key-Return> [cb _remove]\;break
 243        tkwait window $w
 244}
 245
 246method _remove {} {
 247        foreach i [$w_names curselection] {
 248                set name [$w_names get $i]
 249
 250                catch { git config --remove-section guitool.$name }
 251                catch { git config --global --remove-section guitool.$name }
 252        }
 253
 254        load_config 0
 255        tools_populate_all
 256
 257        destroy $w
 258}
 259
 260method _visible {} {
 261        grab $w
 262        focus $w_names
 263}
 264
 265}
 266
 267class tools_askdlg {
 268
 269field w              ; # widget path
 270field w_rev        {}; # revision browser
 271field w_args       {}; # arguments
 272
 273field is_ask_args   0; # has arguments field
 274field is_ask_revs   0; # has revision browser
 275
 276field is_ok         0; # ok to start
 277field argstr       {}; # arguments
 278
 279constructor dialog {fullname} {
 280        global M1B
 281
 282        set title [get_config "guitool.$fullname.title"]
 283        if {$title eq {}} {
 284                regsub {/} $fullname { / } title
 285        }
 286
 287        make_toplevel top w -autodelete 0
 288        wm title $top [append "[appname] ([reponame]): " $title]
 289        if {$top ne {.}} {
 290                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
 291                wm transient $top .
 292        }
 293
 294        set prompt [get_config "guitool.$fullname.prompt"]
 295        if {$prompt eq {}} {
 296                set command [get_config "guitool.$fullname.cmd"]
 297                set prompt [mc "Run Command: %s" $command]
 298        }
 299
 300        label $w.header -text $prompt -font font_uibold
 301        pack $w.header -side top -fill x
 302
 303        set argprompt [get_config "guitool.$fullname.argprompt"]
 304        set revprompt [get_config "guitool.$fullname.revprompt"]
 305
 306        set is_ask_args [expr {$argprompt ne {}}]
 307        set is_ask_revs [expr {$revprompt ne {}}]
 308
 309        if {$is_ask_args} {
 310                if {$argprompt eq {yes} || $argprompt eq {true} || $argprompt eq {1}} {
 311                        set argprompt [mc "Arguments"]
 312                }
 313
 314                labelframe $w.arg -text $argprompt
 315
 316                set w_args $w.arg.txt
 317                entry $w_args \
 318                        -borderwidth 1 \
 319                        -relief sunken \
 320                        -width 40 \
 321                        -textvariable @argstr
 322                pack $w_args -padx 5 -pady 5 -fill both
 323                pack $w.arg -anchor nw -fill both -pady 5 -padx 5
 324        }
 325
 326        if {$is_ask_revs} {
 327                if {$revprompt eq {yes} || $revprompt eq {true} || $revprompt eq {1}} {
 328                        set revprompt [mc "Revision"]
 329                }
 330
 331                if {[is_config_true "guitool.$fullname.revunmerged"]} {
 332                        set w_rev [::choose_rev::new_unmerged $w.rev $revprompt]
 333                } else {
 334                        set w_rev [::choose_rev::new $w.rev $revprompt]
 335                }
 336
 337                pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
 338        }
 339
 340        frame $w.buttons
 341        if {$is_ask_revs} {
 342                button $w.buttons.visualize \
 343                        -text [mc Visualize] \
 344                        -command [cb _visualize]
 345                pack $w.buttons.visualize -side left
 346        }
 347        button $w.buttons.ok \
 348                -text [mc OK] \
 349                -command [cb _start]
 350        pack $w.buttons.ok -side right
 351        button $w.buttons.cancel \
 352                -text [mc "Cancel"] \
 353                -command [cb _cancel]
 354        pack $w.buttons.cancel -side right -padx 5
 355        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
 356
 357        bind $w <$M1B-Key-Return> [cb _start]
 358        bind $w <Key-Return> [cb _start]
 359        bind $w <Key-Escape> [cb _cancel]
 360        wm protocol $w WM_DELETE_WINDOW [cb _cancel]
 361
 362        bind $w <Visibility> [cb _visible]
 363        return $this
 364}
 365
 366method execute {} {
 367        tkwait window $w
 368        set rv $is_ok
 369        delete_this
 370        return $rv
 371}
 372
 373method _visible {} {
 374        grab $w
 375        if {$is_ask_args} {
 376                focus $w_args
 377        } elseif {$is_ask_revs} {
 378                $w_rev focus_filter
 379        }
 380}
 381
 382method _cancel {} {
 383        wm protocol $w WM_DELETE_WINDOW {}
 384        destroy $w
 385}
 386
 387method _rev {} {
 388        if {[catch {$w_rev commit_or_die}]} {
 389                return {}
 390        }
 391        return [$w_rev get]
 392}
 393
 394method _visualize {} {
 395        global current_branch
 396        set rev [_rev $this]
 397        if {$rev ne {}} {
 398                do_gitk [list --left-right "$current_branch...$rev"]
 399        }
 400}
 401
 402method _start {} {
 403        global env
 404
 405        if {$is_ask_revs} {
 406                set name [_rev $this]
 407                if {$name eq {}} {
 408                        return
 409                }
 410                set env(REVISION) $name
 411        }
 412
 413        if {$is_ask_args} {
 414                set env(ARGS) $argstr
 415        }
 416
 417        set is_ok 1
 418        _cancel $this
 419}
 420
 421}