about summary refs log tree commit diff
path: root/git-gui/lib/console.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'git-gui/lib/console.tcl')
-rw-r--r--git-gui/lib/console.tcl223
1 files changed, 223 insertions, 0 deletions
diff --git a/git-gui/lib/console.tcl b/git-gui/lib/console.tcl
new file mode 100644
index 000000000000..1f3248ffd113
--- /dev/null
+++ b/git-gui/lib/console.tcl
@@ -0,0 +1,223 @@
+# git-gui console support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+class console {
+
+field t_short
+field t_long
+field w
+field w_t
+field console_cr
+field is_toplevel    1; # are we our own window?
+
+constructor new {short_title long_title} {
+	set t_short $short_title
+	set t_long $long_title
+	_init $this
+	return $this
+}
+
+constructor embed {path title} {
+	set t_short {}
+	set t_long $title
+	set w $path
+	set is_toplevel 0
+	_init $this
+	return $this
+}
+
+method _init {} {
+	global M1B use_ttk NS
+
+	if {$is_toplevel} {
+		make_dialog top w -autodelete 0
+		wm title $top "[appname] ([reponame]): $t_short"
+	} else {
+		${NS}::frame $w
+	}
+
+	set console_cr 1.0
+	set w_t $w.m.t
+
+	${NS}::frame $w.m
+	${NS}::label $w.m.l1 \
+		-textvariable @t_long  \
+		-anchor w \
+		-justify left \
+		-font font_uibold
+	text $w_t \
+		-background white \
+		-foreground black \
+		-borderwidth 1 \
+		-relief sunken \
+		-width 80 -height 10 \
+		-wrap none \
+		-font font_diff \
+		-state disabled \
+		-xscrollcommand [cb _sb_set $w.m.sbx h] \
+		-yscrollcommand [cb _sb_set $w.m.sby v]
+	label $w.m.s -text [mc "Working... please wait..."] \
+		-anchor w \
+		-justify left \
+		-font font_uibold
+	pack $w.m.l1 -side top -fill x
+	pack $w.m.s -side bottom -fill x
+	pack $w_t -side left -fill both -expand 1
+	pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
+
+	menu $w.ctxm -tearoff 0
+	$w.ctxm add command -label [mc "Copy"] \
+		-command "tk_textCopy $w_t"
+	$w.ctxm add command -label [mc "Select All"] \
+		-command "focus $w_t;$w_t tag add sel 0.0 end"
+	$w.ctxm add command -label [mc "Copy All"] \
+		-command "
+			$w_t tag add sel 0.0 end
+			tk_textCopy $w_t
+			$w_t tag remove sel 0.0 end
+		"
+
+	if {$is_toplevel} {
+		${NS}::button $w.ok -text [mc "Close"] \
+			-state disabled \
+			-command [list destroy $w]
+		pack $w.ok -side bottom -anchor e -pady 10 -padx 10
+		bind $w <Visibility> [list focus $w]
+	}
+
+	bind_button3 $w_t "tk_popup $w.ctxm %X %Y"
+	bind $w_t <$M1B-Key-a> "$w_t tag add sel 0.0 end;break"
+	bind $w_t <$M1B-Key-A> "$w_t tag add sel 0.0 end;break"
+}
+
+method exec {cmd {after {}}} {
+	if {[lindex $cmd 0] eq {git}} {
+		set fd_f [eval git_read --stderr [lrange $cmd 1 end]]
+	} else {
+		lappend cmd 2>@1
+		set fd_f [_open_stdout_stderr $cmd]
+	}
+	fconfigure $fd_f -blocking 0 -translation binary
+	fileevent $fd_f readable [cb _read $fd_f $after]
+}
+
+method _read {fd after} {
+	set buf [read $fd]
+	if {$buf ne {}} {
+		if {![winfo exists $w_t]} {_init $this}
+		$w_t conf -state normal
+		set c 0
+		set n [string length $buf]
+		while {$c < $n} {
+			set cr [string first "\r" $buf $c]
+			set lf [string first "\n" $buf $c]
+			if {$cr < 0} {set cr [expr {$n + 1}]}
+			if {$lf < 0} {set lf [expr {$n + 1}]}
+
+			if {$lf < $cr} {
+				$w_t insert end [string range $buf $c $lf]
+				set console_cr [$w_t index {end -1c}]
+				set c $lf
+				incr c
+			} else {
+				$w_t delete $console_cr end
+				$w_t insert end "\n"
+				$w_t insert end [string range $buf $c [expr {$cr - 1}]]
+				set c $cr
+				incr c
+			}
+		}
+		$w_t conf -state disabled
+		$w_t see end
+	}
+
+	fconfigure $fd -blocking 1
+	if {[eof $fd]} {
+		if {[catch {close $fd}]} {
+			set ok 0
+		} else {
+			set ok 1
+		}
+		if {$after ne {}} {
+			uplevel #0 $after $ok
+		} else {
+			done $this $ok
+		}
+		return
+	}
+	fconfigure $fd -blocking 0
+}
+
+method chain {cmdlist {ok 1}} {
+	if {$ok} {
+		if {[llength $cmdlist] == 0} {
+			done $this $ok
+			return
+		}
+
+		set cmd [lindex $cmdlist 0]
+		set cmdlist [lrange $cmdlist 1 end]
+
+		if {[lindex $cmd 0] eq {exec}} {
+			exec $this \
+				[lrange $cmd 1 end] \
+				[cb chain $cmdlist]
+		} else {
+			uplevel #0 $cmd [cb chain $cmdlist]
+		}
+	} else {
+		done $this $ok
+	}
+}
+
+method insert {txt} {
+	if {![winfo exists $w_t]} {_init $this}
+	$w_t conf -state normal
+	$w_t insert end "$txt\n"
+	set console_cr [$w_t index {end -1c}]
+	$w_t conf -state disabled
+}
+
+method done {ok} {
+	if {$ok} {
+		if {[winfo exists $w.m.s]} {
+			bind $w.m.s <Destroy> [list delete_this $this]
+			$w.m.s conf -background green -foreground black \
+				-text [mc "Success"]
+			if {$is_toplevel} {
+				$w.ok conf -state normal
+				focus $w.ok
+			}
+		} else {
+			delete_this
+		}
+	} else {
+		if {![winfo exists $w.m.s]} {
+			_init $this
+		}
+		bind $w.m.s <Destroy> [list delete_this $this]
+		$w.m.s conf -background red -foreground black \
+			-text [mc "Error: Command Failed"]
+		if {$is_toplevel} {
+			$w.ok conf -state normal
+			focus $w.ok
+		}
+	}
+}
+
+method _sb_set {sb orient first last} {
+	global NS
+	if {![winfo exists $sb]} {
+		if {$first == $last || ($first == 0 && $last == 1)} return
+		if {$orient eq {h}} {
+			${NS}::scrollbar $sb -orient h -command [list $w_t xview]
+			pack $sb -fill x -side bottom -before $w_t
+		} else {
+			${NS}::scrollbar $sb -orient v -command [list $w_t yview]
+			pack $sb -fill y -side right -before $w_t
+		}
+	}
+	$sb set $first $last
+}
+
+}