{"thread":{"id":"16313","subject":"[PATCH (GIT-GUI) 0/3] Add a customizable Tools menu.","startedAt":"2008-11-13T19:35:47Z","lastAt":"2008-11-13T19:35:50Z","messageCount":4,"participants":["Alexander Gavrilov"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"95712","messageId":"1226604950-18667-1-git-send-email-angavrilov@gmail.com","threadId":"16313","inReplyTo":null,"subject":"[PATCH (GIT-GUI) 0/3] Add a customizable Tools menu.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-11-13T19:35:47Z","receivedAt":"2008-11-13T19:35:47Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"This series adds a configurable Tools menu, that can\nbe used to call any external commands from Git Gui.\nIt reduces the inconvenience of using tools like git-svn\ntogether with GUI, by removing the need to jump between\nthe terminal and the GUI even for simple actions. QGit\nalready has a similar feature.\n\n\nPATCHES:\n\n    git-gui: Implement system-wide configuration handling.\n    ---\n    git-gui.sh     |   12 +++++++++---\n    lib/option.tcl |   12 ++++++------\n    2 files changed, 15 insertions(+), 9 deletions(-)\n\n    git-gui: Add a Tools menu for arbitrary commands.\n    ---\n    git-gui.sh        |   17 ++++\n    lib/tools.tcl     |  107 ++++++++++++++++++++++++\n    lib/tools_dlg.tcl |  234 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n    3 files changed, 358 insertions(+), 0 deletions(-)\n    create mode 100644 lib/tools.tcl\n    create mode 100644 lib/tools_dlg.tcl\n\n    git-gui: Allow Tools to request arguments from the user.\n    ---\n    lib/tools.tcl     |   13 +++-\n    lib/tools_dlg.tcl |  194 +++++++++++++++++++++++++++++++++++++++++++++++++++-\n    2 files changed, 202 insertions(+), 5 deletions(-)\n"},{"id":"95715","messageId":"1226604950-18667-2-git-send-email-angavrilov@gmail.com","threadId":"16313","inReplyTo":"1226604950-18667-1-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI) 1/3] git-gui: Implement system-wide configuration handling.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-11-13T19:35:48Z","receivedAt":"2008-11-13T19:35:48Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"With the old implementation any system-wide options appear\nto be set locally in the current repository. This commit\nadds explicit handling of system options, essentially\ninterpreting them as customized default_config.\n\nThe difficulty in interpreting system options stems from\nthe fact that simple 'git config' lists all values, while\n'git config --global' only values set in ~/.gitconfig,\nexcluding both local and system options.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n git-gui.sh     |   12 +++++++++---\n lib/option.tcl |   12 ++++++------\n 2 files changed, 15 insertions(+), 9 deletions(-)\n\ndiff --git a/git-gui.sh b/git-gui.sh\nindex cf9ef6e..34214b6 100755\n--- a/git-gui.sh\n+++ b/git-gui.sh\n@@ -918,19 +918,25 @@ git-version proc _parse_config {arr_name args} {\n }\n \n proc load_config {include_global} {\n-\tglobal repo_config global_config default_config\n+\tglobal repo_config global_config system_config default_config\n \n \tif {$include_global} {\n+\t\t_parse_config system_config --system\n \t\t_parse_config global_config --global\n \t}\n \t_parse_config repo_config\n \n \tforeach name [array names default_config] {\n+\t\tif {[catch {set v $system_config($name)}]} {\n+\t\t\tset system_config($name) $default_config($name)\n+\t\t}\n+\t}\n+\tforeach name [array names system_config] {\n \t\tif {[catch {set v $global_config($name)}]} {\n-\t\t\tset global_config($name) $default_config($name)\n+\t\t\tset global_config($name) $system_config($name)\n \t\t}\n \t\tif {[catch {set v $repo_config($name)}]} {\n-\t\t\tset repo_config($name) $default_config($name)\n+\t\t\tset repo_config($name) $system_config($name)\n \t\t}\n \t}\n }\ndiff --git a/lib/option.tcl b/lib/option.tcl\nindex c80c939..1d55b49 100644\n--- a/lib/option.tcl\n+++ b/lib/option.tcl\n@@ -25,7 +25,7 @@ proc config_check_encodings {} {\n \n proc save_config {} {\n \tglobal default_config font_descs\n-\tglobal repo_config global_config\n+\tglobal repo_config global_config system_config\n \tglobal repo_config_new global_config_new\n \tglobal ui_comm_spell\n \n@@ -49,7 +49,7 @@ proc save_config {} {\n \tforeach name [array names default_config] {\n \t\tset value $global_config_new($name)\n \t\tif {$value ne $global_config($name)} {\n-\t\t\tif {$value eq $default_config($name)} {\n+\t\t\tif {$value eq $system_config($name)} {\n \t\t\t\tcatch {git config --global --unset $name}\n \t\t\t} else {\n \t\t\t\tregsub -all \"\\[{}\\]\" $value {\"} value\n@@ -284,17 +284,17 @@ proc do_options {} {\n }\n \n proc do_restore_defaults {} {\n-\tglobal font_descs default_config repo_config\n+\tglobal font_descs default_config repo_config system_config\n \tglobal repo_config_new global_config_new\n \n \tforeach name [array names default_config] {\n-\t\tset repo_config_new($name) $default_config($name)\n-\t\tset global_config_new($name) $default_config($name)\n+\t\tset repo_config_new($name) $system_config($name)\n+\t\tset global_config_new($name) $system_config($name)\n \t}\n \n \tforeach option $font_descs {\n \t\tset name [lindex $option 0]\n-\t\tset repo_config(gui.$name) $default_config(gui.$name)\n+\t\tset repo_config(gui.$name) $system_config(gui.$name)\n \t}\n \tapply_config\n \n-- \n1.6.0.3.15.gb8d36\n"},{"id":"95714","messageId":"1226604950-18667-3-git-send-email-angavrilov@gmail.com","threadId":"16313","inReplyTo":"1226604950-18667-2-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI) 2/3] git-gui: Add a Tools menu for arbitrary commands.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-11-13T19:35:49Z","receivedAt":"2008-11-13T19:35:49Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"Due to the emphasis on scriptability in the git\ndesign, it is impossible to provide 100% complete\nGUI. Currently unaccounted areas include git-svn\nand other source control system interfaces, TopGit,\nall custom scripts.\n\nThis problem can be mitigated by providing basic\ncustomization capabilities in Git Gui. This commit\nadds a new Tools menu, which can be configured\nto contain items invoking arbitrary shell commands.\n\nThe interface is powerful enough to allow calling\nboth batch text programs like git-svn, and GUI editors.\nTo support the latter use, the commands have access\nto the name of the currently selected file through\nthe environment.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n git-gui.sh        |   17 ++++\n lib/tools.tcl     |  107 ++++++++++++++++++++++++\n lib/tools_dlg.tcl |  234 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 358 insertions(+), 0 deletions(-)\n create mode 100644 lib/tools.tcl\n create mode 100644 lib/tools_dlg.tcl\n\ndiff --git a/git-gui.sh b/git-gui.sh\nindex 34214b6..2efbe73 100755\n--- a/git-gui.sh\n+++ b/git-gui.sh\n@@ -2252,6 +2252,9 @@ if {[is_enabled transport]} {\n \t.mbar add cascade -label [mc Merge] -menu .mbar.merge\n \t.mbar add cascade -label [mc Remote] -menu .mbar.remote\n }\n+if {[is_enabled multicommit] || [is_enabled singlecommit]} {\n+\t.mbar add cascade -label [mc Tools] -menu .mbar.tools\n+}\n . configure -menu .mbar\n \n # -- Repository Menu\n@@ -2526,6 +2529,20 @@ if {[is_MacOSX]} {\n \t\t-command do_options\n }\n \n+# -- Tools Menu\n+#\n+if {[is_enabled multicommit] || [is_enabled singlecommit]} {\n+\tset tools_menubar .mbar.tools\n+\tmenu $tools_menubar\n+\t$tools_menubar add separator\n+\t$tools_menubar add command -label [mc \"Add...\"] -command tools_add::dialog\n+\t$tools_menubar add command -label [mc \"Remove...\"] -command tools_remove::dialog\n+\tset tools_tailcnt 3\n+\tif {[array names repo_config guitool.*.cmd] ne {}} {\n+\t\ttools_populate_all\n+\t}\n+}\n+\n # -- Help Menu\n #\n .mbar add cascade -label [mc Help] -menu .mbar.help\ndiff --git a/lib/tools.tcl b/lib/tools.tcl\nnew file mode 100644\nindex 0000000..0bef503\n--- /dev/null\n+++ b/lib/tools.tcl\n@@ -0,0 +1,107 @@\n+# git-gui Tools menu implementation\n+\n+proc tools_list {} {\n+\tglobal repo_config\n+\n+\tset names {}\n+\tforeach item [array names repo_config guitool.*.cmd] {\n+\t\tlappend names [string range $item 8 end-4]\n+\t}\n+\treturn [lsort $names]\n+}\n+\n+proc tools_populate_all {} {\n+\tglobal tools_menubar tools_menutbl\n+\tglobal tools_tailcnt\n+\n+\tset mbar_end [$tools_menubar index end]\n+\tset mbar_base [expr {$mbar_end - $tools_tailcnt}]\n+\tif {$mbar_base >= 0} {\n+\t\t$tools_menubar delete 0 $mbar_base\n+\t}\n+\n+\tarray unset tools_menutbl\n+\n+\tforeach fullname [tools_list] {\n+\t\ttools_populate_one $fullname\n+\t}\n+}\n+\n+proc tools_create_item {parent args} {\n+\tglobal tools_menubar tools_tailcnt\n+\tif {$parent eq $tools_menubar} {\n+\t\tset pos [expr {[$parent index end]-$tools_tailcnt+1}]\n+\t\teval [list $parent insert $pos] $args\n+\t} else {\n+\t\teval [list $parent add] $args\n+\t}\n+}\n+\n+proc tools_populate_one {fullname} {\n+\tglobal tools_menubar tools_menutbl tools_id\n+\n+\tif {![info exists tools_id]} {\n+\t\tset tools_id 0\n+\t}\n+\n+\tset names [split $fullname '/']\n+\tset parent $tools_menubar\n+\tfor {set i 0} {$i < [llength $names]-1} {incr i} {\n+\t\tset subname [join [lrange $names 0 $i] '/']\n+\t\tif {[info exists tools_menutbl($subname)]} {\n+\t\t\tset parent $tools_menutbl($subname)\n+\t\t} else {\n+\t\t\tset subid $parent.t$tools_id\n+\t\t\ttools_create_item $parent cascade \\\n+\t\t\t\t\t-label [lindex $names $i] -menu $subid\n+\t\t\tmenu $subid\n+\t\t\tset tools_menutbl($subname) $subid\n+\t\t\tset parent $subid\n+\t\t\tincr tools_id\n+\t\t}\n+\t}\n+\n+\ttools_create_item $parent command \\\n+\t\t-label [lindex $names end] \\\n+\t\t-command [list tools_exec $fullname]\n+}\n+\n+proc tools_exec {fullname} {\n+\tglobal repo_config env current_diff_path\n+\tglobal current_branch is_detached\n+\n+\tif {[is_config_true \"guitool.$fullname.needsfile\"]} {\n+\t\tif {$current_diff_path eq {}} {\n+\t\t\terror_popup [mc \"Running %s requires a selected file.\" $fullname]\n+\t\t\treturn\n+\t\t}\n+\t}\n+\n+\tif {[is_config_true \"guitool.$fullname.confirm\"]} {\n+\t\tif {[ask_popup [mc \"Are you sure you want to run %s?\" $fullname]] ne {yes}} {\n+\t\t\treturn\n+\t\t}\n+\t}\n+\n+\tset env(GIT_GUITOOL) $fullname\n+\tset env(FILENAME) $current_diff_path\n+\tif {$is_detached} {\n+\t\tset env(CUR_BRANCH) \"\"\n+\t} else {\n+\t\tset env(CUR_BRANCH) $current_branch\n+\t}\n+\n+\tset cmdline $repo_config(guitool.$fullname.cmd)\n+\tif {[is_config_true \"guitool.$fullname.noconsole\"]} {\n+\t\texec sh -c $cmdline &\n+\t} else {\n+\t\tset w [console::new \\\n+\t\t\t[mc \"Tool %s\" $fullname] \\\n+\t\t\t[mc \"Running %s\" $cmdline]]\n+\t\tconsole::exec $w [list sh -c $cmdline]\n+\t}\n+\n+\tunset env(GIT_GUITOOL)\n+\tunset env(FILENAME)\n+\tunset env(CUR_BRANCH)\n+}\ndiff --git a/lib/tools_dlg.tcl b/lib/tools_dlg.tcl\nnew file mode 100644\nindex 0000000..c221ba9\n--- /dev/null\n+++ b/lib/tools_dlg.tcl\n@@ -0,0 +1,234 @@\n+# git-gui Tools menu dialogs\n+\n+class tools_add {\n+\n+field w              ; # widget path\n+field w_name         ; # new remote name widget\n+field w_cmd          ; # new remote location widget\n+\n+field name         {}; # name of the tool\n+field command      {}; # command to execute\n+field add_global    0; # add to the --global config\n+field no_console    0; # disable using the console\n+field needs_file    0; # ensure filename is set\n+field confirm       0; # ask for confirmation\n+\n+constructor dialog {} {\n+\tglobal repo_config\n+\n+\tmake_toplevel top w\n+\twm title $top [append \"[appname] ([reponame]): \" [mc \"Add Tool\"]]\n+\tif {$top ne {.}} {\n+\t\twm geometry $top \"+[winfo rootx .]+[winfo rooty .]\"\n+\t\twm transient $top .\n+\t}\n+\n+\tlabel $w.header -text [mc \"Add New Tool Command\"] -font font_uibold\n+\tpack $w.header -side top -fill x\n+\n+\tframe $w.buttons\n+\tcheckbutton $w.buttons.global \\\n+\t\t-text [mc \"Add globally\"] \\\n+\t\t-variable @add_global\n+\tpack $w.buttons.global -side left -padx 5\n+\tbutton $w.buttons.create -text [mc Add] \\\n+\t\t-default active \\\n+\t\t-command [cb _add]\n+\tpack $w.buttons.create -side right\n+\tbutton $w.buttons.cancel -text [mc Cancel] \\\n+\t\t-command [list destroy $w]\n+\tpack $w.buttons.cancel -side right -padx 5\n+\tpack $w.buttons -side bottom -fill x -pady 10 -padx 10\n+\n+\tlabelframe $w.desc -text [mc \"Tool Details\"]\n+\n+\tlabel $w.desc.name_cmnt -anchor w\\\n+\t\t-text [mc \"Use '/' separators to create a submenu tree:\"]\n+\tgrid x $w.desc.name_cmnt -sticky we -padx {0 5} -pady {0 2}\n+\tlabel $w.desc.name_l -text [mc \"Name:\"]\n+\tset w_name $w.desc.name_t\n+\tentry $w_name \\\n+\t\t-borderwidth 1 \\\n+\t\t-relief sunken \\\n+\t\t-width 40 \\\n+\t\t-textvariable @name \\\n+\t\t-validate key \\\n+\t\t-validatecommand [cb _validate_name %d %S]\n+\tgrid $w.desc.name_l $w_name -sticky we -padx {0 5}\n+\n+\tlabel $w.desc.cmd_l -text [mc \"Command:\"]\n+\tset w_cmd $w.desc.cmd_t\n+\tentry $w_cmd \\\n+\t\t-borderwidth 1 \\\n+\t\t-relief sunken \\\n+\t\t-width 40 \\\n+\t\t-textvariable @command\n+\tgrid $w.desc.cmd_l $w_cmd -sticky we -padx {0 5} -pady {0 3}\n+\n+\tgrid columnconfigure $w.desc 1 -weight 1\n+\tpack $w.desc -anchor nw -fill x -pady 5 -padx 5\n+\n+\tcheckbutton $w.confirm \\\n+\t\t-text [mc \"Ask for confirmation before running\"] \\\n+\t\t-variable @confirm\n+\tpack $w.confirm -anchor w -pady {5 0} -padx 5\n+\n+\tcheckbutton $w.noconsole \\\n+\t\t-text [mc \"Don't show the command output window\"] \\\n+\t\t-variable @no_console\n+\tpack $w.noconsole -anchor w -padx 5\n+\n+\tcheckbutton $w.needsfile \\\n+\t\t-text [mc \"Run only if a diff is selected (\\$FILENAME not empty)\"] \\\n+\t\t-variable @needs_file\n+\tpack $w.needsfile -anchor w -padx 5\n+\n+\tbind $w <Visibility> [cb _visible]\n+\tbind $w <Key-Escape> [list destroy $w]\n+\tbind $w <Key-Return> [cb _add]\\;break\n+\ttkwait window $w\n+}\n+\n+method _add {} {\n+\tglobal repo_config\n+\n+\tif {$name eq {}} {\n+\t\terror_popup [mc \"Please supply a name for the tool.\"]\n+\t\tfocus $w_name\n+\t\treturn\n+\t}\n+\n+\tset item \"guitool.$name.cmd\"\n+\n+\tif {[info exists repo_config($item)]} {\n+\t\terror_popup [mc \"Tool '%s' already exists.\" $name]\n+\t\tfocus $w_name\n+\t\treturn\n+\t}\n+\n+\tset cmd [list git config]\n+\tif {$add_global} { lappend cmd --global }\n+\tset items {}\n+\tif {$no_console} { lappend items \"guitool.$name.noconsole\" }\n+\tif {$confirm}    { lappend items \"guitool.$name.confirm\" }\n+\tif {$needs_file} { lappend items \"guitool.$name.needsfile\" }\n+\n+\tif {[catch {\n+\t\teval $cmd [list $item $command]\n+\t\tforeach citem $items { eval $cmd [list $citem yes] }\n+\t    } err]} {\n+\t\terror_popup [mc \"Could not add tool:\\n%s\" $err]\n+\t} else {\n+\t\tset repo_config($item) $command\n+\t\tforeach citem $items { set repo_config($citem) yes }\n+\n+\t\ttools_populate_all\n+\t}\n+\n+\tdestroy $w\n+}\n+\n+method _validate_name {d S} {\n+\tif {$d == 1} {\n+\t\tif {[regexp {[~?*&\\[\\0\\\"\\\\\\{]} $S]} {\n+\t\t\treturn 0\n+\t\t}\n+\t}\n+\treturn 1\n+}\n+\n+method _visible {} {\n+\tgrab $w\n+\t$w_name icursor end\n+\tfocus $w_name\n+}\n+\n+}\n+\n+class tools_remove {\n+\n+field w              ; # widget path\n+field w_names        ; # name list\n+\n+constructor dialog {} {\n+\tglobal repo_config global_config system_config\n+\n+\tload_config 1\n+\n+\tmake_toplevel top w\n+\twm title $top [append \"[appname] ([reponame]): \" [mc \"Remove Tool\"]]\n+\tif {$top ne {.}} {\n+\t\twm geometry $top \"+[winfo rootx .]+[winfo rooty .]\"\n+\t\twm transient $top .\n+\t}\n+\n+\tlabel $w.header -text [mc \"Remove Tool Commands\"] -font font_uibold\n+\tpack $w.header -side top -fill x\n+\n+\tframe $w.buttons\n+\tbutton $w.buttons.create -text [mc Remove] \\\n+\t\t-default active \\\n+\t\t-command [cb _remove]\n+\tpack $w.buttons.create -side right\n+\tbutton $w.buttons.cancel -text [mc Cancel] \\\n+\t\t-command [list destroy $w]\n+\tpack $w.buttons.cancel -side right -padx 5\n+\tpack $w.buttons -side bottom -fill x -pady 10 -padx 10\n+\n+\tframe $w.list\n+\tset w_names $w.list.l\n+\tlistbox $w_names \\\n+\t\t-height 10 \\\n+\t\t-width 30 \\\n+\t\t-selectmode extended \\\n+\t\t-exportselection false \\\n+\t\t-yscrollcommand [list $w.list.sby set]\n+\tscrollbar $w.list.sby -command [list $w.list.l yview]\n+\tpack $w.list.sby -side right -fill y\n+\tpack $w.list.l -side left -fill both -expand 1\n+\tpack $w.list -fill both -expand 1 -pady 5 -padx 5\n+\n+\tset local_cnt 0\n+\tforeach fullname [tools_list] {\n+\t\t# Cannot delete system tools\n+\t\tif {[info exists system_config(guitool.$fullname.cmd)]} continue\n+\n+\t\t$w_names insert end $fullname\n+\t\tif {![info exists global_config(guitool.$fullname.cmd)]} {\n+\t\t\t$w_names itemconfigure end -foreground blue\n+\t\t\tincr local_cnt\n+\t\t}\n+\t}\n+\n+\tif {$local_cnt > 0} {\n+\t\tlabel $w.colorlbl -foreground blue \\\n+\t\t\t-text [mc \"(Blue denotes repository-local tools)\"]\n+\t\tpack $w.colorlbl -fill x -pady 5 -padx 5\n+\t}\n+\n+\tbind $w <Visibility> [cb _visible]\n+\tbind $w <Key-Escape> [list destroy $w]\n+\tbind $w <Key-Return> [cb _remove]\\;break\n+\ttkwait window $w\n+}\n+\n+method _remove {} {\n+\tforeach i [$w_names curselection] {\n+\t\tset name [$w_names get $i]\n+\n+\t\tcatch { git config --remove-section guitool.$name }\n+\t\tcatch { git config --global --remove-section guitool.$name }\n+\t}\n+\n+\tload_config 0\n+\ttools_populate_all\n+\n+\tdestroy $w\n+}\n+\n+method _visible {} {\n+\tgrab $w\n+\tfocus $w_names\n+}\n+\n+}\n-- \n1.6.0.3.15.gb8d36\n"},{"id":"95713","messageId":"1226604950-18667-4-git-send-email-angavrilov@gmail.com","threadId":"16313","inReplyTo":"1226604950-18667-3-git-send-email-angavrilov@gmail.com","subject":"[PATCH (GIT-GUI) 3/3] git-gui: Allow Tools to request arguments from the user.","fromName":"Alexander Gavrilov","fromEmail":"angavrilov@gmail.com","sentAt":"2008-11-13T19:35:50Z","receivedAt":"2008-11-13T19:35:50Z","isPatch":true,"sender":{"key":"angavrilov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42666?v=4"},"body":"While static commands are already useful, some tools need\nadditional parameters to reach maximum usability. This\ncommit adds support for passing them one revision name\nparameter, and one arbitrary string. With this addition,\nthe tools menu becomes flexible enough to implement basic\nrebase support:\n\n[core]\n        editor = kwrite\n[guitool \"Rebase/Abort\"]\n        cmd = git rebase --abort\n        confirm = yes\n[guitool \"Rebase/Continue\"]\n        cmd = git rebase --continue\n[guitool \"Rebase/Skip Commit\"]\n        cmd = git rebase --skip\n        confirm = yes\n[guitool \"Rebase/Start...\"]\n        cmd = git rebase $ARGS $REVISION $CUR_BRANCH\n        title = Start Rebase\n        prompt = Rebase Current Branch\n        argprompt = Flags\n        revprompt = New Base\n        revunmerged = yes\n\nSome of the options, like title or prompt, are intentionally\nnot included in the Add dialog to avoid clutter. Also, the\ndialog handles argprompt and revprompt as boolean vars.\n\nSigned-off-by: Alexander Gavrilov <angavrilov@gmail.com>\n---\n lib/tools.tcl     |   13 +++-\n lib/tools_dlg.tcl |  194 +++++++++++++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 202 insertions(+), 5 deletions(-)\n\ndiff --git a/lib/tools.tcl b/lib/tools.tcl\nindex 0bef503..9cb2dbc 100644\n--- a/lib/tools.tcl\n+++ b/lib/tools.tcl\n@@ -77,7 +77,16 @@ proc tools_exec {fullname} {\n \t\t}\n \t}\n \n-\tif {[is_config_true \"guitool.$fullname.confirm\"]} {\n+\tcatch { unset env(ARGS) }\n+\tcatch { unset env(REVISION) }\n+\n+\tif {[get_config \"guitool.$fullname.revprompt\"] ne {} ||\n+\t    [get_config \"guitool.$fullname.argprompt\"] ne {}} {\n+\t\tset dlg [tools_askdlg::dialog $fullname]\n+\t\tif {![tools_askdlg::execute $dlg]} {\n+\t\t\treturn\n+\t\t}\n+\t} elseif {[is_config_true \"guitool.$fullname.confirm\"]} {\n \t\tif {[ask_popup [mc \"Are you sure you want to run %s?\" $fullname]] ne {yes}} {\n \t\t\treturn\n \t\t}\n@@ -104,4 +113,6 @@ proc tools_exec {fullname} {\n \tunset env(GIT_GUITOOL)\n \tunset env(FILENAME)\n \tunset env(CUR_BRANCH)\n+\tcatch { unset env(ARGS) }\n+\tcatch { unset env(REVISION) }\n }\ndiff --git a/lib/tools_dlg.tcl b/lib/tools_dlg.tcl\nindex c221ba9..ca9a95f 100644\n--- a/lib/tools_dlg.tcl\n+++ b/lib/tools_dlg.tcl\n@@ -12,6 +12,8 @@ field add_global    0; # add to the --global config\n field no_console    0; # disable using the console\n field needs_file    0; # ensure filename is set\n field confirm       0; # ask for confirmation\n+field ask_branch    0; # ask for a revision\n+field ask_args      0; # ask for additional args\n \n constructor dialog {} {\n \tglobal repo_config\n@@ -69,9 +71,22 @@ constructor dialog {} {\n \tpack $w.desc -anchor nw -fill x -pady 5 -padx 5\n \n \tcheckbutton $w.confirm \\\n-\t\t-text [mc \"Ask for confirmation before running\"] \\\n-\t\t-variable @confirm\n-\tpack $w.confirm -anchor w -pady {5 0} -padx 5\n+\t\t-text [mc \"Show a dialog before running\"] \\\n+\t\t-variable @confirm -command [cb _check_enable_dlg]\n+\n+\tlabelframe $w.dlg -labelwidget $w.confirm\n+\n+\tcheckbutton $w.dlg.askbranch \\\n+\t\t-text [mc \"Ask the user to select a revision (sets \\$REVISION)\"] \\\n+\t\t-variable @ask_branch -state disabled\n+\tpack $w.dlg.askbranch -anchor w -padx 15\n+\n+\tcheckbutton $w.dlg.askargs \\\n+\t\t-text [mc \"Ask the user for additional arguments (sets \\$ARGS)\"] \\\n+\t\t-variable @ask_args -state disabled\n+\tpack $w.dlg.askargs -anchor w -padx 15\n+\n+\tpack $w.dlg -anchor nw -fill x -pady {0 8} -padx 5\n \n \tcheckbutton $w.noconsole \\\n \t\t-text [mc \"Don't show the command output window\"] \\\n@@ -89,6 +104,16 @@ constructor dialog {} {\n \ttkwait window $w\n }\n \n+method _check_enable_dlg {} {\n+\tif {$confirm} {\n+\t\t$w.dlg.askbranch configure -state normal\n+\t\t$w.dlg.askargs configure -state normal\n+\t} else {\n+\t\t$w.dlg.askbranch configure -state disabled\n+\t\t$w.dlg.askargs configure -state disabled\n+\t}\n+}\n+\n method _add {} {\n \tglobal repo_config\n \n@@ -110,8 +135,14 @@ method _add {} {\n \tif {$add_global} { lappend cmd --global }\n \tset items {}\n \tif {$no_console} { lappend items \"guitool.$name.noconsole\" }\n-\tif {$confirm}    { lappend items \"guitool.$name.confirm\" }\n \tif {$needs_file} { lappend items \"guitool.$name.needsfile\" }\n+\tif {$confirm} {\n+\t\tif {$ask_args}   { lappend items \"guitool.$name.argprompt\" }\n+\t\tif {$ask_branch} { lappend items \"guitool.$name.revprompt\" }\n+\t\tif {!$ask_args && !$ask_branch} {\n+\t\t\tlappend items \"guitool.$name.confirm\"\n+\t\t}\n+\t}\n \n \tif {[catch {\n \t\teval $cmd [list $item $command]\n@@ -232,3 +263,158 @@ method _visible {} {\n }\n \n }\n+\n+class tools_askdlg {\n+\n+field w              ; # widget path\n+field w_rev        {}; # revision browser\n+field w_args       {}; # arguments\n+\n+field is_ask_args   0; # has arguments field\n+field is_ask_revs   0; # has revision browser\n+\n+field is_ok         0; # ok to start\n+field argstr       {}; # arguments\n+\n+constructor dialog {fullname} {\n+\tglobal M1B\n+\n+\tset title [get_config \"guitool.$fullname.title\"]\n+\tif {$title eq {}} {\n+\t\tset title [mc \"Run Tool %s\" $fullname]\n+\t}\n+\n+\tmake_toplevel top w -autodelete 0\n+\twm title $top [append \"[appname] ([reponame]): \" $title]\n+\tif {$top ne {.}} {\n+\t\twm geometry $top \"+[winfo rootx .]+[winfo rooty .]\"\n+\t\twm transient $top .\n+\t}\n+\n+\tset prompt [get_config \"guitool.$fullname.prompt\"]\n+\tif {$prompt eq {}} {\n+\t\tset prompt [mc \"Run Tool Command %s\" $fullname]\n+\t}\n+\n+\tlabel $w.header -text $prompt -font font_uibold\n+\tpack $w.header -side top -fill x\n+\n+\tset argprompt [get_config \"guitool.$fullname.argprompt\"]\n+\tset revprompt [get_config \"guitool.$fullname.revprompt\"]\n+\n+\tset is_ask_args [expr {$argprompt ne {}}]\n+\tset is_ask_revs [expr {$revprompt ne {}}]\n+\n+\tif {$is_ask_args} {\n+\t\tif {$argprompt eq {yes} || $argprompt eq {true} || $argprompt eq {1}} {\n+\t\t\tset argprompt [mc \"Arguments\"]\n+\t\t}\n+\n+\t\tlabelframe $w.arg -text $argprompt\n+\n+\t\tset w_args $w.arg.txt\n+\t\tentry $w_args \\\n+\t\t\t-borderwidth 1 \\\n+\t\t\t-relief sunken \\\n+\t\t\t-width 40 \\\n+\t\t\t-textvariable @argstr\n+\t\tpack $w_args -padx 5 -pady 5 -fill both\n+\t\tpack $w.arg -anchor nw -fill both -pady 5 -padx 5\n+\t}\n+\n+\tif {$is_ask_revs} {\n+\t\tif {$revprompt eq {yes} || $revprompt eq {true} || $revprompt eq {1}} {\n+\t\t\tset revprompt [mc \"Revision\"]\n+\t\t}\n+\n+\t\tif {[is_config_true \"guitool.$fullname.revunmerged\"]} {\n+\t\t\tset w_rev [::choose_rev::new_unmerged $w.rev $revprompt]\n+\t\t} else {\n+\t\t\tset w_rev [::choose_rev::new $w.rev $revprompt]\n+\t\t}\n+\n+\t\tpack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5\n+\t}\n+\n+\tframe $w.buttons\n+\tif {$is_ask_revs} {\n+\t\tbutton $w.buttons.visualize \\\n+\t\t\t-text [mc Visualize] \\\n+\t\t\t-command [cb _visualize]\n+\t\tpack $w.buttons.visualize -side left\n+\t}\n+\tbutton $w.buttons.ok \\\n+\t\t-text [mc OK] \\\n+\t\t-command [cb _start]\n+\tpack $w.buttons.ok -side right\n+\tbutton $w.buttons.cancel \\\n+\t\t-text [mc \"Cancel\"] \\\n+\t\t-command [cb _cancel]\n+\tpack $w.buttons.cancel -side right -padx 5\n+\tpack $w.buttons -side bottom -fill x -pady 10 -padx 10\n+\n+\tbind $w <$M1B-Key-Return> [cb _start]\n+\tbind $w <Key-Return> [cb _start]\n+\tbind $w <Key-Escape> [cb _cancel]\n+\twm protocol $w WM_DELETE_WINDOW [cb _cancel]\n+\n+\tbind $w <Visibility> [cb _visible]\n+\treturn $this\n+}\n+\n+method execute {} {\n+\ttkwait window $w\n+\tset rv $is_ok\n+\tdelete_this\n+\treturn $rv\n+}\n+\n+method _visible {} {\n+\tgrab $w\n+\tif {$is_ask_args} {\n+\t\tfocus $w_args\n+\t} elseif {$is_ask_revs} {\n+\t\t$w_rev focus_filter\n+\t}\n+}\n+\n+method _cancel {} {\n+\twm protocol $w WM_DELETE_WINDOW {}\n+\tdestroy $w\n+}\n+\n+method _rev {} {\n+\tif {[catch {$w_rev commit_or_die}]} {\n+\t\treturn {}\n+\t}\n+\treturn [$w_rev get]\n+}\n+\n+method _visualize {} {\n+\tglobal current_branch\n+\tset rev [_rev $this]\n+\tif {$rev ne {}} {\n+\t\tdo_gitk [list --left-right \"$current_branch...$rev\"]\n+\t}\n+}\n+\n+method _start {} {\n+\tglobal env\n+\n+\tif {$is_ask_revs} {\n+\t\tset name [_rev $this]\n+\t\tif {$name eq {}} {\n+\t\t\treturn\n+\t\t}\n+\t\tset env(REVISION) $name\n+\t}\n+\n+\tif {$is_ask_args} {\n+\t\tset env(ARGS) $argstr\n+\t}\n+\n+\tset is_ok 1\n+\t_cancel $this\n+}\n+\n+}\n-- \n1.6.0.3.15.gb8d36\n"}]}