git-gui: Refactor the delete branch dialog to use class system
authorShawn O. Pearce <spearce@spearce.org>
Wed, 4 Jul 2007 03:33:59 +0000 (23:33 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Mon, 9 Jul 2007 01:12:47 +0000 (21:12 -0400)
A simple refactoring of the delete branch dialog to allow use of
the class construct to better organize the code and to reuse the
revision selection code of our new choose_rev mega-widget.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui.sh
lib/branch.tcl
lib/branch_delete.tcl [new file with mode: 0644]
lib/choose_rev.tcl

index e07f4babd0c6eedb81f0ebd91ace0ab6aa25b0a7..63b2045d96b87b414edfe04dd5f0d951c1f7b233 100755 (executable)
@@ -1507,7 +1507,7 @@ if {[is_enabled branch]} {
                [.mbar.branch index last] -state]
 
        .mbar.branch add command -label {Delete...} \
-               -command do_delete_branch
+               -command branch_delete::dialog
        lappend disable_on_lock [list .mbar.branch entryconf \
                [.mbar.branch index last] -state]
 
index e7559f978912c143453391bca98330818cc13394..e56f674c6dc3348d9ee9e23e8424947fa4a321e7 100644 (file)
@@ -66,170 +66,6 @@ proc radio_selector {varname value args} {
        set var $value
 }
 
-proc do_delete_branch_action {w} {
-       global all_heads
-       global delete_branch_checktype delete_branch_head delete_branch_trackinghead
-
-       set check_rev {}
-       switch -- $delete_branch_checktype {
-       head {set check_rev $delete_branch_head}
-       tracking {set check_rev $delete_branch_trackinghead}
-       always {set check_rev {:none}}
-       }
-       if {$check_rev eq {:none}} {
-               set check_cmt {}
-       } elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} {
-               tk_messageBox \
-                       -icon error \
-                       -type ok \
-                       -title [wm title $w] \
-                       -parent $w \
-                       -message "Invalid check revision: $check_rev"
-               return
-       }
-
-       set to_delete [list]
-       set not_merged [list]
-       foreach i [$w.list.l curselection] {
-               set b [$w.list.l get $i]
-               if {[catch {set o [git rev-parse --verify $b]}]} continue
-               if {$check_cmt ne {}} {
-                       if {$b eq $check_rev} continue
-                       if {[catch {set m [git merge-base $o $check_cmt]}]} continue
-                       if {$o ne $m} {
-                               lappend not_merged $b
-                               continue
-                       }
-               }
-               lappend to_delete [list $b $o]
-       }
-       if {$not_merged ne {}} {
-               set msg "The following branches are not completely merged into $check_rev:
-
- - [join $not_merged "\n - "]"
-               tk_messageBox \
-                       -icon info \
-                       -type ok \
-                       -title [wm title $w] \
-                       -parent $w \
-                       -message $msg
-       }
-       if {$to_delete eq {}} return
-       if {$delete_branch_checktype eq {always}} {
-               set msg {Recovering deleted branches is difficult.
-
-Delete the selected branches?}
-               if {[tk_messageBox \
-                       -icon warning \
-                       -type yesno \
-                       -title [wm title $w] \
-                       -parent $w \
-                       -message $msg] ne yes} {
-                       return
-               }
-       }
-
-       set failed {}
-       foreach i $to_delete {
-               set b [lindex $i 0]
-               set o [lindex $i 1]
-               if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
-                       append failed " - $b: $err\n"
-               } else {
-                       set x [lsearch -sorted -exact $all_heads $b]
-                       if {$x >= 0} {
-                               set all_heads [lreplace $all_heads $x $x]
-                       }
-               }
-       }
-
-       if {$failed ne {}} {
-               tk_messageBox \
-                       -icon error \
-                       -type ok \
-                       -title [wm title $w] \
-                       -parent $w \
-                       -message "Failed to delete branches:\n$failed"
-       }
-
-       set all_heads [lsort $all_heads]
-       populate_branch_menu
-       destroy $w
-}
-
-proc do_delete_branch {} {
-       global all_heads tracking_branches current_branch
-       global delete_branch_checktype delete_branch_head delete_branch_trackinghead
-
-       set w .branch_editor
-       toplevel $w
-       wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
-
-       label $w.header -text {Delete Local Branch} \
-               -font font_uibold
-       pack $w.header -side top -fill x
-
-       frame $w.buttons
-       button $w.buttons.create -text Delete \
-               -command [list do_delete_branch_action $w]
-       pack $w.buttons.create -side right
-       button $w.buttons.cancel -text {Cancel} \
-               -command [list destroy $w]
-       pack $w.buttons.cancel -side right -padx 5
-       pack $w.buttons -side bottom -fill x -pady 10 -padx 10
-
-       labelframe $w.list -text {Local Branches}
-       listbox $w.list.l \
-               -height 10 \
-               -width 70 \
-               -selectmode extended \
-               -yscrollcommand [list $w.list.sby set]
-       foreach h $all_heads {
-               if {$h ne $current_branch} {
-                       $w.list.l insert end $h
-               }
-       }
-       scrollbar $w.list.sby -command [list $w.list.l yview]
-       pack $w.list.sby -side right -fill y
-       pack $w.list.l -side left -fill both -expand 1
-       pack $w.list -fill both -expand 1 -pady 5 -padx 5
-
-       labelframe $w.validate -text {Delete Only If}
-       radiobutton $w.validate.head_r \
-               -text {Merged Into Local Branch:} \
-               -value head \
-               -variable delete_branch_checktype
-       eval tk_optionMenu $w.validate.head_m delete_branch_head $all_heads
-       grid $w.validate.head_r $w.validate.head_m -sticky w
-       set all_trackings [all_tracking_branches]
-       if {$all_trackings ne {}} {
-               set delete_branch_trackinghead [lindex $all_trackings 0]
-               radiobutton $w.validate.tracking_r \
-                       -text {Merged Into Tracking Branch:} \
-                       -value tracking \
-                       -variable delete_branch_checktype
-               eval tk_optionMenu $w.validate.tracking_m \
-                       delete_branch_trackinghead \
-                       $all_trackings
-               grid $w.validate.tracking_r $w.validate.tracking_m -sticky w
-       }
-       radiobutton $w.validate.always_r \
-               -text {Always (Do not perform merge checks)} \
-               -value always \
-               -variable delete_branch_checktype
-       grid $w.validate.always_r -columnspan 2 -sticky w
-       grid columnconfigure $w.validate 1 -weight 1
-       pack $w.validate -anchor nw -fill x -pady 5 -padx 5
-
-       set delete_branch_head $current_branch
-       set delete_branch_checktype head
-
-       bind $w <Visibility> "grab $w; focus $w"
-       bind $w <Key-Escape> "destroy $w"
-       wm title $w "[appname] ([reponame]): Delete Branch"
-       tkwait window $w
-}
-
 proc switch_branch {new_branch} {
        global HEAD commit_type current_branch repo_config
 
diff --git a/lib/branch_delete.tcl b/lib/branch_delete.tcl
new file mode 100644 (file)
index 0000000..16ca693
--- /dev/null
@@ -0,0 +1,163 @@
+# git-gui branch delete support
+# Copyright (C) 2007 Shawn Pearce
+
+class branch_delete {
+
+field w               ; # widget path
+field w_heads         ; # listbox of local head names
+field w_check         ; # revision picker for merge test
+field w_delete        ; # delete button
+
+constructor dialog {} {
+       global all_heads current_branch
+
+       make_toplevel top w
+       wm title $top "[appname] ([reponame]): Delete Branch"
+       if {$top ne {.}} {
+               wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+       }
+
+       label $w.header -text {Delete Local Branch} -font font_uibold
+       pack $w.header -side top -fill x
+
+       frame $w.buttons
+       set w_delete $w.buttons.delete
+       button $w_delete \
+               -text Delete \
+               -default active \
+               -state disabled \
+               -command [cb _delete]
+       pack $w_delete -side right
+       button $w.buttons.cancel \
+               -text {Cancel} \
+               -command [list destroy $w]
+       pack $w.buttons.cancel -side right -padx 5
+       pack $w.buttons -side bottom -fill x -pady 10 -padx 10
+
+       labelframe $w.list -text {Local Branches}
+       set w_heads $w.list.l
+       listbox $w_heads \
+               -height 10 \
+               -width 70 \
+               -selectmode extended \
+               -yscrollcommand [list $w.list.sby set]
+       scrollbar $w.list.sby -command [list $w.list.l yview]
+       pack $w.list.sby -side right -fill y
+       pack $w.list.l -side left -fill both -expand 1
+       pack $w.list -fill both -expand 1 -pady 5 -padx 5
+
+       set w_check [choose_rev::new \
+               $w.check \
+               {Delete Only If Merged Into} \
+               ]
+       $w_check none {Always (Do not perform merge test.)}
+       pack $w.check -anchor nw -fill x -pady 5 -padx 5
+
+       foreach h $all_heads {
+               if {$h ne $current_branch} {
+                       $w_heads insert end $h
+               }
+       }
+
+       bind $w_heads <<ListboxSelect>> [cb _select]
+       bind $w <Visibility> "
+               grab $w
+               focus $w
+       "
+       bind $w <Key-Escape> [list destroy $w]
+       bind $w <Key-Return> [cb _delete]\;break
+       tkwait window $w
+}
+
+method _select {} {
+       if {[$w_heads curselection] eq {}} {
+               $w_delete configure -state disabled
+       } else {
+               $w_delete configure -state normal
+       }
+}
+
+method _delete {} {
+       global all_heads
+
+       if {[catch {set check_cmt [$w_check get_commit]} err]} {
+               tk_messageBox \
+                       -icon error \
+                       -type ok \
+                       -title [wm title $w] \
+                       -parent $w \
+                       -message "Invalid revision: [$w_check get]"
+               return
+       }
+
+       set to_delete [list]
+       set not_merged [list]
+       foreach i [$w_heads curselection] {
+               set b [$w_heads get $i]
+               if {[catch {
+                       set o [git rev-parse --verify "refs/heads/$b"]
+               }]} continue
+               if {$check_cmt ne {}} {
+                       if {[catch {set m [git merge-base $o $check_cmt]}]} continue
+                       if {$o ne $m} {
+                               lappend not_merged $b
+                               continue
+                       }
+               }
+               lappend to_delete [list $b $o]
+       }
+       if {$not_merged ne {}} {
+               set msg "The following branches are not completely merged into [$w_check get]:
+
+ - [join $not_merged "\n - "]"
+               tk_messageBox \
+                       -icon info \
+                       -type ok \
+                       -title [wm title $w] \
+                       -parent $w \
+                       -message $msg
+       }
+       if {$to_delete eq {}} return
+       if {$check_cmt eq {}} {
+               set msg {Recovering deleted branches is difficult.
+
+Delete the selected branches?}
+               if {[tk_messageBox \
+                       -icon warning \
+                       -type yesno \
+                       -title [wm title $w] \
+                       -parent $w \
+                       -message $msg] ne yes} {
+                       return
+               }
+       }
+
+       set failed {}
+       foreach i $to_delete {
+               set b [lindex $i 0]
+               set o [lindex $i 1]
+               if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
+                       append failed " - $b: $err\n"
+               } else {
+                       set x [lsearch -sorted -exact $all_heads $b]
+                       if {$x >= 0} {
+                               set all_heads [lreplace $all_heads $x $x]
+                       }
+               }
+       }
+
+       if {$failed ne {}} {
+               tk_messageBox \
+                       -icon error \
+                       -type ok \
+                       -title [wm title $w] \
+                       -parent $w \
+                       -message "Failed to delete branches:\n$failed"
+       }
+
+       set all_heads [lsort $all_heads]
+       populate_branch_menu
+       destroy $w
+}
+
+}
index 04f77c009296c88093db5eed5ca0b8647440e0c9..01e8efe991599901a5b90b65ec333a3063af635d 100644 (file)
@@ -87,17 +87,38 @@ constructor new {path {title {}}} {
        return $this
 }
 
+method none {text} {
+       if {[winfo exists $w.none_r]} {
+               $w.none_r configure -text $text
+               return
+       }
+
+       radiobutton $w.none_r \
+               -anchor w \
+               -text $text \
+               -value none \
+               -variable @revtype
+       grid $w.none_r -sticky we -padx {0 5} -columnspan 2
+       if {$revtype eq {}} {
+               set revtype none
+       }
+}
+
 method get {} {
        switch -- $revtype {
        head { return $c_head }
        trck { return $c_trck }
        tag  { return $c_tag  }
        expr { return $c_expr }
+       none { return {}      }
        default { error "unknown type of revision" }
        }
 }
 
 method get_commit {} {
+       if {$revtype eq {none}} {
+               return {}
+       }
        set rev [get $this]
        return [git rev-parse --verify "${rev}^0"]
 }